1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>. */
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;; The special asm out single letter directives following a '%' are:
30 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; F,f -- likewise, but for floating-point.
34 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
36 ;; R -- print the prefix for register names.
37 ;; z -- print the opcode suffix for the size of the current operand.
38 ;; Z -- likewise, with special suffixes for x87 instructions.
39 ;; * -- print a star (in certain assembler syntax)
40 ;; A -- print an absolute memory reference.
41 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
42 ;; s -- print a shift double count, followed by the assemblers argument
44 ;; b -- print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; w -- likewise, print the HImode name of the register.
47 ;; k -- likewise, print the SImode name of the register.
48 ;; q -- likewise, print the DImode name of the register.
49 ;; x -- likewise, print the V4SFmode name of the register.
50 ;; t -- likewise, print the V8SFmode name of the register.
51 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
52 ;; y -- print "st(0)" instead of "st" as a register.
53 ;; d -- print duplicated register operand for AVX instruction.
54 ;; D -- print condition for SSE cmp instruction.
55 ;; P -- if PIC, print an @PLT suffix.
56 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; Y -- print condition for XOP pcom* instruction.
60 ;; + -- print a branch hint as 'cs' or 'ds' prefix
61 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
62 ;; @ -- print a segment register of thread base pointer load
66 (define_c_enum "unspec" [
67 ;; Relocation specifiers
78 UNSPEC_MACHOPIC_OFFSET
87 UNSPEC_MEMORY_BLOCKAGE
96 ;; Other random patterns
105 UNSPEC_LD_MPIC ; load_macho_picbase
107 UNSPEC_DIV_ALREADY_SPLIT
109 ;; For SSE/MMX support:
127 UNSPEC_MS_TO_SYSV_CALL
129 ;; Generic math support
131 UNSPEC_IEEE_MIN ; not commutative
132 UNSPEC_IEEE_MAX ; not commutative
134 ;; x87 Floating point
150 UNSPEC_FRNDINT_MASK_PM
154 ;; x87 Double output FP
186 ;; For SSE4.1 support
196 ;; For SSE4.2 support
202 UNSPEC_FMA4_INTRINSIC
205 UNSPEC_XOP_UNSIGNED_CMP
216 UNSPEC_AESKEYGENASSIST
218 ;; For PCLMUL support
234 (define_c_enum "unspecv" [
237 UNSPECV_PROBE_STACK_RANGE
257 UNSPECV_LLWP_INTRINSIC
258 UNSPECV_SLWP_INTRINSIC
259 UNSPECV_LWPVAL_INTRINSIC
260 UNSPECV_LWPINS_INTRINSIC
268 ;; Constants to represent pcomtrue/pcomfalse variants
278 ;; Constants used in the XOP pperm instruction
280 [(PPERM_SRC 0x00) /* copy source */
281 (PPERM_INVERT 0x20) /* invert source */
282 (PPERM_REVERSE 0x40) /* bit reverse source */
283 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
284 (PPERM_ZERO 0x80) /* all 0's */
285 (PPERM_ONES 0xa0) /* all 1's */
286 (PPERM_SIGN 0xc0) /* propagate sign bit */
287 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
288 (PPERM_SRC1 0x00) /* use first source byte */
289 (PPERM_SRC2 0x10) /* use second source byte */
292 ;; Registers by name.
345 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
348 ;; In C guard expressions, put expressions which may be compile-time
349 ;; constants first. This allows for better optimization. For
350 ;; example, write "TARGET_64BIT && reload_completed", not
351 ;; "reload_completed && TARGET_64BIT".
355 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,atom,
356 generic64,amdfam10,bdver1"
357 (const (symbol_ref "ix86_schedule")))
359 ;; A basic instruction type. Refinements due to arguments to be
360 ;; provided in other attributes.
363 alu,alu1,negnot,imov,imovx,lea,
364 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
365 icmp,test,ibr,setcc,icmov,
366 push,pop,call,callv,leave,
368 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
369 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
370 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
371 ssemuladd,sse4arg,lwp,
372 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
373 (const_string "other"))
375 ;; Main data type used by the insn
377 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
378 (const_string "unknown"))
380 ;; The CPU unit operations uses.
381 (define_attr "unit" "integer,i387,sse,mmx,unknown"
382 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
383 (const_string "i387")
384 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
385 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
386 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
388 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
390 (eq_attr "type" "other")
391 (const_string "unknown")]
392 (const_string "integer")))
394 ;; The (bounding maximum) length of an instruction immediate.
395 (define_attr "length_immediate" ""
396 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
399 (eq_attr "unit" "i387,sse,mmx")
401 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
403 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
404 (eq_attr "type" "imov,test")
405 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
406 (eq_attr "type" "call")
407 (if_then_else (match_operand 0 "constant_call_address_operand" "")
410 (eq_attr "type" "callv")
411 (if_then_else (match_operand 1 "constant_call_address_operand" "")
414 ;; We don't know the size before shorten_branches. Expect
415 ;; the instruction to fit for better scheduling.
416 (eq_attr "type" "ibr")
419 (symbol_ref "/* Update immediate_length and other attributes! */
420 gcc_unreachable (),1")))
422 ;; The (bounding maximum) length of an instruction address.
423 (define_attr "length_address" ""
424 (cond [(eq_attr "type" "str,other,multi,fxch")
426 (and (eq_attr "type" "call")
427 (match_operand 0 "constant_call_address_operand" ""))
429 (and (eq_attr "type" "callv")
430 (match_operand 1 "constant_call_address_operand" ""))
433 (symbol_ref "ix86_attr_length_address_default (insn)")))
435 ;; Set when length prefix is used.
436 (define_attr "prefix_data16" ""
437 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
439 (eq_attr "mode" "HI")
441 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
446 ;; Set when string REP prefix is used.
447 (define_attr "prefix_rep" ""
448 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
450 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
455 ;; Set when 0f opcode prefix is used.
456 (define_attr "prefix_0f" ""
458 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
459 (eq_attr "unit" "sse,mmx"))
463 ;; Set when REX opcode prefix is used.
464 (define_attr "prefix_rex" ""
465 (cond [(eq (symbol_ref "TARGET_64BIT") (const_int 0))
467 (and (eq_attr "mode" "DI")
468 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
469 (eq_attr "unit" "!mmx")))
471 (and (eq_attr "mode" "QI")
472 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
475 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
478 (and (eq_attr "type" "imovx")
479 (match_operand:QI 1 "ext_QIreg_operand" ""))
484 ;; There are also additional prefixes in 3DNOW, SSSE3.
485 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
486 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
487 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
488 (define_attr "prefix_extra" ""
489 (cond [(eq_attr "type" "ssemuladd,sse4arg")
491 (eq_attr "type" "sseiadd1,ssecvt1")
496 ;; Prefix used: original, VEX or maybe VEX.
497 (define_attr "prefix" "orig,vex,maybe_vex"
498 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
500 (const_string "orig")))
502 ;; VEX W bit is used.
503 (define_attr "prefix_vex_w" "" (const_int 0))
505 ;; The length of VEX prefix
506 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
507 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
508 ;; still prefix_0f 1, with prefix_extra 1.
509 (define_attr "length_vex" ""
510 (if_then_else (and (eq_attr "prefix_0f" "1")
511 (eq_attr "prefix_extra" "0"))
512 (if_then_else (eq_attr "prefix_vex_w" "1")
513 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
514 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
515 (if_then_else (eq_attr "prefix_vex_w" "1")
516 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
517 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
519 ;; Set when modrm byte is used.
520 (define_attr "modrm" ""
521 (cond [(eq_attr "type" "str,leave")
523 (eq_attr "unit" "i387")
525 (and (eq_attr "type" "incdec")
526 (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
527 (ior (match_operand:SI 1 "register_operand" "")
528 (match_operand:HI 1 "register_operand" ""))))
530 (and (eq_attr "type" "push")
531 (not (match_operand 1 "memory_operand" "")))
533 (and (eq_attr "type" "pop")
534 (not (match_operand 0 "memory_operand" "")))
536 (and (eq_attr "type" "imov")
537 (and (not (eq_attr "mode" "DI"))
538 (ior (and (match_operand 0 "register_operand" "")
539 (match_operand 1 "immediate_operand" ""))
540 (ior (and (match_operand 0 "ax_reg_operand" "")
541 (match_operand 1 "memory_displacement_only_operand" ""))
542 (and (match_operand 0 "memory_displacement_only_operand" "")
543 (match_operand 1 "ax_reg_operand" ""))))))
545 (and (eq_attr "type" "call")
546 (match_operand 0 "constant_call_address_operand" ""))
548 (and (eq_attr "type" "callv")
549 (match_operand 1 "constant_call_address_operand" ""))
551 (and (eq_attr "type" "alu,alu1,icmp,test")
552 (match_operand 0 "ax_reg_operand" ""))
553 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
557 ;; The (bounding maximum) length of an instruction in bytes.
558 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
559 ;; Later we may want to split them and compute proper length as for
561 (define_attr "length" ""
562 (cond [(eq_attr "type" "other,multi,fistp,frndint")
564 (eq_attr "type" "fcmp")
566 (eq_attr "unit" "i387")
568 (plus (attr "prefix_data16")
569 (attr "length_address")))
570 (ior (eq_attr "prefix" "vex")
571 (and (eq_attr "prefix" "maybe_vex")
572 (ne (symbol_ref "TARGET_AVX") (const_int 0))))
573 (plus (attr "length_vex")
574 (plus (attr "length_immediate")
576 (attr "length_address"))))]
577 (plus (plus (attr "modrm")
578 (plus (attr "prefix_0f")
579 (plus (attr "prefix_rex")
580 (plus (attr "prefix_extra")
582 (plus (attr "prefix_rep")
583 (plus (attr "prefix_data16")
584 (plus (attr "length_immediate")
585 (attr "length_address")))))))
587 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
588 ;; `store' if there is a simple memory reference therein, or `unknown'
589 ;; if the instruction is complex.
591 (define_attr "memory" "none,load,store,both,unknown"
592 (cond [(eq_attr "type" "other,multi,str,lwp")
593 (const_string "unknown")
594 (eq_attr "type" "lea,fcmov,fpspc")
595 (const_string "none")
596 (eq_attr "type" "fistp,leave")
597 (const_string "both")
598 (eq_attr "type" "frndint")
599 (const_string "load")
600 (eq_attr "type" "push")
601 (if_then_else (match_operand 1 "memory_operand" "")
602 (const_string "both")
603 (const_string "store"))
604 (eq_attr "type" "pop")
605 (if_then_else (match_operand 0 "memory_operand" "")
606 (const_string "both")
607 (const_string "load"))
608 (eq_attr "type" "setcc")
609 (if_then_else (match_operand 0 "memory_operand" "")
610 (const_string "store")
611 (const_string "none"))
612 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
613 (if_then_else (ior (match_operand 0 "memory_operand" "")
614 (match_operand 1 "memory_operand" ""))
615 (const_string "load")
616 (const_string "none"))
617 (eq_attr "type" "ibr")
618 (if_then_else (match_operand 0 "memory_operand" "")
619 (const_string "load")
620 (const_string "none"))
621 (eq_attr "type" "call")
622 (if_then_else (match_operand 0 "constant_call_address_operand" "")
623 (const_string "none")
624 (const_string "load"))
625 (eq_attr "type" "callv")
626 (if_then_else (match_operand 1 "constant_call_address_operand" "")
627 (const_string "none")
628 (const_string "load"))
629 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
630 (match_operand 1 "memory_operand" ""))
631 (const_string "both")
632 (and (match_operand 0 "memory_operand" "")
633 (match_operand 1 "memory_operand" ""))
634 (const_string "both")
635 (match_operand 0 "memory_operand" "")
636 (const_string "store")
637 (match_operand 1 "memory_operand" "")
638 (const_string "load")
640 "!alu1,negnot,ishift1,
641 imov,imovx,icmp,test,bitmanip,
643 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
644 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
645 (match_operand 2 "memory_operand" ""))
646 (const_string "load")
647 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
648 (match_operand 3 "memory_operand" ""))
649 (const_string "load")
651 (const_string "none")))
653 ;; Indicates if an instruction has both an immediate and a displacement.
655 (define_attr "imm_disp" "false,true,unknown"
656 (cond [(eq_attr "type" "other,multi")
657 (const_string "unknown")
658 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
659 (and (match_operand 0 "memory_displacement_operand" "")
660 (match_operand 1 "immediate_operand" "")))
661 (const_string "true")
662 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
663 (and (match_operand 0 "memory_displacement_operand" "")
664 (match_operand 2 "immediate_operand" "")))
665 (const_string "true")
667 (const_string "false")))
669 ;; Indicates if an FP operation has an integer source.
671 (define_attr "fp_int_src" "false,true"
672 (const_string "false"))
674 ;; Defines rounding mode of an FP operation.
676 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
677 (const_string "any"))
679 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
680 (define_attr "use_carry" "0,1" (const_string "0"))
682 ;; Define attribute to indicate unaligned ssemov insns
683 (define_attr "movu" "0,1" (const_string "0"))
685 ;; Describe a user's asm statement.
686 (define_asm_attributes
687 [(set_attr "length" "128")
688 (set_attr "type" "multi")])
690 (define_code_iterator plusminus [plus minus])
692 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
694 ;; Base name for define_insn
695 (define_code_attr plusminus_insn
696 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
697 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
699 ;; Base name for insn mnemonic.
700 (define_code_attr plusminus_mnemonic
701 [(plus "add") (ss_plus "adds") (us_plus "addus")
702 (minus "sub") (ss_minus "subs") (us_minus "subus")])
703 (define_code_attr plusminus_carry_mnemonic
704 [(plus "adc") (minus "sbb")])
706 ;; Mark commutative operators as such in constraints.
707 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
708 (minus "") (ss_minus "") (us_minus "")])
710 ;; Mapping of signed max and min
711 (define_code_iterator smaxmin [smax smin])
713 ;; Mapping of unsigned max and min
714 (define_code_iterator umaxmin [umax umin])
716 ;; Base name for integer and FP insn mnemonic
717 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
718 (umax "maxu") (umin "minu")])
719 (define_code_attr maxmin_float [(smax "max") (smin "min")])
721 ;; Mapping of logic operators
722 (define_code_iterator any_logic [and ior xor])
723 (define_code_iterator any_or [ior xor])
725 ;; Base name for insn mnemonic.
726 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
728 ;; Mapping of shift-right operators
729 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
731 ;; Base name for define_insn
732 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
734 ;; Base name for insn mnemonic.
735 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
737 ;; Mapping of rotate operators
738 (define_code_iterator any_rotate [rotate rotatert])
740 ;; Base name for define_insn
741 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
743 ;; Base name for insn mnemonic.
744 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
746 ;; Mapping of abs neg operators
747 (define_code_iterator absneg [abs neg])
749 ;; Base name for x87 insn mnemonic.
750 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
752 ;; Used in signed and unsigned widening multiplications.
753 (define_code_iterator any_extend [sign_extend zero_extend])
755 ;; Various insn prefixes for signed and unsigned operations.
756 (define_code_attr u [(sign_extend "") (zero_extend "u")
757 (div "") (udiv "u")])
758 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
760 ;; Used in signed and unsigned divisions.
761 (define_code_iterator any_div [div udiv])
763 ;; Instruction prefix for signed and unsigned operations.
764 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
765 (div "i") (udiv "")])
767 ;; 64bit single word integer modes.
768 (define_mode_iterator SWI1248x [QI HI SI DI])
770 ;; 64bit single word integer modes without QImode and HImode.
771 (define_mode_iterator SWI48x [SI DI])
773 ;; Single word integer modes.
774 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
776 ;; Single word integer modes without SImode and DImode.
777 (define_mode_iterator SWI12 [QI HI])
779 ;; Single word integer modes without DImode.
780 (define_mode_iterator SWI124 [QI HI SI])
782 ;; Single word integer modes without QImode and DImode.
783 (define_mode_iterator SWI24 [HI SI])
785 ;; Single word integer modes without QImode.
786 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
788 ;; Single word integer modes without QImode and HImode.
789 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
791 ;; All math-dependant single and double word integer modes.
792 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
793 (HI "TARGET_HIMODE_MATH")
794 SI DI (TI "TARGET_64BIT")])
796 ;; Math-dependant single word integer modes.
797 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
798 (HI "TARGET_HIMODE_MATH")
799 SI (DI "TARGET_64BIT")])
801 ;; Math-dependant single word integer modes without DImode.
802 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
803 (HI "TARGET_HIMODE_MATH")
806 ;; Math-dependant single word integer modes without QImode.
807 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
808 SI (DI "TARGET_64BIT")])
810 ;; Double word integer modes.
811 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
812 (TI "TARGET_64BIT")])
814 ;; Double word integer modes as mode attribute.
815 (define_mode_attr DWI [(SI "DI") (DI "TI")])
816 (define_mode_attr dwi [(SI "di") (DI "ti")])
818 ;; Half mode for double word integer modes.
819 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
820 (DI "TARGET_64BIT")])
822 ;; Instruction suffix for integer modes.
823 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
825 ;; Pointer size prefix for integer modes (Intel asm dialect)
826 (define_mode_attr iptrsize [(QI "BYTE")
831 ;; Register class for integer modes.
832 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
834 ;; Immediate operand constraint for integer modes.
835 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
837 ;; General operand constraint for word modes.
838 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
840 ;; Immediate operand constraint for double integer modes.
841 (define_mode_attr di [(SI "iF") (DI "e")])
843 ;; Immediate operand constraint for shifts.
844 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
846 ;; General operand predicate for integer modes.
847 (define_mode_attr general_operand
848 [(QI "general_operand")
849 (HI "general_operand")
850 (SI "general_operand")
851 (DI "x86_64_general_operand")
852 (TI "x86_64_general_operand")])
854 ;; General sign/zero extend operand predicate for integer modes.
855 (define_mode_attr general_szext_operand
856 [(QI "general_operand")
857 (HI "general_operand")
858 (SI "general_operand")
859 (DI "x86_64_szext_general_operand")])
861 ;; Immediate operand predicate for integer modes.
862 (define_mode_attr immediate_operand
863 [(QI "immediate_operand")
864 (HI "immediate_operand")
865 (SI "immediate_operand")
866 (DI "x86_64_immediate_operand")])
868 ;; Nonmemory operand predicate for integer modes.
869 (define_mode_attr nonmemory_operand
870 [(QI "nonmemory_operand")
871 (HI "nonmemory_operand")
872 (SI "nonmemory_operand")
873 (DI "x86_64_nonmemory_operand")])
875 ;; Operand predicate for shifts.
876 (define_mode_attr shift_operand
877 [(QI "nonimmediate_operand")
878 (HI "nonimmediate_operand")
879 (SI "nonimmediate_operand")
880 (DI "shiftdi_operand")
881 (TI "register_operand")])
883 ;; Operand predicate for shift argument.
884 (define_mode_attr shift_immediate_operand
885 [(QI "const_1_to_31_operand")
886 (HI "const_1_to_31_operand")
887 (SI "const_1_to_31_operand")
888 (DI "const_1_to_63_operand")])
890 ;; Input operand predicate for arithmetic left shifts.
891 (define_mode_attr ashl_input_operand
892 [(QI "nonimmediate_operand")
893 (HI "nonimmediate_operand")
894 (SI "nonimmediate_operand")
895 (DI "ashldi_input_operand")
896 (TI "reg_or_pm1_operand")])
898 ;; SSE and x87 SFmode and DFmode floating point modes
899 (define_mode_iterator MODEF [SF DF])
901 ;; All x87 floating point modes
902 (define_mode_iterator X87MODEF [SF DF XF])
904 ;; All integer modes handled by x87 fisttp operator.
905 (define_mode_iterator X87MODEI [HI SI DI])
907 ;; All integer modes handled by integer x87 operators.
908 (define_mode_iterator X87MODEI12 [HI SI])
910 ;; All integer modes handled by SSE cvtts?2si* operators.
911 (define_mode_iterator SSEMODEI24 [SI DI])
913 ;; SSE asm suffix for floating point modes
914 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
916 ;; SSE vector mode corresponding to a scalar mode
917 (define_mode_attr ssevecmode
918 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
920 ;; Instruction suffix for REX 64bit operators.
921 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
923 ;; This mode iterator allows :P to be used for patterns that operate on
924 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
925 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
927 ;; Scheduling descriptions
929 (include "pentium.md")
932 (include "athlon.md")
937 ;; Operand and operator predicates and constraints
939 (include "predicates.md")
940 (include "constraints.md")
943 ;; Compare and branch/compare and store instructions.
945 (define_expand "cbranch<mode>4"
946 [(set (reg:CC FLAGS_REG)
947 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
948 (match_operand:SDWIM 2 "<general_operand>" "")))
949 (set (pc) (if_then_else
950 (match_operator 0 "ordered_comparison_operator"
951 [(reg:CC FLAGS_REG) (const_int 0)])
952 (label_ref (match_operand 3 "" ""))
956 if (MEM_P (operands[1]) && MEM_P (operands[2]))
957 operands[1] = force_reg (<MODE>mode, operands[1]);
958 ix86_expand_branch (GET_CODE (operands[0]),
959 operands[1], operands[2], operands[3]);
963 (define_expand "cstore<mode>4"
964 [(set (reg:CC FLAGS_REG)
965 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
966 (match_operand:SWIM 3 "<general_operand>" "")))
967 (set (match_operand:QI 0 "register_operand" "")
968 (match_operator 1 "ordered_comparison_operator"
969 [(reg:CC FLAGS_REG) (const_int 0)]))]
972 if (MEM_P (operands[2]) && MEM_P (operands[3]))
973 operands[2] = force_reg (<MODE>mode, operands[2]);
974 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
975 operands[2], operands[3]);
979 (define_expand "cmp<mode>_1"
980 [(set (reg:CC FLAGS_REG)
981 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
982 (match_operand:SWI48 1 "<general_operand>" "")))])
984 (define_insn "*cmp<mode>_ccno_1"
985 [(set (reg FLAGS_REG)
986 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
987 (match_operand:SWI 1 "const0_operand" "")))]
988 "ix86_match_ccmode (insn, CCNOmode)"
990 test{<imodesuffix>}\t%0, %0
991 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
992 [(set_attr "type" "test,icmp")
993 (set_attr "length_immediate" "0,1")
994 (set_attr "mode" "<MODE>")])
996 (define_insn "*cmp<mode>_1"
997 [(set (reg FLAGS_REG)
998 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
999 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1000 "ix86_match_ccmode (insn, CCmode)"
1001 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1002 [(set_attr "type" "icmp")
1003 (set_attr "mode" "<MODE>")])
1005 (define_insn "*cmp<mode>_minus_1"
1006 [(set (reg FLAGS_REG)
1008 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1009 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1011 "ix86_match_ccmode (insn, CCGOCmode)"
1012 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1013 [(set_attr "type" "icmp")
1014 (set_attr "mode" "<MODE>")])
1016 (define_insn "*cmpqi_ext_1"
1017 [(set (reg FLAGS_REG)
1019 (match_operand:QI 0 "general_operand" "Qm")
1022 (match_operand 1 "ext_register_operand" "Q")
1024 (const_int 8)) 0)))]
1025 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1026 "cmp{b}\t{%h1, %0|%0, %h1}"
1027 [(set_attr "type" "icmp")
1028 (set_attr "mode" "QI")])
1030 (define_insn "*cmpqi_ext_1_rex64"
1031 [(set (reg FLAGS_REG)
1033 (match_operand:QI 0 "register_operand" "Q")
1036 (match_operand 1 "ext_register_operand" "Q")
1038 (const_int 8)) 0)))]
1039 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1040 "cmp{b}\t{%h1, %0|%0, %h1}"
1041 [(set_attr "type" "icmp")
1042 (set_attr "mode" "QI")])
1044 (define_insn "*cmpqi_ext_2"
1045 [(set (reg FLAGS_REG)
1049 (match_operand 0 "ext_register_operand" "Q")
1052 (match_operand:QI 1 "const0_operand" "")))]
1053 "ix86_match_ccmode (insn, CCNOmode)"
1055 [(set_attr "type" "test")
1056 (set_attr "length_immediate" "0")
1057 (set_attr "mode" "QI")])
1059 (define_expand "cmpqi_ext_3"
1060 [(set (reg:CC FLAGS_REG)
1064 (match_operand 0 "ext_register_operand" "")
1067 (match_operand:QI 1 "immediate_operand" "")))])
1069 (define_insn "*cmpqi_ext_3_insn"
1070 [(set (reg FLAGS_REG)
1074 (match_operand 0 "ext_register_operand" "Q")
1077 (match_operand:QI 1 "general_operand" "Qmn")))]
1078 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1079 "cmp{b}\t{%1, %h0|%h0, %1}"
1080 [(set_attr "type" "icmp")
1081 (set_attr "modrm" "1")
1082 (set_attr "mode" "QI")])
1084 (define_insn "*cmpqi_ext_3_insn_rex64"
1085 [(set (reg FLAGS_REG)
1089 (match_operand 0 "ext_register_operand" "Q")
1092 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1093 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1094 "cmp{b}\t{%1, %h0|%h0, %1}"
1095 [(set_attr "type" "icmp")
1096 (set_attr "modrm" "1")
1097 (set_attr "mode" "QI")])
1099 (define_insn "*cmpqi_ext_4"
1100 [(set (reg FLAGS_REG)
1104 (match_operand 0 "ext_register_operand" "Q")
1109 (match_operand 1 "ext_register_operand" "Q")
1111 (const_int 8)) 0)))]
1112 "ix86_match_ccmode (insn, CCmode)"
1113 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1114 [(set_attr "type" "icmp")
1115 (set_attr "mode" "QI")])
1117 ;; These implement float point compares.
1118 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1119 ;; which would allow mix and match FP modes on the compares. Which is what
1120 ;; the old patterns did, but with many more of them.
1122 (define_expand "cbranchxf4"
1123 [(set (reg:CC FLAGS_REG)
1124 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1125 (match_operand:XF 2 "nonmemory_operand" "")))
1126 (set (pc) (if_then_else
1127 (match_operator 0 "ix86_fp_comparison_operator"
1130 (label_ref (match_operand 3 "" ""))
1134 ix86_expand_branch (GET_CODE (operands[0]),
1135 operands[1], operands[2], operands[3]);
1139 (define_expand "cstorexf4"
1140 [(set (reg:CC FLAGS_REG)
1141 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1142 (match_operand:XF 3 "nonmemory_operand" "")))
1143 (set (match_operand:QI 0 "register_operand" "")
1144 (match_operator 1 "ix86_fp_comparison_operator"
1149 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1150 operands[2], operands[3]);
1154 (define_expand "cbranch<mode>4"
1155 [(set (reg:CC FLAGS_REG)
1156 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1157 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1158 (set (pc) (if_then_else
1159 (match_operator 0 "ix86_fp_comparison_operator"
1162 (label_ref (match_operand 3 "" ""))
1164 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1166 ix86_expand_branch (GET_CODE (operands[0]),
1167 operands[1], operands[2], operands[3]);
1171 (define_expand "cstore<mode>4"
1172 [(set (reg:CC FLAGS_REG)
1173 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1174 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1175 (set (match_operand:QI 0 "register_operand" "")
1176 (match_operator 1 "ix86_fp_comparison_operator"
1179 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1181 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1182 operands[2], operands[3]);
1186 (define_expand "cbranchcc4"
1187 [(set (pc) (if_then_else
1188 (match_operator 0 "comparison_operator"
1189 [(match_operand 1 "flags_reg_operand" "")
1190 (match_operand 2 "const0_operand" "")])
1191 (label_ref (match_operand 3 "" ""))
1195 ix86_expand_branch (GET_CODE (operands[0]),
1196 operands[1], operands[2], operands[3]);
1200 (define_expand "cstorecc4"
1201 [(set (match_operand:QI 0 "register_operand" "")
1202 (match_operator 1 "comparison_operator"
1203 [(match_operand 2 "flags_reg_operand" "")
1204 (match_operand 3 "const0_operand" "")]))]
1207 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1208 operands[2], operands[3]);
1213 ;; FP compares, step 1:
1214 ;; Set the FP condition codes.
1216 ;; CCFPmode compare with exceptions
1217 ;; CCFPUmode compare with no exceptions
1219 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1220 ;; used to manage the reg stack popping would not be preserved.
1222 (define_insn "*cmpfp_0"
1223 [(set (match_operand:HI 0 "register_operand" "=a")
1226 (match_operand 1 "register_operand" "f")
1227 (match_operand 2 "const0_operand" ""))]
1229 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1230 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1231 "* return output_fp_compare (insn, operands, 0, 0);"
1232 [(set_attr "type" "multi")
1233 (set_attr "unit" "i387")
1235 (cond [(match_operand:SF 1 "" "")
1237 (match_operand:DF 1 "" "")
1240 (const_string "XF")))])
1242 (define_insn_and_split "*cmpfp_0_cc"
1243 [(set (reg:CCFP FLAGS_REG)
1245 (match_operand 1 "register_operand" "f")
1246 (match_operand 2 "const0_operand" "")))
1247 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1248 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1249 && TARGET_SAHF && !TARGET_CMOVE
1250 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1252 "&& reload_completed"
1255 [(compare:CCFP (match_dup 1)(match_dup 2))]
1257 (set (reg:CC FLAGS_REG)
1258 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1260 [(set_attr "type" "multi")
1261 (set_attr "unit" "i387")
1263 (cond [(match_operand:SF 1 "" "")
1265 (match_operand:DF 1 "" "")
1268 (const_string "XF")))])
1270 (define_insn "*cmpfp_xf"
1271 [(set (match_operand:HI 0 "register_operand" "=a")
1274 (match_operand:XF 1 "register_operand" "f")
1275 (match_operand:XF 2 "register_operand" "f"))]
1278 "* return output_fp_compare (insn, operands, 0, 0);"
1279 [(set_attr "type" "multi")
1280 (set_attr "unit" "i387")
1281 (set_attr "mode" "XF")])
1283 (define_insn_and_split "*cmpfp_xf_cc"
1284 [(set (reg:CCFP FLAGS_REG)
1286 (match_operand:XF 1 "register_operand" "f")
1287 (match_operand:XF 2 "register_operand" "f")))
1288 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1290 && TARGET_SAHF && !TARGET_CMOVE"
1292 "&& reload_completed"
1295 [(compare:CCFP (match_dup 1)(match_dup 2))]
1297 (set (reg:CC FLAGS_REG)
1298 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1300 [(set_attr "type" "multi")
1301 (set_attr "unit" "i387")
1302 (set_attr "mode" "XF")])
1304 (define_insn "*cmpfp_<mode>"
1305 [(set (match_operand:HI 0 "register_operand" "=a")
1308 (match_operand:MODEF 1 "register_operand" "f")
1309 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1312 "* return output_fp_compare (insn, operands, 0, 0);"
1313 [(set_attr "type" "multi")
1314 (set_attr "unit" "i387")
1315 (set_attr "mode" "<MODE>")])
1317 (define_insn_and_split "*cmpfp_<mode>_cc"
1318 [(set (reg:CCFP FLAGS_REG)
1320 (match_operand:MODEF 1 "register_operand" "f")
1321 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1322 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1324 && TARGET_SAHF && !TARGET_CMOVE"
1326 "&& reload_completed"
1329 [(compare:CCFP (match_dup 1)(match_dup 2))]
1331 (set (reg:CC FLAGS_REG)
1332 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1334 [(set_attr "type" "multi")
1335 (set_attr "unit" "i387")
1336 (set_attr "mode" "<MODE>")])
1338 (define_insn "*cmpfp_u"
1339 [(set (match_operand:HI 0 "register_operand" "=a")
1342 (match_operand 1 "register_operand" "f")
1343 (match_operand 2 "register_operand" "f"))]
1345 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1346 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1347 "* return output_fp_compare (insn, operands, 0, 1);"
1348 [(set_attr "type" "multi")
1349 (set_attr "unit" "i387")
1351 (cond [(match_operand:SF 1 "" "")
1353 (match_operand:DF 1 "" "")
1356 (const_string "XF")))])
1358 (define_insn_and_split "*cmpfp_u_cc"
1359 [(set (reg:CCFPU FLAGS_REG)
1361 (match_operand 1 "register_operand" "f")
1362 (match_operand 2 "register_operand" "f")))
1363 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1364 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1365 && TARGET_SAHF && !TARGET_CMOVE
1366 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1368 "&& reload_completed"
1371 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1373 (set (reg:CC FLAGS_REG)
1374 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1376 [(set_attr "type" "multi")
1377 (set_attr "unit" "i387")
1379 (cond [(match_operand:SF 1 "" "")
1381 (match_operand:DF 1 "" "")
1384 (const_string "XF")))])
1386 (define_insn "*cmpfp_<mode>"
1387 [(set (match_operand:HI 0 "register_operand" "=a")
1390 (match_operand 1 "register_operand" "f")
1391 (match_operator 3 "float_operator"
1392 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1394 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1395 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1396 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1397 "* return output_fp_compare (insn, operands, 0, 0);"
1398 [(set_attr "type" "multi")
1399 (set_attr "unit" "i387")
1400 (set_attr "fp_int_src" "true")
1401 (set_attr "mode" "<MODE>")])
1403 (define_insn_and_split "*cmpfp_<mode>_cc"
1404 [(set (reg:CCFP FLAGS_REG)
1406 (match_operand 1 "register_operand" "f")
1407 (match_operator 3 "float_operator"
1408 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1409 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1410 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1411 && TARGET_SAHF && !TARGET_CMOVE
1412 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1413 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1415 "&& reload_completed"
1420 (match_op_dup 3 [(match_dup 2)]))]
1422 (set (reg:CC FLAGS_REG)
1423 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1425 [(set_attr "type" "multi")
1426 (set_attr "unit" "i387")
1427 (set_attr "fp_int_src" "true")
1428 (set_attr "mode" "<MODE>")])
1430 ;; FP compares, step 2
1431 ;; Move the fpsw to ax.
1433 (define_insn "x86_fnstsw_1"
1434 [(set (match_operand:HI 0 "register_operand" "=a")
1435 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1438 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1439 (set_attr "mode" "SI")
1440 (set_attr "unit" "i387")])
1442 ;; FP compares, step 3
1443 ;; Get ax into flags, general case.
1445 (define_insn "x86_sahf_1"
1446 [(set (reg:CC FLAGS_REG)
1447 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1451 #ifndef HAVE_AS_IX86_SAHF
1453 return ASM_BYTE "0x9e";
1458 [(set_attr "length" "1")
1459 (set_attr "athlon_decode" "vector")
1460 (set_attr "amdfam10_decode" "direct")
1461 (set_attr "mode" "SI")])
1463 ;; Pentium Pro can do steps 1 through 3 in one go.
1464 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1465 (define_insn "*cmpfp_i_mixed"
1466 [(set (reg:CCFP FLAGS_REG)
1467 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1468 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1469 "TARGET_MIX_SSE_I387
1470 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1471 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1472 "* return output_fp_compare (insn, operands, 1, 0);"
1473 [(set_attr "type" "fcmp,ssecomi")
1474 (set_attr "prefix" "orig,maybe_vex")
1476 (if_then_else (match_operand:SF 1 "" "")
1478 (const_string "DF")))
1479 (set (attr "prefix_rep")
1480 (if_then_else (eq_attr "type" "ssecomi")
1482 (const_string "*")))
1483 (set (attr "prefix_data16")
1484 (cond [(eq_attr "type" "fcmp")
1486 (eq_attr "mode" "DF")
1489 (const_string "0")))
1490 (set_attr "athlon_decode" "vector")
1491 (set_attr "amdfam10_decode" "direct")])
1493 (define_insn "*cmpfp_i_sse"
1494 [(set (reg:CCFP FLAGS_REG)
1495 (compare:CCFP (match_operand 0 "register_operand" "x")
1496 (match_operand 1 "nonimmediate_operand" "xm")))]
1498 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1499 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1500 "* return output_fp_compare (insn, operands, 1, 0);"
1501 [(set_attr "type" "ssecomi")
1502 (set_attr "prefix" "maybe_vex")
1504 (if_then_else (match_operand:SF 1 "" "")
1506 (const_string "DF")))
1507 (set_attr "prefix_rep" "0")
1508 (set (attr "prefix_data16")
1509 (if_then_else (eq_attr "mode" "DF")
1511 (const_string "0")))
1512 (set_attr "athlon_decode" "vector")
1513 (set_attr "amdfam10_decode" "direct")])
1515 (define_insn "*cmpfp_i_i387"
1516 [(set (reg:CCFP FLAGS_REG)
1517 (compare:CCFP (match_operand 0 "register_operand" "f")
1518 (match_operand 1 "register_operand" "f")))]
1519 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1521 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1522 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1523 "* return output_fp_compare (insn, operands, 1, 0);"
1524 [(set_attr "type" "fcmp")
1526 (cond [(match_operand:SF 1 "" "")
1528 (match_operand:DF 1 "" "")
1531 (const_string "XF")))
1532 (set_attr "athlon_decode" "vector")
1533 (set_attr "amdfam10_decode" "direct")])
1535 (define_insn "*cmpfp_iu_mixed"
1536 [(set (reg:CCFPU FLAGS_REG)
1537 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1538 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1539 "TARGET_MIX_SSE_I387
1540 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1541 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1542 "* return output_fp_compare (insn, operands, 1, 1);"
1543 [(set_attr "type" "fcmp,ssecomi")
1544 (set_attr "prefix" "orig,maybe_vex")
1546 (if_then_else (match_operand:SF 1 "" "")
1548 (const_string "DF")))
1549 (set (attr "prefix_rep")
1550 (if_then_else (eq_attr "type" "ssecomi")
1552 (const_string "*")))
1553 (set (attr "prefix_data16")
1554 (cond [(eq_attr "type" "fcmp")
1556 (eq_attr "mode" "DF")
1559 (const_string "0")))
1560 (set_attr "athlon_decode" "vector")
1561 (set_attr "amdfam10_decode" "direct")])
1563 (define_insn "*cmpfp_iu_sse"
1564 [(set (reg:CCFPU FLAGS_REG)
1565 (compare:CCFPU (match_operand 0 "register_operand" "x")
1566 (match_operand 1 "nonimmediate_operand" "xm")))]
1568 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1569 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1570 "* return output_fp_compare (insn, operands, 1, 1);"
1571 [(set_attr "type" "ssecomi")
1572 (set_attr "prefix" "maybe_vex")
1574 (if_then_else (match_operand:SF 1 "" "")
1576 (const_string "DF")))
1577 (set_attr "prefix_rep" "0")
1578 (set (attr "prefix_data16")
1579 (if_then_else (eq_attr "mode" "DF")
1581 (const_string "0")))
1582 (set_attr "athlon_decode" "vector")
1583 (set_attr "amdfam10_decode" "direct")])
1585 (define_insn "*cmpfp_iu_387"
1586 [(set (reg:CCFPU FLAGS_REG)
1587 (compare:CCFPU (match_operand 0 "register_operand" "f")
1588 (match_operand 1 "register_operand" "f")))]
1589 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1591 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1592 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1593 "* return output_fp_compare (insn, operands, 1, 1);"
1594 [(set_attr "type" "fcmp")
1596 (cond [(match_operand:SF 1 "" "")
1598 (match_operand:DF 1 "" "")
1601 (const_string "XF")))
1602 (set_attr "athlon_decode" "vector")
1603 (set_attr "amdfam10_decode" "direct")])
1605 ;; Push/pop instructions.
1607 (define_insn "*pushdi2_rex64"
1608 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1609 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1614 [(set_attr "type" "push,multi")
1615 (set_attr "mode" "DI")])
1617 ;; Convert impossible pushes of immediate to existing instructions.
1618 ;; First try to get scratch register and go through it. In case this
1619 ;; fails, push sign extended lower part first and then overwrite
1620 ;; upper part by 32bit move.
1622 [(match_scratch:DI 2 "r")
1623 (set (match_operand:DI 0 "push_operand" "")
1624 (match_operand:DI 1 "immediate_operand" ""))]
1625 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1626 && !x86_64_immediate_operand (operands[1], DImode)"
1627 [(set (match_dup 2) (match_dup 1))
1628 (set (match_dup 0) (match_dup 2))])
1630 ;; We need to define this as both peepholer and splitter for case
1631 ;; peephole2 pass is not run.
1632 ;; "&& 1" is needed to keep it from matching the previous pattern.
1634 [(set (match_operand:DI 0 "push_operand" "")
1635 (match_operand:DI 1 "immediate_operand" ""))]
1636 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1637 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1638 [(set (match_dup 0) (match_dup 1))
1639 (set (match_dup 2) (match_dup 3))]
1641 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1643 operands[1] = gen_lowpart (DImode, operands[2]);
1644 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1649 [(set (match_operand:DI 0 "push_operand" "")
1650 (match_operand:DI 1 "immediate_operand" ""))]
1651 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1652 ? epilogue_completed : reload_completed)
1653 && !symbolic_operand (operands[1], DImode)
1654 && !x86_64_immediate_operand (operands[1], DImode)"
1655 [(set (match_dup 0) (match_dup 1))
1656 (set (match_dup 2) (match_dup 3))]
1658 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1660 operands[1] = gen_lowpart (DImode, operands[2]);
1661 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1665 (define_insn "*pushdi2"
1666 [(set (match_operand:DI 0 "push_operand" "=<")
1667 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1672 [(set (match_operand:DI 0 "push_operand" "")
1673 (match_operand:DI 1 "general_operand" ""))]
1674 "!TARGET_64BIT && reload_completed
1675 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1677 "ix86_split_long_move (operands); DONE;")
1679 (define_insn "*pushsi2"
1680 [(set (match_operand:SI 0 "push_operand" "=<")
1681 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1684 [(set_attr "type" "push")
1685 (set_attr "mode" "SI")])
1687 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1688 ;; "push a byte/word". But actually we use pushl, which has the effect
1689 ;; of rounding the amount pushed up to a word.
1691 ;; For TARGET_64BIT we always round up to 8 bytes.
1692 (define_insn "*push<mode>2_rex64"
1693 [(set (match_operand:SWI124 0 "push_operand" "=X")
1694 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1697 [(set_attr "type" "push")
1698 (set_attr "mode" "DI")])
1700 (define_insn "*push<mode>2"
1701 [(set (match_operand:SWI12 0 "push_operand" "=X")
1702 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1705 [(set_attr "type" "push")
1706 (set_attr "mode" "SI")])
1708 (define_insn "*push<mode>2_prologue"
1709 [(set (match_operand:P 0 "push_operand" "=<")
1710 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1711 (clobber (mem:BLK (scratch)))]
1713 "push{<imodesuffix>}\t%1"
1714 [(set_attr "type" "push")
1715 (set_attr "mode" "<MODE>")])
1717 (define_insn "*pop<mode>1"
1718 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1719 (match_operand:P 1 "pop_operand" ">"))]
1721 "pop{<imodesuffix>}\t%0"
1722 [(set_attr "type" "pop")
1723 (set_attr "mode" "<MODE>")])
1725 (define_insn "*pop<mode>1_epilogue"
1726 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1727 (match_operand:P 1 "pop_operand" ">"))
1728 (clobber (mem:BLK (scratch)))]
1730 "pop{<imodesuffix>}\t%0"
1731 [(set_attr "type" "pop")
1732 (set_attr "mode" "<MODE>")])
1734 ;; Move instructions.
1736 (define_expand "movoi"
1737 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1738 (match_operand:OI 1 "general_operand" ""))]
1740 "ix86_expand_move (OImode, operands); DONE;")
1742 (define_expand "movti"
1743 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1744 (match_operand:TI 1 "nonimmediate_operand" ""))]
1745 "TARGET_64BIT || TARGET_SSE"
1748 ix86_expand_move (TImode, operands);
1749 else if (push_operand (operands[0], TImode))
1750 ix86_expand_push (TImode, operands[1]);
1752 ix86_expand_vector_move (TImode, operands);
1756 ;; This expands to what emit_move_complex would generate if we didn't
1757 ;; have a movti pattern. Having this avoids problems with reload on
1758 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1759 ;; to have around all the time.
1760 (define_expand "movcdi"
1761 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1762 (match_operand:CDI 1 "general_operand" ""))]
1765 if (push_operand (operands[0], CDImode))
1766 emit_move_complex_push (CDImode, operands[0], operands[1]);
1768 emit_move_complex_parts (operands[0], operands[1]);
1772 (define_expand "mov<mode>"
1773 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1774 (match_operand:SWI1248x 1 "general_operand" ""))]
1776 "ix86_expand_move (<MODE>mode, operands); DONE;")
1778 (define_insn "*mov<mode>_xor"
1779 [(set (match_operand:SWI48 0 "register_operand" "=r")
1780 (match_operand:SWI48 1 "const0_operand" ""))
1781 (clobber (reg:CC FLAGS_REG))]
1784 [(set_attr "type" "alu1")
1785 (set_attr "mode" "SI")
1786 (set_attr "length_immediate" "0")])
1788 (define_insn "*mov<mode>_or"
1789 [(set (match_operand:SWI48 0 "register_operand" "=r")
1790 (match_operand:SWI48 1 "const_int_operand" ""))
1791 (clobber (reg:CC FLAGS_REG))]
1793 && operands[1] == constm1_rtx"
1794 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1795 [(set_attr "type" "alu1")
1796 (set_attr "mode" "<MODE>")
1797 (set_attr "length_immediate" "1")])
1799 (define_insn "*movoi_internal_avx"
1800 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1801 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1802 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1804 switch (which_alternative)
1807 return "vxorps\t%0, %0, %0";
1810 if (misaligned_operand (operands[0], OImode)
1811 || misaligned_operand (operands[1], OImode))
1812 return "vmovdqu\t{%1, %0|%0, %1}";
1814 return "vmovdqa\t{%1, %0|%0, %1}";
1819 [(set_attr "type" "sselog1,ssemov,ssemov")
1820 (set_attr "prefix" "vex")
1821 (set_attr "mode" "OI")])
1823 (define_insn "*movti_internal_rex64"
1824 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1825 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1826 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1828 switch (which_alternative)
1834 if (get_attr_mode (insn) == MODE_V4SF)
1835 return "%vxorps\t%0, %d0";
1837 return "%vpxor\t%0, %d0";
1840 /* TDmode values are passed as TImode on the stack. Moving them
1841 to stack may result in unaligned memory access. */
1842 if (misaligned_operand (operands[0], TImode)
1843 || misaligned_operand (operands[1], TImode))
1845 if (get_attr_mode (insn) == MODE_V4SF)
1846 return "%vmovups\t{%1, %0|%0, %1}";
1848 return "%vmovdqu\t{%1, %0|%0, %1}";
1852 if (get_attr_mode (insn) == MODE_V4SF)
1853 return "%vmovaps\t{%1, %0|%0, %1}";
1855 return "%vmovdqa\t{%1, %0|%0, %1}";
1861 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1862 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1864 (cond [(eq_attr "alternative" "2,3")
1866 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1868 (const_string "V4SF")
1869 (const_string "TI"))
1870 (eq_attr "alternative" "4")
1872 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1874 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1876 (const_string "V4SF")
1877 (const_string "TI"))]
1878 (const_string "DI")))])
1881 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1882 (match_operand:TI 1 "general_operand" ""))]
1884 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1886 "ix86_split_long_move (operands); DONE;")
1888 (define_insn "*movti_internal_sse"
1889 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1890 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1891 "TARGET_SSE && !TARGET_64BIT
1892 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1894 switch (which_alternative)
1897 if (get_attr_mode (insn) == MODE_V4SF)
1898 return "%vxorps\t%0, %d0";
1900 return "%vpxor\t%0, %d0";
1903 /* TDmode values are passed as TImode on the stack. Moving them
1904 to stack may result in unaligned memory access. */
1905 if (misaligned_operand (operands[0], TImode)
1906 || misaligned_operand (operands[1], TImode))
1908 if (get_attr_mode (insn) == MODE_V4SF)
1909 return "%vmovups\t{%1, %0|%0, %1}";
1911 return "%vmovdqu\t{%1, %0|%0, %1}";
1915 if (get_attr_mode (insn) == MODE_V4SF)
1916 return "%vmovaps\t{%1, %0|%0, %1}";
1918 return "%vmovdqa\t{%1, %0|%0, %1}";
1924 [(set_attr "type" "sselog1,ssemov,ssemov")
1925 (set_attr "prefix" "maybe_vex")
1927 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1928 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1930 (const_string "V4SF")
1931 (and (eq_attr "alternative" "2")
1932 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1934 (const_string "V4SF")]
1935 (const_string "TI")))])
1937 (define_insn "*movdi_internal_rex64"
1938 [(set (match_operand:DI 0 "nonimmediate_operand"
1939 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
1940 (match_operand:DI 1 "general_operand"
1941 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
1942 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1944 switch (get_attr_type (insn))
1947 if (SSE_REG_P (operands[0]))
1948 return "movq2dq\t{%1, %0|%0, %1}";
1950 return "movdq2q\t{%1, %0|%0, %1}";
1955 if (get_attr_mode (insn) == MODE_TI)
1956 return "vmovdqa\t{%1, %0|%0, %1}";
1958 return "vmovq\t{%1, %0|%0, %1}";
1961 if (get_attr_mode (insn) == MODE_TI)
1962 return "movdqa\t{%1, %0|%0, %1}";
1966 /* Moves from and into integer register is done using movd
1967 opcode with REX prefix. */
1968 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1969 return "movd\t{%1, %0|%0, %1}";
1970 return "movq\t{%1, %0|%0, %1}";
1973 return "%vpxor\t%0, %d0";
1976 return "pxor\t%0, %0";
1982 return "lea{q}\t{%a1, %0|%0, %a1}";
1985 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1986 if (get_attr_mode (insn) == MODE_SI)
1987 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1988 else if (which_alternative == 2)
1989 return "movabs{q}\t{%1, %0|%0, %1}";
1991 return "mov{q}\t{%1, %0|%0, %1}";
1995 (cond [(eq_attr "alternative" "5")
1996 (const_string "mmx")
1997 (eq_attr "alternative" "6,7,8,9,10")
1998 (const_string "mmxmov")
1999 (eq_attr "alternative" "11")
2000 (const_string "sselog1")
2001 (eq_attr "alternative" "12,13,14,15,16")
2002 (const_string "ssemov")
2003 (eq_attr "alternative" "17,18")
2004 (const_string "ssecvt")
2005 (eq_attr "alternative" "4")
2006 (const_string "multi")
2007 (match_operand:DI 1 "pic_32bit_operand" "")
2008 (const_string "lea")
2010 (const_string "imov")))
2013 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2015 (const_string "*")))
2016 (set (attr "length_immediate")
2018 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2020 (const_string "*")))
2021 (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2022 (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2023 (set (attr "prefix")
2024 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2025 (const_string "maybe_vex")
2026 (const_string "orig")))
2027 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2029 ;; Convert impossible stores of immediate to existing instructions.
2030 ;; First try to get scratch register and go through it. In case this
2031 ;; fails, move by 32bit parts.
2033 [(match_scratch:DI 2 "r")
2034 (set (match_operand:DI 0 "memory_operand" "")
2035 (match_operand:DI 1 "immediate_operand" ""))]
2036 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2037 && !x86_64_immediate_operand (operands[1], DImode)"
2038 [(set (match_dup 2) (match_dup 1))
2039 (set (match_dup 0) (match_dup 2))])
2041 ;; We need to define this as both peepholer and splitter for case
2042 ;; peephole2 pass is not run.
2043 ;; "&& 1" is needed to keep it from matching the previous pattern.
2045 [(set (match_operand:DI 0 "memory_operand" "")
2046 (match_operand:DI 1 "immediate_operand" ""))]
2047 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2048 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2049 [(set (match_dup 2) (match_dup 3))
2050 (set (match_dup 4) (match_dup 5))]
2051 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2054 [(set (match_operand:DI 0 "memory_operand" "")
2055 (match_operand:DI 1 "immediate_operand" ""))]
2056 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2057 ? epilogue_completed : reload_completed)
2058 && !symbolic_operand (operands[1], DImode)
2059 && !x86_64_immediate_operand (operands[1], DImode)"
2060 [(set (match_dup 2) (match_dup 3))
2061 (set (match_dup 4) (match_dup 5))]
2062 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2064 (define_insn "*movdi_internal"
2065 [(set (match_operand:DI 0 "nonimmediate_operand"
2066 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2067 (match_operand:DI 1 "general_operand"
2068 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2069 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2074 movq\t{%1, %0|%0, %1}
2075 movq\t{%1, %0|%0, %1}
2077 %vmovq\t{%1, %0|%0, %1}
2078 %vmovdqa\t{%1, %0|%0, %1}
2079 %vmovq\t{%1, %0|%0, %1}
2081 movlps\t{%1, %0|%0, %1}
2082 movaps\t{%1, %0|%0, %1}
2083 movlps\t{%1, %0|%0, %1}"
2084 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2085 (set (attr "prefix")
2086 (if_then_else (eq_attr "alternative" "5,6,7,8")
2087 (const_string "vex")
2088 (const_string "orig")))
2089 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2092 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2093 (match_operand:DI 1 "general_operand" ""))]
2094 "!TARGET_64BIT && reload_completed
2095 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2096 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2098 "ix86_split_long_move (operands); DONE;")
2100 (define_insn "*movsi_internal"
2101 [(set (match_operand:SI 0 "nonimmediate_operand"
2102 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2103 (match_operand:SI 1 "general_operand"
2104 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2105 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2107 switch (get_attr_type (insn))
2110 if (get_attr_mode (insn) == MODE_TI)
2111 return "%vpxor\t%0, %d0";
2112 return "%vxorps\t%0, %d0";
2115 switch (get_attr_mode (insn))
2118 return "%vmovdqa\t{%1, %0|%0, %1}";
2120 return "%vmovaps\t{%1, %0|%0, %1}";
2122 return "%vmovd\t{%1, %0|%0, %1}";
2124 return "%vmovss\t{%1, %0|%0, %1}";
2130 return "pxor\t%0, %0";
2133 if (get_attr_mode (insn) == MODE_DI)
2134 return "movq\t{%1, %0|%0, %1}";
2135 return "movd\t{%1, %0|%0, %1}";
2138 return "lea{l}\t{%a1, %0|%0, %a1}";
2141 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2142 return "mov{l}\t{%1, %0|%0, %1}";
2146 (cond [(eq_attr "alternative" "2")
2147 (const_string "mmx")
2148 (eq_attr "alternative" "3,4,5")
2149 (const_string "mmxmov")
2150 (eq_attr "alternative" "6")
2151 (const_string "sselog1")
2152 (eq_attr "alternative" "7,8,9,10,11")
2153 (const_string "ssemov")
2154 (match_operand:DI 1 "pic_32bit_operand" "")
2155 (const_string "lea")
2157 (const_string "imov")))
2158 (set (attr "prefix")
2159 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2160 (const_string "orig")
2161 (const_string "maybe_vex")))
2162 (set (attr "prefix_data16")
2163 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2165 (const_string "*")))
2167 (cond [(eq_attr "alternative" "2,3")
2169 (eq_attr "alternative" "6,7")
2171 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2172 (const_string "V4SF")
2173 (const_string "TI"))
2174 (and (eq_attr "alternative" "8,9,10,11")
2175 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
2178 (const_string "SI")))])
2180 (define_insn "*movhi_internal"
2181 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2182 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2183 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2185 switch (get_attr_type (insn))
2188 /* movzwl is faster than movw on p2 due to partial word stalls,
2189 though not as fast as an aligned movl. */
2190 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2192 if (get_attr_mode (insn) == MODE_SI)
2193 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2195 return "mov{w}\t{%1, %0|%0, %1}";
2199 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2201 (const_string "imov")
2202 (and (eq_attr "alternative" "0")
2203 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2205 (eq (symbol_ref "TARGET_HIMODE_MATH")
2207 (const_string "imov")
2208 (and (eq_attr "alternative" "1,2")
2209 (match_operand:HI 1 "aligned_operand" ""))
2210 (const_string "imov")
2211 (and (ne (symbol_ref "TARGET_MOVX")
2213 (eq_attr "alternative" "0,2"))
2214 (const_string "imovx")
2216 (const_string "imov")))
2218 (cond [(eq_attr "type" "imovx")
2220 (and (eq_attr "alternative" "1,2")
2221 (match_operand:HI 1 "aligned_operand" ""))
2223 (and (eq_attr "alternative" "0")
2224 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2226 (eq (symbol_ref "TARGET_HIMODE_MATH")
2230 (const_string "HI")))])
2232 ;; Situation is quite tricky about when to choose full sized (SImode) move
2233 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2234 ;; partial register dependency machines (such as AMD Athlon), where QImode
2235 ;; moves issue extra dependency and for partial register stalls machines
2236 ;; that don't use QImode patterns (and QImode move cause stall on the next
2239 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2240 ;; register stall machines with, where we use QImode instructions, since
2241 ;; partial register stall can be caused there. Then we use movzx.
2242 (define_insn "*movqi_internal"
2243 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2244 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2245 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2247 switch (get_attr_type (insn))
2250 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2251 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2253 if (get_attr_mode (insn) == MODE_SI)
2254 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2256 return "mov{b}\t{%1, %0|%0, %1}";
2260 (cond [(and (eq_attr "alternative" "5")
2261 (not (match_operand:QI 1 "aligned_operand" "")))
2262 (const_string "imovx")
2263 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2265 (const_string "imov")
2266 (and (eq_attr "alternative" "3")
2267 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2269 (eq (symbol_ref "TARGET_QIMODE_MATH")
2271 (const_string "imov")
2272 (eq_attr "alternative" "3,5")
2273 (const_string "imovx")
2274 (and (ne (symbol_ref "TARGET_MOVX")
2276 (eq_attr "alternative" "2"))
2277 (const_string "imovx")
2279 (const_string "imov")))
2281 (cond [(eq_attr "alternative" "3,4,5")
2283 (eq_attr "alternative" "6")
2285 (eq_attr "type" "imovx")
2287 (and (eq_attr "type" "imov")
2288 (and (eq_attr "alternative" "0,1")
2289 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2291 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2293 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2296 ;; Avoid partial register stalls when not using QImode arithmetic
2297 (and (eq_attr "type" "imov")
2298 (and (eq_attr "alternative" "0,1")
2299 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2301 (eq (symbol_ref "TARGET_QIMODE_MATH")
2305 (const_string "QI")))])
2307 ;; Stores and loads of ax to arbitrary constant address.
2308 ;; We fake an second form of instruction to force reload to load address
2309 ;; into register when rax is not available
2310 (define_insn "*movabs<mode>_1"
2311 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2312 (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2313 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2315 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2316 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2317 [(set_attr "type" "imov")
2318 (set_attr "modrm" "0,*")
2319 (set_attr "length_address" "8,0")
2320 (set_attr "length_immediate" "0,*")
2321 (set_attr "memory" "store")
2322 (set_attr "mode" "<MODE>")])
2324 (define_insn "*movabs<mode>_2"
2325 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2326 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2327 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2329 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2330 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2331 [(set_attr "type" "imov")
2332 (set_attr "modrm" "0,*")
2333 (set_attr "length_address" "8,0")
2334 (set_attr "length_immediate" "0")
2335 (set_attr "memory" "load")
2336 (set_attr "mode" "<MODE>")])
2338 (define_insn "*swap<mode>"
2339 [(set (match_operand:SWI48 0 "register_operand" "+r")
2340 (match_operand:SWI48 1 "register_operand" "+r"))
2344 "xchg{<imodesuffix>}\t%1, %0"
2345 [(set_attr "type" "imov")
2346 (set_attr "mode" "<MODE>")
2347 (set_attr "pent_pair" "np")
2348 (set_attr "athlon_decode" "vector")
2349 (set_attr "amdfam10_decode" "double")])
2351 (define_insn "*swap<mode>_1"
2352 [(set (match_operand:SWI12 0 "register_operand" "+r")
2353 (match_operand:SWI12 1 "register_operand" "+r"))
2356 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2358 [(set_attr "type" "imov")
2359 (set_attr "mode" "SI")
2360 (set_attr "pent_pair" "np")
2361 (set_attr "athlon_decode" "vector")
2362 (set_attr "amdfam10_decode" "double")])
2364 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2365 ;; is disabled for AMDFAM10
2366 (define_insn "*swap<mode>_2"
2367 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2368 (match_operand:SWI12 1 "register_operand" "+<r>"))
2371 "TARGET_PARTIAL_REG_STALL"
2372 "xchg{<imodesuffix>}\t%1, %0"
2373 [(set_attr "type" "imov")
2374 (set_attr "mode" "<MODE>")
2375 (set_attr "pent_pair" "np")
2376 (set_attr "athlon_decode" "vector")])
2378 (define_expand "movstrict<mode>"
2379 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2380 (match_operand:SWI12 1 "general_operand" ""))]
2383 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2385 /* Don't generate memory->memory moves, go through a register */
2386 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2387 operands[1] = force_reg (<MODE>mode, operands[1]);
2390 (define_insn "*movstrict<mode>_1"
2391 [(set (strict_low_part
2392 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2393 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2394 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2395 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2396 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2397 [(set_attr "type" "imov")
2398 (set_attr "mode" "<MODE>")])
2400 (define_insn "*movstrict<mode>_xor"
2401 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2402 (match_operand:SWI12 1 "const0_operand" ""))
2403 (clobber (reg:CC FLAGS_REG))]
2405 "xor{<imodesuffix>}\t%0, %0"
2406 [(set_attr "type" "alu1")
2407 (set_attr "mode" "<MODE>")
2408 (set_attr "length_immediate" "0")])
2410 (define_insn "*mov<mode>_extv_1"
2411 [(set (match_operand:SWI24 0 "register_operand" "=R")
2412 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2416 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2417 [(set_attr "type" "imovx")
2418 (set_attr "mode" "SI")])
2420 (define_insn "*movqi_extv_1_rex64"
2421 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2422 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2427 switch (get_attr_type (insn))
2430 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2432 return "mov{b}\t{%h1, %0|%0, %h1}";
2436 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2437 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2438 (ne (symbol_ref "TARGET_MOVX")
2440 (const_string "imovx")
2441 (const_string "imov")))
2443 (if_then_else (eq_attr "type" "imovx")
2445 (const_string "QI")))])
2447 (define_insn "*movqi_extv_1"
2448 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?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 "*mov<mode>_extzv_1"
2475 [(set (match_operand:SWI48 0 "register_operand" "=R")
2476 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2480 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2481 [(set_attr "type" "imovx")
2482 (set_attr "mode" "SI")])
2484 (define_insn "*movqi_extzv_2_rex64"
2485 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2487 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2492 switch (get_attr_type (insn))
2495 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2497 return "mov{b}\t{%h1, %0|%0, %h1}";
2501 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2502 (ne (symbol_ref "TARGET_MOVX")
2504 (const_string "imovx")
2505 (const_string "imov")))
2507 (if_then_else (eq_attr "type" "imovx")
2509 (const_string "QI")))])
2511 (define_insn "*movqi_extzv_2"
2512 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?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 (and (match_operand:QI 0 "register_operand" "")
2529 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2530 (ne (symbol_ref "TARGET_MOVX")
2532 (const_string "imovx")
2533 (const_string "imov")))
2535 (if_then_else (eq_attr "type" "imovx")
2537 (const_string "QI")))])
2539 (define_expand "mov<mode>_insv_1"
2540 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2543 (match_operand:SWI48 1 "nonmemory_operand" ""))])
2545 (define_insn "*mov<mode>_insv_1_rex64"
2546 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2549 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2551 "mov{b}\t{%b1, %h0|%h0, %b1}"
2552 [(set_attr "type" "imov")
2553 (set_attr "mode" "QI")])
2555 (define_insn "*movsi_insv_1"
2556 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2559 (match_operand:SI 1 "general_operand" "Qmn"))]
2561 "mov{b}\t{%b1, %h0|%h0, %b1}"
2562 [(set_attr "type" "imov")
2563 (set_attr "mode" "QI")])
2565 (define_insn "*movqi_insv_2"
2566 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2569 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2572 "mov{b}\t{%h1, %h0|%h0, %h1}"
2573 [(set_attr "type" "imov")
2574 (set_attr "mode" "QI")])
2576 ;; Floating point push instructions.
2578 (define_insn "*pushtf"
2579 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2580 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2583 /* This insn should be already split before reg-stack. */
2586 [(set_attr "type" "multi")
2587 (set_attr "unit" "sse,*,*")
2588 (set_attr "mode" "TF,SI,SI")])
2591 [(set (match_operand:TF 0 "push_operand" "")
2592 (match_operand:TF 1 "sse_reg_operand" ""))]
2593 "TARGET_SSE2 && reload_completed"
2594 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2595 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2598 [(set (match_operand:TF 0 "push_operand" "")
2599 (match_operand:TF 1 "general_operand" ""))]
2600 "TARGET_SSE2 && reload_completed
2601 && !SSE_REG_P (operands[1])"
2603 "ix86_split_long_move (operands); DONE;")
2605 (define_insn "*pushxf"
2606 [(set (match_operand:XF 0 "push_operand" "=<,<")
2607 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2608 "optimize_function_for_speed_p (cfun)"
2610 /* This insn should be already split before reg-stack. */
2613 [(set_attr "type" "multi")
2614 (set_attr "unit" "i387,*")
2615 (set_attr "mode" "XF,SI")])
2617 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2618 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2619 ;; Pushing using integer instructions is longer except for constants
2620 ;; and direct memory references (assuming that any given constant is pushed
2621 ;; only once, but this ought to be handled elsewhere).
2623 (define_insn "*pushxf_nointeger"
2624 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2625 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2626 "optimize_function_for_size_p (cfun)"
2628 /* This insn should be already split before reg-stack. */
2631 [(set_attr "type" "multi")
2632 (set_attr "unit" "i387,*,*")
2633 (set_attr "mode" "XF,SI,SI")])
2636 [(set (match_operand:XF 0 "push_operand" "")
2637 (match_operand:XF 1 "fp_register_operand" ""))]
2639 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2640 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2641 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2644 [(set (match_operand:XF 0 "push_operand" "")
2645 (match_operand:XF 1 "general_operand" ""))]
2647 && !FP_REG_P (operands[1])"
2649 "ix86_split_long_move (operands); DONE;")
2651 (define_insn "*pushdf"
2652 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2653 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2654 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2656 /* This insn should be already split before reg-stack. */
2659 [(set_attr "type" "multi")
2660 (set_attr "unit" "i387,*,*")
2661 (set_attr "mode" "DF,SI,DF")])
2663 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2664 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2665 ;; On the average, pushdf using integers can be still shorter. Allow this
2666 ;; pattern for optimize_size too.
2668 (define_insn "*pushdf_nointeger"
2669 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2670 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2671 "!(TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES)"
2673 /* This insn should be already split before reg-stack. */
2676 [(set_attr "type" "multi")
2677 (set_attr "unit" "i387,*,*,*")
2678 (set_attr "mode" "DF,SI,SI,DF")])
2680 ;; %%% Kill this when call knows how to work this out.
2682 [(set (match_operand:DF 0 "push_operand" "")
2683 (match_operand:DF 1 "any_fp_register_operand" ""))]
2685 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2686 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2689 [(set (match_operand:DF 0 "push_operand" "")
2690 (match_operand:DF 1 "general_operand" ""))]
2692 && !ANY_FP_REG_P (operands[1])"
2694 "ix86_split_long_move (operands); DONE;")
2696 (define_insn "*pushsf_rex64"
2697 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2698 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2701 /* Anything else should be already split before reg-stack. */
2702 gcc_assert (which_alternative == 1);
2703 return "push{q}\t%q1";
2705 [(set_attr "type" "multi,push,multi")
2706 (set_attr "unit" "i387,*,*")
2707 (set_attr "mode" "SF,DI,SF")])
2709 (define_insn "*pushsf"
2710 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2711 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2714 /* Anything else should be already split before reg-stack. */
2715 gcc_assert (which_alternative == 1);
2716 return "push{l}\t%1";
2718 [(set_attr "type" "multi,push,multi")
2719 (set_attr "unit" "i387,*,*")
2720 (set_attr "mode" "SF,SI,SF")])
2723 [(set (match_operand:SF 0 "push_operand" "")
2724 (match_operand:SF 1 "memory_operand" ""))]
2726 && MEM_P (operands[1])
2727 && (operands[2] = find_constant_src (insn))"
2731 ;; %%% Kill this when call knows how to work this out.
2733 [(set (match_operand:SF 0 "push_operand" "")
2734 (match_operand:SF 1 "any_fp_register_operand" ""))]
2736 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2737 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2738 "operands[2] = GEN_INT (-GET_MODE_SIZE (<MODE>mode));")
2740 ;; Floating point move instructions.
2742 (define_expand "movtf"
2743 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2744 (match_operand:TF 1 "nonimmediate_operand" ""))]
2747 ix86_expand_move (TFmode, operands);
2751 (define_expand "mov<mode>"
2752 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2753 (match_operand:X87MODEF 1 "general_operand" ""))]
2755 "ix86_expand_move (<MODE>mode, operands); DONE;")
2757 (define_insn "*movtf_internal"
2758 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
2759 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
2761 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2763 switch (which_alternative)
2767 if (get_attr_mode (insn) == MODE_V4SF)
2768 return "%vmovaps\t{%1, %0|%0, %1}";
2770 return "%vmovdqa\t{%1, %0|%0, %1}";
2772 if (get_attr_mode (insn) == MODE_V4SF)
2773 return "%vxorps\t%0, %d0";
2775 return "%vpxor\t%0, %d0";
2783 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2784 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2786 (cond [(eq_attr "alternative" "0,2")
2788 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2790 (const_string "V4SF")
2791 (const_string "TI"))
2792 (eq_attr "alternative" "1")
2794 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2796 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2798 (const_string "V4SF")
2799 (const_string "TI"))]
2800 (const_string "DI")))])
2803 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2804 (match_operand:TF 1 "general_operand" ""))]
2806 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
2808 "ix86_split_long_move (operands); DONE;")
2810 (define_insn "*movxf_internal"
2811 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2812 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2813 "optimize_function_for_speed_p (cfun)
2814 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2815 && (reload_in_progress || reload_completed
2816 || GET_CODE (operands[1]) != CONST_DOUBLE
2817 || memory_operand (operands[0], XFmode))"
2819 switch (which_alternative)
2823 return output_387_reg_move (insn, operands);
2826 return standard_80387_constant_opcode (operands[1]);
2835 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2836 (set_attr "mode" "XF,XF,XF,SI,SI")])
2838 ;; Do not use integer registers when optimizing for size
2839 (define_insn "*movxf_internal_nointeger"
2840 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2841 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2842 "optimize_function_for_size_p (cfun)
2843 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2844 && (reload_in_progress || reload_completed
2845 || standard_80387_constant_p (operands[1])
2846 || GET_CODE (operands[1]) != CONST_DOUBLE
2847 || memory_operand (operands[0], XFmode))"
2849 switch (which_alternative)
2853 return output_387_reg_move (insn, operands);
2856 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")])
2868 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2869 (match_operand:XF 1 "general_operand" ""))]
2871 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2872 && ! (FP_REG_P (operands[0]) ||
2873 (GET_CODE (operands[0]) == SUBREG
2874 && FP_REG_P (SUBREG_REG (operands[0]))))
2875 && ! (FP_REG_P (operands[1]) ||
2876 (GET_CODE (operands[1]) == SUBREG
2877 && FP_REG_P (SUBREG_REG (operands[1]))))"
2879 "ix86_split_long_move (operands); DONE;")
2881 (define_insn "*movdf_internal_rex64"
2882 [(set (match_operand:DF 0 "nonimmediate_operand"
2883 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2884 (match_operand:DF 1 "general_operand"
2885 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2886 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2887 && (reload_in_progress || reload_completed
2888 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2889 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2890 && optimize_function_for_size_p (cfun)
2891 && standard_80387_constant_p (operands[1]))
2892 || GET_CODE (operands[1]) != CONST_DOUBLE
2893 || memory_operand (operands[0], DFmode))"
2895 switch (which_alternative)
2899 return output_387_reg_move (insn, operands);
2902 return standard_80387_constant_opcode (operands[1]);
2909 switch (get_attr_mode (insn))
2912 return "%vxorps\t%0, %d0";
2914 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2915 return "%vxorps\t%0, %d0";
2917 return "%vxorpd\t%0, %d0";
2919 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2920 return "%vxorps\t%0, %d0";
2922 return "%vpxor\t%0, %d0";
2929 switch (get_attr_mode (insn))
2932 return "%vmovaps\t{%1, %0|%0, %1}";
2934 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2935 return "%vmovaps\t{%1, %0|%0, %1}";
2937 return "%vmovapd\t{%1, %0|%0, %1}";
2939 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2940 return "%vmovaps\t{%1, %0|%0, %1}";
2942 return "%vmovdqa\t{%1, %0|%0, %1}";
2944 return "%vmovq\t{%1, %0|%0, %1}";
2948 if (REG_P (operands[0]) && REG_P (operands[1]))
2949 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2951 return "vmovsd\t{%1, %0|%0, %1}";
2954 return "movsd\t{%1, %0|%0, %1}";
2956 return "%vmovlpd\t{%1, %d0|%d0, %1}";
2958 return "%vmovlps\t{%1, %d0|%d0, %1}";
2965 return "%vmovd\t{%1, %0|%0, %1}";
2971 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2972 (set (attr "prefix")
2973 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
2974 (const_string "orig")
2975 (const_string "maybe_vex")))
2976 (set (attr "prefix_data16")
2977 (if_then_else (eq_attr "mode" "V1DF")
2979 (const_string "*")))
2981 (cond [(eq_attr "alternative" "0,1,2")
2983 (eq_attr "alternative" "3,4,9,10")
2986 /* For SSE1, we have many fewer alternatives. */
2987 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2988 (cond [(eq_attr "alternative" "5,6")
2989 (const_string "V4SF")
2991 (const_string "V2SF"))
2993 /* xorps is one byte shorter. */
2994 (eq_attr "alternative" "5")
2995 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2997 (const_string "V4SF")
2998 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3002 (const_string "V2DF"))
3004 /* For architectures resolving dependencies on
3005 whole SSE registers use APD move to break dependency
3006 chains, otherwise use short move to avoid extra work.
3008 movaps encodes one byte shorter. */
3009 (eq_attr "alternative" "6")
3011 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3013 (const_string "V4SF")
3014 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3016 (const_string "V2DF")
3018 (const_string "DF"))
3019 /* For architectures resolving dependencies on register
3020 parts we may avoid extra work to zero out upper part
3022 (eq_attr "alternative" "7")
3024 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3026 (const_string "V1DF")
3027 (const_string "DF"))
3029 (const_string "DF")))])
3031 (define_insn "*movdf_internal"
3032 [(set (match_operand:DF 0 "nonimmediate_operand"
3033 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3034 (match_operand:DF 1 "general_operand"
3035 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3036 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3037 && optimize_function_for_speed_p (cfun)
3038 && TARGET_INTEGER_DFMODE_MOVES
3039 && (reload_in_progress || reload_completed
3040 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3041 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3042 && optimize_function_for_size_p (cfun)
3043 && standard_80387_constant_p (operands[1]))
3044 || GET_CODE (operands[1]) != CONST_DOUBLE
3045 || memory_operand (operands[0], DFmode))"
3047 switch (which_alternative)
3051 return output_387_reg_move (insn, operands);
3054 return standard_80387_constant_opcode (operands[1]);
3061 switch (get_attr_mode (insn))
3064 return "xorps\t%0, %0";
3066 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3067 return "xorps\t%0, %0";
3069 return "xorpd\t%0, %0";
3071 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3072 return "xorps\t%0, %0";
3074 return "pxor\t%0, %0";
3081 switch (get_attr_mode (insn))
3084 return "movaps\t{%1, %0|%0, %1}";
3086 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3087 return "movaps\t{%1, %0|%0, %1}";
3089 return "movapd\t{%1, %0|%0, %1}";
3091 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3092 return "movaps\t{%1, %0|%0, %1}";
3094 return "movdqa\t{%1, %0|%0, %1}";
3096 return "movq\t{%1, %0|%0, %1}";
3098 return "movsd\t{%1, %0|%0, %1}";
3100 return "movlpd\t{%1, %0|%0, %1}";
3102 return "movlps\t{%1, %0|%0, %1}";
3111 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3112 (set (attr "prefix_data16")
3113 (if_then_else (eq_attr "mode" "V1DF")
3115 (const_string "*")))
3117 (cond [(eq_attr "alternative" "0,1,2")
3119 (eq_attr "alternative" "3,4")
3122 /* For SSE1, we have many fewer alternatives. */
3123 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3124 (cond [(eq_attr "alternative" "5,6")
3125 (const_string "V4SF")
3127 (const_string "V2SF"))
3129 /* xorps is one byte shorter. */
3130 (eq_attr "alternative" "5")
3131 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3133 (const_string "V4SF")
3134 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3138 (const_string "V2DF"))
3140 /* For architectures resolving dependencies on
3141 whole SSE registers use APD move to break dependency
3142 chains, otherwise use short move to avoid extra work.
3144 movaps encodes one byte shorter. */
3145 (eq_attr "alternative" "6")
3147 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3149 (const_string "V4SF")
3150 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3152 (const_string "V2DF")
3154 (const_string "DF"))
3155 /* For architectures resolving dependencies on register
3156 parts we may avoid extra work to zero out upper part
3158 (eq_attr "alternative" "7")
3160 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3162 (const_string "V1DF")
3163 (const_string "DF"))
3165 (const_string "DF")))])
3167 ;; Moving is usually shorter when only FP registers are used. This separate
3168 ;; movdf pattern avoids the use of integer registers for FP operations
3169 ;; when optimizing for size.
3171 (define_insn "*movdf_internal_nointeger"
3172 [(set (match_operand:DF 0 "nonimmediate_operand"
3173 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
3174 (match_operand:DF 1 "general_operand"
3175 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
3176 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3177 && ((optimize_function_for_size_p (cfun)
3178 || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3179 && (reload_in_progress || reload_completed
3180 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3181 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3182 && optimize_function_for_size_p (cfun)
3183 && !memory_operand (operands[0], DFmode)
3184 && standard_80387_constant_p (operands[1]))
3185 || GET_CODE (operands[1]) != CONST_DOUBLE
3186 || ((optimize_function_for_size_p (cfun)
3187 || !TARGET_MEMORY_MISMATCH_STALL
3188 || reload_in_progress || reload_completed)
3189 && memory_operand (operands[0], DFmode)))"
3191 switch (which_alternative)
3195 return output_387_reg_move (insn, operands);
3198 return standard_80387_constant_opcode (operands[1]);
3205 switch (get_attr_mode (insn))
3208 return "%vxorps\t%0, %d0";
3210 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3211 return "%vxorps\t%0, %d0";
3213 return "%vxorpd\t%0, %d0";
3215 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3216 return "%vxorps\t%0, %d0";
3218 return "%vpxor\t%0, %d0";
3225 switch (get_attr_mode (insn))
3228 return "%vmovaps\t{%1, %0|%0, %1}";
3230 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3231 return "%vmovaps\t{%1, %0|%0, %1}";
3233 return "%vmovapd\t{%1, %0|%0, %1}";
3235 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3236 return "%vmovaps\t{%1, %0|%0, %1}";
3238 return "%vmovdqa\t{%1, %0|%0, %1}";
3240 return "%vmovq\t{%1, %0|%0, %1}";
3244 if (REG_P (operands[0]) && REG_P (operands[1]))
3245 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3247 return "vmovsd\t{%1, %0|%0, %1}";
3250 return "movsd\t{%1, %0|%0, %1}";
3254 if (REG_P (operands[0]))
3255 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3257 return "vmovlpd\t{%1, %0|%0, %1}";
3260 return "movlpd\t{%1, %0|%0, %1}";
3264 if (REG_P (operands[0]))
3265 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3267 return "vmovlps\t{%1, %0|%0, %1}";
3270 return "movlps\t{%1, %0|%0, %1}";
3279 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3280 (set (attr "prefix")
3281 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3282 (const_string "orig")
3283 (const_string "maybe_vex")))
3284 (set (attr "prefix_data16")
3285 (if_then_else (eq_attr "mode" "V1DF")
3287 (const_string "*")))
3289 (cond [(eq_attr "alternative" "0,1,2")
3291 (eq_attr "alternative" "3,4")
3294 /* For SSE1, we have many fewer alternatives. */
3295 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3296 (cond [(eq_attr "alternative" "5,6")
3297 (const_string "V4SF")
3299 (const_string "V2SF"))
3301 /* xorps is one byte shorter. */
3302 (eq_attr "alternative" "5")
3303 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3305 (const_string "V4SF")
3306 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3310 (const_string "V2DF"))
3312 /* For architectures resolving dependencies on
3313 whole SSE registers use APD move to break dependency
3314 chains, otherwise use short move to avoid extra work.
3316 movaps encodes one byte shorter. */
3317 (eq_attr "alternative" "6")
3319 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3321 (const_string "V4SF")
3322 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3324 (const_string "V2DF")
3326 (const_string "DF"))
3327 /* For architectures resolving dependencies on register
3328 parts we may avoid extra work to zero out upper part
3330 (eq_attr "alternative" "7")
3332 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3334 (const_string "V1DF")
3335 (const_string "DF"))
3337 (const_string "DF")))])
3340 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3341 (match_operand:DF 1 "general_operand" ""))]
3343 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3344 && ! (ANY_FP_REG_P (operands[0]) ||
3345 (GET_CODE (operands[0]) == SUBREG
3346 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3347 && ! (ANY_FP_REG_P (operands[1]) ||
3348 (GET_CODE (operands[1]) == SUBREG
3349 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3351 "ix86_split_long_move (operands); DONE;")
3353 (define_insn "*movsf_internal"
3354 [(set (match_operand:SF 0 "nonimmediate_operand"
3355 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3356 (match_operand:SF 1 "general_operand"
3357 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3358 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3359 && (reload_in_progress || reload_completed
3360 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3361 || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
3362 && standard_80387_constant_p (operands[1]))
3363 || GET_CODE (operands[1]) != CONST_DOUBLE
3364 || memory_operand (operands[0], SFmode))"
3366 switch (which_alternative)
3370 return output_387_reg_move (insn, operands);
3373 return standard_80387_constant_opcode (operands[1]);
3377 return "mov{l}\t{%1, %0|%0, %1}";
3379 if (get_attr_mode (insn) == MODE_TI)
3380 return "%vpxor\t%0, %d0";
3382 return "%vxorps\t%0, %d0";
3384 if (get_attr_mode (insn) == MODE_V4SF)
3385 return "%vmovaps\t{%1, %0|%0, %1}";
3387 return "%vmovss\t{%1, %d0|%d0, %1}";
3390 return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
3391 : "vmovss\t{%1, %0|%0, %1}";
3393 return "movss\t{%1, %0|%0, %1}";
3395 return "%vmovss\t{%1, %0|%0, %1}";
3397 case 9: case 10: case 14: case 15:
3398 return "movd\t{%1, %0|%0, %1}";
3400 return "%vmovd\t{%1, %0|%0, %1}";
3403 return "movq\t{%1, %0|%0, %1}";
3409 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3410 (set (attr "prefix")
3411 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3412 (const_string "maybe_vex")
3413 (const_string "orig")))
3415 (cond [(eq_attr "alternative" "3,4,9,10")
3417 (eq_attr "alternative" "5")
3419 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3421 (ne (symbol_ref "TARGET_SSE2")
3423 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3426 (const_string "V4SF"))
3427 /* For architectures resolving dependencies on
3428 whole SSE registers use APS move to break dependency
3429 chains, otherwise use short move to avoid extra work.
3431 Do the same for architectures resolving dependencies on
3432 the parts. While in DF mode it is better to always handle
3433 just register parts, the SF mode is different due to lack
3434 of instructions to load just part of the register. It is
3435 better to maintain the whole registers in single format
3436 to avoid problems on using packed logical operations. */
3437 (eq_attr "alternative" "6")
3439 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3441 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3443 (const_string "V4SF")
3444 (const_string "SF"))
3445 (eq_attr "alternative" "11")
3446 (const_string "DI")]
3447 (const_string "SF")))])
3450 [(set (match_operand 0 "register_operand" "")
3451 (match_operand 1 "memory_operand" ""))]
3453 && MEM_P (operands[1])
3454 && (GET_MODE (operands[0]) == TFmode
3455 || GET_MODE (operands[0]) == XFmode
3456 || GET_MODE (operands[0]) == DFmode
3457 || GET_MODE (operands[0]) == SFmode)
3458 && (operands[2] = find_constant_src (insn))"
3459 [(set (match_dup 0) (match_dup 2))]
3461 rtx c = operands[2];
3462 rtx r = operands[0];
3464 if (GET_CODE (r) == SUBREG)
3469 if (!standard_sse_constant_p (c))
3472 else if (FP_REG_P (r))
3474 if (!standard_80387_constant_p (c))
3477 else if (MMX_REG_P (r))
3482 [(set (match_operand 0 "register_operand" "")
3483 (float_extend (match_operand 1 "memory_operand" "")))]
3485 && MEM_P (operands[1])
3486 && (GET_MODE (operands[0]) == TFmode
3487 || GET_MODE (operands[0]) == XFmode
3488 || GET_MODE (operands[0]) == DFmode
3489 || GET_MODE (operands[0]) == SFmode)
3490 && (operands[2] = find_constant_src (insn))"
3491 [(set (match_dup 0) (match_dup 2))]
3493 rtx c = operands[2];
3494 rtx r = operands[0];
3496 if (GET_CODE (r) == SUBREG)
3501 if (!standard_sse_constant_p (c))
3504 else if (FP_REG_P (r))
3506 if (!standard_80387_constant_p (c))
3509 else if (MMX_REG_P (r))
3513 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3515 [(set (match_operand:X87MODEF 0 "register_operand" "")
3516 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3517 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3518 && (standard_80387_constant_p (operands[1]) == 8
3519 || standard_80387_constant_p (operands[1]) == 9)"
3520 [(set (match_dup 0)(match_dup 1))
3522 (neg:X87MODEF (match_dup 0)))]
3526 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3527 if (real_isnegzero (&r))
3528 operands[1] = CONST0_RTX (<MODE>mode);
3530 operands[1] = CONST1_RTX (<MODE>mode);
3533 (define_insn "swapxf"
3534 [(set (match_operand:XF 0 "register_operand" "+f")
3535 (match_operand:XF 1 "register_operand" "+f"))
3540 if (STACK_TOP_P (operands[0]))
3545 [(set_attr "type" "fxch")
3546 (set_attr "mode" "XF")])
3548 (define_insn "*swap<mode>"
3549 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3550 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3553 "TARGET_80387 || reload_completed"
3555 if (STACK_TOP_P (operands[0]))
3560 [(set_attr "type" "fxch")
3561 (set_attr "mode" "<MODE>")])
3563 ;; Zero extension instructions
3565 (define_expand "zero_extendsidi2"
3566 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3567 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3572 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3577 (define_insn "*zero_extendsidi2_rex64"
3578 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3580 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3583 mov\t{%k1, %k0|%k0, %k1}
3585 movd\t{%1, %0|%0, %1}
3586 movd\t{%1, %0|%0, %1}
3587 %vmovd\t{%1, %0|%0, %1}
3588 %vmovd\t{%1, %0|%0, %1}"
3589 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3590 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3591 (set_attr "prefix_0f" "0,*,*,*,*,*")
3592 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3595 [(set (match_operand:DI 0 "memory_operand" "")
3596 (zero_extend:DI (match_dup 0)))]
3598 [(set (match_dup 4) (const_int 0))]
3599 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3601 ;; %%% Kill me once multi-word ops are sane.
3602 (define_insn "zero_extendsidi2_1"
3603 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3605 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3606 (clobber (reg:CC FLAGS_REG))]
3612 movd\t{%1, %0|%0, %1}
3613 movd\t{%1, %0|%0, %1}
3614 %vmovd\t{%1, %0|%0, %1}
3615 %vmovd\t{%1, %0|%0, %1}"
3616 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3617 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3618 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3621 [(set (match_operand:DI 0 "register_operand" "")
3622 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3623 (clobber (reg:CC FLAGS_REG))]
3624 "!TARGET_64BIT && reload_completed
3625 && true_regnum (operands[0]) == true_regnum (operands[1])"
3626 [(set (match_dup 4) (const_int 0))]
3627 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3630 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3631 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3632 (clobber (reg:CC FLAGS_REG))]
3633 "!TARGET_64BIT && reload_completed
3634 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3635 [(set (match_dup 3) (match_dup 1))
3636 (set (match_dup 4) (const_int 0))]
3637 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3639 (define_insn "zero_extend<mode>di2"
3640 [(set (match_operand:DI 0 "register_operand" "=r")
3642 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3644 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3645 [(set_attr "type" "imovx")
3646 (set_attr "mode" "SI")])
3648 (define_expand "zero_extendhisi2"
3649 [(set (match_operand:SI 0 "register_operand" "")
3650 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3653 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3655 operands[1] = force_reg (HImode, operands[1]);
3656 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3661 (define_insn_and_split "zero_extendhisi2_and"
3662 [(set (match_operand:SI 0 "register_operand" "=r")
3663 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3664 (clobber (reg:CC FLAGS_REG))]
3665 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3667 "&& reload_completed"
3668 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3669 (clobber (reg:CC FLAGS_REG))])]
3671 [(set_attr "type" "alu1")
3672 (set_attr "mode" "SI")])
3674 (define_insn "*zero_extendhisi2_movzwl"
3675 [(set (match_operand:SI 0 "register_operand" "=r")
3676 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3677 "!TARGET_ZERO_EXTEND_WITH_AND
3678 || optimize_function_for_size_p (cfun)"
3679 "movz{wl|x}\t{%1, %0|%0, %1}"
3680 [(set_attr "type" "imovx")
3681 (set_attr "mode" "SI")])
3683 (define_expand "zero_extendqi<mode>2"
3685 [(set (match_operand:SWI24 0 "register_operand" "")
3686 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3687 (clobber (reg:CC FLAGS_REG))])])
3689 (define_insn "*zero_extendqi<mode>2_and"
3690 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3691 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3692 (clobber (reg:CC FLAGS_REG))]
3693 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3695 [(set_attr "type" "alu1")
3696 (set_attr "mode" "<MODE>")])
3698 ;; When source and destination does not overlap, clear destination
3699 ;; first and then do the movb
3701 [(set (match_operand:SWI24 0 "register_operand" "")
3702 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3703 (clobber (reg:CC FLAGS_REG))]
3705 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3706 && ANY_QI_REG_P (operands[0])
3707 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3708 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3709 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3711 operands[2] = gen_lowpart (QImode, operands[0]);
3712 ix86_expand_clear (operands[0]);
3715 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3716 [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3717 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3718 (clobber (reg:CC FLAGS_REG))]
3719 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3721 [(set_attr "type" "imovx,alu1")
3722 (set_attr "mode" "<MODE>")])
3724 ;; For the movzbl case strip only the clobber
3726 [(set (match_operand:SWI24 0 "register_operand" "")
3727 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3728 (clobber (reg:CC FLAGS_REG))]
3730 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3731 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3733 (zero_extend:SWI24 (match_dup 1)))])
3735 ; zero extend to SImode to avoid partial register stalls
3736 (define_insn "*zero_extendqi<mode>2_movzbl"
3737 [(set (match_operand:SWI24 0 "register_operand" "=r")
3738 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3740 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3741 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3742 [(set_attr "type" "imovx")
3743 (set_attr "mode" "SI")])
3745 ;; Rest is handled by single and.
3747 [(set (match_operand:SWI24 0 "register_operand" "")
3748 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3749 (clobber (reg:CC FLAGS_REG))]
3751 && true_regnum (operands[0]) == true_regnum (operands[1])"
3752 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3753 (clobber (reg:CC FLAGS_REG))])])
3755 ;; Sign extension instructions
3757 (define_expand "extendsidi2"
3758 [(set (match_operand:DI 0 "register_operand" "")
3759 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3764 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3769 (define_insn "*extendsidi2_rex64"
3770 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3771 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3775 movs{lq|x}\t{%1, %0|%0, %1}"
3776 [(set_attr "type" "imovx")
3777 (set_attr "mode" "DI")
3778 (set_attr "prefix_0f" "0")
3779 (set_attr "modrm" "0,1")])
3781 (define_insn "extendsidi2_1"
3782 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3783 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3784 (clobber (reg:CC FLAGS_REG))
3785 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3789 ;; Extend to memory case when source register does die.
3791 [(set (match_operand:DI 0 "memory_operand" "")
3792 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3793 (clobber (reg:CC FLAGS_REG))
3794 (clobber (match_operand:SI 2 "register_operand" ""))]
3796 && dead_or_set_p (insn, operands[1])
3797 && !reg_mentioned_p (operands[1], operands[0]))"
3798 [(set (match_dup 3) (match_dup 1))
3799 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3800 (clobber (reg:CC FLAGS_REG))])
3801 (set (match_dup 4) (match_dup 1))]
3802 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3804 ;; Extend to memory case when source register does not die.
3806 [(set (match_operand:DI 0 "memory_operand" "")
3807 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3808 (clobber (reg:CC FLAGS_REG))
3809 (clobber (match_operand:SI 2 "register_operand" ""))]
3813 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3815 emit_move_insn (operands[3], operands[1]);
3817 /* Generate a cltd if possible and doing so it profitable. */
3818 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3819 && true_regnum (operands[1]) == AX_REG
3820 && true_regnum (operands[2]) == DX_REG)
3822 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3826 emit_move_insn (operands[2], operands[1]);
3827 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3829 emit_move_insn (operands[4], operands[2]);
3833 ;; Extend to register case. Optimize case where source and destination
3834 ;; registers match and cases where we can use cltd.
3836 [(set (match_operand:DI 0 "register_operand" "")
3837 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3838 (clobber (reg:CC FLAGS_REG))
3839 (clobber (match_scratch:SI 2 ""))]
3843 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3845 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3846 emit_move_insn (operands[3], operands[1]);
3848 /* Generate a cltd if possible and doing so it profitable. */
3849 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3850 && true_regnum (operands[3]) == AX_REG
3851 && true_regnum (operands[4]) == DX_REG)
3853 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3857 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3858 emit_move_insn (operands[4], operands[1]);
3860 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3864 (define_insn "extend<mode>di2"
3865 [(set (match_operand:DI 0 "register_operand" "=r")
3867 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3869 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3870 [(set_attr "type" "imovx")
3871 (set_attr "mode" "DI")])
3873 (define_insn "extendhisi2"
3874 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3875 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3878 switch (get_attr_prefix_0f (insn))
3881 return "{cwtl|cwde}";
3883 return "movs{wl|x}\t{%1, %0|%0, %1}";
3886 [(set_attr "type" "imovx")
3887 (set_attr "mode" "SI")
3888 (set (attr "prefix_0f")
3889 ;; movsx is short decodable while cwtl is vector decoded.
3890 (if_then_else (and (eq_attr "cpu" "!k6")
3891 (eq_attr "alternative" "0"))
3893 (const_string "1")))
3895 (if_then_else (eq_attr "prefix_0f" "0")
3897 (const_string "1")))])
3899 (define_insn "*extendhisi2_zext"
3900 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3903 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3906 switch (get_attr_prefix_0f (insn))
3909 return "{cwtl|cwde}";
3911 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3914 [(set_attr "type" "imovx")
3915 (set_attr "mode" "SI")
3916 (set (attr "prefix_0f")
3917 ;; movsx is short decodable while cwtl is vector decoded.
3918 (if_then_else (and (eq_attr "cpu" "!k6")
3919 (eq_attr "alternative" "0"))
3921 (const_string "1")))
3923 (if_then_else (eq_attr "prefix_0f" "0")
3925 (const_string "1")))])
3927 (define_insn "extendqisi2"
3928 [(set (match_operand:SI 0 "register_operand" "=r")
3929 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3931 "movs{bl|x}\t{%1, %0|%0, %1}"
3932 [(set_attr "type" "imovx")
3933 (set_attr "mode" "SI")])
3935 (define_insn "*extendqisi2_zext"
3936 [(set (match_operand:DI 0 "register_operand" "=r")
3938 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3940 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3941 [(set_attr "type" "imovx")
3942 (set_attr "mode" "SI")])
3944 (define_insn "extendqihi2"
3945 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3946 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3949 switch (get_attr_prefix_0f (insn))
3952 return "{cbtw|cbw}";
3954 return "movs{bw|x}\t{%1, %0|%0, %1}";
3957 [(set_attr "type" "imovx")
3958 (set_attr "mode" "HI")
3959 (set (attr "prefix_0f")
3960 ;; movsx is short decodable while cwtl is vector decoded.
3961 (if_then_else (and (eq_attr "cpu" "!k6")
3962 (eq_attr "alternative" "0"))
3964 (const_string "1")))
3966 (if_then_else (eq_attr "prefix_0f" "0")
3968 (const_string "1")))])
3970 ;; Conversions between float and double.
3972 ;; These are all no-ops in the model used for the 80387.
3973 ;; So just emit moves.
3975 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3977 [(set (match_operand:DF 0 "push_operand" "")
3978 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3980 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3981 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3984 [(set (match_operand:XF 0 "push_operand" "")
3985 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3987 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3988 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3989 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3991 (define_expand "extendsfdf2"
3992 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3993 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3994 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3996 /* ??? Needed for compress_float_constant since all fp constants
3997 are LEGITIMATE_CONSTANT_P. */
3998 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4000 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4001 && standard_80387_constant_p (operands[1]) > 0)
4003 operands[1] = simplify_const_unary_operation
4004 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4005 emit_move_insn_1 (operands[0], operands[1]);
4008 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4012 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4014 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4016 We do the conversion post reload to avoid producing of 128bit spills
4017 that might lead to ICE on 32bit target. The sequence unlikely combine
4020 [(set (match_operand:DF 0 "register_operand" "")
4022 (match_operand:SF 1 "nonimmediate_operand" "")))]
4023 "TARGET_USE_VECTOR_FP_CONVERTS
4024 && optimize_insn_for_speed_p ()
4025 && reload_completed && SSE_REG_P (operands[0])"
4030 (parallel [(const_int 0) (const_int 1)]))))]
4032 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4033 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4034 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4035 Try to avoid move when unpacking can be done in source. */
4036 if (REG_P (operands[1]))
4038 /* If it is unsafe to overwrite upper half of source, we need
4039 to move to destination and unpack there. */
4040 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4041 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4042 && true_regnum (operands[0]) != true_regnum (operands[1]))
4044 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4045 emit_move_insn (tmp, operands[1]);
4048 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4049 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4053 emit_insn (gen_vec_setv4sf_0 (operands[3],
4054 CONST0_RTX (V4SFmode), operands[1]));
4057 (define_insn "*extendsfdf2_mixed"
4058 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4060 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4061 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4063 switch (which_alternative)
4067 return output_387_reg_move (insn, operands);
4070 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4076 [(set_attr "type" "fmov,fmov,ssecvt")
4077 (set_attr "prefix" "orig,orig,maybe_vex")
4078 (set_attr "mode" "SF,XF,DF")])
4080 (define_insn "*extendsfdf2_sse"
4081 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4082 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4083 "TARGET_SSE2 && TARGET_SSE_MATH"
4084 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4085 [(set_attr "type" "ssecvt")
4086 (set_attr "prefix" "maybe_vex")
4087 (set_attr "mode" "DF")])
4089 (define_insn "*extendsfdf2_i387"
4090 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4091 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4093 "* return output_387_reg_move (insn, operands);"
4094 [(set_attr "type" "fmov")
4095 (set_attr "mode" "SF,XF")])
4097 (define_expand "extend<mode>xf2"
4098 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4099 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4102 /* ??? Needed for compress_float_constant since all fp constants
4103 are LEGITIMATE_CONSTANT_P. */
4104 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4106 if (standard_80387_constant_p (operands[1]) > 0)
4108 operands[1] = simplify_const_unary_operation
4109 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4110 emit_move_insn_1 (operands[0], operands[1]);
4113 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4117 (define_insn "*extend<mode>xf2_i387"
4118 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4120 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4122 "* return output_387_reg_move (insn, operands);"
4123 [(set_attr "type" "fmov")
4124 (set_attr "mode" "<MODE>,XF")])
4126 ;; %%% This seems bad bad news.
4127 ;; This cannot output into an f-reg because there is no way to be sure
4128 ;; of truncating in that case. Otherwise this is just like a simple move
4129 ;; insn. So we pretend we can output to a reg in order to get better
4130 ;; register preferencing, but we really use a stack slot.
4132 ;; Conversion from DFmode to SFmode.
4134 (define_expand "truncdfsf2"
4135 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4137 (match_operand:DF 1 "nonimmediate_operand" "")))]
4138 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4140 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4142 else if (flag_unsafe_math_optimizations)
4146 enum ix86_stack_slot slot = (virtuals_instantiated
4149 rtx temp = assign_386_stack_local (SFmode, slot);
4150 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4155 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4157 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4159 We do the conversion post reload to avoid producing of 128bit spills
4160 that might lead to ICE on 32bit target. The sequence unlikely combine
4163 [(set (match_operand:SF 0 "register_operand" "")
4165 (match_operand:DF 1 "nonimmediate_operand" "")))]
4166 "TARGET_USE_VECTOR_FP_CONVERTS
4167 && optimize_insn_for_speed_p ()
4168 && reload_completed && SSE_REG_P (operands[0])"
4171 (float_truncate:V2SF
4175 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4176 operands[3] = CONST0_RTX (V2SFmode);
4177 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4178 /* Use movsd for loading from memory, unpcklpd for registers.
4179 Try to avoid move when unpacking can be done in source, or SSE3
4180 movddup is available. */
4181 if (REG_P (operands[1]))
4184 && true_regnum (operands[0]) != true_regnum (operands[1])
4185 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4186 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4188 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4189 emit_move_insn (tmp, operands[1]);
4192 else if (!TARGET_SSE3)
4193 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4194 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4197 emit_insn (gen_sse2_loadlpd (operands[4],
4198 CONST0_RTX (V2DFmode), operands[1]));
4201 (define_expand "truncdfsf2_with_temp"
4202 [(parallel [(set (match_operand:SF 0 "" "")
4203 (float_truncate:SF (match_operand:DF 1 "" "")))
4204 (clobber (match_operand:SF 2 "" ""))])])
4206 (define_insn "*truncdfsf_fast_mixed"
4207 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4209 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4210 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4212 switch (which_alternative)
4215 return output_387_reg_move (insn, operands);
4217 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4222 [(set_attr "type" "fmov,ssecvt")
4223 (set_attr "prefix" "orig,maybe_vex")
4224 (set_attr "mode" "SF")])
4226 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4227 ;; because nothing we do here is unsafe.
4228 (define_insn "*truncdfsf_fast_sse"
4229 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4231 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4232 "TARGET_SSE2 && TARGET_SSE_MATH"
4233 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4234 [(set_attr "type" "ssecvt")
4235 (set_attr "prefix" "maybe_vex")
4236 (set_attr "mode" "SF")])
4238 (define_insn "*truncdfsf_fast_i387"
4239 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4241 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4242 "TARGET_80387 && flag_unsafe_math_optimizations"
4243 "* return output_387_reg_move (insn, operands);"
4244 [(set_attr "type" "fmov")
4245 (set_attr "mode" "SF")])
4247 (define_insn "*truncdfsf_mixed"
4248 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4250 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4251 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4252 "TARGET_MIX_SSE_I387"
4254 switch (which_alternative)
4257 return output_387_reg_move (insn, operands);
4259 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4265 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4266 (set_attr "unit" "*,*,i387,i387,i387")
4267 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4268 (set_attr "mode" "SF")])
4270 (define_insn "*truncdfsf_i387"
4271 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4273 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4274 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4277 switch (which_alternative)
4280 return output_387_reg_move (insn, operands);
4286 [(set_attr "type" "fmov,multi,multi,multi")
4287 (set_attr "unit" "*,i387,i387,i387")
4288 (set_attr "mode" "SF")])
4290 (define_insn "*truncdfsf2_i387_1"
4291 [(set (match_operand:SF 0 "memory_operand" "=m")
4293 (match_operand:DF 1 "register_operand" "f")))]
4295 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4296 && !TARGET_MIX_SSE_I387"
4297 "* return output_387_reg_move (insn, operands);"
4298 [(set_attr "type" "fmov")
4299 (set_attr "mode" "SF")])
4302 [(set (match_operand:SF 0 "register_operand" "")
4304 (match_operand:DF 1 "fp_register_operand" "")))
4305 (clobber (match_operand 2 "" ""))]
4307 [(set (match_dup 2) (match_dup 1))
4308 (set (match_dup 0) (match_dup 2))]
4309 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4311 ;; Conversion from XFmode to {SF,DF}mode
4313 (define_expand "truncxf<mode>2"
4314 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4315 (float_truncate:MODEF
4316 (match_operand:XF 1 "register_operand" "")))
4317 (clobber (match_dup 2))])]
4320 if (flag_unsafe_math_optimizations)
4322 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4323 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4324 if (reg != operands[0])
4325 emit_move_insn (operands[0], reg);
4330 enum ix86_stack_slot slot = (virtuals_instantiated
4333 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4337 (define_insn "*truncxfsf2_mixed"
4338 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4340 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4341 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4344 gcc_assert (!which_alternative);
4345 return output_387_reg_move (insn, operands);
4347 [(set_attr "type" "fmov,multi,multi,multi")
4348 (set_attr "unit" "*,i387,i387,i387")
4349 (set_attr "mode" "SF")])
4351 (define_insn "*truncxfdf2_mixed"
4352 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4354 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4355 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4358 gcc_assert (!which_alternative);
4359 return output_387_reg_move (insn, operands);
4361 [(set_attr "type" "fmov,multi,multi,multi")
4362 (set_attr "unit" "*,i387,i387,i387")
4363 (set_attr "mode" "DF")])
4365 (define_insn "truncxf<mode>2_i387_noop"
4366 [(set (match_operand:MODEF 0 "register_operand" "=f")
4367 (float_truncate:MODEF
4368 (match_operand:XF 1 "register_operand" "f")))]
4369 "TARGET_80387 && flag_unsafe_math_optimizations"
4370 "* return output_387_reg_move (insn, operands);"
4371 [(set_attr "type" "fmov")
4372 (set_attr "mode" "<MODE>")])
4374 (define_insn "*truncxf<mode>2_i387"
4375 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4376 (float_truncate:MODEF
4377 (match_operand:XF 1 "register_operand" "f")))]
4379 "* return output_387_reg_move (insn, operands);"
4380 [(set_attr "type" "fmov")
4381 (set_attr "mode" "<MODE>")])
4384 [(set (match_operand:MODEF 0 "register_operand" "")
4385 (float_truncate:MODEF
4386 (match_operand:XF 1 "register_operand" "")))
4387 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4388 "TARGET_80387 && reload_completed"
4389 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4390 (set (match_dup 0) (match_dup 2))])
4393 [(set (match_operand:MODEF 0 "memory_operand" "")
4394 (float_truncate:MODEF
4395 (match_operand:XF 1 "register_operand" "")))
4396 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4398 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4400 ;; Signed conversion to DImode.
4402 (define_expand "fix_truncxfdi2"
4403 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4404 (fix:DI (match_operand:XF 1 "register_operand" "")))
4405 (clobber (reg:CC FLAGS_REG))])]
4410 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4415 (define_expand "fix_trunc<mode>di2"
4416 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4417 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4418 (clobber (reg:CC FLAGS_REG))])]
4419 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4422 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4424 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4427 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4429 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4430 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4431 if (out != operands[0])
4432 emit_move_insn (operands[0], out);
4437 ;; Signed conversion to SImode.
4439 (define_expand "fix_truncxfsi2"
4440 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4441 (fix:SI (match_operand:XF 1 "register_operand" "")))
4442 (clobber (reg:CC FLAGS_REG))])]
4447 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4452 (define_expand "fix_trunc<mode>si2"
4453 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4454 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4455 (clobber (reg:CC FLAGS_REG))])]
4456 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4459 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4461 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4464 if (SSE_FLOAT_MODE_P (<MODE>mode))
4466 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4467 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4468 if (out != operands[0])
4469 emit_move_insn (operands[0], out);
4474 ;; Signed conversion to HImode.
4476 (define_expand "fix_trunc<mode>hi2"
4477 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4478 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4479 (clobber (reg:CC FLAGS_REG))])]
4481 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4485 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4490 ;; Unsigned conversion to SImode.
4492 (define_expand "fixuns_trunc<mode>si2"
4494 [(set (match_operand:SI 0 "register_operand" "")
4496 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4498 (clobber (match_scratch:<ssevecmode> 3 ""))
4499 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4500 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4502 enum machine_mode mode = <MODE>mode;
4503 enum machine_mode vecmode = <ssevecmode>mode;
4504 REAL_VALUE_TYPE TWO31r;
4507 if (optimize_insn_for_size_p ())
4510 real_ldexp (&TWO31r, &dconst1, 31);
4511 two31 = const_double_from_real_value (TWO31r, mode);
4512 two31 = ix86_build_const_vector (mode, true, two31);
4513 operands[2] = force_reg (vecmode, two31);
4516 (define_insn_and_split "*fixuns_trunc<mode>_1"
4517 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4519 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4520 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4521 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4522 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4523 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4524 && optimize_function_for_speed_p (cfun)"
4526 "&& reload_completed"
4529 ix86_split_convert_uns_si_sse (operands);
4533 ;; Unsigned conversion to HImode.
4534 ;; Without these patterns, we'll try the unsigned SI conversion which
4535 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4537 (define_expand "fixuns_trunc<mode>hi2"
4539 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4540 (set (match_operand:HI 0 "nonimmediate_operand" "")
4541 (subreg:HI (match_dup 2) 0))]
4542 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4543 "operands[2] = gen_reg_rtx (SImode);")
4545 ;; When SSE is available, it is always faster to use it!
4546 (define_insn "fix_trunc<mode>di_sse"
4547 [(set (match_operand:DI 0 "register_operand" "=r,r")
4548 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4549 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4550 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4551 "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4552 [(set_attr "type" "sseicvt")
4553 (set_attr "prefix" "maybe_vex")
4554 (set_attr "prefix_rex" "1")
4555 (set_attr "mode" "<MODE>")
4556 (set_attr "athlon_decode" "double,vector")
4557 (set_attr "amdfam10_decode" "double,double")])
4559 (define_insn "fix_trunc<mode>si_sse"
4560 [(set (match_operand:SI 0 "register_operand" "=r,r")
4561 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4562 "SSE_FLOAT_MODE_P (<MODE>mode)
4563 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4564 "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4565 [(set_attr "type" "sseicvt")
4566 (set_attr "prefix" "maybe_vex")
4567 (set_attr "mode" "<MODE>")
4568 (set_attr "athlon_decode" "double,vector")
4569 (set_attr "amdfam10_decode" "double,double")])
4571 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4573 [(set (match_operand:MODEF 0 "register_operand" "")
4574 (match_operand:MODEF 1 "memory_operand" ""))
4575 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4576 (fix:SSEMODEI24 (match_dup 0)))]
4577 "TARGET_SHORTEN_X87_SSE
4578 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4579 && peep2_reg_dead_p (2, operands[0])"
4580 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))])
4582 ;; Avoid vector decoded forms of the instruction.
4584 [(match_scratch:DF 2 "Y2")
4585 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4586 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4587 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4588 [(set (match_dup 2) (match_dup 1))
4589 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4592 [(match_scratch:SF 2 "x")
4593 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4594 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4595 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4596 [(set (match_dup 2) (match_dup 1))
4597 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4599 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4600 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4601 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4602 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4604 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4605 && (TARGET_64BIT || <MODE>mode != DImode))
4607 && can_create_pseudo_p ()"
4612 if (memory_operand (operands[0], VOIDmode))
4613 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4616 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4617 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4623 [(set_attr "type" "fisttp")
4624 (set_attr "mode" "<MODE>")])
4626 (define_insn "fix_trunc<mode>_i387_fisttp"
4627 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4628 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4629 (clobber (match_scratch:XF 2 "=&1f"))]
4630 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4632 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4633 && (TARGET_64BIT || <MODE>mode != DImode))
4634 && TARGET_SSE_MATH)"
4635 "* return output_fix_trunc (insn, operands, 1);"
4636 [(set_attr "type" "fisttp")
4637 (set_attr "mode" "<MODE>")])
4639 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4640 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4641 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4642 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4643 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4644 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4646 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4647 && (TARGET_64BIT || <MODE>mode != DImode))
4648 && TARGET_SSE_MATH)"
4650 [(set_attr "type" "fisttp")
4651 (set_attr "mode" "<MODE>")])
4654 [(set (match_operand:X87MODEI 0 "register_operand" "")
4655 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4656 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4657 (clobber (match_scratch 3 ""))]
4659 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4660 (clobber (match_dup 3))])
4661 (set (match_dup 0) (match_dup 2))])
4664 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4665 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4666 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4667 (clobber (match_scratch 3 ""))]
4669 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4670 (clobber (match_dup 3))])])
4672 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4673 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4674 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4675 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4676 ;; function in i386.c.
4677 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4678 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4679 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4680 (clobber (reg:CC FLAGS_REG))]
4681 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4683 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4684 && (TARGET_64BIT || <MODE>mode != DImode))
4685 && can_create_pseudo_p ()"
4690 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4692 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4693 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4694 if (memory_operand (operands[0], VOIDmode))
4695 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4696 operands[2], operands[3]));
4699 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4700 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4701 operands[2], operands[3],
4706 [(set_attr "type" "fistp")
4707 (set_attr "i387_cw" "trunc")
4708 (set_attr "mode" "<MODE>")])
4710 (define_insn "fix_truncdi_i387"
4711 [(set (match_operand:DI 0 "memory_operand" "=m")
4712 (fix:DI (match_operand 1 "register_operand" "f")))
4713 (use (match_operand:HI 2 "memory_operand" "m"))
4714 (use (match_operand:HI 3 "memory_operand" "m"))
4715 (clobber (match_scratch:XF 4 "=&1f"))]
4716 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4718 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4719 "* return output_fix_trunc (insn, operands, 0);"
4720 [(set_attr "type" "fistp")
4721 (set_attr "i387_cw" "trunc")
4722 (set_attr "mode" "DI")])
4724 (define_insn "fix_truncdi_i387_with_temp"
4725 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4726 (fix:DI (match_operand 1 "register_operand" "f,f")))
4727 (use (match_operand:HI 2 "memory_operand" "m,m"))
4728 (use (match_operand:HI 3 "memory_operand" "m,m"))
4729 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4730 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4731 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4733 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4735 [(set_attr "type" "fistp")
4736 (set_attr "i387_cw" "trunc")
4737 (set_attr "mode" "DI")])
4740 [(set (match_operand:DI 0 "register_operand" "")
4741 (fix:DI (match_operand 1 "register_operand" "")))
4742 (use (match_operand:HI 2 "memory_operand" ""))
4743 (use (match_operand:HI 3 "memory_operand" ""))
4744 (clobber (match_operand:DI 4 "memory_operand" ""))
4745 (clobber (match_scratch 5 ""))]
4747 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4750 (clobber (match_dup 5))])
4751 (set (match_dup 0) (match_dup 4))])
4754 [(set (match_operand:DI 0 "memory_operand" "")
4755 (fix:DI (match_operand 1 "register_operand" "")))
4756 (use (match_operand:HI 2 "memory_operand" ""))
4757 (use (match_operand:HI 3 "memory_operand" ""))
4758 (clobber (match_operand:DI 4 "memory_operand" ""))
4759 (clobber (match_scratch 5 ""))]
4761 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4764 (clobber (match_dup 5))])])
4766 (define_insn "fix_trunc<mode>_i387"
4767 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4768 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4769 (use (match_operand:HI 2 "memory_operand" "m"))
4770 (use (match_operand:HI 3 "memory_operand" "m"))]
4771 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4773 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4774 "* return output_fix_trunc (insn, operands, 0);"
4775 [(set_attr "type" "fistp")
4776 (set_attr "i387_cw" "trunc")
4777 (set_attr "mode" "<MODE>")])
4779 (define_insn "fix_trunc<mode>_i387_with_temp"
4780 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4781 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4782 (use (match_operand:HI 2 "memory_operand" "m,m"))
4783 (use (match_operand:HI 3 "memory_operand" "m,m"))
4784 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4785 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4787 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4789 [(set_attr "type" "fistp")
4790 (set_attr "i387_cw" "trunc")
4791 (set_attr "mode" "<MODE>")])
4794 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4795 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4796 (use (match_operand:HI 2 "memory_operand" ""))
4797 (use (match_operand:HI 3 "memory_operand" ""))
4798 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4800 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4802 (use (match_dup 3))])
4803 (set (match_dup 0) (match_dup 4))])
4806 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4807 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4808 (use (match_operand:HI 2 "memory_operand" ""))
4809 (use (match_operand:HI 3 "memory_operand" ""))
4810 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4812 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4814 (use (match_dup 3))])])
4816 (define_insn "x86_fnstcw_1"
4817 [(set (match_operand:HI 0 "memory_operand" "=m")
4818 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4821 [(set (attr "length")
4822 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4823 (set_attr "mode" "HI")
4824 (set_attr "unit" "i387")])
4826 (define_insn "x86_fldcw_1"
4827 [(set (reg:HI FPCR_REG)
4828 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4831 [(set (attr "length")
4832 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4833 (set_attr "mode" "HI")
4834 (set_attr "unit" "i387")
4835 (set_attr "athlon_decode" "vector")
4836 (set_attr "amdfam10_decode" "vector")])
4838 ;; Conversion between fixed point and floating point.
4840 ;; Even though we only accept memory inputs, the backend _really_
4841 ;; wants to be able to do this between registers.
4843 (define_expand "floathi<mode>2"
4844 [(set (match_operand:X87MODEF 0 "register_operand" "")
4845 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4847 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4848 || TARGET_MIX_SSE_I387)")
4850 ;; Pre-reload splitter to add memory clobber to the pattern.
4851 (define_insn_and_split "*floathi<mode>2_1"
4852 [(set (match_operand:X87MODEF 0 "register_operand" "")
4853 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4855 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4856 || TARGET_MIX_SSE_I387)
4857 && can_create_pseudo_p ()"
4860 [(parallel [(set (match_dup 0)
4861 (float:X87MODEF (match_dup 1)))
4862 (clobber (match_dup 2))])]
4863 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4865 (define_insn "*floathi<mode>2_i387_with_temp"
4866 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4867 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4868 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4870 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4871 || TARGET_MIX_SSE_I387)"
4873 [(set_attr "type" "fmov,multi")
4874 (set_attr "mode" "<MODE>")
4875 (set_attr "unit" "*,i387")
4876 (set_attr "fp_int_src" "true")])
4878 (define_insn "*floathi<mode>2_i387"
4879 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4880 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4882 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4883 || TARGET_MIX_SSE_I387)"
4885 [(set_attr "type" "fmov")
4886 (set_attr "mode" "<MODE>")
4887 (set_attr "fp_int_src" "true")])
4890 [(set (match_operand:X87MODEF 0 "register_operand" "")
4891 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4892 (clobber (match_operand:HI 2 "memory_operand" ""))]
4894 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4895 || TARGET_MIX_SSE_I387)
4896 && reload_completed"
4897 [(set (match_dup 2) (match_dup 1))
4898 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4901 [(set (match_operand:X87MODEF 0 "register_operand" "")
4902 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4903 (clobber (match_operand:HI 2 "memory_operand" ""))]
4905 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4906 || TARGET_MIX_SSE_I387)
4907 && reload_completed"
4908 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4910 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
4911 [(set (match_operand:X87MODEF 0 "register_operand" "")
4913 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
4915 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4916 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4918 if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4919 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4920 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
4922 rtx reg = gen_reg_rtx (XFmode);
4925 emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
4927 if (<X87MODEF:MODE>mode == SFmode)
4928 insn = gen_truncxfsf2 (operands[0], reg);
4929 else if (<X87MODEF:MODE>mode == DFmode)
4930 insn = gen_truncxfdf2 (operands[0], reg);
4939 ;; Pre-reload splitter to add memory clobber to the pattern.
4940 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
4941 [(set (match_operand:X87MODEF 0 "register_operand" "")
4942 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
4944 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
4945 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4946 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4947 || TARGET_MIX_SSE_I387))
4948 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4949 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4950 && ((<SSEMODEI24:MODE>mode == SImode
4951 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4952 && optimize_function_for_speed_p (cfun)
4953 && flag_trapping_math)
4954 || !(TARGET_INTER_UNIT_CONVERSIONS
4955 || optimize_function_for_size_p (cfun)))))
4956 && can_create_pseudo_p ()"
4959 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4960 (clobber (match_dup 2))])]
4962 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
4964 /* Avoid store forwarding (partial memory) stall penalty
4965 by passing DImode value through XMM registers. */
4966 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
4967 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4968 && optimize_function_for_speed_p (cfun))
4970 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4977 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4978 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4980 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4981 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4982 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4983 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4985 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4986 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4987 (set_attr "unit" "*,i387,*,*,*")
4988 (set_attr "athlon_decode" "*,*,double,direct,double")
4989 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4990 (set_attr "fp_int_src" "true")])
4992 (define_insn "*floatsi<mode>2_vector_mixed"
4993 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4994 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4995 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4996 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5000 [(set_attr "type" "fmov,sseicvt")
5001 (set_attr "mode" "<MODE>,<ssevecmode>")
5002 (set_attr "unit" "i387,*")
5003 (set_attr "athlon_decode" "*,direct")
5004 (set_attr "amdfam10_decode" "*,double")
5005 (set_attr "fp_int_src" "true")])
5007 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5008 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5010 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5011 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5012 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5013 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5015 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5016 (set_attr "mode" "<MODEF:MODE>")
5017 (set_attr "unit" "*,i387,*,*")
5018 (set_attr "athlon_decode" "*,*,double,direct")
5019 (set_attr "amdfam10_decode" "*,*,vector,double")
5020 (set_attr "fp_int_src" "true")])
5023 [(set (match_operand:MODEF 0 "register_operand" "")
5024 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5025 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5026 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5027 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5028 && TARGET_INTER_UNIT_CONVERSIONS
5030 && (SSE_REG_P (operands[0])
5031 || (GET_CODE (operands[0]) == SUBREG
5032 && SSE_REG_P (operands[0])))"
5033 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5036 [(set (match_operand:MODEF 0 "register_operand" "")
5037 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5038 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5039 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5040 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5041 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5043 && (SSE_REG_P (operands[0])
5044 || (GET_CODE (operands[0]) == SUBREG
5045 && SSE_REG_P (operands[0])))"
5046 [(set (match_dup 2) (match_dup 1))
5047 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5049 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5050 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5052 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5053 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5054 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5055 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5058 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5059 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5060 [(set_attr "type" "fmov,sseicvt,sseicvt")
5061 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5062 (set_attr "mode" "<MODEF:MODE>")
5063 (set (attr "prefix_rex")
5065 (and (eq_attr "prefix" "maybe_vex")
5066 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5068 (const_string "*")))
5069 (set_attr "unit" "i387,*,*")
5070 (set_attr "athlon_decode" "*,double,direct")
5071 (set_attr "amdfam10_decode" "*,vector,double")
5072 (set_attr "fp_int_src" "true")])
5074 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5075 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5077 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5078 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5079 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5080 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5083 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5084 [(set_attr "type" "fmov,sseicvt")
5085 (set_attr "prefix" "orig,maybe_vex")
5086 (set_attr "mode" "<MODEF:MODE>")
5087 (set (attr "prefix_rex")
5089 (and (eq_attr "prefix" "maybe_vex")
5090 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5092 (const_string "*")))
5093 (set_attr "athlon_decode" "*,direct")
5094 (set_attr "amdfam10_decode" "*,double")
5095 (set_attr "fp_int_src" "true")])
5097 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5098 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5100 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5101 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5102 "TARGET_SSE2 && TARGET_SSE_MATH
5103 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5105 [(set_attr "type" "sseicvt")
5106 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5107 (set_attr "athlon_decode" "double,direct,double")
5108 (set_attr "amdfam10_decode" "vector,double,double")
5109 (set_attr "fp_int_src" "true")])
5111 (define_insn "*floatsi<mode>2_vector_sse"
5112 [(set (match_operand:MODEF 0 "register_operand" "=x")
5113 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5114 "TARGET_SSE2 && TARGET_SSE_MATH
5115 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5117 [(set_attr "type" "sseicvt")
5118 (set_attr "mode" "<MODE>")
5119 (set_attr "athlon_decode" "direct")
5120 (set_attr "amdfam10_decode" "double")
5121 (set_attr "fp_int_src" "true")])
5124 [(set (match_operand:MODEF 0 "register_operand" "")
5125 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5126 (clobber (match_operand:SI 2 "memory_operand" ""))]
5127 "TARGET_SSE2 && TARGET_SSE_MATH
5128 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5130 && (SSE_REG_P (operands[0])
5131 || (GET_CODE (operands[0]) == SUBREG
5132 && SSE_REG_P (operands[0])))"
5135 rtx op1 = operands[1];
5137 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5139 if (GET_CODE (op1) == SUBREG)
5140 op1 = SUBREG_REG (op1);
5142 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5144 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5145 emit_insn (gen_sse2_loadld (operands[4],
5146 CONST0_RTX (V4SImode), operands[1]));
5148 /* We can ignore possible trapping value in the
5149 high part of SSE register for non-trapping math. */
5150 else if (SSE_REG_P (op1) && !flag_trapping_math)
5151 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5154 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5155 emit_move_insn (operands[2], operands[1]);
5156 emit_insn (gen_sse2_loadld (operands[4],
5157 CONST0_RTX (V4SImode), operands[2]));
5160 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5165 [(set (match_operand:MODEF 0 "register_operand" "")
5166 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5167 (clobber (match_operand:SI 2 "memory_operand" ""))]
5168 "TARGET_SSE2 && TARGET_SSE_MATH
5169 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5171 && (SSE_REG_P (operands[0])
5172 || (GET_CODE (operands[0]) == SUBREG
5173 && SSE_REG_P (operands[0])))"
5176 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5178 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5180 emit_insn (gen_sse2_loadld (operands[4],
5181 CONST0_RTX (V4SImode), operands[1]));
5183 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5188 [(set (match_operand:MODEF 0 "register_operand" "")
5189 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5190 "TARGET_SSE2 && TARGET_SSE_MATH
5191 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5193 && (SSE_REG_P (operands[0])
5194 || (GET_CODE (operands[0]) == SUBREG
5195 && SSE_REG_P (operands[0])))"
5198 rtx op1 = operands[1];
5200 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5202 if (GET_CODE (op1) == SUBREG)
5203 op1 = SUBREG_REG (op1);
5205 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5207 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5208 emit_insn (gen_sse2_loadld (operands[4],
5209 CONST0_RTX (V4SImode), operands[1]));
5211 /* We can ignore possible trapping value in the
5212 high part of SSE register for non-trapping math. */
5213 else if (SSE_REG_P (op1) && !flag_trapping_math)
5214 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5218 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5223 [(set (match_operand:MODEF 0 "register_operand" "")
5224 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5225 "TARGET_SSE2 && TARGET_SSE_MATH
5226 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5228 && (SSE_REG_P (operands[0])
5229 || (GET_CODE (operands[0]) == SUBREG
5230 && SSE_REG_P (operands[0])))"
5233 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5235 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5237 emit_insn (gen_sse2_loadld (operands[4],
5238 CONST0_RTX (V4SImode), operands[1]));
5240 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5244 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5245 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5247 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5248 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5249 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5250 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5252 [(set_attr "type" "sseicvt")
5253 (set_attr "mode" "<MODEF:MODE>")
5254 (set_attr "athlon_decode" "double,direct")
5255 (set_attr "amdfam10_decode" "vector,double")
5256 (set_attr "fp_int_src" "true")])
5258 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5259 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5261 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5262 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5263 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5264 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5265 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5266 [(set_attr "type" "sseicvt")
5267 (set_attr "prefix" "maybe_vex")
5268 (set_attr "mode" "<MODEF:MODE>")
5269 (set (attr "prefix_rex")
5271 (and (eq_attr "prefix" "maybe_vex")
5272 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5274 (const_string "*")))
5275 (set_attr "athlon_decode" "double,direct")
5276 (set_attr "amdfam10_decode" "vector,double")
5277 (set_attr "fp_int_src" "true")])
5280 [(set (match_operand:MODEF 0 "register_operand" "")
5281 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5282 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5283 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5284 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5285 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5287 && (SSE_REG_P (operands[0])
5288 || (GET_CODE (operands[0]) == SUBREG
5289 && SSE_REG_P (operands[0])))"
5290 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5292 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5293 [(set (match_operand:MODEF 0 "register_operand" "=x")
5295 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5296 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5297 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5298 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5299 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5300 [(set_attr "type" "sseicvt")
5301 (set_attr "prefix" "maybe_vex")
5302 (set_attr "mode" "<MODEF:MODE>")
5303 (set (attr "prefix_rex")
5305 (and (eq_attr "prefix" "maybe_vex")
5306 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5308 (const_string "*")))
5309 (set_attr "athlon_decode" "direct")
5310 (set_attr "amdfam10_decode" "double")
5311 (set_attr "fp_int_src" "true")])
5314 [(set (match_operand:MODEF 0 "register_operand" "")
5315 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5316 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5317 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5318 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5319 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5321 && (SSE_REG_P (operands[0])
5322 || (GET_CODE (operands[0]) == SUBREG
5323 && SSE_REG_P (operands[0])))"
5324 [(set (match_dup 2) (match_dup 1))
5325 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5328 [(set (match_operand:MODEF 0 "register_operand" "")
5329 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5330 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5331 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5332 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5334 && (SSE_REG_P (operands[0])
5335 || (GET_CODE (operands[0]) == SUBREG
5336 && SSE_REG_P (operands[0])))"
5337 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5339 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5340 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5342 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5343 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5345 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5349 [(set_attr "type" "fmov,multi")
5350 (set_attr "mode" "<X87MODEF:MODE>")
5351 (set_attr "unit" "*,i387")
5352 (set_attr "fp_int_src" "true")])
5354 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5355 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5357 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5359 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5361 [(set_attr "type" "fmov")
5362 (set_attr "mode" "<X87MODEF:MODE>")
5363 (set_attr "fp_int_src" "true")])
5366 [(set (match_operand:X87MODEF 0 "register_operand" "")
5367 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5368 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5370 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5372 && FP_REG_P (operands[0])"
5373 [(set (match_dup 2) (match_dup 1))
5374 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5377 [(set (match_operand:X87MODEF 0 "register_operand" "")
5378 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5379 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5381 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5383 && FP_REG_P (operands[0])"
5384 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5386 ;; Avoid store forwarding (partial memory) stall penalty
5387 ;; by passing DImode value through XMM registers. */
5389 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5390 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5392 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5393 (clobber (match_scratch:V4SI 3 "=X,x"))
5394 (clobber (match_scratch:V4SI 4 "=X,x"))
5395 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5396 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5397 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5398 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5400 [(set_attr "type" "multi")
5401 (set_attr "mode" "<X87MODEF:MODE>")
5402 (set_attr "unit" "i387")
5403 (set_attr "fp_int_src" "true")])
5406 [(set (match_operand:X87MODEF 0 "register_operand" "")
5407 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5408 (clobber (match_scratch:V4SI 3 ""))
5409 (clobber (match_scratch:V4SI 4 ""))
5410 (clobber (match_operand:DI 2 "memory_operand" ""))]
5411 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5412 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5413 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5415 && FP_REG_P (operands[0])"
5416 [(set (match_dup 2) (match_dup 3))
5417 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5419 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5420 Assemble the 64-bit DImode value in an xmm register. */
5421 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5422 gen_rtx_SUBREG (SImode, operands[1], 0)));
5423 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5424 gen_rtx_SUBREG (SImode, operands[1], 4)));
5425 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5428 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5432 [(set (match_operand:X87MODEF 0 "register_operand" "")
5433 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5434 (clobber (match_scratch:V4SI 3 ""))
5435 (clobber (match_scratch:V4SI 4 ""))
5436 (clobber (match_operand:DI 2 "memory_operand" ""))]
5437 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5438 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5439 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5441 && FP_REG_P (operands[0])"
5442 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5444 ;; Avoid store forwarding (partial memory) stall penalty by extending
5445 ;; SImode value to DImode through XMM register instead of pushing two
5446 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5447 ;; targets benefit from this optimization. Also note that fild
5448 ;; loads from memory only.
5450 (define_insn "*floatunssi<mode>2_1"
5451 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5452 (unsigned_float:X87MODEF
5453 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5454 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5455 (clobber (match_scratch:SI 3 "=X,x"))]
5457 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5460 [(set_attr "type" "multi")
5461 (set_attr "mode" "<MODE>")])
5464 [(set (match_operand:X87MODEF 0 "register_operand" "")
5465 (unsigned_float:X87MODEF
5466 (match_operand:SI 1 "register_operand" "")))
5467 (clobber (match_operand:DI 2 "memory_operand" ""))
5468 (clobber (match_scratch:SI 3 ""))]
5470 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5472 && reload_completed"
5473 [(set (match_dup 2) (match_dup 1))
5475 (float:X87MODEF (match_dup 2)))]
5476 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5479 [(set (match_operand:X87MODEF 0 "register_operand" "")
5480 (unsigned_float:X87MODEF
5481 (match_operand:SI 1 "memory_operand" "")))
5482 (clobber (match_operand:DI 2 "memory_operand" ""))
5483 (clobber (match_scratch:SI 3 ""))]
5485 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5487 && reload_completed"
5488 [(set (match_dup 2) (match_dup 3))
5490 (float:X87MODEF (match_dup 2)))]
5492 emit_move_insn (operands[3], operands[1]);
5493 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5496 (define_expand "floatunssi<mode>2"
5498 [(set (match_operand:X87MODEF 0 "register_operand" "")
5499 (unsigned_float:X87MODEF
5500 (match_operand:SI 1 "nonimmediate_operand" "")))
5501 (clobber (match_dup 2))
5502 (clobber (match_scratch:SI 3 ""))])]
5504 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5506 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5508 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5510 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5515 enum ix86_stack_slot slot = (virtuals_instantiated
5518 operands[2] = assign_386_stack_local (DImode, slot);
5522 (define_expand "floatunsdisf2"
5523 [(use (match_operand:SF 0 "register_operand" ""))
5524 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5525 "TARGET_64BIT && TARGET_SSE_MATH"
5526 "x86_emit_floatuns (operands); DONE;")
5528 (define_expand "floatunsdidf2"
5529 [(use (match_operand:DF 0 "register_operand" ""))
5530 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5531 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5532 && TARGET_SSE2 && TARGET_SSE_MATH"
5535 x86_emit_floatuns (operands);
5537 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5543 (define_expand "add<mode>3"
5544 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5545 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5546 (match_operand:SDWIM 2 "<general_operand>" "")))]
5548 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5550 (define_insn_and_split "*add<dwi>3_doubleword"
5551 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5553 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5554 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5555 (clobber (reg:CC FLAGS_REG))]
5556 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5559 [(parallel [(set (reg:CC FLAGS_REG)
5560 (unspec:CC [(match_dup 1) (match_dup 2)]
5563 (plus:DWIH (match_dup 1) (match_dup 2)))])
5564 (parallel [(set (match_dup 3)
5568 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5570 (clobber (reg:CC FLAGS_REG))])]
5571 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5573 (define_insn "*add<mode>3_cc"
5574 [(set (reg:CC FLAGS_REG)
5576 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5577 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5579 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5580 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5581 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5582 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5583 [(set_attr "type" "alu")
5584 (set_attr "mode" "<MODE>")])
5586 (define_insn "addqi3_cc"
5587 [(set (reg:CC FLAGS_REG)
5589 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5590 (match_operand:QI 2 "general_operand" "qn,qm")]
5592 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5593 (plus:QI (match_dup 1) (match_dup 2)))]
5594 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5595 "add{b}\t{%2, %0|%0, %2}"
5596 [(set_attr "type" "alu")
5597 (set_attr "mode" "QI")])
5599 (define_insn "*lea_1"
5600 [(set (match_operand:P 0 "register_operand" "=r")
5601 (match_operand:P 1 "no_seg_address_operand" "p"))]
5603 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5604 [(set_attr "type" "lea")
5605 (set_attr "mode" "<MODE>")])
5607 (define_insn "*lea_2"
5608 [(set (match_operand:SI 0 "register_operand" "=r")
5609 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5611 "lea{l}\t{%a1, %0|%0, %a1}"
5612 [(set_attr "type" "lea")
5613 (set_attr "mode" "SI")])
5615 (define_insn "*lea_2_zext"
5616 [(set (match_operand:DI 0 "register_operand" "=r")
5618 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5620 "lea{l}\t{%a1, %k0|%k0, %a1}"
5621 [(set_attr "type" "lea")
5622 (set_attr "mode" "SI")])
5624 (define_insn "*add<mode>_1"
5625 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5627 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5628 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5629 (clobber (reg:CC FLAGS_REG))]
5630 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5632 switch (get_attr_type (insn))
5638 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5639 if (operands[2] == const1_rtx)
5640 return "inc{<imodesuffix>}\t%0";
5643 gcc_assert (operands[2] == constm1_rtx);
5644 return "dec{<imodesuffix>}\t%0";
5648 /* For most processors, ADD is faster than LEA. This alternative
5649 was added to use ADD as much as possible. */
5650 if (which_alternative == 2)
5653 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5656 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5657 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5658 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5660 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5664 (cond [(eq_attr "alternative" "3")
5665 (const_string "lea")
5666 (match_operand:SWI48 2 "incdec_operand" "")
5667 (const_string "incdec")
5669 (const_string "alu")))
5670 (set (attr "length_immediate")
5672 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5674 (const_string "*")))
5675 (set_attr "mode" "<MODE>")])
5677 ;; It may seem that nonimmediate operand is proper one for operand 1.
5678 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5679 ;; we take care in ix86_binary_operator_ok to not allow two memory
5680 ;; operands so proper swapping will be done in reload. This allow
5681 ;; patterns constructed from addsi_1 to match.
5683 (define_insn "*addsi_1_zext"
5684 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5686 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5687 (match_operand:SI 2 "general_operand" "g,0,li"))))
5688 (clobber (reg:CC FLAGS_REG))]
5689 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5691 switch (get_attr_type (insn))
5697 if (operands[2] == const1_rtx)
5698 return "inc{l}\t%k0";
5701 gcc_assert (operands[2] == constm1_rtx);
5702 return "dec{l}\t%k0";
5706 /* For most processors, ADD is faster than LEA. This alternative
5707 was added to use ADD as much as possible. */
5708 if (which_alternative == 1)
5711 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5714 if (x86_maybe_negate_const_int (&operands[2], SImode))
5715 return "sub{l}\t{%2, %k0|%k0, %2}";
5717 return "add{l}\t{%2, %k0|%k0, %2}";
5721 (cond [(eq_attr "alternative" "2")
5722 (const_string "lea")
5723 (match_operand:SI 2 "incdec_operand" "")
5724 (const_string "incdec")
5726 (const_string "alu")))
5727 (set (attr "length_immediate")
5729 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5731 (const_string "*")))
5732 (set_attr "mode" "SI")])
5734 (define_insn "*addhi_1"
5735 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5736 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5737 (match_operand:HI 2 "general_operand" "rn,rm")))
5738 (clobber (reg:CC FLAGS_REG))]
5739 "TARGET_PARTIAL_REG_STALL
5740 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5742 switch (get_attr_type (insn))
5745 if (operands[2] == const1_rtx)
5746 return "inc{w}\t%0";
5749 gcc_assert (operands[2] == constm1_rtx);
5750 return "dec{w}\t%0";
5754 if (x86_maybe_negate_const_int (&operands[2], HImode))
5755 return "sub{w}\t{%2, %0|%0, %2}";
5757 return "add{w}\t{%2, %0|%0, %2}";
5761 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5762 (const_string "incdec")
5763 (const_string "alu")))
5764 (set (attr "length_immediate")
5766 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5768 (const_string "*")))
5769 (set_attr "mode" "HI")])
5771 (define_insn "*addhi_1_lea"
5772 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r")
5773 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r")
5774 (match_operand:HI 2 "general_operand" "rmn,rn,0,ln")))
5775 (clobber (reg:CC FLAGS_REG))]
5776 "!TARGET_PARTIAL_REG_STALL
5777 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5779 switch (get_attr_type (insn))
5785 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5786 if (operands[2] == const1_rtx)
5787 return "inc{w}\t%0";
5790 gcc_assert (operands[2] == constm1_rtx);
5791 return "dec{w}\t%0";
5795 /* For most processors, ADD is faster than LEA. This alternative
5796 was added to use ADD as much as possible. */
5797 if (which_alternative == 2)
5800 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5803 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5804 if (x86_maybe_negate_const_int (&operands[2], HImode))
5805 return "sub{w}\t{%2, %0|%0, %2}";
5807 return "add{w}\t{%2, %0|%0, %2}";
5811 (cond [(eq_attr "alternative" "3")
5812 (const_string "lea")
5813 (match_operand:HI 2 "incdec_operand" "")
5814 (const_string "incdec")
5816 (const_string "alu")))
5817 (set (attr "length_immediate")
5819 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5821 (const_string "*")))
5822 (set_attr "mode" "HI,HI,HI,SI")])
5824 ;; %%% Potential partial reg stall on alternative 2. What to do?
5825 (define_insn "*addqi_1"
5826 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5827 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5828 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5829 (clobber (reg:CC FLAGS_REG))]
5830 "TARGET_PARTIAL_REG_STALL
5831 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5833 int widen = (which_alternative == 2);
5834 switch (get_attr_type (insn))
5837 if (operands[2] == const1_rtx)
5838 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5841 gcc_assert (operands[2] == constm1_rtx);
5842 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5846 if (x86_maybe_negate_const_int (&operands[2], QImode))
5849 return "sub{l}\t{%2, %k0|%k0, %2}";
5851 return "sub{b}\t{%2, %0|%0, %2}";
5854 return "add{l}\t{%k2, %k0|%k0, %k2}";
5856 return "add{b}\t{%2, %0|%0, %2}";
5860 (if_then_else (match_operand:QI 2 "incdec_operand" "")
5861 (const_string "incdec")
5862 (const_string "alu")))
5863 (set (attr "length_immediate")
5865 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5867 (const_string "*")))
5868 (set_attr "mode" "QI,QI,SI")])
5870 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5871 (define_insn "*addqi_1_lea"
5872 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r")
5873 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r")
5874 (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln")))
5875 (clobber (reg:CC FLAGS_REG))]
5876 "!TARGET_PARTIAL_REG_STALL
5877 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5879 int widen = (which_alternative == 3 || which_alternative == 4);
5881 switch (get_attr_type (insn))
5887 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5888 if (operands[2] == const1_rtx)
5889 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5892 gcc_assert (operands[2] == constm1_rtx);
5893 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5897 /* For most processors, ADD is faster than LEA. These alternatives
5898 were added to use ADD as much as possible. */
5899 if (which_alternative == 2 || which_alternative == 4)
5902 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5905 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5906 if (x86_maybe_negate_const_int (&operands[2], QImode))
5909 return "sub{l}\t{%2, %k0|%k0, %2}";
5911 return "sub{b}\t{%2, %0|%0, %2}";
5914 return "add{l}\t{%k2, %k0|%k0, %k2}";
5916 return "add{b}\t{%2, %0|%0, %2}";
5920 (cond [(eq_attr "alternative" "5")
5921 (const_string "lea")
5922 (match_operand:QI 2 "incdec_operand" "")
5923 (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" "QI,QI,QI,SI,SI,SI")])
5933 (define_insn "*addqi_1_slp"
5934 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5935 (plus:QI (match_dup 0)
5936 (match_operand:QI 1 "general_operand" "qn,qnm")))
5937 (clobber (reg:CC FLAGS_REG))]
5938 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5939 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5941 switch (get_attr_type (insn))
5944 if (operands[1] == const1_rtx)
5945 return "inc{b}\t%0";
5948 gcc_assert (operands[1] == constm1_rtx);
5949 return "dec{b}\t%0";
5953 if (x86_maybe_negate_const_int (&operands[1], QImode))
5954 return "sub{b}\t{%1, %0|%0, %1}";
5956 return "add{b}\t{%1, %0|%0, %1}";
5960 (if_then_else (match_operand:QI 1 "incdec_operand" "")
5961 (const_string "incdec")
5962 (const_string "alu1")))
5963 (set (attr "memory")
5964 (if_then_else (match_operand 1 "memory_operand" "")
5965 (const_string "load")
5966 (const_string "none")))
5967 (set_attr "mode" "QI")])
5969 ;; Convert lea to the lea pattern to avoid flags dependency.
5971 [(set (match_operand 0 "register_operand" "")
5972 (plus (match_operand 1 "register_operand" "")
5973 (match_operand 2 "nonmemory_operand" "")))
5974 (clobber (reg:CC FLAGS_REG))]
5975 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5979 enum machine_mode mode = GET_MODE (operands[0]);
5981 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5982 may confuse gen_lowpart. */
5985 operands[1] = gen_lowpart (Pmode, operands[1]);
5986 operands[2] = gen_lowpart (Pmode, operands[2]);
5989 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
5991 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5992 operands[0] = gen_lowpart (SImode, operands[0]);
5994 if (TARGET_64BIT && mode != Pmode)
5995 pat = gen_rtx_SUBREG (SImode, pat, 0);
5997 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6001 ;; Convert lea to the lea pattern to avoid flags dependency.
6002 ;; ??? This pattern handles immediate operands that do not satisfy immediate
6003 ;; operand predicate (LEGITIMATE_CONSTANT_P) in the previous pattern.
6005 [(set (match_operand:DI 0 "register_operand" "")
6006 (plus:DI (match_operand:DI 1 "register_operand" "")
6007 (match_operand:DI 2 "x86_64_immediate_operand" "")))
6008 (clobber (reg:CC FLAGS_REG))]
6009 "TARGET_64BIT && reload_completed
6010 && true_regnum (operands[0]) != true_regnum (operands[1])"
6012 (plus:DI (match_dup 1) (match_dup 2)))])
6014 ;; Convert lea to the lea pattern to avoid flags dependency.
6016 [(set (match_operand:DI 0 "register_operand" "")
6018 (plus:SI (match_operand:SI 1 "register_operand" "")
6019 (match_operand:SI 2 "nonmemory_operand" ""))))
6020 (clobber (reg:CC FLAGS_REG))]
6021 "TARGET_64BIT && reload_completed
6022 && ix86_lea_for_add_ok (insn, operands)"
6024 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6026 operands[1] = gen_lowpart (DImode, operands[1]);
6027 operands[2] = gen_lowpart (DImode, operands[2]);
6030 (define_insn "*add<mode>_2"
6031 [(set (reg FLAGS_REG)
6034 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6035 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
6037 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6038 (plus:SWI (match_dup 1) (match_dup 2)))]
6039 "ix86_match_ccmode (insn, CCGOCmode)
6040 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6042 switch (get_attr_type (insn))
6045 if (operands[2] == const1_rtx)
6046 return "inc{<imodesuffix>}\t%0";
6049 gcc_assert (operands[2] == constm1_rtx);
6050 return "dec{<imodesuffix>}\t%0";
6054 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6055 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6057 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6061 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6062 (const_string "incdec")
6063 (const_string "alu")))
6064 (set (attr "length_immediate")
6066 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6068 (const_string "*")))
6069 (set_attr "mode" "<MODE>")])
6071 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6072 (define_insn "*addsi_2_zext"
6073 [(set (reg FLAGS_REG)
6075 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6076 (match_operand:SI 2 "general_operand" "g"))
6078 (set (match_operand:DI 0 "register_operand" "=r")
6079 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6080 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6081 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6083 switch (get_attr_type (insn))
6086 if (operands[2] == const1_rtx)
6087 return "inc{l}\t%k0";
6090 gcc_assert (operands[2] == constm1_rtx);
6091 return "dec{l}\t%k0";
6095 if (x86_maybe_negate_const_int (&operands[2], SImode))
6096 return "sub{l}\t{%2, %k0|%k0, %2}";
6098 return "add{l}\t{%2, %k0|%k0, %2}";
6102 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6103 (const_string "incdec")
6104 (const_string "alu")))
6105 (set (attr "length_immediate")
6107 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6109 (const_string "*")))
6110 (set_attr "mode" "SI")])
6112 (define_insn "*add<mode>_3"
6113 [(set (reg FLAGS_REG)
6115 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
6116 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
6117 (clobber (match_scratch:SWI 0 "=<r>"))]
6118 "ix86_match_ccmode (insn, CCZmode)
6119 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6121 switch (get_attr_type (insn))
6124 if (operands[2] == const1_rtx)
6125 return "inc{<imodesuffix>}\t%0";
6128 gcc_assert (operands[2] == constm1_rtx);
6129 return "dec{<imodesuffix>}\t%0";
6133 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6134 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6136 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6140 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6141 (const_string "incdec")
6142 (const_string "alu")))
6143 (set (attr "length_immediate")
6145 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6147 (const_string "*")))
6148 (set_attr "mode" "<MODE>")])
6150 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6151 (define_insn "*addsi_3_zext"
6152 [(set (reg FLAGS_REG)
6154 (neg:SI (match_operand:SI 2 "general_operand" "g"))
6155 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6156 (set (match_operand:DI 0 "register_operand" "=r")
6157 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6158 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6159 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6161 switch (get_attr_type (insn))
6164 if (operands[2] == const1_rtx)
6165 return "inc{l}\t%k0";
6168 gcc_assert (operands[2] == constm1_rtx);
6169 return "dec{l}\t%k0";
6173 if (x86_maybe_negate_const_int (&operands[2], SImode))
6174 return "sub{l}\t{%2, %k0|%k0, %2}";
6176 return "add{l}\t{%2, %k0|%k0, %2}";
6180 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6181 (const_string "incdec")
6182 (const_string "alu")))
6183 (set (attr "length_immediate")
6185 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6187 (const_string "*")))
6188 (set_attr "mode" "SI")])
6190 ; For comparisons against 1, -1 and 128, we may generate better code
6191 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6192 ; is matched then. We can't accept general immediate, because for
6193 ; case of overflows, the result is messed up.
6194 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6195 ; only for comparisons not depending on it.
6197 (define_insn "*adddi_4"
6198 [(set (reg FLAGS_REG)
6200 (match_operand:DI 1 "nonimmediate_operand" "0")
6201 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6202 (clobber (match_scratch:DI 0 "=rm"))]
6204 && ix86_match_ccmode (insn, CCGCmode)"
6206 switch (get_attr_type (insn))
6209 if (operands[2] == constm1_rtx)
6210 return "inc{q}\t%0";
6213 gcc_assert (operands[2] == const1_rtx);
6214 return "dec{q}\t%0";
6218 if (x86_maybe_negate_const_int (&operands[2], DImode))
6219 return "add{q}\t{%2, %0|%0, %2}";
6221 return "sub{q}\t{%2, %0|%0, %2}";
6225 (if_then_else (match_operand:DI 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" "DI")])
6235 ; For comparisons against 1, -1 and 128, we may generate better code
6236 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6237 ; is matched then. We can't accept general immediate, because for
6238 ; case of overflows, the result is messed up.
6239 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6240 ; only for comparisons not depending on it.
6242 (define_insn "*add<mode>_4"
6243 [(set (reg FLAGS_REG)
6245 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6246 (match_operand:SWI124 2 "const_int_operand" "n")))
6247 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6248 "ix86_match_ccmode (insn, CCGCmode)"
6250 switch (get_attr_type (insn))
6253 if (operands[2] == constm1_rtx)
6254 return "inc{<imodesuffix>}\t%0";
6257 gcc_assert (operands[2] == const1_rtx);
6258 return "dec{<imodesuffix>}\t%0";
6262 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6263 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6265 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6269 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6270 (const_string "incdec")
6271 (const_string "alu")))
6272 (set (attr "length_immediate")
6274 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6276 (const_string "*")))
6277 (set_attr "mode" "<MODE>")])
6279 (define_insn "*add<mode>_5"
6280 [(set (reg FLAGS_REG)
6283 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6284 (match_operand:SWI 2 "<general_operand>" "<g>"))
6286 (clobber (match_scratch:SWI 0 "=<r>"))]
6287 "ix86_match_ccmode (insn, CCGOCmode)
6288 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6290 switch (get_attr_type (insn))
6293 if (operands[2] == const1_rtx)
6294 return "inc{<imodesuffix>}\t%0";
6297 gcc_assert (operands[2] == constm1_rtx);
6298 return "dec{<imodesuffix>}\t%0";
6302 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6303 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6305 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6309 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6310 (const_string "incdec")
6311 (const_string "alu")))
6312 (set (attr "length_immediate")
6314 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6316 (const_string "*")))
6317 (set_attr "mode" "<MODE>")])
6319 (define_insn "*addqi_ext_1_rex64"
6320 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6325 (match_operand 1 "ext_register_operand" "0")
6328 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6329 (clobber (reg:CC FLAGS_REG))]
6332 switch (get_attr_type (insn))
6335 if (operands[2] == const1_rtx)
6336 return "inc{b}\t%h0";
6339 gcc_assert (operands[2] == constm1_rtx);
6340 return "dec{b}\t%h0";
6344 return "add{b}\t{%2, %h0|%h0, %2}";
6348 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6349 (const_string "incdec")
6350 (const_string "alu")))
6351 (set_attr "modrm" "1")
6352 (set_attr "mode" "QI")])
6354 (define_insn "addqi_ext_1"
6355 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6360 (match_operand 1 "ext_register_operand" "0")
6363 (match_operand:QI 2 "general_operand" "Qmn")))
6364 (clobber (reg:CC FLAGS_REG))]
6367 switch (get_attr_type (insn))
6370 if (operands[2] == const1_rtx)
6371 return "inc{b}\t%h0";
6374 gcc_assert (operands[2] == constm1_rtx);
6375 return "dec{b}\t%h0";
6379 return "add{b}\t{%2, %h0|%h0, %2}";
6383 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6384 (const_string "incdec")
6385 (const_string "alu")))
6386 (set_attr "modrm" "1")
6387 (set_attr "mode" "QI")])
6389 (define_insn "*addqi_ext_2"
6390 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6395 (match_operand 1 "ext_register_operand" "%0")
6399 (match_operand 2 "ext_register_operand" "Q")
6402 (clobber (reg:CC FLAGS_REG))]
6404 "add{b}\t{%h2, %h0|%h0, %h2}"
6405 [(set_attr "type" "alu")
6406 (set_attr "mode" "QI")])
6408 ;; The lea patterns for non-Pmodes needs to be matched by
6409 ;; several insns converted to real lea by splitters.
6411 (define_insn_and_split "*lea_general_1"
6412 [(set (match_operand 0 "register_operand" "=r")
6413 (plus (plus (match_operand 1 "index_register_operand" "l")
6414 (match_operand 2 "register_operand" "r"))
6415 (match_operand 3 "immediate_operand" "i")))]
6416 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6417 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6418 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6419 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6420 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6421 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6422 || GET_MODE (operands[3]) == VOIDmode)"
6424 "&& reload_completed"
6428 operands[0] = gen_lowpart (SImode, operands[0]);
6429 operands[1] = gen_lowpart (Pmode, operands[1]);
6430 operands[2] = gen_lowpart (Pmode, operands[2]);
6431 operands[3] = gen_lowpart (Pmode, operands[3]);
6432 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6434 if (Pmode != SImode)
6435 pat = gen_rtx_SUBREG (SImode, pat, 0);
6436 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6439 [(set_attr "type" "lea")
6440 (set_attr "mode" "SI")])
6442 (define_insn_and_split "*lea_general_1_zext"
6443 [(set (match_operand:DI 0 "register_operand" "=r")
6446 (match_operand:SI 1 "index_register_operand" "l")
6447 (match_operand:SI 2 "register_operand" "r"))
6448 (match_operand:SI 3 "immediate_operand" "i"))))]
6451 "&& reload_completed"
6453 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6455 (match_dup 3)) 0)))]
6457 operands[1] = gen_lowpart (Pmode, operands[1]);
6458 operands[2] = gen_lowpart (Pmode, operands[2]);
6459 operands[3] = gen_lowpart (Pmode, operands[3]);
6461 [(set_attr "type" "lea")
6462 (set_attr "mode" "SI")])
6464 (define_insn_and_split "*lea_general_2"
6465 [(set (match_operand 0 "register_operand" "=r")
6466 (plus (mult (match_operand 1 "index_register_operand" "l")
6467 (match_operand 2 "const248_operand" "i"))
6468 (match_operand 3 "nonmemory_operand" "ri")))]
6469 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6470 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6471 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6472 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6473 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6474 || GET_MODE (operands[3]) == VOIDmode)"
6476 "&& reload_completed"
6480 operands[0] = gen_lowpart (SImode, operands[0]);
6481 operands[1] = gen_lowpart (Pmode, operands[1]);
6482 operands[3] = gen_lowpart (Pmode, operands[3]);
6483 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6485 if (Pmode != SImode)
6486 pat = gen_rtx_SUBREG (SImode, pat, 0);
6487 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6490 [(set_attr "type" "lea")
6491 (set_attr "mode" "SI")])
6493 (define_insn_and_split "*lea_general_2_zext"
6494 [(set (match_operand:DI 0 "register_operand" "=r")
6497 (match_operand:SI 1 "index_register_operand" "l")
6498 (match_operand:SI 2 "const248_operand" "n"))
6499 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6502 "&& reload_completed"
6504 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6506 (match_dup 3)) 0)))]
6508 operands[1] = gen_lowpart (Pmode, operands[1]);
6509 operands[3] = gen_lowpart (Pmode, operands[3]);
6511 [(set_attr "type" "lea")
6512 (set_attr "mode" "SI")])
6514 (define_insn_and_split "*lea_general_3"
6515 [(set (match_operand 0 "register_operand" "=r")
6516 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6517 (match_operand 2 "const248_operand" "i"))
6518 (match_operand 3 "register_operand" "r"))
6519 (match_operand 4 "immediate_operand" "i")))]
6520 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6521 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6522 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6523 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6524 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6526 "&& reload_completed"
6530 operands[0] = gen_lowpart (SImode, operands[0]);
6531 operands[1] = gen_lowpart (Pmode, operands[1]);
6532 operands[3] = gen_lowpart (Pmode, operands[3]);
6533 operands[4] = gen_lowpart (Pmode, operands[4]);
6534 pat = gen_rtx_PLUS (Pmode,
6535 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6539 if (Pmode != SImode)
6540 pat = gen_rtx_SUBREG (SImode, pat, 0);
6541 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6544 [(set_attr "type" "lea")
6545 (set_attr "mode" "SI")])
6547 (define_insn_and_split "*lea_general_3_zext"
6548 [(set (match_operand:DI 0 "register_operand" "=r")
6552 (match_operand:SI 1 "index_register_operand" "l")
6553 (match_operand:SI 2 "const248_operand" "n"))
6554 (match_operand:SI 3 "register_operand" "r"))
6555 (match_operand:SI 4 "immediate_operand" "i"))))]
6558 "&& reload_completed"
6560 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6563 (match_dup 4)) 0)))]
6565 operands[1] = gen_lowpart (Pmode, operands[1]);
6566 operands[3] = gen_lowpart (Pmode, operands[3]);
6567 operands[4] = gen_lowpart (Pmode, operands[4]);
6569 [(set_attr "type" "lea")
6570 (set_attr "mode" "SI")])
6572 ;; Subtract instructions
6574 (define_expand "sub<mode>3"
6575 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6576 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6577 (match_operand:SDWIM 2 "<general_operand>" "")))]
6579 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6581 (define_insn_and_split "*sub<dwi>3_doubleword"
6582 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6584 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6585 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6586 (clobber (reg:CC FLAGS_REG))]
6587 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6590 [(parallel [(set (reg:CC FLAGS_REG)
6591 (compare:CC (match_dup 1) (match_dup 2)))
6593 (minus:DWIH (match_dup 1) (match_dup 2)))])
6594 (parallel [(set (match_dup 3)
6598 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6600 (clobber (reg:CC FLAGS_REG))])]
6601 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6603 (define_insn "*sub<mode>_1"
6604 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6606 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6607 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6608 (clobber (reg:CC FLAGS_REG))]
6609 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6610 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6611 [(set_attr "type" "alu")
6612 (set_attr "mode" "<MODE>")])
6614 (define_insn "*subsi_1_zext"
6615 [(set (match_operand:DI 0 "register_operand" "=r")
6617 (minus:SI (match_operand:SI 1 "register_operand" "0")
6618 (match_operand:SI 2 "general_operand" "g"))))
6619 (clobber (reg:CC FLAGS_REG))]
6620 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6621 "sub{l}\t{%2, %k0|%k0, %2}"
6622 [(set_attr "type" "alu")
6623 (set_attr "mode" "SI")])
6625 (define_insn "*subqi_1_slp"
6626 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6627 (minus:QI (match_dup 0)
6628 (match_operand:QI 1 "general_operand" "qn,qm")))
6629 (clobber (reg:CC FLAGS_REG))]
6630 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6631 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6632 "sub{b}\t{%1, %0|%0, %1}"
6633 [(set_attr "type" "alu1")
6634 (set_attr "mode" "QI")])
6636 (define_insn "*sub<mode>_2"
6637 [(set (reg FLAGS_REG)
6640 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6641 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6643 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6644 (minus:SWI (match_dup 1) (match_dup 2)))]
6645 "ix86_match_ccmode (insn, CCGOCmode)
6646 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6647 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6648 [(set_attr "type" "alu")
6649 (set_attr "mode" "<MODE>")])
6651 (define_insn "*subsi_2_zext"
6652 [(set (reg FLAGS_REG)
6654 (minus:SI (match_operand:SI 1 "register_operand" "0")
6655 (match_operand:SI 2 "general_operand" "g"))
6657 (set (match_operand:DI 0 "register_operand" "=r")
6659 (minus:SI (match_dup 1)
6661 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6662 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6663 "sub{l}\t{%2, %k0|%k0, %2}"
6664 [(set_attr "type" "alu")
6665 (set_attr "mode" "SI")])
6667 (define_insn "*sub<mode>_3"
6668 [(set (reg FLAGS_REG)
6669 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6670 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6671 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6672 (minus:SWI (match_dup 1) (match_dup 2)))]
6673 "ix86_match_ccmode (insn, CCmode)
6674 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6675 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6676 [(set_attr "type" "alu")
6677 (set_attr "mode" "<MODE>")])
6679 (define_insn "*subsi_3_zext"
6680 [(set (reg FLAGS_REG)
6681 (compare (match_operand:SI 1 "register_operand" "0")
6682 (match_operand:SI 2 "general_operand" "g")))
6683 (set (match_operand:DI 0 "register_operand" "=r")
6685 (minus:SI (match_dup 1)
6687 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6688 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6689 "sub{l}\t{%2, %1|%1, %2}"
6690 [(set_attr "type" "alu")
6691 (set_attr "mode" "SI")])
6693 ;; Add with carry and subtract with borrow
6695 (define_expand "<plusminus_insn><mode>3_carry"
6697 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6699 (match_operand:SWI 1 "nonimmediate_operand" "")
6700 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6701 [(match_operand 3 "flags_reg_operand" "")
6703 (match_operand:SWI 2 "<general_operand>" ""))))
6704 (clobber (reg:CC FLAGS_REG))])]
6705 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6707 (define_insn "*<plusminus_insn><mode>3_carry"
6708 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6710 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6712 (match_operator 3 "ix86_carry_flag_operator"
6713 [(reg FLAGS_REG) (const_int 0)])
6714 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6715 (clobber (reg:CC FLAGS_REG))]
6716 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6717 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6718 [(set_attr "type" "alu")
6719 (set_attr "use_carry" "1")
6720 (set_attr "pent_pair" "pu")
6721 (set_attr "mode" "<MODE>")])
6723 (define_insn "*addsi3_carry_zext"
6724 [(set (match_operand:DI 0 "register_operand" "=r")
6726 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6727 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6728 [(reg FLAGS_REG) (const_int 0)])
6729 (match_operand:SI 2 "general_operand" "g")))))
6730 (clobber (reg:CC FLAGS_REG))]
6731 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6732 "adc{l}\t{%2, %k0|%k0, %2}"
6733 [(set_attr "type" "alu")
6734 (set_attr "use_carry" "1")
6735 (set_attr "pent_pair" "pu")
6736 (set_attr "mode" "SI")])
6738 (define_insn "*subsi3_carry_zext"
6739 [(set (match_operand:DI 0 "register_operand" "=r")
6741 (minus:SI (match_operand:SI 1 "register_operand" "0")
6742 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6743 [(reg FLAGS_REG) (const_int 0)])
6744 (match_operand:SI 2 "general_operand" "g")))))
6745 (clobber (reg:CC FLAGS_REG))]
6746 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6747 "sbb{l}\t{%2, %k0|%k0, %2}"
6748 [(set_attr "type" "alu")
6749 (set_attr "pent_pair" "pu")
6750 (set_attr "mode" "SI")])
6752 ;; Overflow setting add and subtract instructions
6754 (define_insn "*add<mode>3_cconly_overflow"
6755 [(set (reg:CCC FLAGS_REG)
6758 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6759 (match_operand:SWI 2 "<general_operand>" "<g>"))
6761 (clobber (match_scratch:SWI 0 "=<r>"))]
6762 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6763 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6764 [(set_attr "type" "alu")
6765 (set_attr "mode" "<MODE>")])
6767 (define_insn "*sub<mode>3_cconly_overflow"
6768 [(set (reg:CCC FLAGS_REG)
6771 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6772 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6775 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6776 [(set_attr "type" "icmp")
6777 (set_attr "mode" "<MODE>")])
6779 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6780 [(set (reg:CCC FLAGS_REG)
6783 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6784 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6786 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6787 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6788 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6789 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6790 [(set_attr "type" "alu")
6791 (set_attr "mode" "<MODE>")])
6793 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6794 [(set (reg:CCC FLAGS_REG)
6797 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6798 (match_operand:SI 2 "general_operand" "g"))
6800 (set (match_operand:DI 0 "register_operand" "=r")
6801 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6802 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6803 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6804 [(set_attr "type" "alu")
6805 (set_attr "mode" "SI")])
6807 ;; The patterns that match these are at the end of this file.
6809 (define_expand "<plusminus_insn>xf3"
6810 [(set (match_operand:XF 0 "register_operand" "")
6812 (match_operand:XF 1 "register_operand" "")
6813 (match_operand:XF 2 "register_operand" "")))]
6816 (define_expand "<plusminus_insn><mode>3"
6817 [(set (match_operand:MODEF 0 "register_operand" "")
6819 (match_operand:MODEF 1 "register_operand" "")
6820 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6821 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6822 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6824 ;; Multiply instructions
6826 (define_expand "mul<mode>3"
6827 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6829 (match_operand:SWIM248 1 "register_operand" "")
6830 (match_operand:SWIM248 2 "<general_operand>" "")))
6831 (clobber (reg:CC FLAGS_REG))])])
6833 (define_expand "mulqi3"
6834 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6836 (match_operand:QI 1 "register_operand" "")
6837 (match_operand:QI 2 "nonimmediate_operand" "")))
6838 (clobber (reg:CC FLAGS_REG))])]
6839 "TARGET_QIMODE_MATH")
6842 ;; IMUL reg32/64, reg32/64, imm8 Direct
6843 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6844 ;; IMUL reg32/64, reg32/64, imm32 Direct
6845 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6846 ;; IMUL reg32/64, reg32/64 Direct
6847 ;; IMUL reg32/64, mem32/64 Direct
6849 (define_insn "*mul<mode>3_1"
6850 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6852 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6853 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6854 (clobber (reg:CC FLAGS_REG))]
6855 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6857 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6858 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6859 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6860 [(set_attr "type" "imul")
6861 (set_attr "prefix_0f" "0,0,1")
6862 (set (attr "athlon_decode")
6863 (cond [(eq_attr "cpu" "athlon")
6864 (const_string "vector")
6865 (eq_attr "alternative" "1")
6866 (const_string "vector")
6867 (and (eq_attr "alternative" "2")
6868 (match_operand 1 "memory_operand" ""))
6869 (const_string "vector")]
6870 (const_string "direct")))
6871 (set (attr "amdfam10_decode")
6872 (cond [(and (eq_attr "alternative" "0,1")
6873 (match_operand 1 "memory_operand" ""))
6874 (const_string "vector")]
6875 (const_string "direct")))
6876 (set_attr "mode" "<MODE>")])
6878 (define_insn "*mulsi3_1_zext"
6879 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6881 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6882 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6883 (clobber (reg:CC FLAGS_REG))]
6885 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6887 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6888 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6889 imul{l}\t{%2, %k0|%k0, %2}"
6890 [(set_attr "type" "imul")
6891 (set_attr "prefix_0f" "0,0,1")
6892 (set (attr "athlon_decode")
6893 (cond [(eq_attr "cpu" "athlon")
6894 (const_string "vector")
6895 (eq_attr "alternative" "1")
6896 (const_string "vector")
6897 (and (eq_attr "alternative" "2")
6898 (match_operand 1 "memory_operand" ""))
6899 (const_string "vector")]
6900 (const_string "direct")))
6901 (set (attr "amdfam10_decode")
6902 (cond [(and (eq_attr "alternative" "0,1")
6903 (match_operand 1 "memory_operand" ""))
6904 (const_string "vector")]
6905 (const_string "direct")))
6906 (set_attr "mode" "SI")])
6909 ;; IMUL reg16, reg16, imm8 VectorPath
6910 ;; IMUL reg16, mem16, imm8 VectorPath
6911 ;; IMUL reg16, reg16, imm16 VectorPath
6912 ;; IMUL reg16, mem16, imm16 VectorPath
6913 ;; IMUL reg16, reg16 Direct
6914 ;; IMUL reg16, mem16 Direct
6916 (define_insn "*mulhi3_1"
6917 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6918 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6919 (match_operand:HI 2 "general_operand" "K,n,mr")))
6920 (clobber (reg:CC FLAGS_REG))]
6922 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6924 imul{w}\t{%2, %1, %0|%0, %1, %2}
6925 imul{w}\t{%2, %1, %0|%0, %1, %2}
6926 imul{w}\t{%2, %0|%0, %2}"
6927 [(set_attr "type" "imul")
6928 (set_attr "prefix_0f" "0,0,1")
6929 (set (attr "athlon_decode")
6930 (cond [(eq_attr "cpu" "athlon")
6931 (const_string "vector")
6932 (eq_attr "alternative" "1,2")
6933 (const_string "vector")]
6934 (const_string "direct")))
6935 (set (attr "amdfam10_decode")
6936 (cond [(eq_attr "alternative" "0,1")
6937 (const_string "vector")]
6938 (const_string "direct")))
6939 (set_attr "mode" "HI")])
6945 (define_insn "*mulqi3_1"
6946 [(set (match_operand:QI 0 "register_operand" "=a")
6947 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6948 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6949 (clobber (reg:CC FLAGS_REG))]
6951 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6953 [(set_attr "type" "imul")
6954 (set_attr "length_immediate" "0")
6955 (set (attr "athlon_decode")
6956 (if_then_else (eq_attr "cpu" "athlon")
6957 (const_string "vector")
6958 (const_string "direct")))
6959 (set_attr "amdfam10_decode" "direct")
6960 (set_attr "mode" "QI")])
6962 (define_expand "<u>mul<mode><dwi>3"
6963 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6966 (match_operand:DWIH 1 "nonimmediate_operand" ""))
6968 (match_operand:DWIH 2 "register_operand" ""))))
6969 (clobber (reg:CC FLAGS_REG))])])
6971 (define_expand "<u>mulqihi3"
6972 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6975 (match_operand:QI 1 "nonimmediate_operand" ""))
6977 (match_operand:QI 2 "register_operand" ""))))
6978 (clobber (reg:CC FLAGS_REG))])]
6979 "TARGET_QIMODE_MATH")
6981 (define_insn "*<u>mul<mode><dwi>3_1"
6982 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6985 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6987 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6988 (clobber (reg:CC FLAGS_REG))]
6989 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6990 "<sgnprefix>mul{<imodesuffix>}\t%2"
6991 [(set_attr "type" "imul")
6992 (set_attr "length_immediate" "0")
6993 (set (attr "athlon_decode")
6994 (if_then_else (eq_attr "cpu" "athlon")
6995 (const_string "vector")
6996 (const_string "double")))
6997 (set_attr "amdfam10_decode" "double")
6998 (set_attr "mode" "<MODE>")])
7000 (define_insn "*<u>mulqihi3_1"
7001 [(set (match_operand:HI 0 "register_operand" "=a")
7004 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7006 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7007 (clobber (reg:CC FLAGS_REG))]
7009 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7010 "<sgnprefix>mul{b}\t%2"
7011 [(set_attr "type" "imul")
7012 (set_attr "length_immediate" "0")
7013 (set (attr "athlon_decode")
7014 (if_then_else (eq_attr "cpu" "athlon")
7015 (const_string "vector")
7016 (const_string "direct")))
7017 (set_attr "amdfam10_decode" "direct")
7018 (set_attr "mode" "QI")])
7020 (define_expand "<s>mul<mode>3_highpart"
7021 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7026 (match_operand:SWI48 1 "nonimmediate_operand" ""))
7028 (match_operand:SWI48 2 "register_operand" "")))
7030 (clobber (match_scratch:SWI48 3 ""))
7031 (clobber (reg:CC FLAGS_REG))])]
7033 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7035 (define_insn "*<s>muldi3_highpart_1"
7036 [(set (match_operand:DI 0 "register_operand" "=d")
7041 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7043 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7045 (clobber (match_scratch:DI 3 "=1"))
7046 (clobber (reg:CC FLAGS_REG))]
7048 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7049 "<sgnprefix>mul{q}\t%2"
7050 [(set_attr "type" "imul")
7051 (set_attr "length_immediate" "0")
7052 (set (attr "athlon_decode")
7053 (if_then_else (eq_attr "cpu" "athlon")
7054 (const_string "vector")
7055 (const_string "double")))
7056 (set_attr "amdfam10_decode" "double")
7057 (set_attr "mode" "DI")])
7059 (define_insn "*<s>mulsi3_highpart_1"
7060 [(set (match_operand:SI 0 "register_operand" "=d")
7065 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7067 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7069 (clobber (match_scratch:SI 3 "=1"))
7070 (clobber (reg:CC FLAGS_REG))]
7071 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7072 "<sgnprefix>mul{l}\t%2"
7073 [(set_attr "type" "imul")
7074 (set_attr "length_immediate" "0")
7075 (set (attr "athlon_decode")
7076 (if_then_else (eq_attr "cpu" "athlon")
7077 (const_string "vector")
7078 (const_string "double")))
7079 (set_attr "amdfam10_decode" "double")
7080 (set_attr "mode" "SI")])
7082 (define_insn "*<s>mulsi3_highpart_zext"
7083 [(set (match_operand:DI 0 "register_operand" "=d")
7084 (zero_extend:DI (truncate:SI
7086 (mult:DI (any_extend:DI
7087 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7089 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7091 (clobber (match_scratch:SI 3 "=1"))
7092 (clobber (reg:CC FLAGS_REG))]
7094 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7095 "<sgnprefix>mul{l}\t%2"
7096 [(set_attr "type" "imul")
7097 (set_attr "length_immediate" "0")
7098 (set (attr "athlon_decode")
7099 (if_then_else (eq_attr "cpu" "athlon")
7100 (const_string "vector")
7101 (const_string "double")))
7102 (set_attr "amdfam10_decode" "double")
7103 (set_attr "mode" "SI")])
7105 ;; The patterns that match these are at the end of this file.
7107 (define_expand "mulxf3"
7108 [(set (match_operand:XF 0 "register_operand" "")
7109 (mult:XF (match_operand:XF 1 "register_operand" "")
7110 (match_operand:XF 2 "register_operand" "")))]
7113 (define_expand "mul<mode>3"
7114 [(set (match_operand:MODEF 0 "register_operand" "")
7115 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7116 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7117 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7118 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7120 ;; Divide instructions
7122 ;; The patterns that match these are at the end of this file.
7124 (define_expand "divxf3"
7125 [(set (match_operand:XF 0 "register_operand" "")
7126 (div:XF (match_operand:XF 1 "register_operand" "")
7127 (match_operand:XF 2 "register_operand" "")))]
7130 (define_expand "divdf3"
7131 [(set (match_operand:DF 0 "register_operand" "")
7132 (div:DF (match_operand:DF 1 "register_operand" "")
7133 (match_operand:DF 2 "nonimmediate_operand" "")))]
7134 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7135 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7137 (define_expand "divsf3"
7138 [(set (match_operand:SF 0 "register_operand" "")
7139 (div:SF (match_operand:SF 1 "register_operand" "")
7140 (match_operand:SF 2 "nonimmediate_operand" "")))]
7141 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7144 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7145 && flag_finite_math_only && !flag_trapping_math
7146 && flag_unsafe_math_optimizations)
7148 ix86_emit_swdivsf (operands[0], operands[1],
7149 operands[2], SFmode);
7154 ;; Divmod instructions.
7156 (define_expand "divmod<mode>4"
7157 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7159 (match_operand:SWIM248 1 "register_operand" "")
7160 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7161 (set (match_operand:SWIM248 3 "register_operand" "")
7162 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7163 (clobber (reg:CC FLAGS_REG))])])
7165 ;; Split with 8bit unsigned divide:
7166 ;; if (dividend an divisor are in [0-255])
7167 ;; use 8bit unsigned integer divide
7169 ;; use original integer divide
7171 [(set (match_operand:SWI48 0 "register_operand" "")
7172 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7173 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7174 (set (match_operand:SWI48 1 "register_operand" "")
7175 (mod:SWI48 (match_dup 2) (match_dup 3)))
7176 (clobber (reg:CC FLAGS_REG))]
7177 "TARGET_USE_8BIT_IDIV
7178 && TARGET_QIMODE_MATH
7179 && can_create_pseudo_p ()
7180 && !optimize_insn_for_size_p ()"
7182 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7184 (define_insn_and_split "divmod<mode>4_1"
7185 [(set (match_operand:SWI48 0 "register_operand" "=a")
7186 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7187 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7188 (set (match_operand:SWI48 1 "register_operand" "=&d")
7189 (mod:SWI48 (match_dup 2) (match_dup 3)))
7190 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7191 (clobber (reg:CC FLAGS_REG))]
7195 [(parallel [(set (match_dup 1)
7196 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7197 (clobber (reg:CC FLAGS_REG))])
7198 (parallel [(set (match_dup 0)
7199 (div:SWI48 (match_dup 2) (match_dup 3)))
7201 (mod:SWI48 (match_dup 2) (match_dup 3)))
7203 (clobber (reg:CC FLAGS_REG))])]
7205 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7207 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7208 operands[4] = operands[2];
7211 /* Avoid use of cltd in favor of a mov+shift. */
7212 emit_move_insn (operands[1], operands[2]);
7213 operands[4] = operands[1];
7216 [(set_attr "type" "multi")
7217 (set_attr "mode" "<MODE>")])
7219 (define_insn_and_split "*divmod<mode>4"
7220 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7221 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7222 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7223 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7224 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7225 (clobber (reg:CC FLAGS_REG))]
7229 [(parallel [(set (match_dup 1)
7230 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7231 (clobber (reg:CC FLAGS_REG))])
7232 (parallel [(set (match_dup 0)
7233 (div:SWIM248 (match_dup 2) (match_dup 3)))
7235 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7237 (clobber (reg:CC FLAGS_REG))])]
7239 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7241 if (<MODE>mode != HImode
7242 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7243 operands[4] = operands[2];
7246 /* Avoid use of cltd in favor of a mov+shift. */
7247 emit_move_insn (operands[1], operands[2]);
7248 operands[4] = operands[1];
7251 [(set_attr "type" "multi")
7252 (set_attr "mode" "<MODE>")])
7254 (define_insn "*divmod<mode>4_noext"
7255 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7256 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7257 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7258 (set (match_operand:SWIM248 1 "register_operand" "=d")
7259 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7260 (use (match_operand:SWIM248 4 "register_operand" "1"))
7261 (clobber (reg:CC FLAGS_REG))]
7263 "idiv{<imodesuffix>}\t%3"
7264 [(set_attr "type" "idiv")
7265 (set_attr "mode" "<MODE>")])
7267 (define_expand "divmodqi4"
7268 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7270 (match_operand:QI 1 "register_operand" "")
7271 (match_operand:QI 2 "nonimmediate_operand" "")))
7272 (set (match_operand:QI 3 "register_operand" "")
7273 (mod:QI (match_dup 1) (match_dup 2)))
7274 (clobber (reg:CC FLAGS_REG))])]
7275 "TARGET_QIMODE_MATH"
7280 tmp0 = gen_reg_rtx (HImode);
7281 tmp1 = gen_reg_rtx (HImode);
7283 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7285 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7286 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7288 /* Extract remainder from AH. */
7289 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7290 insn = emit_move_insn (operands[3], tmp1);
7292 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7293 set_unique_reg_note (insn, REG_EQUAL, mod);
7295 /* Extract quotient from AL. */
7296 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7298 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7299 set_unique_reg_note (insn, REG_EQUAL, div);
7304 ;; Divide AX by r/m8, with result stored in
7307 ;; Change div/mod to HImode and extend the second argument to HImode
7308 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7309 ;; combine may fail.
7310 (define_insn "divmodhiqi3"
7311 [(set (match_operand:HI 0 "register_operand" "=a")
7316 (mod:HI (match_operand:HI 1 "register_operand" "0")
7318 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7322 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7323 (clobber (reg:CC FLAGS_REG))]
7324 "TARGET_QIMODE_MATH"
7326 [(set_attr "type" "idiv")
7327 (set_attr "mode" "QI")])
7329 (define_expand "udivmod<mode>4"
7330 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7332 (match_operand:SWIM248 1 "register_operand" "")
7333 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7334 (set (match_operand:SWIM248 3 "register_operand" "")
7335 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7336 (clobber (reg:CC FLAGS_REG))])])
7338 ;; Split with 8bit unsigned divide:
7339 ;; if (dividend an divisor are in [0-255])
7340 ;; use 8bit unsigned integer divide
7342 ;; use original integer divide
7344 [(set (match_operand:SWI48 0 "register_operand" "")
7345 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7346 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7347 (set (match_operand:SWI48 1 "register_operand" "")
7348 (umod:SWI48 (match_dup 2) (match_dup 3)))
7349 (clobber (reg:CC FLAGS_REG))]
7350 "TARGET_USE_8BIT_IDIV
7351 && TARGET_QIMODE_MATH
7352 && can_create_pseudo_p ()
7353 && !optimize_insn_for_size_p ()"
7355 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7357 (define_insn_and_split "udivmod<mode>4_1"
7358 [(set (match_operand:SWI48 0 "register_operand" "=a")
7359 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7360 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7361 (set (match_operand:SWI48 1 "register_operand" "=&d")
7362 (umod:SWI48 (match_dup 2) (match_dup 3)))
7363 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7364 (clobber (reg:CC FLAGS_REG))]
7368 [(set (match_dup 1) (const_int 0))
7369 (parallel [(set (match_dup 0)
7370 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7372 (umod:SWI48 (match_dup 2) (match_dup 3)))
7374 (clobber (reg:CC FLAGS_REG))])]
7376 [(set_attr "type" "multi")
7377 (set_attr "mode" "<MODE>")])
7379 (define_insn_and_split "*udivmod<mode>4"
7380 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7381 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7382 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7383 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7384 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7385 (clobber (reg:CC FLAGS_REG))]
7389 [(set (match_dup 1) (const_int 0))
7390 (parallel [(set (match_dup 0)
7391 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7393 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7395 (clobber (reg:CC FLAGS_REG))])]
7397 [(set_attr "type" "multi")
7398 (set_attr "mode" "<MODE>")])
7400 (define_insn "*udivmod<mode>4_noext"
7401 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7402 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7403 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7404 (set (match_operand:SWIM248 1 "register_operand" "=d")
7405 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7406 (use (match_operand:SWIM248 4 "register_operand" "1"))
7407 (clobber (reg:CC FLAGS_REG))]
7409 "div{<imodesuffix>}\t%3"
7410 [(set_attr "type" "idiv")
7411 (set_attr "mode" "<MODE>")])
7413 (define_expand "udivmodqi4"
7414 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7416 (match_operand:QI 1 "register_operand" "")
7417 (match_operand:QI 2 "nonimmediate_operand" "")))
7418 (set (match_operand:QI 3 "register_operand" "")
7419 (umod:QI (match_dup 1) (match_dup 2)))
7420 (clobber (reg:CC FLAGS_REG))])]
7421 "TARGET_QIMODE_MATH"
7426 tmp0 = gen_reg_rtx (HImode);
7427 tmp1 = gen_reg_rtx (HImode);
7429 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7431 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7432 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7434 /* Extract remainder from AH. */
7435 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7436 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7437 insn = emit_move_insn (operands[3], tmp1);
7439 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7440 set_unique_reg_note (insn, REG_EQUAL, mod);
7442 /* Extract quotient from AL. */
7443 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7445 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7446 set_unique_reg_note (insn, REG_EQUAL, div);
7451 (define_insn "udivmodhiqi3"
7452 [(set (match_operand:HI 0 "register_operand" "=a")
7457 (mod:HI (match_operand:HI 1 "register_operand" "0")
7459 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7463 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7464 (clobber (reg:CC FLAGS_REG))]
7465 "TARGET_QIMODE_MATH"
7467 [(set_attr "type" "idiv")
7468 (set_attr "mode" "QI")])
7470 ;; We cannot use div/idiv for double division, because it causes
7471 ;; "division by zero" on the overflow and that's not what we expect
7472 ;; from truncate. Because true (non truncating) double division is
7473 ;; never generated, we can't create this insn anyway.
7476 ; [(set (match_operand:SI 0 "register_operand" "=a")
7478 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7480 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7481 ; (set (match_operand:SI 3 "register_operand" "=d")
7483 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7484 ; (clobber (reg:CC FLAGS_REG))]
7486 ; "div{l}\t{%2, %0|%0, %2}"
7487 ; [(set_attr "type" "idiv")])
7489 ;;- Logical AND instructions
7491 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7492 ;; Note that this excludes ah.
7494 (define_expand "testsi_ccno_1"
7495 [(set (reg:CCNO FLAGS_REG)
7497 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7498 (match_operand:SI 1 "nonmemory_operand" ""))
7501 (define_expand "testqi_ccz_1"
7502 [(set (reg:CCZ FLAGS_REG)
7503 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7504 (match_operand:QI 1 "nonmemory_operand" ""))
7507 (define_expand "testdi_ccno_1"
7508 [(set (reg:CCNO FLAGS_REG)
7510 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7511 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7513 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7515 (define_insn "*testdi_1"
7516 [(set (reg FLAGS_REG)
7519 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7520 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7522 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7523 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7525 test{l}\t{%k1, %k0|%k0, %k1}
7526 test{l}\t{%k1, %k0|%k0, %k1}
7527 test{q}\t{%1, %0|%0, %1}
7528 test{q}\t{%1, %0|%0, %1}
7529 test{q}\t{%1, %0|%0, %1}"
7530 [(set_attr "type" "test")
7531 (set_attr "modrm" "0,1,0,1,1")
7532 (set_attr "mode" "SI,SI,DI,DI,DI")])
7534 (define_insn "*testqi_1_maybe_si"
7535 [(set (reg FLAGS_REG)
7538 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7539 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7541 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7542 && ix86_match_ccmode (insn,
7543 CONST_INT_P (operands[1])
7544 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7546 if (which_alternative == 3)
7548 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7549 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7550 return "test{l}\t{%1, %k0|%k0, %1}";
7552 return "test{b}\t{%1, %0|%0, %1}";
7554 [(set_attr "type" "test")
7555 (set_attr "modrm" "0,1,1,1")
7556 (set_attr "mode" "QI,QI,QI,SI")
7557 (set_attr "pent_pair" "uv,np,uv,np")])
7559 (define_insn "*test<mode>_1"
7560 [(set (reg FLAGS_REG)
7563 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7564 (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7566 "ix86_match_ccmode (insn, CCNOmode)
7567 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7568 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7569 [(set_attr "type" "test")
7570 (set_attr "modrm" "0,1,1")
7571 (set_attr "mode" "<MODE>")
7572 (set_attr "pent_pair" "uv,np,uv")])
7574 (define_expand "testqi_ext_ccno_0"
7575 [(set (reg:CCNO FLAGS_REG)
7579 (match_operand 0 "ext_register_operand" "")
7582 (match_operand 1 "const_int_operand" ""))
7585 (define_insn "*testqi_ext_0"
7586 [(set (reg FLAGS_REG)
7590 (match_operand 0 "ext_register_operand" "Q")
7593 (match_operand 1 "const_int_operand" "n"))
7595 "ix86_match_ccmode (insn, CCNOmode)"
7596 "test{b}\t{%1, %h0|%h0, %1}"
7597 [(set_attr "type" "test")
7598 (set_attr "mode" "QI")
7599 (set_attr "length_immediate" "1")
7600 (set_attr "modrm" "1")
7601 (set_attr "pent_pair" "np")])
7603 (define_insn "*testqi_ext_1_rex64"
7604 [(set (reg FLAGS_REG)
7608 (match_operand 0 "ext_register_operand" "Q")
7612 (match_operand:QI 1 "register_operand" "Q")))
7614 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7615 "test{b}\t{%1, %h0|%h0, %1}"
7616 [(set_attr "type" "test")
7617 (set_attr "mode" "QI")])
7619 (define_insn "*testqi_ext_1"
7620 [(set (reg FLAGS_REG)
7624 (match_operand 0 "ext_register_operand" "Q")
7628 (match_operand:QI 1 "general_operand" "Qm")))
7630 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7631 "test{b}\t{%1, %h0|%h0, %1}"
7632 [(set_attr "type" "test")
7633 (set_attr "mode" "QI")])
7635 (define_insn "*testqi_ext_2"
7636 [(set (reg FLAGS_REG)
7640 (match_operand 0 "ext_register_operand" "Q")
7644 (match_operand 1 "ext_register_operand" "Q")
7648 "ix86_match_ccmode (insn, CCNOmode)"
7649 "test{b}\t{%h1, %h0|%h0, %h1}"
7650 [(set_attr "type" "test")
7651 (set_attr "mode" "QI")])
7653 (define_insn "*testqi_ext_3_rex64"
7654 [(set (reg FLAGS_REG)
7655 (compare (zero_extract:DI
7656 (match_operand 0 "nonimmediate_operand" "rm")
7657 (match_operand:DI 1 "const_int_operand" "")
7658 (match_operand:DI 2 "const_int_operand" ""))
7661 && ix86_match_ccmode (insn, CCNOmode)
7662 && INTVAL (operands[1]) > 0
7663 && INTVAL (operands[2]) >= 0
7664 /* Ensure that resulting mask is zero or sign extended operand. */
7665 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7666 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7667 && INTVAL (operands[1]) > 32))
7668 && (GET_MODE (operands[0]) == SImode
7669 || GET_MODE (operands[0]) == DImode
7670 || GET_MODE (operands[0]) == HImode
7671 || GET_MODE (operands[0]) == QImode)"
7674 ;; Combine likes to form bit extractions for some tests. Humor it.
7675 (define_insn "*testqi_ext_3"
7676 [(set (reg FLAGS_REG)
7677 (compare (zero_extract:SI
7678 (match_operand 0 "nonimmediate_operand" "rm")
7679 (match_operand:SI 1 "const_int_operand" "")
7680 (match_operand:SI 2 "const_int_operand" ""))
7682 "ix86_match_ccmode (insn, CCNOmode)
7683 && INTVAL (operands[1]) > 0
7684 && INTVAL (operands[2]) >= 0
7685 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7686 && (GET_MODE (operands[0]) == SImode
7687 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7688 || GET_MODE (operands[0]) == HImode
7689 || GET_MODE (operands[0]) == QImode)"
7693 [(set (match_operand 0 "flags_reg_operand" "")
7694 (match_operator 1 "compare_operator"
7696 (match_operand 2 "nonimmediate_operand" "")
7697 (match_operand 3 "const_int_operand" "")
7698 (match_operand 4 "const_int_operand" ""))
7700 "ix86_match_ccmode (insn, CCNOmode)"
7701 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7703 rtx val = operands[2];
7704 HOST_WIDE_INT len = INTVAL (operands[3]);
7705 HOST_WIDE_INT pos = INTVAL (operands[4]);
7707 enum machine_mode mode, submode;
7709 mode = GET_MODE (val);
7712 /* ??? Combine likes to put non-volatile mem extractions in QImode
7713 no matter the size of the test. So find a mode that works. */
7714 if (! MEM_VOLATILE_P (val))
7716 mode = smallest_mode_for_size (pos + len, MODE_INT);
7717 val = adjust_address (val, mode, 0);
7720 else if (GET_CODE (val) == SUBREG
7721 && (submode = GET_MODE (SUBREG_REG (val)),
7722 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7723 && pos + len <= GET_MODE_BITSIZE (submode)
7724 && GET_MODE_CLASS (submode) == MODE_INT)
7726 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7728 val = SUBREG_REG (val);
7730 else if (mode == HImode && pos + len <= 8)
7732 /* Small HImode tests can be converted to QImode. */
7734 val = gen_lowpart (QImode, val);
7737 if (len == HOST_BITS_PER_WIDE_INT)
7740 mask = ((HOST_WIDE_INT)1 << len) - 1;
7743 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7746 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7747 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7748 ;; this is relatively important trick.
7749 ;; Do the conversion only post-reload to avoid limiting of the register class
7752 [(set (match_operand 0 "flags_reg_operand" "")
7753 (match_operator 1 "compare_operator"
7754 [(and (match_operand 2 "register_operand" "")
7755 (match_operand 3 "const_int_operand" ""))
7758 && QI_REG_P (operands[2])
7759 && GET_MODE (operands[2]) != QImode
7760 && ((ix86_match_ccmode (insn, CCZmode)
7761 && !(INTVAL (operands[3]) & ~(255 << 8)))
7762 || (ix86_match_ccmode (insn, CCNOmode)
7763 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7766 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7769 "operands[2] = gen_lowpart (SImode, operands[2]);
7770 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7773 [(set (match_operand 0 "flags_reg_operand" "")
7774 (match_operator 1 "compare_operator"
7775 [(and (match_operand 2 "nonimmediate_operand" "")
7776 (match_operand 3 "const_int_operand" ""))
7779 && GET_MODE (operands[2]) != QImode
7780 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7781 && ((ix86_match_ccmode (insn, CCZmode)
7782 && !(INTVAL (operands[3]) & ~255))
7783 || (ix86_match_ccmode (insn, CCNOmode)
7784 && !(INTVAL (operands[3]) & ~127)))"
7786 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7788 "operands[2] = gen_lowpart (QImode, operands[2]);
7789 operands[3] = gen_lowpart (QImode, operands[3]);")
7791 ;; %%% This used to optimize known byte-wide and operations to memory,
7792 ;; and sometimes to QImode registers. If this is considered useful,
7793 ;; it should be done with splitters.
7795 (define_expand "and<mode>3"
7796 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7797 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7798 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7800 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7802 (define_insn "*anddi_1"
7803 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7805 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7806 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7807 (clobber (reg:CC FLAGS_REG))]
7808 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7810 switch (get_attr_type (insn))
7814 enum machine_mode mode;
7816 gcc_assert (CONST_INT_P (operands[2]));
7817 if (INTVAL (operands[2]) == 0xff)
7821 gcc_assert (INTVAL (operands[2]) == 0xffff);
7825 operands[1] = gen_lowpart (mode, operands[1]);
7827 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7829 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7833 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7834 if (get_attr_mode (insn) == MODE_SI)
7835 return "and{l}\t{%k2, %k0|%k0, %k2}";
7837 return "and{q}\t{%2, %0|%0, %2}";
7840 [(set_attr "type" "alu,alu,alu,imovx")
7841 (set_attr "length_immediate" "*,*,*,0")
7842 (set (attr "prefix_rex")
7844 (and (eq_attr "type" "imovx")
7845 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7846 (match_operand 1 "ext_QIreg_nomode_operand" "")))
7848 (const_string "*")))
7849 (set_attr "mode" "SI,DI,DI,SI")])
7851 (define_insn "*andsi_1"
7852 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7853 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7854 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7855 (clobber (reg:CC FLAGS_REG))]
7856 "ix86_binary_operator_ok (AND, SImode, operands)"
7858 switch (get_attr_type (insn))
7862 enum machine_mode mode;
7864 gcc_assert (CONST_INT_P (operands[2]));
7865 if (INTVAL (operands[2]) == 0xff)
7869 gcc_assert (INTVAL (operands[2]) == 0xffff);
7873 operands[1] = gen_lowpart (mode, operands[1]);
7875 return "movz{bl|x}\t{%1, %0|%0, %1}";
7877 return "movz{wl|x}\t{%1, %0|%0, %1}";
7881 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7882 return "and{l}\t{%2, %0|%0, %2}";
7885 [(set_attr "type" "alu,alu,imovx")
7886 (set (attr "prefix_rex")
7888 (and (eq_attr "type" "imovx")
7889 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7890 (match_operand 1 "ext_QIreg_nomode_operand" "")))
7892 (const_string "*")))
7893 (set_attr "length_immediate" "*,*,0")
7894 (set_attr "mode" "SI")])
7896 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7897 (define_insn "*andsi_1_zext"
7898 [(set (match_operand:DI 0 "register_operand" "=r")
7900 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7901 (match_operand:SI 2 "general_operand" "g"))))
7902 (clobber (reg:CC FLAGS_REG))]
7903 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7904 "and{l}\t{%2, %k0|%k0, %2}"
7905 [(set_attr "type" "alu")
7906 (set_attr "mode" "SI")])
7908 (define_insn "*andhi_1"
7909 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7910 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7911 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7912 (clobber (reg:CC FLAGS_REG))]
7913 "ix86_binary_operator_ok (AND, HImode, operands)"
7915 switch (get_attr_type (insn))
7918 gcc_assert (CONST_INT_P (operands[2]));
7919 gcc_assert (INTVAL (operands[2]) == 0xff);
7920 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7923 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7925 return "and{w}\t{%2, %0|%0, %2}";
7928 [(set_attr "type" "alu,alu,imovx")
7929 (set_attr "length_immediate" "*,*,0")
7930 (set (attr "prefix_rex")
7932 (and (eq_attr "type" "imovx")
7933 (match_operand 1 "ext_QIreg_nomode_operand" ""))
7935 (const_string "*")))
7936 (set_attr "mode" "HI,HI,SI")])
7938 ;; %%% Potential partial reg stall on alternative 2. What to do?
7939 (define_insn "*andqi_1"
7940 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7941 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7942 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7943 (clobber (reg:CC FLAGS_REG))]
7944 "ix86_binary_operator_ok (AND, QImode, operands)"
7946 and{b}\t{%2, %0|%0, %2}
7947 and{b}\t{%2, %0|%0, %2}
7948 and{l}\t{%k2, %k0|%k0, %k2}"
7949 [(set_attr "type" "alu")
7950 (set_attr "mode" "QI,QI,SI")])
7952 (define_insn "*andqi_1_slp"
7953 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7954 (and:QI (match_dup 0)
7955 (match_operand:QI 1 "general_operand" "qn,qmn")))
7956 (clobber (reg:CC FLAGS_REG))]
7957 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7958 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7959 "and{b}\t{%1, %0|%0, %1}"
7960 [(set_attr "type" "alu1")
7961 (set_attr "mode" "QI")])
7964 [(set (match_operand 0 "register_operand" "")
7966 (const_int -65536)))
7967 (clobber (reg:CC FLAGS_REG))]
7968 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7969 || optimize_function_for_size_p (cfun)"
7970 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7971 "operands[1] = gen_lowpart (HImode, operands[0]);")
7974 [(set (match_operand 0 "ext_register_operand" "")
7977 (clobber (reg:CC FLAGS_REG))]
7978 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7979 && reload_completed"
7980 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7981 "operands[1] = gen_lowpart (QImode, operands[0]);")
7984 [(set (match_operand 0 "ext_register_operand" "")
7986 (const_int -65281)))
7987 (clobber (reg:CC FLAGS_REG))]
7988 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7989 && reload_completed"
7990 [(parallel [(set (zero_extract:SI (match_dup 0)
7994 (zero_extract:SI (match_dup 0)
7997 (zero_extract:SI (match_dup 0)
8000 (clobber (reg:CC FLAGS_REG))])]
8001 "operands[0] = gen_lowpart (SImode, operands[0]);")
8003 (define_insn "*anddi_2"
8004 [(set (reg FLAGS_REG)
8007 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8008 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8010 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8011 (and:DI (match_dup 1) (match_dup 2)))]
8012 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8013 && ix86_binary_operator_ok (AND, DImode, operands)"
8015 and{l}\t{%k2, %k0|%k0, %k2}
8016 and{q}\t{%2, %0|%0, %2}
8017 and{q}\t{%2, %0|%0, %2}"
8018 [(set_attr "type" "alu")
8019 (set_attr "mode" "SI,DI,DI")])
8021 (define_insn "*andqi_2_maybe_si"
8022 [(set (reg FLAGS_REG)
8024 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8025 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8027 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8028 (and:QI (match_dup 1) (match_dup 2)))]
8029 "ix86_binary_operator_ok (AND, QImode, operands)
8030 && ix86_match_ccmode (insn,
8031 CONST_INT_P (operands[2])
8032 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8034 if (which_alternative == 2)
8036 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8037 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8038 return "and{l}\t{%2, %k0|%k0, %2}";
8040 return "and{b}\t{%2, %0|%0, %2}";
8042 [(set_attr "type" "alu")
8043 (set_attr "mode" "QI,QI,SI")])
8045 (define_insn "*and<mode>_2"
8046 [(set (reg FLAGS_REG)
8047 (compare (and:SWI124
8048 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8049 (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
8051 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8052 (and:SWI124 (match_dup 1) (match_dup 2)))]
8053 "ix86_match_ccmode (insn, CCNOmode)
8054 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8055 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8056 [(set_attr "type" "alu")
8057 (set_attr "mode" "<MODE>")])
8059 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8060 (define_insn "*andsi_2_zext"
8061 [(set (reg FLAGS_REG)
8063 (match_operand:SI 1 "nonimmediate_operand" "%0")
8064 (match_operand:SI 2 "general_operand" "g"))
8066 (set (match_operand:DI 0 "register_operand" "=r")
8067 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8068 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8069 && ix86_binary_operator_ok (AND, SImode, operands)"
8070 "and{l}\t{%2, %k0|%k0, %2}"
8071 [(set_attr "type" "alu")
8072 (set_attr "mode" "SI")])
8074 (define_insn "*andqi_2_slp"
8075 [(set (reg FLAGS_REG)
8077 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8078 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8080 (set (strict_low_part (match_dup 0))
8081 (and:QI (match_dup 0) (match_dup 1)))]
8082 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8083 && ix86_match_ccmode (insn, CCNOmode)
8084 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8085 "and{b}\t{%1, %0|%0, %1}"
8086 [(set_attr "type" "alu1")
8087 (set_attr "mode" "QI")])
8089 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8090 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8091 ;; for a QImode operand, which of course failed.
8092 (define_insn "andqi_ext_0"
8093 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8098 (match_operand 1 "ext_register_operand" "0")
8101 (match_operand 2 "const_int_operand" "n")))
8102 (clobber (reg:CC FLAGS_REG))]
8104 "and{b}\t{%2, %h0|%h0, %2}"
8105 [(set_attr "type" "alu")
8106 (set_attr "length_immediate" "1")
8107 (set_attr "modrm" "1")
8108 (set_attr "mode" "QI")])
8110 ;; Generated by peephole translating test to and. This shows up
8111 ;; often in fp comparisons.
8112 (define_insn "*andqi_ext_0_cc"
8113 [(set (reg FLAGS_REG)
8117 (match_operand 1 "ext_register_operand" "0")
8120 (match_operand 2 "const_int_operand" "n"))
8122 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8131 "ix86_match_ccmode (insn, CCNOmode)"
8132 "and{b}\t{%2, %h0|%h0, %2}"
8133 [(set_attr "type" "alu")
8134 (set_attr "length_immediate" "1")
8135 (set_attr "modrm" "1")
8136 (set_attr "mode" "QI")])
8138 (define_insn "*andqi_ext_1_rex64"
8139 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8144 (match_operand 1 "ext_register_operand" "0")
8148 (match_operand 2 "ext_register_operand" "Q"))))
8149 (clobber (reg:CC FLAGS_REG))]
8151 "and{b}\t{%2, %h0|%h0, %2}"
8152 [(set_attr "type" "alu")
8153 (set_attr "length_immediate" "0")
8154 (set_attr "mode" "QI")])
8156 (define_insn "*andqi_ext_1"
8157 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8162 (match_operand 1 "ext_register_operand" "0")
8166 (match_operand:QI 2 "general_operand" "Qm"))))
8167 (clobber (reg:CC FLAGS_REG))]
8169 "and{b}\t{%2, %h0|%h0, %2}"
8170 [(set_attr "type" "alu")
8171 (set_attr "length_immediate" "0")
8172 (set_attr "mode" "QI")])
8174 (define_insn "*andqi_ext_2"
8175 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8180 (match_operand 1 "ext_register_operand" "%0")
8184 (match_operand 2 "ext_register_operand" "Q")
8187 (clobber (reg:CC FLAGS_REG))]
8189 "and{b}\t{%h2, %h0|%h0, %h2}"
8190 [(set_attr "type" "alu")
8191 (set_attr "length_immediate" "0")
8192 (set_attr "mode" "QI")])
8194 ;; Convert wide AND instructions with immediate operand to shorter QImode
8195 ;; equivalents when possible.
8196 ;; Don't do the splitting with memory operands, since it introduces risk
8197 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8198 ;; for size, but that can (should?) be handled by generic code instead.
8200 [(set (match_operand 0 "register_operand" "")
8201 (and (match_operand 1 "register_operand" "")
8202 (match_operand 2 "const_int_operand" "")))
8203 (clobber (reg:CC FLAGS_REG))]
8205 && QI_REG_P (operands[0])
8206 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8207 && !(~INTVAL (operands[2]) & ~(255 << 8))
8208 && GET_MODE (operands[0]) != QImode"
8209 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8210 (and:SI (zero_extract:SI (match_dup 1)
8211 (const_int 8) (const_int 8))
8213 (clobber (reg:CC FLAGS_REG))])]
8214 "operands[0] = gen_lowpart (SImode, operands[0]);
8215 operands[1] = gen_lowpart (SImode, operands[1]);
8216 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8218 ;; Since AND can be encoded with sign extended immediate, this is only
8219 ;; profitable when 7th bit is not set.
8221 [(set (match_operand 0 "register_operand" "")
8222 (and (match_operand 1 "general_operand" "")
8223 (match_operand 2 "const_int_operand" "")))
8224 (clobber (reg:CC FLAGS_REG))]
8226 && ANY_QI_REG_P (operands[0])
8227 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8228 && !(~INTVAL (operands[2]) & ~255)
8229 && !(INTVAL (operands[2]) & 128)
8230 && GET_MODE (operands[0]) != QImode"
8231 [(parallel [(set (strict_low_part (match_dup 0))
8232 (and:QI (match_dup 1)
8234 (clobber (reg:CC FLAGS_REG))])]
8235 "operands[0] = gen_lowpart (QImode, operands[0]);
8236 operands[1] = gen_lowpart (QImode, operands[1]);
8237 operands[2] = gen_lowpart (QImode, operands[2]);")
8239 ;; Logical inclusive and exclusive OR instructions
8241 ;; %%% This used to optimize known byte-wide and operations to memory.
8242 ;; If this is considered useful, it should be done with splitters.
8244 (define_expand "<code><mode>3"
8245 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8246 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8247 (match_operand:SWIM 2 "<general_operand>" "")))]
8249 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8251 (define_insn "*<code><mode>_1"
8252 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8254 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8255 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8256 (clobber (reg:CC FLAGS_REG))]
8257 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8258 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8259 [(set_attr "type" "alu")
8260 (set_attr "mode" "<MODE>")])
8262 ;; %%% Potential partial reg stall on alternative 2. What to do?
8263 (define_insn "*<code>qi_1"
8264 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8265 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8266 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8267 (clobber (reg:CC FLAGS_REG))]
8268 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8270 <logic>{b}\t{%2, %0|%0, %2}
8271 <logic>{b}\t{%2, %0|%0, %2}
8272 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8273 [(set_attr "type" "alu")
8274 (set_attr "mode" "QI,QI,SI")])
8276 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8277 (define_insn "*<code>si_1_zext"
8278 [(set (match_operand:DI 0 "register_operand" "=r")
8280 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8281 (match_operand:SI 2 "general_operand" "g"))))
8282 (clobber (reg:CC FLAGS_REG))]
8283 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8284 "<logic>{l}\t{%2, %k0|%k0, %2}"
8285 [(set_attr "type" "alu")
8286 (set_attr "mode" "SI")])
8288 (define_insn "*<code>si_1_zext_imm"
8289 [(set (match_operand:DI 0 "register_operand" "=r")
8291 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8292 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8293 (clobber (reg:CC FLAGS_REG))]
8294 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8295 "<logic>{l}\t{%2, %k0|%k0, %2}"
8296 [(set_attr "type" "alu")
8297 (set_attr "mode" "SI")])
8299 (define_insn "*<code>qi_1_slp"
8300 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8301 (any_or:QI (match_dup 0)
8302 (match_operand:QI 1 "general_operand" "qmn,qn")))
8303 (clobber (reg:CC FLAGS_REG))]
8304 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8305 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8306 "<logic>{b}\t{%1, %0|%0, %1}"
8307 [(set_attr "type" "alu1")
8308 (set_attr "mode" "QI")])
8310 (define_insn "*<code><mode>_2"
8311 [(set (reg FLAGS_REG)
8312 (compare (any_or:SWI
8313 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8314 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8316 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8317 (any_or:SWI (match_dup 1) (match_dup 2)))]
8318 "ix86_match_ccmode (insn, CCNOmode)
8319 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8320 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8321 [(set_attr "type" "alu")
8322 (set_attr "mode" "<MODE>")])
8324 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8325 ;; ??? Special case for immediate operand is missing - it is tricky.
8326 (define_insn "*<code>si_2_zext"
8327 [(set (reg FLAGS_REG)
8328 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8329 (match_operand:SI 2 "general_operand" "g"))
8331 (set (match_operand:DI 0 "register_operand" "=r")
8332 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8333 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8334 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8335 "<logic>{l}\t{%2, %k0|%k0, %2}"
8336 [(set_attr "type" "alu")
8337 (set_attr "mode" "SI")])
8339 (define_insn "*<code>si_2_zext_imm"
8340 [(set (reg FLAGS_REG)
8342 (match_operand:SI 1 "nonimmediate_operand" "%0")
8343 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8345 (set (match_operand:DI 0 "register_operand" "=r")
8346 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8347 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8348 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8349 "<logic>{l}\t{%2, %k0|%k0, %2}"
8350 [(set_attr "type" "alu")
8351 (set_attr "mode" "SI")])
8353 (define_insn "*<code>qi_2_slp"
8354 [(set (reg FLAGS_REG)
8355 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8356 (match_operand:QI 1 "general_operand" "qmn,qn"))
8358 (set (strict_low_part (match_dup 0))
8359 (any_or:QI (match_dup 0) (match_dup 1)))]
8360 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8361 && ix86_match_ccmode (insn, CCNOmode)
8362 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8363 "<logic>{b}\t{%1, %0|%0, %1}"
8364 [(set_attr "type" "alu1")
8365 (set_attr "mode" "QI")])
8367 (define_insn "*<code><mode>_3"
8368 [(set (reg FLAGS_REG)
8369 (compare (any_or:SWI
8370 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8371 (match_operand:SWI 2 "<general_operand>" "<g>"))
8373 (clobber (match_scratch:SWI 0 "=<r>"))]
8374 "ix86_match_ccmode (insn, CCNOmode)
8375 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8376 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8377 [(set_attr "type" "alu")
8378 (set_attr "mode" "<MODE>")])
8380 (define_insn "*<code>qi_ext_0"
8381 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8386 (match_operand 1 "ext_register_operand" "0")
8389 (match_operand 2 "const_int_operand" "n")))
8390 (clobber (reg:CC FLAGS_REG))]
8391 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8392 "<logic>{b}\t{%2, %h0|%h0, %2}"
8393 [(set_attr "type" "alu")
8394 (set_attr "length_immediate" "1")
8395 (set_attr "modrm" "1")
8396 (set_attr "mode" "QI")])
8398 (define_insn "*<code>qi_ext_1_rex64"
8399 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8404 (match_operand 1 "ext_register_operand" "0")
8408 (match_operand 2 "ext_register_operand" "Q"))))
8409 (clobber (reg:CC FLAGS_REG))]
8411 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8412 "<logic>{b}\t{%2, %h0|%h0, %2}"
8413 [(set_attr "type" "alu")
8414 (set_attr "length_immediate" "0")
8415 (set_attr "mode" "QI")])
8417 (define_insn "*<code>qi_ext_1"
8418 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8423 (match_operand 1 "ext_register_operand" "0")
8427 (match_operand:QI 2 "general_operand" "Qm"))))
8428 (clobber (reg:CC FLAGS_REG))]
8430 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8431 "<logic>{b}\t{%2, %h0|%h0, %2}"
8432 [(set_attr "type" "alu")
8433 (set_attr "length_immediate" "0")
8434 (set_attr "mode" "QI")])
8436 (define_insn "*<code>qi_ext_2"
8437 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8441 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8444 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8447 (clobber (reg:CC FLAGS_REG))]
8448 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8449 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8450 [(set_attr "type" "alu")
8451 (set_attr "length_immediate" "0")
8452 (set_attr "mode" "QI")])
8455 [(set (match_operand 0 "register_operand" "")
8456 (any_or (match_operand 1 "register_operand" "")
8457 (match_operand 2 "const_int_operand" "")))
8458 (clobber (reg:CC FLAGS_REG))]
8460 && QI_REG_P (operands[0])
8461 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8462 && !(INTVAL (operands[2]) & ~(255 << 8))
8463 && GET_MODE (operands[0]) != QImode"
8464 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8465 (any_or:SI (zero_extract:SI (match_dup 1)
8466 (const_int 8) (const_int 8))
8468 (clobber (reg:CC FLAGS_REG))])]
8469 "operands[0] = gen_lowpart (SImode, operands[0]);
8470 operands[1] = gen_lowpart (SImode, operands[1]);
8471 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8473 ;; Since OR can be encoded with sign extended immediate, this is only
8474 ;; profitable when 7th bit is set.
8476 [(set (match_operand 0 "register_operand" "")
8477 (any_or (match_operand 1 "general_operand" "")
8478 (match_operand 2 "const_int_operand" "")))
8479 (clobber (reg:CC FLAGS_REG))]
8481 && ANY_QI_REG_P (operands[0])
8482 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8483 && !(INTVAL (operands[2]) & ~255)
8484 && (INTVAL (operands[2]) & 128)
8485 && GET_MODE (operands[0]) != QImode"
8486 [(parallel [(set (strict_low_part (match_dup 0))
8487 (any_or:QI (match_dup 1)
8489 (clobber (reg:CC FLAGS_REG))])]
8490 "operands[0] = gen_lowpart (QImode, operands[0]);
8491 operands[1] = gen_lowpart (QImode, operands[1]);
8492 operands[2] = gen_lowpart (QImode, operands[2]);")
8494 (define_expand "xorqi_cc_ext_1"
8496 (set (reg:CCNO FLAGS_REG)
8500 (match_operand 1 "ext_register_operand" "")
8503 (match_operand:QI 2 "general_operand" ""))
8505 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8515 (define_insn "*xorqi_cc_ext_1_rex64"
8516 [(set (reg FLAGS_REG)
8520 (match_operand 1 "ext_register_operand" "0")
8523 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8525 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8534 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8535 "xor{b}\t{%2, %h0|%h0, %2}"
8536 [(set_attr "type" "alu")
8537 (set_attr "modrm" "1")
8538 (set_attr "mode" "QI")])
8540 (define_insn "*xorqi_cc_ext_1"
8541 [(set (reg FLAGS_REG)
8545 (match_operand 1 "ext_register_operand" "0")
8548 (match_operand:QI 2 "general_operand" "qmn"))
8550 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8559 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8560 "xor{b}\t{%2, %h0|%h0, %2}"
8561 [(set_attr "type" "alu")
8562 (set_attr "modrm" "1")
8563 (set_attr "mode" "QI")])
8565 ;; Negation instructions
8567 (define_expand "neg<mode>2"
8568 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8569 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8571 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8573 (define_insn_and_split "*neg<dwi>2_doubleword"
8574 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8575 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8576 (clobber (reg:CC FLAGS_REG))]
8577 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8581 [(set (reg:CCZ FLAGS_REG)
8582 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8583 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8586 (plus:DWIH (match_dup 3)
8587 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8589 (clobber (reg:CC FLAGS_REG))])
8592 (neg:DWIH (match_dup 2)))
8593 (clobber (reg:CC FLAGS_REG))])]
8594 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8596 (define_insn "*neg<mode>2_1"
8597 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8598 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8599 (clobber (reg:CC FLAGS_REG))]
8600 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8601 "neg{<imodesuffix>}\t%0"
8602 [(set_attr "type" "negnot")
8603 (set_attr "mode" "<MODE>")])
8605 ;; Combine is quite creative about this pattern.
8606 (define_insn "*negsi2_1_zext"
8607 [(set (match_operand:DI 0 "register_operand" "=r")
8609 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8612 (clobber (reg:CC FLAGS_REG))]
8613 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8615 [(set_attr "type" "negnot")
8616 (set_attr "mode" "SI")])
8618 ;; The problem with neg is that it does not perform (compare x 0),
8619 ;; it really performs (compare 0 x), which leaves us with the zero
8620 ;; flag being the only useful item.
8622 (define_insn "*neg<mode>2_cmpz"
8623 [(set (reg:CCZ FLAGS_REG)
8625 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8627 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8628 (neg:SWI (match_dup 1)))]
8629 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8630 "neg{<imodesuffix>}\t%0"
8631 [(set_attr "type" "negnot")
8632 (set_attr "mode" "<MODE>")])
8634 (define_insn "*negsi2_cmpz_zext"
8635 [(set (reg:CCZ FLAGS_REG)
8639 (match_operand:DI 1 "register_operand" "0")
8643 (set (match_operand:DI 0 "register_operand" "=r")
8644 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8647 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8649 [(set_attr "type" "negnot")
8650 (set_attr "mode" "SI")])
8652 ;; Changing of sign for FP values is doable using integer unit too.
8654 (define_expand "<code><mode>2"
8655 [(set (match_operand:X87MODEF 0 "register_operand" "")
8656 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8657 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8658 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8660 (define_insn "*absneg<mode>2_mixed"
8661 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8662 (match_operator:MODEF 3 "absneg_operator"
8663 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8664 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8665 (clobber (reg:CC FLAGS_REG))]
8666 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8669 (define_insn "*absneg<mode>2_sse"
8670 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8671 (match_operator:MODEF 3 "absneg_operator"
8672 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8673 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8674 (clobber (reg:CC FLAGS_REG))]
8675 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8678 (define_insn "*absneg<mode>2_i387"
8679 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8680 (match_operator:X87MODEF 3 "absneg_operator"
8681 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8682 (use (match_operand 2 "" ""))
8683 (clobber (reg:CC FLAGS_REG))]
8684 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8687 (define_expand "<code>tf2"
8688 [(set (match_operand:TF 0 "register_operand" "")
8689 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8691 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8693 (define_insn "*absnegtf2_sse"
8694 [(set (match_operand:TF 0 "register_operand" "=x,x")
8695 (match_operator:TF 3 "absneg_operator"
8696 [(match_operand:TF 1 "register_operand" "0,x")]))
8697 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8698 (clobber (reg:CC FLAGS_REG))]
8702 ;; Splitters for fp abs and neg.
8705 [(set (match_operand 0 "fp_register_operand" "")
8706 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8707 (use (match_operand 2 "" ""))
8708 (clobber (reg:CC FLAGS_REG))]
8710 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8713 [(set (match_operand 0 "register_operand" "")
8714 (match_operator 3 "absneg_operator"
8715 [(match_operand 1 "register_operand" "")]))
8716 (use (match_operand 2 "nonimmediate_operand" ""))
8717 (clobber (reg:CC FLAGS_REG))]
8718 "reload_completed && SSE_REG_P (operands[0])"
8719 [(set (match_dup 0) (match_dup 3))]
8721 enum machine_mode mode = GET_MODE (operands[0]);
8722 enum machine_mode vmode = GET_MODE (operands[2]);
8725 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8726 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8727 if (operands_match_p (operands[0], operands[2]))
8730 operands[1] = operands[2];
8733 if (GET_CODE (operands[3]) == ABS)
8734 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8736 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8741 [(set (match_operand:SF 0 "register_operand" "")
8742 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8743 (use (match_operand:V4SF 2 "" ""))
8744 (clobber (reg:CC FLAGS_REG))]
8746 [(parallel [(set (match_dup 0) (match_dup 1))
8747 (clobber (reg:CC FLAGS_REG))])]
8750 operands[0] = gen_lowpart (SImode, operands[0]);
8751 if (GET_CODE (operands[1]) == ABS)
8753 tmp = gen_int_mode (0x7fffffff, SImode);
8754 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8758 tmp = gen_int_mode (0x80000000, SImode);
8759 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8765 [(set (match_operand:DF 0 "register_operand" "")
8766 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8767 (use (match_operand 2 "" ""))
8768 (clobber (reg:CC FLAGS_REG))]
8770 [(parallel [(set (match_dup 0) (match_dup 1))
8771 (clobber (reg:CC FLAGS_REG))])]
8776 tmp = gen_lowpart (DImode, operands[0]);
8777 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8780 if (GET_CODE (operands[1]) == ABS)
8783 tmp = gen_rtx_NOT (DImode, tmp);
8787 operands[0] = gen_highpart (SImode, operands[0]);
8788 if (GET_CODE (operands[1]) == ABS)
8790 tmp = gen_int_mode (0x7fffffff, SImode);
8791 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8795 tmp = gen_int_mode (0x80000000, SImode);
8796 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8803 [(set (match_operand:XF 0 "register_operand" "")
8804 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8805 (use (match_operand 2 "" ""))
8806 (clobber (reg:CC FLAGS_REG))]
8808 [(parallel [(set (match_dup 0) (match_dup 1))
8809 (clobber (reg:CC FLAGS_REG))])]
8812 operands[0] = gen_rtx_REG (SImode,
8813 true_regnum (operands[0])
8814 + (TARGET_64BIT ? 1 : 2));
8815 if (GET_CODE (operands[1]) == ABS)
8817 tmp = GEN_INT (0x7fff);
8818 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8822 tmp = GEN_INT (0x8000);
8823 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8828 ;; Conditionalize these after reload. If they match before reload, we
8829 ;; lose the clobber and ability to use integer instructions.
8831 (define_insn "*<code><mode>2_1"
8832 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8833 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8835 && (reload_completed
8836 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8837 "f<absneg_mnemonic>"
8838 [(set_attr "type" "fsgn")
8839 (set_attr "mode" "<MODE>")])
8841 (define_insn "*<code>extendsfdf2"
8842 [(set (match_operand:DF 0 "register_operand" "=f")
8843 (absneg:DF (float_extend:DF
8844 (match_operand:SF 1 "register_operand" "0"))))]
8845 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8846 "f<absneg_mnemonic>"
8847 [(set_attr "type" "fsgn")
8848 (set_attr "mode" "DF")])
8850 (define_insn "*<code>extendsfxf2"
8851 [(set (match_operand:XF 0 "register_operand" "=f")
8852 (absneg:XF (float_extend:XF
8853 (match_operand:SF 1 "register_operand" "0"))))]
8855 "f<absneg_mnemonic>"
8856 [(set_attr "type" "fsgn")
8857 (set_attr "mode" "XF")])
8859 (define_insn "*<code>extenddfxf2"
8860 [(set (match_operand:XF 0 "register_operand" "=f")
8861 (absneg:XF (float_extend:XF
8862 (match_operand:DF 1 "register_operand" "0"))))]
8864 "f<absneg_mnemonic>"
8865 [(set_attr "type" "fsgn")
8866 (set_attr "mode" "XF")])
8868 ;; Copysign instructions
8870 (define_mode_iterator CSGNMODE [SF DF TF])
8871 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8873 (define_expand "copysign<mode>3"
8874 [(match_operand:CSGNMODE 0 "register_operand" "")
8875 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8876 (match_operand:CSGNMODE 2 "register_operand" "")]
8877 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8878 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8879 "ix86_expand_copysign (operands); DONE;")
8881 (define_insn_and_split "copysign<mode>3_const"
8882 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8884 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8885 (match_operand:CSGNMODE 2 "register_operand" "0")
8886 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8888 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8889 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8891 "&& reload_completed"
8893 "ix86_split_copysign_const (operands); DONE;")
8895 (define_insn "copysign<mode>3_var"
8896 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8898 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8899 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8900 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8901 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8903 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8904 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8905 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8909 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8911 [(match_operand:CSGNMODE 2 "register_operand" "")
8912 (match_operand:CSGNMODE 3 "register_operand" "")
8913 (match_operand:<CSGNVMODE> 4 "" "")
8914 (match_operand:<CSGNVMODE> 5 "" "")]
8916 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8917 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8918 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8919 && reload_completed"
8921 "ix86_split_copysign_var (operands); DONE;")
8923 ;; One complement instructions
8925 (define_expand "one_cmpl<mode>2"
8926 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8927 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8929 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8931 (define_insn "*one_cmpl<mode>2_1"
8932 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8933 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8934 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8935 "not{<imodesuffix>}\t%0"
8936 [(set_attr "type" "negnot")
8937 (set_attr "mode" "<MODE>")])
8939 ;; %%% Potential partial reg stall on alternative 1. What to do?
8940 (define_insn "*one_cmplqi2_1"
8941 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8942 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8943 "ix86_unary_operator_ok (NOT, QImode, operands)"
8947 [(set_attr "type" "negnot")
8948 (set_attr "mode" "QI,SI")])
8950 ;; ??? Currently never generated - xor is used instead.
8951 (define_insn "*one_cmplsi2_1_zext"
8952 [(set (match_operand:DI 0 "register_operand" "=r")
8954 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8955 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8957 [(set_attr "type" "negnot")
8958 (set_attr "mode" "SI")])
8960 (define_insn "*one_cmpl<mode>2_2"
8961 [(set (reg FLAGS_REG)
8962 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8964 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8965 (not:SWI (match_dup 1)))]
8966 "ix86_match_ccmode (insn, CCNOmode)
8967 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8969 [(set_attr "type" "alu1")
8970 (set_attr "mode" "<MODE>")])
8973 [(set (match_operand 0 "flags_reg_operand" "")
8974 (match_operator 2 "compare_operator"
8975 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8977 (set (match_operand:SWI 1 "nonimmediate_operand" "")
8978 (not:SWI (match_dup 3)))]
8979 "ix86_match_ccmode (insn, CCNOmode)"
8980 [(parallel [(set (match_dup 0)
8981 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8984 (xor:SWI (match_dup 3) (const_int -1)))])])
8986 ;; ??? Currently never generated - xor is used instead.
8987 (define_insn "*one_cmplsi2_2_zext"
8988 [(set (reg FLAGS_REG)
8989 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8991 (set (match_operand:DI 0 "register_operand" "=r")
8992 (zero_extend:DI (not:SI (match_dup 1))))]
8993 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8994 && ix86_unary_operator_ok (NOT, SImode, operands)"
8996 [(set_attr "type" "alu1")
8997 (set_attr "mode" "SI")])
9000 [(set (match_operand 0 "flags_reg_operand" "")
9001 (match_operator 2 "compare_operator"
9002 [(not:SI (match_operand:SI 3 "register_operand" ""))
9004 (set (match_operand:DI 1 "register_operand" "")
9005 (zero_extend:DI (not:SI (match_dup 3))))]
9006 "ix86_match_ccmode (insn, CCNOmode)"
9007 [(parallel [(set (match_dup 0)
9008 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9011 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9013 ;; Shift instructions
9015 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9016 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9017 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9018 ;; from the assembler input.
9020 ;; This instruction shifts the target reg/mem as usual, but instead of
9021 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9022 ;; is a left shift double, bits are taken from the high order bits of
9023 ;; reg, else if the insn is a shift right double, bits are taken from the
9024 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9025 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9027 ;; Since sh[lr]d does not change the `reg' operand, that is done
9028 ;; separately, making all shifts emit pairs of shift double and normal
9029 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9030 ;; support a 63 bit shift, each shift where the count is in a reg expands
9031 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9033 ;; If the shift count is a constant, we need never emit more than one
9034 ;; shift pair, instead using moves and sign extension for counts greater
9037 (define_expand "ashl<mode>3"
9038 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9039 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
9040 (match_operand:QI 2 "nonmemory_operand" "")))]
9042 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9044 (define_insn "*ashl<mode>3_doubleword"
9045 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9046 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9047 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9048 (clobber (reg:CC FLAGS_REG))]
9051 [(set_attr "type" "multi")])
9054 [(set (match_operand:DWI 0 "register_operand" "")
9055 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
9056 (match_operand:QI 2 "nonmemory_operand" "")))
9057 (clobber (reg:CC FLAGS_REG))]
9058 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9060 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9062 ;; By default we don't ask for a scratch register, because when DWImode
9063 ;; values are manipulated, registers are already at a premium. But if
9064 ;; we have one handy, we won't turn it away.
9067 [(match_scratch:DWIH 3 "r")
9068 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9070 (match_operand:<DWI> 1 "nonmemory_operand" "")
9071 (match_operand:QI 2 "nonmemory_operand" "")))
9072 (clobber (reg:CC FLAGS_REG))])
9076 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9078 (define_insn "x86_64_shld"
9079 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9080 (ior:DI (ashift:DI (match_dup 0)
9081 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9082 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9083 (minus:QI (const_int 64) (match_dup 2)))))
9084 (clobber (reg:CC FLAGS_REG))]
9086 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9087 [(set_attr "type" "ishift")
9088 (set_attr "prefix_0f" "1")
9089 (set_attr "mode" "DI")
9090 (set_attr "athlon_decode" "vector")
9091 (set_attr "amdfam10_decode" "vector")])
9093 (define_insn "x86_shld"
9094 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9095 (ior:SI (ashift:SI (match_dup 0)
9096 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9097 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9098 (minus:QI (const_int 32) (match_dup 2)))))
9099 (clobber (reg:CC FLAGS_REG))]
9101 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9102 [(set_attr "type" "ishift")
9103 (set_attr "prefix_0f" "1")
9104 (set_attr "mode" "SI")
9105 (set_attr "pent_pair" "np")
9106 (set_attr "athlon_decode" "vector")
9107 (set_attr "amdfam10_decode" "vector")])
9109 (define_expand "x86_shift<mode>_adj_1"
9110 [(set (reg:CCZ FLAGS_REG)
9111 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9114 (set (match_operand:SWI48 0 "register_operand" "")
9115 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9116 (match_operand:SWI48 1 "register_operand" "")
9119 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9120 (match_operand:SWI48 3 "register_operand" "r")
9123 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9125 (define_expand "x86_shift<mode>_adj_2"
9126 [(use (match_operand:SWI48 0 "register_operand" ""))
9127 (use (match_operand:SWI48 1 "register_operand" ""))
9128 (use (match_operand:QI 2 "register_operand" ""))]
9131 rtx label = gen_label_rtx ();
9134 emit_insn (gen_testqi_ccz_1 (operands[2],
9135 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9137 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9138 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9139 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9140 gen_rtx_LABEL_REF (VOIDmode, label),
9142 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9143 JUMP_LABEL (tmp) = label;
9145 emit_move_insn (operands[0], operands[1]);
9146 ix86_expand_clear (operands[1]);
9149 LABEL_NUSES (label) = 1;
9154 (define_insn "*ashl<mode>3_1"
9155 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9156 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9157 (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9158 (clobber (reg:CC FLAGS_REG))]
9159 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9161 switch (get_attr_type (insn))
9167 gcc_assert (operands[2] == const1_rtx);
9168 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9169 return "add{<imodesuffix>}\t%0, %0";
9172 if (operands[2] == const1_rtx
9173 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9174 return "sal{<imodesuffix>}\t%0";
9176 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9180 (cond [(eq_attr "alternative" "1")
9181 (const_string "lea")
9182 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9184 (match_operand 0 "register_operand" ""))
9185 (match_operand 2 "const1_operand" ""))
9186 (const_string "alu")
9188 (const_string "ishift")))
9189 (set (attr "length_immediate")
9191 (ior (eq_attr "type" "alu")
9192 (and (eq_attr "type" "ishift")
9193 (and (match_operand 2 "const1_operand" "")
9194 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9197 (const_string "*")))
9198 (set_attr "mode" "<MODE>")])
9200 (define_insn "*ashlsi3_1_zext"
9201 [(set (match_operand:DI 0 "register_operand" "=r,r")
9203 (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9204 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9205 (clobber (reg:CC FLAGS_REG))]
9206 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9208 switch (get_attr_type (insn))
9214 gcc_assert (operands[2] == const1_rtx);
9215 return "add{l}\t%k0, %k0";
9218 if (operands[2] == const1_rtx
9219 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9220 return "sal{l}\t%k0";
9222 return "sal{l}\t{%2, %k0|%k0, %2}";
9226 (cond [(eq_attr "alternative" "1")
9227 (const_string "lea")
9228 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9230 (match_operand 2 "const1_operand" ""))
9231 (const_string "alu")
9233 (const_string "ishift")))
9234 (set (attr "length_immediate")
9236 (ior (eq_attr "type" "alu")
9237 (and (eq_attr "type" "ishift")
9238 (and (match_operand 2 "const1_operand" "")
9239 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9242 (const_string "*")))
9243 (set_attr "mode" "SI")])
9245 (define_insn "*ashlhi3_1"
9246 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9247 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9248 (match_operand:QI 2 "nonmemory_operand" "cI")))
9249 (clobber (reg:CC FLAGS_REG))]
9250 "TARGET_PARTIAL_REG_STALL
9251 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9253 switch (get_attr_type (insn))
9256 gcc_assert (operands[2] == const1_rtx);
9257 return "add{w}\t%0, %0";
9260 if (operands[2] == const1_rtx
9261 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9262 return "sal{w}\t%0";
9264 return "sal{w}\t{%2, %0|%0, %2}";
9268 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9270 (match_operand 0 "register_operand" ""))
9271 (match_operand 2 "const1_operand" ""))
9272 (const_string "alu")
9274 (const_string "ishift")))
9275 (set (attr "length_immediate")
9277 (ior (eq_attr "type" "alu")
9278 (and (eq_attr "type" "ishift")
9279 (and (match_operand 2 "const1_operand" "")
9280 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9283 (const_string "*")))
9284 (set_attr "mode" "HI")])
9286 (define_insn "*ashlhi3_1_lea"
9287 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9288 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9289 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9290 (clobber (reg:CC FLAGS_REG))]
9291 "!TARGET_PARTIAL_REG_STALL
9292 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9294 switch (get_attr_type (insn))
9300 gcc_assert (operands[2] == const1_rtx);
9301 return "add{w}\t%0, %0";
9304 if (operands[2] == const1_rtx
9305 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9306 return "sal{w}\t%0";
9308 return "sal{w}\t{%2, %0|%0, %2}";
9312 (cond [(eq_attr "alternative" "1")
9313 (const_string "lea")
9314 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9316 (match_operand 0 "register_operand" ""))
9317 (match_operand 2 "const1_operand" ""))
9318 (const_string "alu")
9320 (const_string "ishift")))
9321 (set (attr "length_immediate")
9323 (ior (eq_attr "type" "alu")
9324 (and (eq_attr "type" "ishift")
9325 (and (match_operand 2 "const1_operand" "")
9326 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9329 (const_string "*")))
9330 (set_attr "mode" "HI,SI")])
9332 (define_insn "*ashlqi3_1"
9333 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9334 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9335 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9336 (clobber (reg:CC FLAGS_REG))]
9337 "TARGET_PARTIAL_REG_STALL
9338 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9340 switch (get_attr_type (insn))
9343 gcc_assert (operands[2] == const1_rtx);
9344 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9345 return "add{l}\t%k0, %k0";
9347 return "add{b}\t%0, %0";
9350 if (operands[2] == const1_rtx
9351 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9353 if (get_attr_mode (insn) == MODE_SI)
9354 return "sal{l}\t%k0";
9356 return "sal{b}\t%0";
9360 if (get_attr_mode (insn) == MODE_SI)
9361 return "sal{l}\t{%2, %k0|%k0, %2}";
9363 return "sal{b}\t{%2, %0|%0, %2}";
9368 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9370 (match_operand 0 "register_operand" ""))
9371 (match_operand 2 "const1_operand" ""))
9372 (const_string "alu")
9374 (const_string "ishift")))
9375 (set (attr "length_immediate")
9377 (ior (eq_attr "type" "alu")
9378 (and (eq_attr "type" "ishift")
9379 (and (match_operand 2 "const1_operand" "")
9380 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9383 (const_string "*")))
9384 (set_attr "mode" "QI,SI")])
9386 ;; %%% Potential partial reg stall on alternative 2. What to do?
9387 (define_insn "*ashlqi3_1_lea"
9388 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9389 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9390 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9391 (clobber (reg:CC FLAGS_REG))]
9392 "!TARGET_PARTIAL_REG_STALL
9393 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9395 switch (get_attr_type (insn))
9401 gcc_assert (operands[2] == const1_rtx);
9402 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9403 return "add{l}\t%k0, %k0";
9405 return "add{b}\t%0, %0";
9408 if (operands[2] == const1_rtx
9409 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9411 if (get_attr_mode (insn) == MODE_SI)
9412 return "sal{l}\t%k0";
9414 return "sal{b}\t%0";
9418 if (get_attr_mode (insn) == MODE_SI)
9419 return "sal{l}\t{%2, %k0|%k0, %2}";
9421 return "sal{b}\t{%2, %0|%0, %2}";
9426 (cond [(eq_attr "alternative" "2")
9427 (const_string "lea")
9428 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9430 (match_operand 0 "register_operand" ""))
9431 (match_operand 2 "const1_operand" ""))
9432 (const_string "alu")
9434 (const_string "ishift")))
9435 (set (attr "length_immediate")
9437 (ior (eq_attr "type" "alu")
9438 (and (eq_attr "type" "ishift")
9439 (and (match_operand 2 "const1_operand" "")
9440 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9443 (const_string "*")))
9444 (set_attr "mode" "QI,SI,SI")])
9446 (define_insn "*ashlqi3_1_slp"
9447 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9448 (ashift:QI (match_dup 0)
9449 (match_operand:QI 1 "nonmemory_operand" "cI")))
9450 (clobber (reg:CC FLAGS_REG))]
9451 "(optimize_function_for_size_p (cfun)
9452 || !TARGET_PARTIAL_FLAG_REG_STALL
9453 || (operands[1] == const1_rtx
9455 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9457 switch (get_attr_type (insn))
9460 gcc_assert (operands[1] == const1_rtx);
9461 return "add{b}\t%0, %0";
9464 if (operands[1] == const1_rtx
9465 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9466 return "sal{b}\t%0";
9468 return "sal{b}\t{%1, %0|%0, %1}";
9472 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9474 (match_operand 0 "register_operand" ""))
9475 (match_operand 1 "const1_operand" ""))
9476 (const_string "alu")
9478 (const_string "ishift1")))
9479 (set (attr "length_immediate")
9481 (ior (eq_attr "type" "alu")
9482 (and (eq_attr "type" "ishift1")
9483 (and (match_operand 1 "const1_operand" "")
9484 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9487 (const_string "*")))
9488 (set_attr "mode" "QI")])
9490 ;; Convert lea to the lea pattern to avoid flags dependency.
9492 [(set (match_operand 0 "register_operand" "")
9493 (ashift (match_operand 1 "index_register_operand" "")
9494 (match_operand:QI 2 "const_int_operand" "")))
9495 (clobber (reg:CC FLAGS_REG))]
9497 && true_regnum (operands[0]) != true_regnum (operands[1])"
9501 enum machine_mode mode = GET_MODE (operands[0]);
9504 operands[1] = gen_lowpart (Pmode, operands[1]);
9505 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9507 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9509 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9510 operands[0] = gen_lowpart (SImode, operands[0]);
9512 if (TARGET_64BIT && mode != Pmode)
9513 pat = gen_rtx_SUBREG (SImode, pat, 0);
9515 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9519 ;; Convert lea to the lea pattern to avoid flags dependency.
9521 [(set (match_operand:DI 0 "register_operand" "")
9523 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9524 (match_operand:QI 2 "const_int_operand" ""))))
9525 (clobber (reg:CC FLAGS_REG))]
9526 "TARGET_64BIT && reload_completed
9527 && true_regnum (operands[0]) != true_regnum (operands[1])"
9529 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9531 operands[1] = gen_lowpart (DImode, operands[1]);
9532 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9535 ;; This pattern can't accept a variable shift count, since shifts by
9536 ;; zero don't affect the flags. We assume that shifts by constant
9537 ;; zero are optimized away.
9538 (define_insn "*ashl<mode>3_cmp"
9539 [(set (reg FLAGS_REG)
9541 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9542 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9544 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9545 (ashift:SWI (match_dup 1) (match_dup 2)))]
9546 "(optimize_function_for_size_p (cfun)
9547 || !TARGET_PARTIAL_FLAG_REG_STALL
9548 || (operands[2] == const1_rtx
9550 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9551 && ix86_match_ccmode (insn, CCGOCmode)
9552 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9554 switch (get_attr_type (insn))
9557 gcc_assert (operands[2] == const1_rtx);
9558 return "add{<imodesuffix>}\t%0, %0";
9561 if (operands[2] == const1_rtx
9562 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9563 return "sal{<imodesuffix>}\t%0";
9565 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9569 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9571 (match_operand 0 "register_operand" ""))
9572 (match_operand 2 "const1_operand" ""))
9573 (const_string "alu")
9575 (const_string "ishift")))
9576 (set (attr "length_immediate")
9578 (ior (eq_attr "type" "alu")
9579 (and (eq_attr "type" "ishift")
9580 (and (match_operand 2 "const1_operand" "")
9581 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9584 (const_string "*")))
9585 (set_attr "mode" "<MODE>")])
9587 (define_insn "*ashlsi3_cmp_zext"
9588 [(set (reg FLAGS_REG)
9590 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9591 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9593 (set (match_operand:DI 0 "register_operand" "=r")
9594 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9596 && (optimize_function_for_size_p (cfun)
9597 || !TARGET_PARTIAL_FLAG_REG_STALL
9598 || (operands[2] == const1_rtx
9600 || TARGET_DOUBLE_WITH_ADD)))
9601 && ix86_match_ccmode (insn, CCGOCmode)
9602 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9604 switch (get_attr_type (insn))
9607 gcc_assert (operands[2] == const1_rtx);
9608 return "add{l}\t%k0, %k0";
9611 if (operands[2] == const1_rtx
9612 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9613 return "sal{l}\t%k0";
9615 return "sal{l}\t{%2, %k0|%k0, %2}";
9619 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9621 (match_operand 2 "const1_operand" ""))
9622 (const_string "alu")
9624 (const_string "ishift")))
9625 (set (attr "length_immediate")
9627 (ior (eq_attr "type" "alu")
9628 (and (eq_attr "type" "ishift")
9629 (and (match_operand 2 "const1_operand" "")
9630 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9633 (const_string "*")))
9634 (set_attr "mode" "SI")])
9636 (define_insn "*ashl<mode>3_cconly"
9637 [(set (reg FLAGS_REG)
9639 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9640 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9642 (clobber (match_scratch:SWI 0 "=<r>"))]
9643 "(optimize_function_for_size_p (cfun)
9644 || !TARGET_PARTIAL_FLAG_REG_STALL
9645 || (operands[2] == const1_rtx
9647 || TARGET_DOUBLE_WITH_ADD)))
9648 && ix86_match_ccmode (insn, CCGOCmode)
9649 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9651 switch (get_attr_type (insn))
9654 gcc_assert (operands[2] == const1_rtx);
9655 return "add{<imodesuffix>}\t%0, %0";
9658 if (operands[2] == const1_rtx
9659 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9660 return "sal{<imodesuffix>}\t%0";
9662 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9666 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9668 (match_operand 0 "register_operand" ""))
9669 (match_operand 2 "const1_operand" ""))
9670 (const_string "alu")
9672 (const_string "ishift")))
9673 (set (attr "length_immediate")
9675 (ior (eq_attr "type" "alu")
9676 (and (eq_attr "type" "ishift")
9677 (and (match_operand 2 "const1_operand" "")
9678 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9681 (const_string "*")))
9682 (set_attr "mode" "<MODE>")])
9684 ;; See comment above `ashl<mode>3' about how this works.
9686 (define_expand "<shiftrt_insn><mode>3"
9687 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9688 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9689 (match_operand:QI 2 "nonmemory_operand" "")))]
9691 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9693 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9694 [(set (match_operand:DWI 0 "register_operand" "=r")
9695 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9696 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9697 (clobber (reg:CC FLAGS_REG))]
9700 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9702 "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9703 [(set_attr "type" "multi")])
9705 ;; By default we don't ask for a scratch register, because when DWImode
9706 ;; values are manipulated, registers are already at a premium. But if
9707 ;; we have one handy, we won't turn it away.
9710 [(match_scratch:DWIH 3 "r")
9711 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9713 (match_operand:<DWI> 1 "register_operand" "")
9714 (match_operand:QI 2 "nonmemory_operand" "")))
9715 (clobber (reg:CC FLAGS_REG))])
9719 "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9721 (define_insn "x86_64_shrd"
9722 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9723 (ior:DI (ashiftrt:DI (match_dup 0)
9724 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9725 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9726 (minus:QI (const_int 64) (match_dup 2)))))
9727 (clobber (reg:CC FLAGS_REG))]
9729 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9730 [(set_attr "type" "ishift")
9731 (set_attr "prefix_0f" "1")
9732 (set_attr "mode" "DI")
9733 (set_attr "athlon_decode" "vector")
9734 (set_attr "amdfam10_decode" "vector")])
9736 (define_insn "x86_shrd"
9737 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9738 (ior:SI (ashiftrt:SI (match_dup 0)
9739 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9740 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9741 (minus:QI (const_int 32) (match_dup 2)))))
9742 (clobber (reg:CC FLAGS_REG))]
9744 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9745 [(set_attr "type" "ishift")
9746 (set_attr "prefix_0f" "1")
9747 (set_attr "mode" "SI")
9748 (set_attr "pent_pair" "np")
9749 (set_attr "athlon_decode" "vector")
9750 (set_attr "amdfam10_decode" "vector")])
9752 (define_insn "ashrdi3_cvt"
9753 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9754 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9755 (match_operand:QI 2 "const_int_operand" "")))
9756 (clobber (reg:CC FLAGS_REG))]
9757 "TARGET_64BIT && INTVAL (operands[2]) == 63
9758 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9759 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9762 sar{q}\t{%2, %0|%0, %2}"
9763 [(set_attr "type" "imovx,ishift")
9764 (set_attr "prefix_0f" "0,*")
9765 (set_attr "length_immediate" "0,*")
9766 (set_attr "modrm" "0,1")
9767 (set_attr "mode" "DI")])
9769 (define_insn "ashrsi3_cvt"
9770 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9771 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9772 (match_operand:QI 2 "const_int_operand" "")))
9773 (clobber (reg:CC FLAGS_REG))]
9774 "INTVAL (operands[2]) == 31
9775 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9776 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9779 sar{l}\t{%2, %0|%0, %2}"
9780 [(set_attr "type" "imovx,ishift")
9781 (set_attr "prefix_0f" "0,*")
9782 (set_attr "length_immediate" "0,*")
9783 (set_attr "modrm" "0,1")
9784 (set_attr "mode" "SI")])
9786 (define_insn "*ashrsi3_cvt_zext"
9787 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9789 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9790 (match_operand:QI 2 "const_int_operand" ""))))
9791 (clobber (reg:CC FLAGS_REG))]
9792 "TARGET_64BIT && INTVAL (operands[2]) == 31
9793 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9794 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9797 sar{l}\t{%2, %k0|%k0, %2}"
9798 [(set_attr "type" "imovx,ishift")
9799 (set_attr "prefix_0f" "0,*")
9800 (set_attr "length_immediate" "0,*")
9801 (set_attr "modrm" "0,1")
9802 (set_attr "mode" "SI")])
9804 (define_expand "x86_shift<mode>_adj_3"
9805 [(use (match_operand:SWI48 0 "register_operand" ""))
9806 (use (match_operand:SWI48 1 "register_operand" ""))
9807 (use (match_operand:QI 2 "register_operand" ""))]
9810 rtx label = gen_label_rtx ();
9813 emit_insn (gen_testqi_ccz_1 (operands[2],
9814 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9816 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9817 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9818 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9819 gen_rtx_LABEL_REF (VOIDmode, label),
9821 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9822 JUMP_LABEL (tmp) = label;
9824 emit_move_insn (operands[0], operands[1]);
9825 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9826 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9828 LABEL_NUSES (label) = 1;
9833 (define_insn "*<shiftrt_insn><mode>3_1"
9834 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9835 (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9836 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9837 (clobber (reg:CC FLAGS_REG))]
9838 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9840 if (operands[2] == const1_rtx
9841 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9842 return "<shiftrt>{<imodesuffix>}\t%0";
9844 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9846 [(set_attr "type" "ishift")
9847 (set (attr "length_immediate")
9849 (and (match_operand 2 "const1_operand" "")
9850 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9853 (const_string "*")))
9854 (set_attr "mode" "<MODE>")])
9856 (define_insn "*<shiftrt_insn>si3_1_zext"
9857 [(set (match_operand:DI 0 "register_operand" "=r")
9859 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9860 (match_operand:QI 2 "nonmemory_operand" "cI"))))
9861 (clobber (reg:CC FLAGS_REG))]
9862 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9864 if (operands[2] == const1_rtx
9865 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9866 return "<shiftrt>{l}\t%k0";
9868 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9870 [(set_attr "type" "ishift")
9871 (set (attr "length_immediate")
9873 (and (match_operand 2 "const1_operand" "")
9874 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9877 (const_string "*")))
9878 (set_attr "mode" "SI")])
9880 (define_insn "*<shiftrt_insn>qi3_1_slp"
9881 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9882 (any_shiftrt:QI (match_dup 0)
9883 (match_operand:QI 1 "nonmemory_operand" "cI")))
9884 (clobber (reg:CC FLAGS_REG))]
9885 "(optimize_function_for_size_p (cfun)
9886 || !TARGET_PARTIAL_REG_STALL
9887 || (operands[1] == const1_rtx
9890 if (operands[1] == const1_rtx
9891 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9892 return "<shiftrt>{b}\t%0";
9894 return "<shiftrt>{b}\t{%1, %0|%0, %1}";
9896 [(set_attr "type" "ishift1")
9897 (set (attr "length_immediate")
9899 (and (match_operand 1 "const1_operand" "")
9900 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9903 (const_string "*")))
9904 (set_attr "mode" "QI")])
9906 ;; This pattern can't accept a variable shift count, since shifts by
9907 ;; zero don't affect the flags. We assume that shifts by constant
9908 ;; zero are optimized away.
9909 (define_insn "*<shiftrt_insn><mode>3_cmp"
9910 [(set (reg FLAGS_REG)
9913 (match_operand:SWI 1 "nonimmediate_operand" "0")
9914 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9916 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9917 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9918 "(optimize_function_for_size_p (cfun)
9919 || !TARGET_PARTIAL_FLAG_REG_STALL
9920 || (operands[2] == const1_rtx
9922 && ix86_match_ccmode (insn, CCGOCmode)
9923 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9925 if (operands[2] == const1_rtx
9926 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9927 return "<shiftrt>{<imodesuffix>}\t%0";
9929 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9931 [(set_attr "type" "ishift")
9932 (set (attr "length_immediate")
9934 (and (match_operand 2 "const1_operand" "")
9935 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9938 (const_string "*")))
9939 (set_attr "mode" "<MODE>")])
9941 (define_insn "*<shiftrt_insn>si3_cmp_zext"
9942 [(set (reg FLAGS_REG)
9944 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9945 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9947 (set (match_operand:DI 0 "register_operand" "=r")
9948 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9950 && (optimize_function_for_size_p (cfun)
9951 || !TARGET_PARTIAL_FLAG_REG_STALL
9952 || (operands[2] == const1_rtx
9954 && ix86_match_ccmode (insn, CCGOCmode)
9955 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9957 if (operands[2] == const1_rtx
9958 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9959 return "<shiftrt>{l}\t%k0";
9961 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9963 [(set_attr "type" "ishift")
9964 (set (attr "length_immediate")
9966 (and (match_operand 2 "const1_operand" "")
9967 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9970 (const_string "*")))
9971 (set_attr "mode" "SI")])
9973 (define_insn "*<shiftrt_insn><mode>3_cconly"
9974 [(set (reg FLAGS_REG)
9977 (match_operand:SWI 1 "nonimmediate_operand" "0")
9978 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9980 (clobber (match_scratch:SWI 0 "=<r>"))]
9981 "(optimize_function_for_size_p (cfun)
9982 || !TARGET_PARTIAL_FLAG_REG_STALL
9983 || (operands[2] == const1_rtx
9985 && ix86_match_ccmode (insn, CCGOCmode)
9986 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9988 if (operands[2] == const1_rtx
9989 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9990 return "<shiftrt>{<imodesuffix>}\t%0";
9992 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9994 [(set_attr "type" "ishift")
9995 (set (attr "length_immediate")
9997 (and (match_operand 2 "const1_operand" "")
9998 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10001 (const_string "*")))
10002 (set_attr "mode" "<MODE>")])
10004 ;; Rotate instructions
10006 (define_expand "<rotate_insn>ti3"
10007 [(set (match_operand:TI 0 "register_operand" "")
10008 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10009 (match_operand:QI 2 "nonmemory_operand" "")))]
10012 if (const_1_to_63_operand (operands[2], VOIDmode))
10013 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10014 (operands[0], operands[1], operands[2]));
10021 (define_expand "<rotate_insn>di3"
10022 [(set (match_operand:DI 0 "shiftdi_operand" "")
10023 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10024 (match_operand:QI 2 "nonmemory_operand" "")))]
10028 ix86_expand_binary_operator (<CODE>, DImode, operands);
10029 else if (const_1_to_31_operand (operands[2], VOIDmode))
10030 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10031 (operands[0], operands[1], operands[2]));
10038 (define_expand "<rotate_insn><mode>3"
10039 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10040 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10041 (match_operand:QI 2 "nonmemory_operand" "")))]
10043 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10045 ;; Implement rotation using two double-precision
10046 ;; shift instructions and a scratch register.
10048 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10049 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10050 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10051 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10052 (clobber (reg:CC FLAGS_REG))
10053 (clobber (match_scratch:DWIH 3 "=&r"))]
10057 [(set (match_dup 3) (match_dup 4))
10059 [(set (match_dup 4)
10060 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10061 (lshiftrt:DWIH (match_dup 5)
10062 (minus:QI (match_dup 6) (match_dup 2)))))
10063 (clobber (reg:CC FLAGS_REG))])
10065 [(set (match_dup 5)
10066 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10067 (lshiftrt:DWIH (match_dup 3)
10068 (minus:QI (match_dup 6) (match_dup 2)))))
10069 (clobber (reg:CC FLAGS_REG))])]
10071 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10073 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10076 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10077 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10078 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10079 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10080 (clobber (reg:CC FLAGS_REG))
10081 (clobber (match_scratch:DWIH 3 "=&r"))]
10085 [(set (match_dup 3) (match_dup 4))
10087 [(set (match_dup 4)
10088 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10089 (ashift:DWIH (match_dup 5)
10090 (minus:QI (match_dup 6) (match_dup 2)))))
10091 (clobber (reg:CC FLAGS_REG))])
10093 [(set (match_dup 5)
10094 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10095 (ashift:DWIH (match_dup 3)
10096 (minus:QI (match_dup 6) (match_dup 2)))))
10097 (clobber (reg:CC FLAGS_REG))])]
10099 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10101 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10104 (define_insn "*<rotate_insn><mode>3_1"
10105 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10106 (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10107 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10108 (clobber (reg:CC FLAGS_REG))]
10109 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10111 if (operands[2] == const1_rtx
10112 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10113 return "<rotate>{<imodesuffix>}\t%0";
10115 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10117 [(set_attr "type" "rotate")
10118 (set (attr "length_immediate")
10120 (and (match_operand 2 "const1_operand" "")
10121 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10124 (const_string "*")))
10125 (set_attr "mode" "<MODE>")])
10127 (define_insn "*<rotate_insn>si3_1_zext"
10128 [(set (match_operand:DI 0 "register_operand" "=r")
10130 (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10131 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10132 (clobber (reg:CC FLAGS_REG))]
10133 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10135 if (operands[2] == const1_rtx
10136 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10137 return "<rotate>{l}\t%k0";
10139 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10141 [(set_attr "type" "rotate")
10142 (set (attr "length_immediate")
10144 (and (match_operand 2 "const1_operand" "")
10145 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10148 (const_string "*")))
10149 (set_attr "mode" "SI")])
10151 (define_insn "*<rotate_insn>qi3_1_slp"
10152 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10153 (any_rotate:QI (match_dup 0)
10154 (match_operand:QI 1 "nonmemory_operand" "cI")))
10155 (clobber (reg:CC FLAGS_REG))]
10156 "(optimize_function_for_size_p (cfun)
10157 || !TARGET_PARTIAL_REG_STALL
10158 || (operands[1] == const1_rtx
10159 && TARGET_SHIFT1))"
10161 if (operands[1] == const1_rtx
10162 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10163 return "<rotate>{b}\t%0";
10165 return "<rotate>{b}\t{%1, %0|%0, %1}";
10167 [(set_attr "type" "rotate1")
10168 (set (attr "length_immediate")
10170 (and (match_operand 1 "const1_operand" "")
10171 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10174 (const_string "*")))
10175 (set_attr "mode" "QI")])
10178 [(set (match_operand:HI 0 "register_operand" "")
10179 (any_rotate:HI (match_dup 0) (const_int 8)))
10180 (clobber (reg:CC FLAGS_REG))]
10182 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10183 [(parallel [(set (strict_low_part (match_dup 0))
10184 (bswap:HI (match_dup 0)))
10185 (clobber (reg:CC FLAGS_REG))])])
10187 ;; Bit set / bit test instructions
10189 (define_expand "extv"
10190 [(set (match_operand:SI 0 "register_operand" "")
10191 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10192 (match_operand:SI 2 "const8_operand" "")
10193 (match_operand:SI 3 "const8_operand" "")))]
10196 /* Handle extractions from %ah et al. */
10197 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10200 /* From mips.md: extract_bit_field doesn't verify that our source
10201 matches the predicate, so check it again here. */
10202 if (! ext_register_operand (operands[1], VOIDmode))
10206 (define_expand "extzv"
10207 [(set (match_operand:SI 0 "register_operand" "")
10208 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10209 (match_operand:SI 2 "const8_operand" "")
10210 (match_operand:SI 3 "const8_operand" "")))]
10213 /* Handle extractions from %ah et al. */
10214 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10217 /* From mips.md: extract_bit_field doesn't verify that our source
10218 matches the predicate, so check it again here. */
10219 if (! ext_register_operand (operands[1], VOIDmode))
10223 (define_expand "insv"
10224 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
10225 (match_operand 1 "const8_operand" "")
10226 (match_operand 2 "const8_operand" ""))
10227 (match_operand 3 "register_operand" ""))]
10230 rtx (*gen_mov_insv_1) (rtx, rtx);
10232 /* Handle insertions to %ah et al. */
10233 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10236 /* From mips.md: insert_bit_field doesn't verify that our source
10237 matches the predicate, so check it again here. */
10238 if (! ext_register_operand (operands[0], VOIDmode))
10241 gen_mov_insv_1 = (TARGET_64BIT
10242 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10244 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10248 ;; %%% bts, btr, btc, bt.
10249 ;; In general these instructions are *slow* when applied to memory,
10250 ;; since they enforce atomic operation. When applied to registers,
10251 ;; it depends on the cpu implementation. They're never faster than
10252 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10253 ;; no point. But in 64-bit, we can't hold the relevant immediates
10254 ;; within the instruction itself, so operating on bits in the high
10255 ;; 32-bits of a register becomes easier.
10257 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10258 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10259 ;; negdf respectively, so they can never be disabled entirely.
10261 (define_insn "*btsq"
10262 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10264 (match_operand:DI 1 "const_0_to_63_operand" ""))
10266 (clobber (reg:CC FLAGS_REG))]
10267 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10268 "bts{q}\t{%1, %0|%0, %1}"
10269 [(set_attr "type" "alu1")
10270 (set_attr "prefix_0f" "1")
10271 (set_attr "mode" "DI")])
10273 (define_insn "*btrq"
10274 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10276 (match_operand:DI 1 "const_0_to_63_operand" ""))
10278 (clobber (reg:CC FLAGS_REG))]
10279 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10280 "btr{q}\t{%1, %0|%0, %1}"
10281 [(set_attr "type" "alu1")
10282 (set_attr "prefix_0f" "1")
10283 (set_attr "mode" "DI")])
10285 (define_insn "*btcq"
10286 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10288 (match_operand:DI 1 "const_0_to_63_operand" ""))
10289 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10290 (clobber (reg:CC FLAGS_REG))]
10291 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10292 "btc{q}\t{%1, %0|%0, %1}"
10293 [(set_attr "type" "alu1")
10294 (set_attr "prefix_0f" "1")
10295 (set_attr "mode" "DI")])
10297 ;; Allow Nocona to avoid these instructions if a register is available.
10300 [(match_scratch:DI 2 "r")
10301 (parallel [(set (zero_extract:DI
10302 (match_operand:DI 0 "register_operand" "")
10304 (match_operand:DI 1 "const_0_to_63_operand" ""))
10306 (clobber (reg:CC FLAGS_REG))])]
10307 "TARGET_64BIT && !TARGET_USE_BT"
10310 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10313 if (HOST_BITS_PER_WIDE_INT >= 64)
10314 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10315 else if (i < HOST_BITS_PER_WIDE_INT)
10316 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10318 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10320 op1 = immed_double_const (lo, hi, DImode);
10323 emit_move_insn (operands[2], op1);
10327 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10332 [(match_scratch:DI 2 "r")
10333 (parallel [(set (zero_extract:DI
10334 (match_operand:DI 0 "register_operand" "")
10336 (match_operand:DI 1 "const_0_to_63_operand" ""))
10338 (clobber (reg:CC FLAGS_REG))])]
10339 "TARGET_64BIT && !TARGET_USE_BT"
10342 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10345 if (HOST_BITS_PER_WIDE_INT >= 64)
10346 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10347 else if (i < HOST_BITS_PER_WIDE_INT)
10348 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10350 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10352 op1 = immed_double_const (~lo, ~hi, DImode);
10355 emit_move_insn (operands[2], op1);
10359 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10364 [(match_scratch:DI 2 "r")
10365 (parallel [(set (zero_extract:DI
10366 (match_operand:DI 0 "register_operand" "")
10368 (match_operand:DI 1 "const_0_to_63_operand" ""))
10369 (not:DI (zero_extract:DI
10370 (match_dup 0) (const_int 1) (match_dup 1))))
10371 (clobber (reg:CC FLAGS_REG))])]
10372 "TARGET_64BIT && !TARGET_USE_BT"
10375 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10378 if (HOST_BITS_PER_WIDE_INT >= 64)
10379 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10380 else if (i < HOST_BITS_PER_WIDE_INT)
10381 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10383 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10385 op1 = immed_double_const (lo, hi, DImode);
10388 emit_move_insn (operands[2], op1);
10392 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10396 (define_insn "*bt<mode>"
10397 [(set (reg:CCC FLAGS_REG)
10399 (zero_extract:SWI48
10400 (match_operand:SWI48 0 "register_operand" "r")
10402 (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10404 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10405 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10406 [(set_attr "type" "alu1")
10407 (set_attr "prefix_0f" "1")
10408 (set_attr "mode" "<MODE>")])
10410 ;; Store-flag instructions.
10412 ;; For all sCOND expanders, also expand the compare or test insn that
10413 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10415 (define_insn_and_split "*setcc_di_1"
10416 [(set (match_operand:DI 0 "register_operand" "=q")
10417 (match_operator:DI 1 "ix86_comparison_operator"
10418 [(reg FLAGS_REG) (const_int 0)]))]
10419 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10421 "&& reload_completed"
10422 [(set (match_dup 2) (match_dup 1))
10423 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10425 PUT_MODE (operands[1], QImode);
10426 operands[2] = gen_lowpart (QImode, operands[0]);
10429 (define_insn_and_split "*setcc_si_1_and"
10430 [(set (match_operand:SI 0 "register_operand" "=q")
10431 (match_operator:SI 1 "ix86_comparison_operator"
10432 [(reg FLAGS_REG) (const_int 0)]))
10433 (clobber (reg:CC FLAGS_REG))]
10434 "!TARGET_PARTIAL_REG_STALL
10435 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10437 "&& reload_completed"
10438 [(set (match_dup 2) (match_dup 1))
10439 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10440 (clobber (reg:CC FLAGS_REG))])]
10442 PUT_MODE (operands[1], QImode);
10443 operands[2] = gen_lowpart (QImode, operands[0]);
10446 (define_insn_and_split "*setcc_si_1_movzbl"
10447 [(set (match_operand:SI 0 "register_operand" "=q")
10448 (match_operator:SI 1 "ix86_comparison_operator"
10449 [(reg FLAGS_REG) (const_int 0)]))]
10450 "!TARGET_PARTIAL_REG_STALL
10451 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10453 "&& reload_completed"
10454 [(set (match_dup 2) (match_dup 1))
10455 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10457 PUT_MODE (operands[1], QImode);
10458 operands[2] = gen_lowpart (QImode, operands[0]);
10461 (define_insn "*setcc_qi"
10462 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10463 (match_operator:QI 1 "ix86_comparison_operator"
10464 [(reg FLAGS_REG) (const_int 0)]))]
10467 [(set_attr "type" "setcc")
10468 (set_attr "mode" "QI")])
10470 (define_insn "*setcc_qi_slp"
10471 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10472 (match_operator:QI 1 "ix86_comparison_operator"
10473 [(reg FLAGS_REG) (const_int 0)]))]
10476 [(set_attr "type" "setcc")
10477 (set_attr "mode" "QI")])
10479 ;; In general it is not safe to assume too much about CCmode registers,
10480 ;; so simplify-rtx stops when it sees a second one. Under certain
10481 ;; conditions this is safe on x86, so help combine not create
10488 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10489 (ne:QI (match_operator 1 "ix86_comparison_operator"
10490 [(reg FLAGS_REG) (const_int 0)])
10493 [(set (match_dup 0) (match_dup 1))]
10494 "PUT_MODE (operands[1], QImode);")
10497 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10498 (ne:QI (match_operator 1 "ix86_comparison_operator"
10499 [(reg FLAGS_REG) (const_int 0)])
10502 [(set (match_dup 0) (match_dup 1))]
10503 "PUT_MODE (operands[1], QImode);")
10506 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10507 (eq:QI (match_operator 1 "ix86_comparison_operator"
10508 [(reg FLAGS_REG) (const_int 0)])
10511 [(set (match_dup 0) (match_dup 1))]
10513 rtx new_op1 = copy_rtx (operands[1]);
10514 operands[1] = new_op1;
10515 PUT_MODE (new_op1, QImode);
10516 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10517 GET_MODE (XEXP (new_op1, 0))));
10519 /* Make sure that (a) the CCmode we have for the flags is strong
10520 enough for the reversed compare or (b) we have a valid FP compare. */
10521 if (! ix86_comparison_operator (new_op1, VOIDmode))
10526 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10527 (eq:QI (match_operator 1 "ix86_comparison_operator"
10528 [(reg FLAGS_REG) (const_int 0)])
10531 [(set (match_dup 0) (match_dup 1))]
10533 rtx new_op1 = copy_rtx (operands[1]);
10534 operands[1] = new_op1;
10535 PUT_MODE (new_op1, QImode);
10536 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10537 GET_MODE (XEXP (new_op1, 0))));
10539 /* Make sure that (a) the CCmode we have for the flags is strong
10540 enough for the reversed compare or (b) we have a valid FP compare. */
10541 if (! ix86_comparison_operator (new_op1, VOIDmode))
10545 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10546 ;; subsequent logical operations are used to imitate conditional moves.
10547 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10550 (define_insn "*avx_setcc<mode>"
10551 [(set (match_operand:MODEF 0 "register_operand" "=x")
10552 (match_operator:MODEF 1 "avx_comparison_float_operator"
10553 [(match_operand:MODEF 2 "register_operand" "x")
10554 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10556 "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
10557 [(set_attr "type" "ssecmp")
10558 (set_attr "prefix" "vex")
10559 (set_attr "length_immediate" "1")
10560 (set_attr "mode" "<MODE>")])
10562 (define_insn "*sse_setcc<mode>"
10563 [(set (match_operand:MODEF 0 "register_operand" "=x")
10564 (match_operator:MODEF 1 "sse_comparison_operator"
10565 [(match_operand:MODEF 2 "register_operand" "0")
10566 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10567 "SSE_FLOAT_MODE_P (<MODE>mode)"
10568 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
10569 [(set_attr "type" "ssecmp")
10570 (set_attr "length_immediate" "1")
10571 (set_attr "mode" "<MODE>")])
10573 ;; Basic conditional jump instructions.
10574 ;; We ignore the overflow flag for signed branch instructions.
10576 (define_insn "*jcc_1"
10578 (if_then_else (match_operator 1 "ix86_comparison_operator"
10579 [(reg FLAGS_REG) (const_int 0)])
10580 (label_ref (match_operand 0 "" ""))
10584 [(set_attr "type" "ibr")
10585 (set_attr "modrm" "0")
10586 (set (attr "length")
10587 (if_then_else (and (ge (minus (match_dup 0) (pc))
10589 (lt (minus (match_dup 0) (pc))
10594 (define_insn "*jcc_2"
10596 (if_then_else (match_operator 1 "ix86_comparison_operator"
10597 [(reg FLAGS_REG) (const_int 0)])
10599 (label_ref (match_operand 0 "" ""))))]
10602 [(set_attr "type" "ibr")
10603 (set_attr "modrm" "0")
10604 (set (attr "length")
10605 (if_then_else (and (ge (minus (match_dup 0) (pc))
10607 (lt (minus (match_dup 0) (pc))
10612 ;; In general it is not safe to assume too much about CCmode registers,
10613 ;; so simplify-rtx stops when it sees a second one. Under certain
10614 ;; conditions this is safe on x86, so help combine not create
10622 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10623 [(reg FLAGS_REG) (const_int 0)])
10625 (label_ref (match_operand 1 "" ""))
10629 (if_then_else (match_dup 0)
10630 (label_ref (match_dup 1))
10632 "PUT_MODE (operands[0], VOIDmode);")
10636 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10637 [(reg FLAGS_REG) (const_int 0)])
10639 (label_ref (match_operand 1 "" ""))
10643 (if_then_else (match_dup 0)
10644 (label_ref (match_dup 1))
10647 rtx new_op0 = copy_rtx (operands[0]);
10648 operands[0] = new_op0;
10649 PUT_MODE (new_op0, VOIDmode);
10650 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10651 GET_MODE (XEXP (new_op0, 0))));
10653 /* Make sure that (a) the CCmode we have for the flags is strong
10654 enough for the reversed compare or (b) we have a valid FP compare. */
10655 if (! ix86_comparison_operator (new_op0, VOIDmode))
10659 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10660 ;; pass generates from shift insn with QImode operand. Actually, the mode
10661 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10662 ;; appropriate modulo of the bit offset value.
10664 (define_insn_and_split "*jcc_bt<mode>"
10666 (if_then_else (match_operator 0 "bt_comparison_operator"
10667 [(zero_extract:SWI48
10668 (match_operand:SWI48 1 "register_operand" "r")
10671 (match_operand:QI 2 "register_operand" "r")))
10673 (label_ref (match_operand 3 "" ""))
10675 (clobber (reg:CC FLAGS_REG))]
10676 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10679 [(set (reg:CCC FLAGS_REG)
10681 (zero_extract:SWI48
10687 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10688 (label_ref (match_dup 3))
10691 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10693 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10696 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10697 ;; also for DImode, this is what combine produces.
10698 (define_insn_and_split "*jcc_bt<mode>_mask"
10700 (if_then_else (match_operator 0 "bt_comparison_operator"
10701 [(zero_extract:SWI48
10702 (match_operand:SWI48 1 "register_operand" "r")
10705 (match_operand:SI 2 "register_operand" "r")
10706 (match_operand:SI 3 "const_int_operand" "n")))])
10707 (label_ref (match_operand 4 "" ""))
10709 (clobber (reg:CC FLAGS_REG))]
10710 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10711 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10712 == GET_MODE_BITSIZE (<MODE>mode)-1"
10715 [(set (reg:CCC FLAGS_REG)
10717 (zero_extract:SWI48
10723 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10724 (label_ref (match_dup 4))
10727 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10729 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10732 (define_insn_and_split "*jcc_btsi_1"
10734 (if_then_else (match_operator 0 "bt_comparison_operator"
10737 (match_operand:SI 1 "register_operand" "r")
10738 (match_operand:QI 2 "register_operand" "r"))
10741 (label_ref (match_operand 3 "" ""))
10743 (clobber (reg:CC FLAGS_REG))]
10744 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10747 [(set (reg:CCC FLAGS_REG)
10755 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10756 (label_ref (match_dup 3))
10759 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10761 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10764 ;; avoid useless masking of bit offset operand
10765 (define_insn_and_split "*jcc_btsi_mask_1"
10768 (match_operator 0 "bt_comparison_operator"
10771 (match_operand:SI 1 "register_operand" "r")
10774 (match_operand:SI 2 "register_operand" "r")
10775 (match_operand:SI 3 "const_int_operand" "n")) 0))
10778 (label_ref (match_operand 4 "" ""))
10780 (clobber (reg:CC FLAGS_REG))]
10781 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10782 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10785 [(set (reg:CCC FLAGS_REG)
10793 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10794 (label_ref (match_dup 4))
10796 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10798 ;; Define combination compare-and-branch fp compare instructions to help
10801 (define_insn "*fp_jcc_1_387"
10803 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10804 [(match_operand 1 "register_operand" "f")
10805 (match_operand 2 "nonimmediate_operand" "fm")])
10806 (label_ref (match_operand 3 "" ""))
10808 (clobber (reg:CCFP FPSR_REG))
10809 (clobber (reg:CCFP FLAGS_REG))
10810 (clobber (match_scratch:HI 4 "=a"))]
10812 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10813 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10814 && SELECT_CC_MODE (GET_CODE (operands[0]),
10815 operands[1], operands[2]) == CCFPmode
10819 (define_insn "*fp_jcc_1r_387"
10821 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10822 [(match_operand 1 "register_operand" "f")
10823 (match_operand 2 "nonimmediate_operand" "fm")])
10825 (label_ref (match_operand 3 "" ""))))
10826 (clobber (reg:CCFP FPSR_REG))
10827 (clobber (reg:CCFP FLAGS_REG))
10828 (clobber (match_scratch:HI 4 "=a"))]
10830 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10831 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10832 && SELECT_CC_MODE (GET_CODE (operands[0]),
10833 operands[1], operands[2]) == CCFPmode
10837 (define_insn "*fp_jcc_2_387"
10839 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10840 [(match_operand 1 "register_operand" "f")
10841 (match_operand 2 "register_operand" "f")])
10842 (label_ref (match_operand 3 "" ""))
10844 (clobber (reg:CCFP FPSR_REG))
10845 (clobber (reg:CCFP FLAGS_REG))
10846 (clobber (match_scratch:HI 4 "=a"))]
10847 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10848 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10852 (define_insn "*fp_jcc_2r_387"
10854 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10855 [(match_operand 1 "register_operand" "f")
10856 (match_operand 2 "register_operand" "f")])
10858 (label_ref (match_operand 3 "" ""))))
10859 (clobber (reg:CCFP FPSR_REG))
10860 (clobber (reg:CCFP FLAGS_REG))
10861 (clobber (match_scratch:HI 4 "=a"))]
10862 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10863 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10867 (define_insn "*fp_jcc_3_387"
10869 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10870 [(match_operand 1 "register_operand" "f")
10871 (match_operand 2 "const0_operand" "")])
10872 (label_ref (match_operand 3 "" ""))
10874 (clobber (reg:CCFP FPSR_REG))
10875 (clobber (reg:CCFP FLAGS_REG))
10876 (clobber (match_scratch:HI 4 "=a"))]
10877 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10878 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10879 && SELECT_CC_MODE (GET_CODE (operands[0]),
10880 operands[1], operands[2]) == CCFPmode
10886 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10887 [(match_operand 1 "register_operand" "")
10888 (match_operand 2 "nonimmediate_operand" "")])
10889 (match_operand 3 "" "")
10890 (match_operand 4 "" "")))
10891 (clobber (reg:CCFP FPSR_REG))
10892 (clobber (reg:CCFP FLAGS_REG))]
10896 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10897 operands[3], operands[4], NULL_RTX, NULL_RTX);
10903 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10904 [(match_operand 1 "register_operand" "")
10905 (match_operand 2 "general_operand" "")])
10906 (match_operand 3 "" "")
10907 (match_operand 4 "" "")))
10908 (clobber (reg:CCFP FPSR_REG))
10909 (clobber (reg:CCFP FLAGS_REG))
10910 (clobber (match_scratch:HI 5 "=a"))]
10914 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10915 operands[3], operands[4], operands[5], NULL_RTX);
10919 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
10920 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
10921 ;; with a precedence over other operators and is always put in the first
10922 ;; place. Swap condition and operands to match ficom instruction.
10924 (define_insn "*fp_jcc_4_<mode>_387"
10927 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10928 [(match_operator 1 "float_operator"
10929 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
10930 (match_operand 3 "register_operand" "f,f")])
10931 (label_ref (match_operand 4 "" ""))
10933 (clobber (reg:CCFP FPSR_REG))
10934 (clobber (reg:CCFP FLAGS_REG))
10935 (clobber (match_scratch:HI 5 "=a,a"))]
10936 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
10937 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
10938 && GET_MODE (operands[1]) == GET_MODE (operands[3])
10939 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
10946 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10947 [(match_operator 1 "float_operator"
10948 [(match_operand:X87MODEI12 2 "memory_operand" "")])
10949 (match_operand 3 "register_operand" "")])
10950 (match_operand 4 "" "")
10951 (match_operand 5 "" "")))
10952 (clobber (reg:CCFP FPSR_REG))
10953 (clobber (reg:CCFP FLAGS_REG))
10954 (clobber (match_scratch:HI 6 "=a"))]
10958 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
10960 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10961 operands[3], operands[7],
10962 operands[4], operands[5], operands[6], NULL_RTX);
10966 ;; %%% Kill this when reload knows how to do it.
10970 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10971 [(match_operator 1 "float_operator"
10972 [(match_operand:X87MODEI12 2 "register_operand" "")])
10973 (match_operand 3 "register_operand" "")])
10974 (match_operand 4 "" "")
10975 (match_operand 5 "" "")))
10976 (clobber (reg:CCFP FPSR_REG))
10977 (clobber (reg:CCFP FLAGS_REG))
10978 (clobber (match_scratch:HI 6 "=a"))]
10982 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
10983 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
10985 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10986 operands[3], operands[7],
10987 operands[4], operands[5], operands[6], operands[2]);
10991 ;; Unconditional and other jump instructions
10993 (define_insn "jump"
10995 (label_ref (match_operand 0 "" "")))]
10998 [(set_attr "type" "ibr")
10999 (set (attr "length")
11000 (if_then_else (and (ge (minus (match_dup 0) (pc))
11002 (lt (minus (match_dup 0) (pc))
11006 (set_attr "modrm" "0")])
11008 (define_expand "indirect_jump"
11009 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
11013 (define_insn "*indirect_jump"
11014 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
11017 [(set_attr "type" "ibr")
11018 (set_attr "length_immediate" "0")])
11020 (define_expand "tablejump"
11021 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
11022 (use (label_ref (match_operand 1 "" "")))])]
11025 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11026 relative. Convert the relative address to an absolute address. */
11030 enum rtx_code code;
11032 /* We can't use @GOTOFF for text labels on VxWorks;
11033 see gotoff_operand. */
11034 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11038 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11040 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11044 op1 = pic_offset_table_rtx;
11049 op0 = pic_offset_table_rtx;
11053 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11058 (define_insn "*tablejump_1"
11059 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11060 (use (label_ref (match_operand 1 "" "")))]
11063 [(set_attr "type" "ibr")
11064 (set_attr "length_immediate" "0")])
11066 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11069 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11070 (set (match_operand:QI 1 "register_operand" "")
11071 (match_operator:QI 2 "ix86_comparison_operator"
11072 [(reg FLAGS_REG) (const_int 0)]))
11073 (set (match_operand 3 "q_regs_operand" "")
11074 (zero_extend (match_dup 1)))]
11075 "(peep2_reg_dead_p (3, operands[1])
11076 || operands_match_p (operands[1], operands[3]))
11077 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11078 [(set (match_dup 4) (match_dup 0))
11079 (set (strict_low_part (match_dup 5))
11082 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11083 operands[5] = gen_lowpart (QImode, operands[3]);
11084 ix86_expand_clear (operands[3]);
11087 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11090 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11091 (set (match_operand:QI 1 "register_operand" "")
11092 (match_operator:QI 2 "ix86_comparison_operator"
11093 [(reg FLAGS_REG) (const_int 0)]))
11094 (parallel [(set (match_operand 3 "q_regs_operand" "")
11095 (zero_extend (match_dup 1)))
11096 (clobber (reg:CC FLAGS_REG))])]
11097 "(peep2_reg_dead_p (3, operands[1])
11098 || operands_match_p (operands[1], operands[3]))
11099 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11100 [(set (match_dup 4) (match_dup 0))
11101 (set (strict_low_part (match_dup 5))
11104 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11105 operands[5] = gen_lowpart (QImode, operands[3]);
11106 ix86_expand_clear (operands[3]);
11109 ;; Call instructions.
11111 ;; The predicates normally associated with named expanders are not properly
11112 ;; checked for calls. This is a bug in the generic code, but it isn't that
11113 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11115 ;; P6 processors will jump to the address after the decrement when %esp
11116 ;; is used as a call operand, so they will execute return address as a code.
11117 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11119 ;; Call subroutine returning no value.
11121 (define_expand "call_pop"
11122 [(parallel [(call (match_operand:QI 0 "" "")
11123 (match_operand:SI 1 "" ""))
11124 (set (reg:SI SP_REG)
11125 (plus:SI (reg:SI SP_REG)
11126 (match_operand:SI 3 "" "")))])]
11129 ix86_expand_call (NULL, operands[0], operands[1],
11130 operands[2], operands[3], 0);
11134 (define_insn "*call_pop_0"
11135 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11136 (match_operand:SI 1 "" ""))
11137 (set (reg:SI SP_REG)
11138 (plus:SI (reg:SI SP_REG)
11139 (match_operand:SI 2 "immediate_operand" "")))]
11142 if (SIBLING_CALL_P (insn))
11145 return "call\t%P0";
11147 [(set_attr "type" "call")])
11149 (define_insn "*call_pop_1"
11150 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11151 (match_operand:SI 1 "" ""))
11152 (set (reg:SI SP_REG)
11153 (plus:SI (reg:SI SP_REG)
11154 (match_operand:SI 2 "immediate_operand" "i")))]
11155 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11157 if (constant_call_address_operand (operands[0], Pmode))
11158 return "call\t%P0";
11159 return "call\t%A0";
11161 [(set_attr "type" "call")])
11163 (define_insn "*sibcall_pop_1"
11164 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11165 (match_operand:SI 1 "" ""))
11166 (set (reg:SI SP_REG)
11167 (plus:SI (reg:SI SP_REG)
11168 (match_operand:SI 2 "immediate_operand" "i,i")))]
11169 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11173 [(set_attr "type" "call")])
11175 (define_expand "call"
11176 [(call (match_operand:QI 0 "" "")
11177 (match_operand 1 "" ""))
11178 (use (match_operand 2 "" ""))]
11181 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
11185 (define_expand "sibcall"
11186 [(call (match_operand:QI 0 "" "")
11187 (match_operand 1 "" ""))
11188 (use (match_operand 2 "" ""))]
11191 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
11195 (define_insn "*call_0"
11196 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11197 (match_operand 1 "" ""))]
11200 if (SIBLING_CALL_P (insn))
11203 return "call\t%P0";
11205 [(set_attr "type" "call")])
11207 (define_insn "*call_1"
11208 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11209 (match_operand 1 "" ""))]
11210 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11212 if (constant_call_address_operand (operands[0], Pmode))
11213 return "call\t%P0";
11214 return "call\t%A0";
11216 [(set_attr "type" "call")])
11218 (define_insn "*sibcall_1"
11219 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11220 (match_operand 1 "" ""))]
11221 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11225 [(set_attr "type" "call")])
11227 (define_insn "*call_1_rex64"
11228 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11229 (match_operand 1 "" ""))]
11230 "TARGET_64BIT && !SIBLING_CALL_P (insn)
11231 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11233 if (constant_call_address_operand (operands[0], Pmode))
11234 return "call\t%P0";
11235 return "call\t%A0";
11237 [(set_attr "type" "call")])
11239 (define_insn "*call_1_rex64_ms_sysv"
11240 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11241 (match_operand 1 "" ""))
11242 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11243 (clobber (reg:TI XMM6_REG))
11244 (clobber (reg:TI XMM7_REG))
11245 (clobber (reg:TI XMM8_REG))
11246 (clobber (reg:TI XMM9_REG))
11247 (clobber (reg:TI XMM10_REG))
11248 (clobber (reg:TI XMM11_REG))
11249 (clobber (reg:TI XMM12_REG))
11250 (clobber (reg:TI XMM13_REG))
11251 (clobber (reg:TI XMM14_REG))
11252 (clobber (reg:TI XMM15_REG))
11253 (clobber (reg:DI SI_REG))
11254 (clobber (reg:DI DI_REG))]
11255 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11257 if (constant_call_address_operand (operands[0], Pmode))
11258 return "call\t%P0";
11259 return "call\t%A0";
11261 [(set_attr "type" "call")])
11263 (define_insn "*call_1_rex64_large"
11264 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11265 (match_operand 1 "" ""))]
11266 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11268 [(set_attr "type" "call")])
11270 (define_insn "*sibcall_1_rex64"
11271 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11272 (match_operand 1 "" ""))]
11273 "TARGET_64BIT && SIBLING_CALL_P (insn)"
11277 [(set_attr "type" "call")])
11279 ;; Call subroutine, returning value in operand 0
11280 (define_expand "call_value_pop"
11281 [(parallel [(set (match_operand 0 "" "")
11282 (call (match_operand:QI 1 "" "")
11283 (match_operand:SI 2 "" "")))
11284 (set (reg:SI SP_REG)
11285 (plus:SI (reg:SI SP_REG)
11286 (match_operand:SI 4 "" "")))])]
11289 ix86_expand_call (operands[0], operands[1], operands[2],
11290 operands[3], operands[4], 0);
11294 (define_expand "call_value"
11295 [(set (match_operand 0 "" "")
11296 (call (match_operand:QI 1 "" "")
11297 (match_operand:SI 2 "" "")))
11298 (use (match_operand:SI 3 "" ""))]
11299 ;; Operand 3 is not used on the i386.
11302 ix86_expand_call (operands[0], operands[1], operands[2],
11303 operands[3], NULL, 0);
11307 (define_expand "sibcall_value"
11308 [(set (match_operand 0 "" "")
11309 (call (match_operand:QI 1 "" "")
11310 (match_operand:SI 2 "" "")))
11311 (use (match_operand:SI 3 "" ""))]
11312 ;; Operand 3 is not used on the i386.
11315 ix86_expand_call (operands[0], operands[1], operands[2],
11316 operands[3], NULL, 1);
11320 ;; Call subroutine returning any type.
11322 (define_expand "untyped_call"
11323 [(parallel [(call (match_operand 0 "" "")
11325 (match_operand 1 "" "")
11326 (match_operand 2 "" "")])]
11331 /* In order to give reg-stack an easier job in validating two
11332 coprocessor registers as containing a possible return value,
11333 simply pretend the untyped call returns a complex long double
11336 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11337 and should have the default ABI. */
11339 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11340 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11341 operands[0], const0_rtx,
11342 GEN_INT ((TARGET_64BIT
11343 ? (ix86_abi == SYSV_ABI
11344 ? X86_64_SSE_REGPARM_MAX
11345 : X86_64_MS_SSE_REGPARM_MAX)
11346 : X86_32_SSE_REGPARM_MAX)
11350 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11352 rtx set = XVECEXP (operands[2], 0, i);
11353 emit_move_insn (SET_DEST (set), SET_SRC (set));
11356 /* The optimizer does not know that the call sets the function value
11357 registers we stored in the result block. We avoid problems by
11358 claiming that all hard registers are used and clobbered at this
11360 emit_insn (gen_blockage ());
11365 ;; Prologue and epilogue instructions
11367 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11368 ;; all of memory. This blocks insns from being moved across this point.
11370 (define_insn "blockage"
11371 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11374 [(set_attr "length" "0")])
11376 ;; Do not schedule instructions accessing memory across this point.
11378 (define_expand "memory_blockage"
11379 [(set (match_dup 0)
11380 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11383 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11384 MEM_VOLATILE_P (operands[0]) = 1;
11387 (define_insn "*memory_blockage"
11388 [(set (match_operand:BLK 0 "" "")
11389 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11392 [(set_attr "length" "0")])
11394 ;; As USE insns aren't meaningful after reload, this is used instead
11395 ;; to prevent deleting instructions setting registers for PIC code
11396 (define_insn "prologue_use"
11397 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11400 [(set_attr "length" "0")])
11402 ;; Insn emitted into the body of a function to return from a function.
11403 ;; This is only done if the function's epilogue is known to be simple.
11404 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11406 (define_expand "return"
11408 "ix86_can_use_return_insn_p ()"
11410 if (crtl->args.pops_args)
11412 rtx popc = GEN_INT (crtl->args.pops_args);
11413 emit_jump_insn (gen_return_pop_internal (popc));
11418 (define_insn "return_internal"
11422 [(set_attr "length" "1")
11423 (set_attr "atom_unit" "jeu")
11424 (set_attr "length_immediate" "0")
11425 (set_attr "modrm" "0")])
11427 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11428 ;; instruction Athlon and K8 have.
11430 (define_insn "return_internal_long"
11432 (unspec [(const_int 0)] UNSPEC_REP)]
11435 [(set_attr "length" "2")
11436 (set_attr "atom_unit" "jeu")
11437 (set_attr "length_immediate" "0")
11438 (set_attr "prefix_rep" "1")
11439 (set_attr "modrm" "0")])
11441 (define_insn "return_pop_internal"
11443 (use (match_operand:SI 0 "const_int_operand" ""))]
11446 [(set_attr "length" "3")
11447 (set_attr "atom_unit" "jeu")
11448 (set_attr "length_immediate" "2")
11449 (set_attr "modrm" "0")])
11451 (define_insn "return_indirect_internal"
11453 (use (match_operand:SI 0 "register_operand" "r"))]
11456 [(set_attr "type" "ibr")
11457 (set_attr "length_immediate" "0")])
11463 [(set_attr "length" "1")
11464 (set_attr "length_immediate" "0")
11465 (set_attr "modrm" "0")])
11467 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11468 (define_insn "nops"
11469 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11473 int num = INTVAL (operands[0]);
11475 gcc_assert (num >= 1 && num <= 8);
11478 fputs ("\tnop\n", asm_out_file);
11482 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11483 (set_attr "length_immediate" "0")
11484 (set_attr "modrm" "0")])
11486 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11487 ;; branch prediction penalty for the third jump in a 16-byte
11491 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11494 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11495 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11497 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11498 The align insn is used to avoid 3 jump instructions in the row to improve
11499 branch prediction and the benefits hardly outweigh the cost of extra 8
11500 nops on the average inserted by full alignment pseudo operation. */
11504 [(set_attr "length" "16")])
11506 (define_expand "prologue"
11509 "ix86_expand_prologue (); DONE;")
11511 (define_insn "set_got"
11512 [(set (match_operand:SI 0 "register_operand" "=r")
11513 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11514 (clobber (reg:CC FLAGS_REG))]
11516 "* return output_set_got (operands[0], NULL_RTX);"
11517 [(set_attr "type" "multi")
11518 (set_attr "length" "12")])
11520 (define_insn "set_got_labelled"
11521 [(set (match_operand:SI 0 "register_operand" "=r")
11522 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11524 (clobber (reg:CC FLAGS_REG))]
11526 "* return output_set_got (operands[0], operands[1]);"
11527 [(set_attr "type" "multi")
11528 (set_attr "length" "12")])
11530 (define_insn "set_got_rex64"
11531 [(set (match_operand:DI 0 "register_operand" "=r")
11532 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11534 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11535 [(set_attr "type" "lea")
11536 (set_attr "length_address" "4")
11537 (set_attr "mode" "DI")])
11539 (define_insn "set_rip_rex64"
11540 [(set (match_operand:DI 0 "register_operand" "=r")
11541 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11543 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11544 [(set_attr "type" "lea")
11545 (set_attr "length_address" "4")
11546 (set_attr "mode" "DI")])
11548 (define_insn "set_got_offset_rex64"
11549 [(set (match_operand:DI 0 "register_operand" "=r")
11551 [(label_ref (match_operand 1 "" ""))]
11552 UNSPEC_SET_GOT_OFFSET))]
11554 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11555 [(set_attr "type" "imov")
11556 (set_attr "length_immediate" "0")
11557 (set_attr "length_address" "8")
11558 (set_attr "mode" "DI")])
11560 (define_expand "epilogue"
11563 "ix86_expand_epilogue (1); DONE;")
11565 (define_expand "sibcall_epilogue"
11568 "ix86_expand_epilogue (0); DONE;")
11570 (define_expand "eh_return"
11571 [(use (match_operand 0 "register_operand" ""))]
11574 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11576 /* Tricky bit: we write the address of the handler to which we will
11577 be returning into someone else's stack frame, one word below the
11578 stack address we wish to restore. */
11579 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11580 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11581 tmp = gen_rtx_MEM (Pmode, tmp);
11582 emit_move_insn (tmp, ra);
11584 emit_jump_insn (gen_eh_return_internal ());
11589 (define_insn_and_split "eh_return_internal"
11593 "epilogue_completed"
11595 "ix86_expand_epilogue (2); DONE;")
11597 (define_insn "leave"
11598 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11599 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11600 (clobber (mem:BLK (scratch)))]
11603 [(set_attr "type" "leave")])
11605 (define_insn "leave_rex64"
11606 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11607 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11608 (clobber (mem:BLK (scratch)))]
11611 [(set_attr "type" "leave")])
11613 ;; Handle -fsplit-stack.
11615 (define_expand "split_stack_prologue"
11619 ix86_expand_split_stack_prologue ();
11623 ;; In order to support the call/return predictor, we use a return
11624 ;; instruction which the middle-end doesn't see.
11625 (define_insn "split_stack_return"
11626 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11627 UNSPEC_STACK_CHECK)]
11630 if (operands[0] == const0_rtx)
11635 [(set_attr "atom_unit" "jeu")
11636 (set_attr "modrm" "0")
11637 (set (attr "length")
11638 (if_then_else (match_operand:SI 0 "const0_operand" "")
11641 (set (attr "length_immediate")
11642 (if_then_else (match_operand:SI 0 "const0_operand" "")
11646 ;; If there are operand 0 bytes available on the stack, jump to
11649 (define_expand "split_stack_space_check"
11650 [(set (pc) (if_then_else
11651 (ltu (minus (reg SP_REG)
11652 (match_operand 0 "register_operand" ""))
11653 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11654 (label_ref (match_operand 1 "" ""))
11658 rtx reg, size, limit;
11660 reg = gen_reg_rtx (Pmode);
11661 size = force_reg (Pmode, operands[0]);
11662 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11663 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11664 UNSPEC_STACK_CHECK);
11665 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11666 ix86_expand_branch (GEU, reg, limit, operands[1]);
11671 ;; Bit manipulation instructions.
11673 (define_expand "ffs<mode>2"
11674 [(set (match_dup 2) (const_int -1))
11675 (parallel [(set (reg:CCZ FLAGS_REG)
11677 (match_operand:SWI48 1 "nonimmediate_operand" "")
11679 (set (match_operand:SWI48 0 "register_operand" "")
11680 (ctz:SWI48 (match_dup 1)))])
11681 (set (match_dup 0) (if_then_else:SWI48
11682 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11685 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11686 (clobber (reg:CC FLAGS_REG))])]
11689 if (<MODE>mode == SImode && !TARGET_CMOVE)
11691 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11694 operands[2] = gen_reg_rtx (<MODE>mode);
11697 (define_insn_and_split "ffssi2_no_cmove"
11698 [(set (match_operand:SI 0 "register_operand" "=r")
11699 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11700 (clobber (match_scratch:SI 2 "=&q"))
11701 (clobber (reg:CC FLAGS_REG))]
11704 "&& reload_completed"
11705 [(parallel [(set (reg:CCZ FLAGS_REG)
11706 (compare:CCZ (match_dup 1) (const_int 0)))
11707 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11708 (set (strict_low_part (match_dup 3))
11709 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11710 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11711 (clobber (reg:CC FLAGS_REG))])
11712 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11713 (clobber (reg:CC FLAGS_REG))])
11714 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11715 (clobber (reg:CC FLAGS_REG))])]
11717 operands[3] = gen_lowpart (QImode, operands[2]);
11718 ix86_expand_clear (operands[2]);
11721 (define_insn "*ffs<mode>_1"
11722 [(set (reg:CCZ FLAGS_REG)
11723 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11725 (set (match_operand:SWI48 0 "register_operand" "=r")
11726 (ctz:SWI48 (match_dup 1)))]
11728 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11729 [(set_attr "type" "alu1")
11730 (set_attr "prefix_0f" "1")
11731 (set_attr "mode" "<MODE>")])
11733 (define_insn "ctz<mode>2"
11734 [(set (match_operand:SWI48 0 "register_operand" "=r")
11735 (ctz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
11736 (clobber (reg:CC FLAGS_REG))]
11738 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11739 [(set_attr "type" "alu1")
11740 (set_attr "prefix_0f" "1")
11741 (set_attr "mode" "<MODE>")])
11743 (define_expand "clz<mode>2"
11745 [(set (match_operand:SWI248 0 "register_operand" "")
11748 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
11749 (clobber (reg:CC FLAGS_REG))])
11751 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
11752 (clobber (reg:CC FLAGS_REG))])]
11757 emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
11760 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11763 (define_insn "clz<mode>2_abm"
11764 [(set (match_operand:SWI248 0 "register_operand" "=r")
11765 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11766 (clobber (reg:CC FLAGS_REG))]
11768 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11769 [(set_attr "prefix_rep" "1")
11770 (set_attr "type" "bitmanip")
11771 (set_attr "mode" "<MODE>")])
11773 (define_insn "bsr_rex64"
11774 [(set (match_operand:DI 0 "register_operand" "=r")
11775 (minus:DI (const_int 63)
11776 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
11777 (clobber (reg:CC FLAGS_REG))]
11779 "bsr{q}\t{%1, %0|%0, %1}"
11780 [(set_attr "type" "alu1")
11781 (set_attr "prefix_0f" "1")
11782 (set_attr "mode" "DI")])
11785 [(set (match_operand:SI 0 "register_operand" "=r")
11786 (minus:SI (const_int 31)
11787 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
11788 (clobber (reg:CC FLAGS_REG))]
11790 "bsr{l}\t{%1, %0|%0, %1}"
11791 [(set_attr "type" "alu1")
11792 (set_attr "prefix_0f" "1")
11793 (set_attr "mode" "SI")])
11795 (define_insn "*bsrhi"
11796 [(set (match_operand:HI 0 "register_operand" "=r")
11797 (minus:HI (const_int 15)
11798 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
11799 (clobber (reg:CC FLAGS_REG))]
11801 "bsr{w}\t{%1, %0|%0, %1}"
11802 [(set_attr "type" "alu1")
11803 (set_attr "prefix_0f" "1")
11804 (set_attr "mode" "HI")])
11806 (define_insn "popcount<mode>2"
11807 [(set (match_operand:SWI248 0 "register_operand" "=r")
11809 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11810 (clobber (reg:CC FLAGS_REG))]
11814 return "popcnt\t{%1, %0|%0, %1}";
11816 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11819 [(set_attr "prefix_rep" "1")
11820 (set_attr "type" "bitmanip")
11821 (set_attr "mode" "<MODE>")])
11823 (define_insn "*popcount<mode>2_cmp"
11824 [(set (reg FLAGS_REG)
11827 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
11829 (set (match_operand:SWI248 0 "register_operand" "=r")
11830 (popcount:SWI248 (match_dup 1)))]
11831 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
11834 return "popcnt\t{%1, %0|%0, %1}";
11836 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11839 [(set_attr "prefix_rep" "1")
11840 (set_attr "type" "bitmanip")
11841 (set_attr "mode" "<MODE>")])
11843 (define_insn "*popcountsi2_cmp_zext"
11844 [(set (reg FLAGS_REG)
11846 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
11848 (set (match_operand:DI 0 "register_operand" "=r")
11849 (zero_extend:DI(popcount:SI (match_dup 1))))]
11850 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
11853 return "popcnt\t{%1, %0|%0, %1}";
11855 return "popcnt{l}\t{%1, %0|%0, %1}";
11858 [(set_attr "prefix_rep" "1")
11859 (set_attr "type" "bitmanip")
11860 (set_attr "mode" "SI")])
11862 (define_expand "bswap<mode>2"
11863 [(set (match_operand:SWI48 0 "register_operand" "")
11864 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
11867 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
11869 rtx x = operands[0];
11871 emit_move_insn (x, operands[1]);
11872 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
11873 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
11874 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
11879 (define_insn "*bswap<mode>2_movbe"
11880 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
11881 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
11883 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11886 movbe\t{%1, %0|%0, %1}
11887 movbe\t{%1, %0|%0, %1}"
11888 [(set_attr "type" "bitmanip,imov,imov")
11889 (set_attr "modrm" "0,1,1")
11890 (set_attr "prefix_0f" "*,1,1")
11891 (set_attr "prefix_extra" "*,1,1")
11892 (set_attr "mode" "<MODE>")])
11894 (define_insn "*bswap<mode>2_1"
11895 [(set (match_operand:SWI48 0 "register_operand" "=r")
11896 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
11899 [(set_attr "type" "bitmanip")
11900 (set_attr "modrm" "0")
11901 (set_attr "mode" "<MODE>")])
11903 (define_insn "*bswaphi_lowpart_1"
11904 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
11905 (bswap:HI (match_dup 0)))
11906 (clobber (reg:CC FLAGS_REG))]
11907 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
11909 xchg{b}\t{%h0, %b0|%b0, %h0}
11910 rol{w}\t{$8, %0|%0, 8}"
11911 [(set_attr "length" "2,4")
11912 (set_attr "mode" "QI,HI")])
11914 (define_insn "bswaphi_lowpart"
11915 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
11916 (bswap:HI (match_dup 0)))
11917 (clobber (reg:CC FLAGS_REG))]
11919 "rol{w}\t{$8, %0|%0, 8}"
11920 [(set_attr "length" "4")
11921 (set_attr "mode" "HI")])
11923 (define_expand "paritydi2"
11924 [(set (match_operand:DI 0 "register_operand" "")
11925 (parity:DI (match_operand:DI 1 "register_operand" "")))]
11928 rtx scratch = gen_reg_rtx (QImode);
11931 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
11932 NULL_RTX, operands[1]));
11934 cond = gen_rtx_fmt_ee (ORDERED, QImode,
11935 gen_rtx_REG (CCmode, FLAGS_REG),
11937 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
11940 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
11943 rtx tmp = gen_reg_rtx (SImode);
11945 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
11946 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
11951 (define_expand "paritysi2"
11952 [(set (match_operand:SI 0 "register_operand" "")
11953 (parity:SI (match_operand:SI 1 "register_operand" "")))]
11956 rtx scratch = gen_reg_rtx (QImode);
11959 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
11961 cond = gen_rtx_fmt_ee (ORDERED, QImode,
11962 gen_rtx_REG (CCmode, FLAGS_REG),
11964 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
11966 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
11970 (define_insn_and_split "paritydi2_cmp"
11971 [(set (reg:CC FLAGS_REG)
11972 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
11974 (clobber (match_scratch:DI 0 "=r"))
11975 (clobber (match_scratch:SI 1 "=&r"))
11976 (clobber (match_scratch:HI 2 "=Q"))]
11979 "&& reload_completed"
11981 [(set (match_dup 1)
11982 (xor:SI (match_dup 1) (match_dup 4)))
11983 (clobber (reg:CC FLAGS_REG))])
11985 [(set (reg:CC FLAGS_REG)
11986 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
11987 (clobber (match_dup 1))
11988 (clobber (match_dup 2))])]
11990 operands[4] = gen_lowpart (SImode, operands[3]);
11994 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
11995 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
11998 operands[1] = gen_highpart (SImode, operands[3]);
12001 (define_insn_and_split "paritysi2_cmp"
12002 [(set (reg:CC FLAGS_REG)
12003 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12005 (clobber (match_scratch:SI 0 "=r"))
12006 (clobber (match_scratch:HI 1 "=&Q"))]
12009 "&& reload_completed"
12011 [(set (match_dup 1)
12012 (xor:HI (match_dup 1) (match_dup 3)))
12013 (clobber (reg:CC FLAGS_REG))])
12015 [(set (reg:CC FLAGS_REG)
12016 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12017 (clobber (match_dup 1))])]
12019 operands[3] = gen_lowpart (HImode, operands[2]);
12021 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12022 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12025 (define_insn "*parityhi2_cmp"
12026 [(set (reg:CC FLAGS_REG)
12027 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12029 (clobber (match_scratch:HI 0 "=Q"))]
12031 "xor{b}\t{%h0, %b0|%b0, %h0}"
12032 [(set_attr "length" "2")
12033 (set_attr "mode" "HI")])
12035 ;; Thread-local storage patterns for ELF.
12037 ;; Note that these code sequences must appear exactly as shown
12038 ;; in order to allow linker relaxation.
12040 (define_insn "*tls_global_dynamic_32_gnu"
12041 [(set (match_operand:SI 0 "register_operand" "=a")
12042 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12043 (match_operand:SI 2 "tls_symbolic_operand" "")
12044 (match_operand:SI 3 "call_insn_operand" "")]
12046 (clobber (match_scratch:SI 4 "=d"))
12047 (clobber (match_scratch:SI 5 "=c"))
12048 (clobber (reg:CC FLAGS_REG))]
12049 "!TARGET_64BIT && TARGET_GNU_TLS"
12050 "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
12051 [(set_attr "type" "multi")
12052 (set_attr "length" "12")])
12054 (define_expand "tls_global_dynamic_32"
12055 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12058 (match_operand:SI 1 "tls_symbolic_operand" "")
12061 (clobber (match_scratch:SI 4 ""))
12062 (clobber (match_scratch:SI 5 ""))
12063 (clobber (reg:CC FLAGS_REG))])]
12067 operands[2] = pic_offset_table_rtx;
12070 operands[2] = gen_reg_rtx (Pmode);
12071 emit_insn (gen_set_got (operands[2]));
12073 if (TARGET_GNU2_TLS)
12075 emit_insn (gen_tls_dynamic_gnu2_32
12076 (operands[0], operands[1], operands[2]));
12079 operands[3] = ix86_tls_get_addr ();
12082 (define_insn "*tls_global_dynamic_64"
12083 [(set (match_operand:DI 0 "register_operand" "=a")
12084 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
12085 (match_operand:DI 3 "" "")))
12086 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12089 { 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"; }
12090 [(set_attr "type" "multi")
12091 (set_attr "length" "16")])
12093 (define_expand "tls_global_dynamic_64"
12094 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12095 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
12096 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12100 if (TARGET_GNU2_TLS)
12102 emit_insn (gen_tls_dynamic_gnu2_64
12103 (operands[0], operands[1]));
12106 operands[2] = ix86_tls_get_addr ();
12109 (define_insn "*tls_local_dynamic_base_32_gnu"
12110 [(set (match_operand:SI 0 "register_operand" "=a")
12111 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12112 (match_operand:SI 2 "call_insn_operand" "")]
12113 UNSPEC_TLS_LD_BASE))
12114 (clobber (match_scratch:SI 3 "=d"))
12115 (clobber (match_scratch:SI 4 "=c"))
12116 (clobber (reg:CC FLAGS_REG))]
12117 "!TARGET_64BIT && TARGET_GNU_TLS"
12118 "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
12119 [(set_attr "type" "multi")
12120 (set_attr "length" "11")])
12122 (define_expand "tls_local_dynamic_base_32"
12123 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12124 (unspec:SI [(match_dup 1) (match_dup 2)]
12125 UNSPEC_TLS_LD_BASE))
12126 (clobber (match_scratch:SI 3 ""))
12127 (clobber (match_scratch:SI 4 ""))
12128 (clobber (reg:CC FLAGS_REG))])]
12132 operands[1] = pic_offset_table_rtx;
12135 operands[1] = gen_reg_rtx (Pmode);
12136 emit_insn (gen_set_got (operands[1]));
12138 if (TARGET_GNU2_TLS)
12140 emit_insn (gen_tls_dynamic_gnu2_32
12141 (operands[0], ix86_tls_module_base (), operands[1]));
12144 operands[2] = ix86_tls_get_addr ();
12147 (define_insn "*tls_local_dynamic_base_64"
12148 [(set (match_operand:DI 0 "register_operand" "=a")
12149 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
12150 (match_operand:DI 2 "" "")))
12151 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12153 "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
12154 [(set_attr "type" "multi")
12155 (set_attr "length" "12")])
12157 (define_expand "tls_local_dynamic_base_64"
12158 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12159 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
12160 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12163 if (TARGET_GNU2_TLS)
12165 emit_insn (gen_tls_dynamic_gnu2_64
12166 (operands[0], ix86_tls_module_base ()));
12169 operands[1] = ix86_tls_get_addr ();
12172 ;; Local dynamic of a single variable is a lose. Show combine how
12173 ;; to convert that back to global dynamic.
12175 (define_insn_and_split "*tls_local_dynamic_32_once"
12176 [(set (match_operand:SI 0 "register_operand" "=a")
12177 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12178 (match_operand:SI 2 "call_insn_operand" "")]
12179 UNSPEC_TLS_LD_BASE)
12180 (const:SI (unspec:SI
12181 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12183 (clobber (match_scratch:SI 4 "=d"))
12184 (clobber (match_scratch:SI 5 "=c"))
12185 (clobber (reg:CC FLAGS_REG))]
12189 [(parallel [(set (match_dup 0)
12190 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12192 (clobber (match_dup 4))
12193 (clobber (match_dup 5))
12194 (clobber (reg:CC FLAGS_REG))])])
12196 ;; Segment register for the thread base ptr load
12197 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12199 ;; Load and add the thread base pointer from %gs:0.
12200 (define_insn "*load_tp_<mode>"
12201 [(set (match_operand:P 0 "register_operand" "=r")
12202 (unspec:P [(const_int 0)] UNSPEC_TP))]
12204 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12205 [(set_attr "type" "imov")
12206 (set_attr "modrm" "0")
12207 (set_attr "length" "7")
12208 (set_attr "memory" "load")
12209 (set_attr "imm_disp" "false")])
12211 (define_insn "*add_tp_<mode>"
12212 [(set (match_operand:P 0 "register_operand" "=r")
12213 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12214 (match_operand:P 1 "register_operand" "0")))
12215 (clobber (reg:CC FLAGS_REG))]
12217 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12218 [(set_attr "type" "alu")
12219 (set_attr "modrm" "0")
12220 (set_attr "length" "7")
12221 (set_attr "memory" "load")
12222 (set_attr "imm_disp" "false")])
12224 ;; GNU2 TLS patterns can be split.
12226 (define_expand "tls_dynamic_gnu2_32"
12227 [(set (match_dup 3)
12228 (plus:SI (match_operand:SI 2 "register_operand" "")
12230 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12233 [(set (match_operand:SI 0 "register_operand" "")
12234 (unspec:SI [(match_dup 1) (match_dup 3)
12235 (match_dup 2) (reg:SI SP_REG)]
12237 (clobber (reg:CC FLAGS_REG))])]
12238 "!TARGET_64BIT && TARGET_GNU2_TLS"
12240 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12241 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12244 (define_insn "*tls_dynamic_lea_32"
12245 [(set (match_operand:SI 0 "register_operand" "=r")
12246 (plus:SI (match_operand:SI 1 "register_operand" "b")
12248 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12249 UNSPEC_TLSDESC))))]
12250 "!TARGET_64BIT && TARGET_GNU2_TLS"
12251 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12252 [(set_attr "type" "lea")
12253 (set_attr "mode" "SI")
12254 (set_attr "length" "6")
12255 (set_attr "length_address" "4")])
12257 (define_insn "*tls_dynamic_call_32"
12258 [(set (match_operand:SI 0 "register_operand" "=a")
12259 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12260 (match_operand:SI 2 "register_operand" "0")
12261 ;; we have to make sure %ebx still points to the GOT
12262 (match_operand:SI 3 "register_operand" "b")
12265 (clobber (reg:CC FLAGS_REG))]
12266 "!TARGET_64BIT && TARGET_GNU2_TLS"
12267 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12268 [(set_attr "type" "call")
12269 (set_attr "length" "2")
12270 (set_attr "length_address" "0")])
12272 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12273 [(set (match_operand:SI 0 "register_operand" "=&a")
12275 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12276 (match_operand:SI 4 "" "")
12277 (match_operand:SI 2 "register_operand" "b")
12280 (const:SI (unspec:SI
12281 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12283 (clobber (reg:CC FLAGS_REG))]
12284 "!TARGET_64BIT && TARGET_GNU2_TLS"
12287 [(set (match_dup 0) (match_dup 5))]
12289 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12290 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12293 (define_expand "tls_dynamic_gnu2_64"
12294 [(set (match_dup 2)
12295 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12298 [(set (match_operand:DI 0 "register_operand" "")
12299 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12301 (clobber (reg:CC FLAGS_REG))])]
12302 "TARGET_64BIT && TARGET_GNU2_TLS"
12304 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12305 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12308 (define_insn "*tls_dynamic_lea_64"
12309 [(set (match_operand:DI 0 "register_operand" "=r")
12310 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12312 "TARGET_64BIT && TARGET_GNU2_TLS"
12313 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12314 [(set_attr "type" "lea")
12315 (set_attr "mode" "DI")
12316 (set_attr "length" "7")
12317 (set_attr "length_address" "4")])
12319 (define_insn "*tls_dynamic_call_64"
12320 [(set (match_operand:DI 0 "register_operand" "=a")
12321 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12322 (match_operand:DI 2 "register_operand" "0")
12325 (clobber (reg:CC FLAGS_REG))]
12326 "TARGET_64BIT && TARGET_GNU2_TLS"
12327 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12328 [(set_attr "type" "call")
12329 (set_attr "length" "2")
12330 (set_attr "length_address" "0")])
12332 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12333 [(set (match_operand:DI 0 "register_operand" "=&a")
12335 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12336 (match_operand:DI 3 "" "")
12339 (const:DI (unspec:DI
12340 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12342 (clobber (reg:CC FLAGS_REG))]
12343 "TARGET_64BIT && TARGET_GNU2_TLS"
12346 [(set (match_dup 0) (match_dup 4))]
12348 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12349 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12352 ;; These patterns match the binary 387 instructions for addM3, subM3,
12353 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12354 ;; SFmode. The first is the normal insn, the second the same insn but
12355 ;; with one operand a conversion, and the third the same insn but with
12356 ;; the other operand a conversion. The conversion may be SFmode or
12357 ;; SImode if the target mode DFmode, but only SImode if the target mode
12360 ;; Gcc is slightly more smart about handling normal two address instructions
12361 ;; so use special patterns for add and mull.
12363 (define_insn "*fop_<mode>_comm_mixed_avx"
12364 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12365 (match_operator:MODEF 3 "binary_fp_operator"
12366 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12367 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12368 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12369 && COMMUTATIVE_ARITH_P (operands[3])
12370 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12371 "* return output_387_binary_op (insn, operands);"
12372 [(set (attr "type")
12373 (if_then_else (eq_attr "alternative" "1")
12374 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12375 (const_string "ssemul")
12376 (const_string "sseadd"))
12377 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12378 (const_string "fmul")
12379 (const_string "fop"))))
12380 (set_attr "prefix" "orig,maybe_vex")
12381 (set_attr "mode" "<MODE>")])
12383 (define_insn "*fop_<mode>_comm_mixed"
12384 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12385 (match_operator:MODEF 3 "binary_fp_operator"
12386 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
12387 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12388 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12389 && COMMUTATIVE_ARITH_P (operands[3])
12390 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12391 "* return output_387_binary_op (insn, operands);"
12392 [(set (attr "type")
12393 (if_then_else (eq_attr "alternative" "1")
12394 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12395 (const_string "ssemul")
12396 (const_string "sseadd"))
12397 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12398 (const_string "fmul")
12399 (const_string "fop"))))
12400 (set_attr "mode" "<MODE>")])
12402 (define_insn "*fop_<mode>_comm_avx"
12403 [(set (match_operand:MODEF 0 "register_operand" "=x")
12404 (match_operator:MODEF 3 "binary_fp_operator"
12405 [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
12406 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12407 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12408 && COMMUTATIVE_ARITH_P (operands[3])
12409 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12410 "* return output_387_binary_op (insn, operands);"
12411 [(set (attr "type")
12412 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12413 (const_string "ssemul")
12414 (const_string "sseadd")))
12415 (set_attr "prefix" "vex")
12416 (set_attr "mode" "<MODE>")])
12418 (define_insn "*fop_<mode>_comm_sse"
12419 [(set (match_operand:MODEF 0 "register_operand" "=x")
12420 (match_operator:MODEF 3 "binary_fp_operator"
12421 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12422 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12423 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12424 && COMMUTATIVE_ARITH_P (operands[3])
12425 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12426 "* return output_387_binary_op (insn, operands);"
12427 [(set (attr "type")
12428 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12429 (const_string "ssemul")
12430 (const_string "sseadd")))
12431 (set_attr "mode" "<MODE>")])
12433 (define_insn "*fop_<mode>_comm_i387"
12434 [(set (match_operand:MODEF 0 "register_operand" "=f")
12435 (match_operator:MODEF 3 "binary_fp_operator"
12436 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12437 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12438 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12439 && COMMUTATIVE_ARITH_P (operands[3])
12440 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12441 "* return output_387_binary_op (insn, operands);"
12442 [(set (attr "type")
12443 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12444 (const_string "fmul")
12445 (const_string "fop")))
12446 (set_attr "mode" "<MODE>")])
12448 (define_insn "*fop_<mode>_1_mixed_avx"
12449 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12450 (match_operator:MODEF 3 "binary_fp_operator"
12451 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
12452 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12453 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12454 && !COMMUTATIVE_ARITH_P (operands[3])
12455 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12456 "* return output_387_binary_op (insn, operands);"
12457 [(set (attr "type")
12458 (cond [(and (eq_attr "alternative" "2")
12459 (match_operand:MODEF 3 "mult_operator" ""))
12460 (const_string "ssemul")
12461 (and (eq_attr "alternative" "2")
12462 (match_operand:MODEF 3 "div_operator" ""))
12463 (const_string "ssediv")
12464 (eq_attr "alternative" "2")
12465 (const_string "sseadd")
12466 (match_operand:MODEF 3 "mult_operator" "")
12467 (const_string "fmul")
12468 (match_operand:MODEF 3 "div_operator" "")
12469 (const_string "fdiv")
12471 (const_string "fop")))
12472 (set_attr "prefix" "orig,orig,maybe_vex")
12473 (set_attr "mode" "<MODE>")])
12475 (define_insn "*fop_<mode>_1_mixed"
12476 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12477 (match_operator:MODEF 3 "binary_fp_operator"
12478 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
12479 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12480 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12481 && !COMMUTATIVE_ARITH_P (operands[3])
12482 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12483 "* return output_387_binary_op (insn, operands);"
12484 [(set (attr "type")
12485 (cond [(and (eq_attr "alternative" "2")
12486 (match_operand:MODEF 3 "mult_operator" ""))
12487 (const_string "ssemul")
12488 (and (eq_attr "alternative" "2")
12489 (match_operand:MODEF 3 "div_operator" ""))
12490 (const_string "ssediv")
12491 (eq_attr "alternative" "2")
12492 (const_string "sseadd")
12493 (match_operand:MODEF 3 "mult_operator" "")
12494 (const_string "fmul")
12495 (match_operand:MODEF 3 "div_operator" "")
12496 (const_string "fdiv")
12498 (const_string "fop")))
12499 (set_attr "mode" "<MODE>")])
12501 (define_insn "*rcpsf2_sse"
12502 [(set (match_operand:SF 0 "register_operand" "=x")
12503 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12506 "%vrcpss\t{%1, %d0|%d0, %1}"
12507 [(set_attr "type" "sse")
12508 (set_attr "atom_sse_attr" "rcp")
12509 (set_attr "prefix" "maybe_vex")
12510 (set_attr "mode" "SF")])
12512 (define_insn "*fop_<mode>_1_avx"
12513 [(set (match_operand:MODEF 0 "register_operand" "=x")
12514 (match_operator:MODEF 3 "binary_fp_operator"
12515 [(match_operand:MODEF 1 "register_operand" "x")
12516 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12517 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12518 && !COMMUTATIVE_ARITH_P (operands[3])"
12519 "* return output_387_binary_op (insn, operands);"
12520 [(set (attr "type")
12521 (cond [(match_operand:MODEF 3 "mult_operator" "")
12522 (const_string "ssemul")
12523 (match_operand:MODEF 3 "div_operator" "")
12524 (const_string "ssediv")
12526 (const_string "sseadd")))
12527 (set_attr "prefix" "vex")
12528 (set_attr "mode" "<MODE>")])
12530 (define_insn "*fop_<mode>_1_sse"
12531 [(set (match_operand:MODEF 0 "register_operand" "=x")
12532 (match_operator:MODEF 3 "binary_fp_operator"
12533 [(match_operand:MODEF 1 "register_operand" "0")
12534 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12535 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12536 && !COMMUTATIVE_ARITH_P (operands[3])"
12537 "* return output_387_binary_op (insn, operands);"
12538 [(set (attr "type")
12539 (cond [(match_operand:MODEF 3 "mult_operator" "")
12540 (const_string "ssemul")
12541 (match_operand:MODEF 3 "div_operator" "")
12542 (const_string "ssediv")
12544 (const_string "sseadd")))
12545 (set_attr "mode" "<MODE>")])
12547 ;; This pattern is not fully shadowed by the pattern above.
12548 (define_insn "*fop_<mode>_1_i387"
12549 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12550 (match_operator:MODEF 3 "binary_fp_operator"
12551 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12552 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12553 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12554 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12555 && !COMMUTATIVE_ARITH_P (operands[3])
12556 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12557 "* return output_387_binary_op (insn, operands);"
12558 [(set (attr "type")
12559 (cond [(match_operand:MODEF 3 "mult_operator" "")
12560 (const_string "fmul")
12561 (match_operand:MODEF 3 "div_operator" "")
12562 (const_string "fdiv")
12564 (const_string "fop")))
12565 (set_attr "mode" "<MODE>")])
12567 ;; ??? Add SSE splitters for these!
12568 (define_insn "*fop_<MODEF:mode>_2_i387"
12569 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12570 (match_operator:MODEF 3 "binary_fp_operator"
12572 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12573 (match_operand:MODEF 2 "register_operand" "0,0")]))]
12574 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12575 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12576 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12577 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12578 [(set (attr "type")
12579 (cond [(match_operand:MODEF 3 "mult_operator" "")
12580 (const_string "fmul")
12581 (match_operand:MODEF 3 "div_operator" "")
12582 (const_string "fdiv")
12584 (const_string "fop")))
12585 (set_attr "fp_int_src" "true")
12586 (set_attr "mode" "<X87MODEI12:MODE>")])
12588 (define_insn "*fop_<MODEF:mode>_3_i387"
12589 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12590 (match_operator:MODEF 3 "binary_fp_operator"
12591 [(match_operand:MODEF 1 "register_operand" "0,0")
12593 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12594 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12595 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12596 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12597 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12598 [(set (attr "type")
12599 (cond [(match_operand:MODEF 3 "mult_operator" "")
12600 (const_string "fmul")
12601 (match_operand:MODEF 3 "div_operator" "")
12602 (const_string "fdiv")
12604 (const_string "fop")))
12605 (set_attr "fp_int_src" "true")
12606 (set_attr "mode" "<MODE>")])
12608 (define_insn "*fop_df_4_i387"
12609 [(set (match_operand:DF 0 "register_operand" "=f,f")
12610 (match_operator:DF 3 "binary_fp_operator"
12612 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12613 (match_operand:DF 2 "register_operand" "0,f")]))]
12614 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12615 && !(TARGET_SSE2 && TARGET_SSE_MATH)
12616 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12617 "* return output_387_binary_op (insn, operands);"
12618 [(set (attr "type")
12619 (cond [(match_operand:DF 3 "mult_operator" "")
12620 (const_string "fmul")
12621 (match_operand:DF 3 "div_operator" "")
12622 (const_string "fdiv")
12624 (const_string "fop")))
12625 (set_attr "mode" "SF")])
12627 (define_insn "*fop_df_5_i387"
12628 [(set (match_operand:DF 0 "register_operand" "=f,f")
12629 (match_operator:DF 3 "binary_fp_operator"
12630 [(match_operand:DF 1 "register_operand" "0,f")
12632 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12633 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12634 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12635 "* return output_387_binary_op (insn, operands);"
12636 [(set (attr "type")
12637 (cond [(match_operand:DF 3 "mult_operator" "")
12638 (const_string "fmul")
12639 (match_operand:DF 3 "div_operator" "")
12640 (const_string "fdiv")
12642 (const_string "fop")))
12643 (set_attr "mode" "SF")])
12645 (define_insn "*fop_df_6_i387"
12646 [(set (match_operand:DF 0 "register_operand" "=f,f")
12647 (match_operator:DF 3 "binary_fp_operator"
12649 (match_operand:SF 1 "register_operand" "0,f"))
12651 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12652 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12653 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12654 "* return output_387_binary_op (insn, operands);"
12655 [(set (attr "type")
12656 (cond [(match_operand:DF 3 "mult_operator" "")
12657 (const_string "fmul")
12658 (match_operand:DF 3 "div_operator" "")
12659 (const_string "fdiv")
12661 (const_string "fop")))
12662 (set_attr "mode" "SF")])
12664 (define_insn "*fop_xf_comm_i387"
12665 [(set (match_operand:XF 0 "register_operand" "=f")
12666 (match_operator:XF 3 "binary_fp_operator"
12667 [(match_operand:XF 1 "register_operand" "%0")
12668 (match_operand:XF 2 "register_operand" "f")]))]
12670 && COMMUTATIVE_ARITH_P (operands[3])"
12671 "* return output_387_binary_op (insn, operands);"
12672 [(set (attr "type")
12673 (if_then_else (match_operand:XF 3 "mult_operator" "")
12674 (const_string "fmul")
12675 (const_string "fop")))
12676 (set_attr "mode" "XF")])
12678 (define_insn "*fop_xf_1_i387"
12679 [(set (match_operand:XF 0 "register_operand" "=f,f")
12680 (match_operator:XF 3 "binary_fp_operator"
12681 [(match_operand:XF 1 "register_operand" "0,f")
12682 (match_operand:XF 2 "register_operand" "f,0")]))]
12684 && !COMMUTATIVE_ARITH_P (operands[3])"
12685 "* return output_387_binary_op (insn, operands);"
12686 [(set (attr "type")
12687 (cond [(match_operand:XF 3 "mult_operator" "")
12688 (const_string "fmul")
12689 (match_operand:XF 3 "div_operator" "")
12690 (const_string "fdiv")
12692 (const_string "fop")))
12693 (set_attr "mode" "XF")])
12695 (define_insn "*fop_xf_2_i387"
12696 [(set (match_operand:XF 0 "register_operand" "=f,f")
12697 (match_operator:XF 3 "binary_fp_operator"
12699 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12700 (match_operand:XF 2 "register_operand" "0,0")]))]
12701 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12702 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12703 [(set (attr "type")
12704 (cond [(match_operand:XF 3 "mult_operator" "")
12705 (const_string "fmul")
12706 (match_operand:XF 3 "div_operator" "")
12707 (const_string "fdiv")
12709 (const_string "fop")))
12710 (set_attr "fp_int_src" "true")
12711 (set_attr "mode" "<MODE>")])
12713 (define_insn "*fop_xf_3_i387"
12714 [(set (match_operand:XF 0 "register_operand" "=f,f")
12715 (match_operator:XF 3 "binary_fp_operator"
12716 [(match_operand:XF 1 "register_operand" "0,0")
12718 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12719 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12720 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12721 [(set (attr "type")
12722 (cond [(match_operand:XF 3 "mult_operator" "")
12723 (const_string "fmul")
12724 (match_operand:XF 3 "div_operator" "")
12725 (const_string "fdiv")
12727 (const_string "fop")))
12728 (set_attr "fp_int_src" "true")
12729 (set_attr "mode" "<MODE>")])
12731 (define_insn "*fop_xf_4_i387"
12732 [(set (match_operand:XF 0 "register_operand" "=f,f")
12733 (match_operator:XF 3 "binary_fp_operator"
12735 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
12736 (match_operand:XF 2 "register_operand" "0,f")]))]
12738 "* return output_387_binary_op (insn, operands);"
12739 [(set (attr "type")
12740 (cond [(match_operand:XF 3 "mult_operator" "")
12741 (const_string "fmul")
12742 (match_operand:XF 3 "div_operator" "")
12743 (const_string "fdiv")
12745 (const_string "fop")))
12746 (set_attr "mode" "<MODE>")])
12748 (define_insn "*fop_xf_5_i387"
12749 [(set (match_operand:XF 0 "register_operand" "=f,f")
12750 (match_operator:XF 3 "binary_fp_operator"
12751 [(match_operand:XF 1 "register_operand" "0,f")
12753 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12755 "* return output_387_binary_op (insn, operands);"
12756 [(set (attr "type")
12757 (cond [(match_operand:XF 3 "mult_operator" "")
12758 (const_string "fmul")
12759 (match_operand:XF 3 "div_operator" "")
12760 (const_string "fdiv")
12762 (const_string "fop")))
12763 (set_attr "mode" "<MODE>")])
12765 (define_insn "*fop_xf_6_i387"
12766 [(set (match_operand:XF 0 "register_operand" "=f,f")
12767 (match_operator:XF 3 "binary_fp_operator"
12769 (match_operand:MODEF 1 "register_operand" "0,f"))
12771 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12773 "* return output_387_binary_op (insn, operands);"
12774 [(set (attr "type")
12775 (cond [(match_operand:XF 3 "mult_operator" "")
12776 (const_string "fmul")
12777 (match_operand:XF 3 "div_operator" "")
12778 (const_string "fdiv")
12780 (const_string "fop")))
12781 (set_attr "mode" "<MODE>")])
12784 [(set (match_operand 0 "register_operand" "")
12785 (match_operator 3 "binary_fp_operator"
12786 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
12787 (match_operand 2 "register_operand" "")]))]
12789 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12790 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
12793 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
12794 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12795 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12796 gen_rtx_fmt_ee (GET_CODE (operands[3]),
12797 GET_MODE (operands[3]),
12800 ix86_free_from_memory (GET_MODE (operands[1]));
12805 [(set (match_operand 0 "register_operand" "")
12806 (match_operator 3 "binary_fp_operator"
12807 [(match_operand 1 "register_operand" "")
12808 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
12810 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12811 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
12814 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
12815 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12816 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12817 gen_rtx_fmt_ee (GET_CODE (operands[3]),
12818 GET_MODE (operands[3]),
12821 ix86_free_from_memory (GET_MODE (operands[2]));
12825 ;; FPU special functions.
12827 ;; This pattern implements a no-op XFmode truncation for
12828 ;; all fancy i386 XFmode math functions.
12830 (define_insn "truncxf<mode>2_i387_noop_unspec"
12831 [(set (match_operand:MODEF 0 "register_operand" "=f")
12832 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
12833 UNSPEC_TRUNC_NOOP))]
12834 "TARGET_USE_FANCY_MATH_387"
12835 "* return output_387_reg_move (insn, operands);"
12836 [(set_attr "type" "fmov")
12837 (set_attr "mode" "<MODE>")])
12839 (define_insn "sqrtxf2"
12840 [(set (match_operand:XF 0 "register_operand" "=f")
12841 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
12842 "TARGET_USE_FANCY_MATH_387"
12844 [(set_attr "type" "fpspc")
12845 (set_attr "mode" "XF")
12846 (set_attr "athlon_decode" "direct")
12847 (set_attr "amdfam10_decode" "direct")])
12849 (define_insn "sqrt_extend<mode>xf2_i387"
12850 [(set (match_operand:XF 0 "register_operand" "=f")
12853 (match_operand:MODEF 1 "register_operand" "0"))))]
12854 "TARGET_USE_FANCY_MATH_387"
12856 [(set_attr "type" "fpspc")
12857 (set_attr "mode" "XF")
12858 (set_attr "athlon_decode" "direct")
12859 (set_attr "amdfam10_decode" "direct")])
12861 (define_insn "*rsqrtsf2_sse"
12862 [(set (match_operand:SF 0 "register_operand" "=x")
12863 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12866 "%vrsqrtss\t{%1, %d0|%d0, %1}"
12867 [(set_attr "type" "sse")
12868 (set_attr "atom_sse_attr" "rcp")
12869 (set_attr "prefix" "maybe_vex")
12870 (set_attr "mode" "SF")])
12872 (define_expand "rsqrtsf2"
12873 [(set (match_operand:SF 0 "register_operand" "")
12874 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
12878 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
12882 (define_insn "*sqrt<mode>2_sse"
12883 [(set (match_operand:MODEF 0 "register_operand" "=x")
12885 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
12886 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
12887 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
12888 [(set_attr "type" "sse")
12889 (set_attr "atom_sse_attr" "sqrt")
12890 (set_attr "prefix" "maybe_vex")
12891 (set_attr "mode" "<MODE>")
12892 (set_attr "athlon_decode" "*")
12893 (set_attr "amdfam10_decode" "*")])
12895 (define_expand "sqrt<mode>2"
12896 [(set (match_operand:MODEF 0 "register_operand" "")
12898 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
12899 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
12900 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
12902 if (<MODE>mode == SFmode
12903 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
12904 && flag_finite_math_only && !flag_trapping_math
12905 && flag_unsafe_math_optimizations)
12907 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
12911 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
12913 rtx op0 = gen_reg_rtx (XFmode);
12914 rtx op1 = force_reg (<MODE>mode, operands[1]);
12916 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
12917 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
12922 (define_insn "fpremxf4_i387"
12923 [(set (match_operand:XF 0 "register_operand" "=f")
12924 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
12925 (match_operand:XF 3 "register_operand" "1")]
12927 (set (match_operand:XF 1 "register_operand" "=u")
12928 (unspec:XF [(match_dup 2) (match_dup 3)]
12930 (set (reg:CCFP FPSR_REG)
12931 (unspec:CCFP [(match_dup 2) (match_dup 3)]
12933 "TARGET_USE_FANCY_MATH_387"
12935 [(set_attr "type" "fpspc")
12936 (set_attr "mode" "XF")])
12938 (define_expand "fmodxf3"
12939 [(use (match_operand:XF 0 "register_operand" ""))
12940 (use (match_operand:XF 1 "general_operand" ""))
12941 (use (match_operand:XF 2 "general_operand" ""))]
12942 "TARGET_USE_FANCY_MATH_387"
12944 rtx label = gen_label_rtx ();
12946 rtx op1 = gen_reg_rtx (XFmode);
12947 rtx op2 = gen_reg_rtx (XFmode);
12949 emit_move_insn (op2, operands[2]);
12950 emit_move_insn (op1, operands[1]);
12952 emit_label (label);
12953 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
12954 ix86_emit_fp_unordered_jump (label);
12955 LABEL_NUSES (label) = 1;
12957 emit_move_insn (operands[0], op1);
12961 (define_expand "fmod<mode>3"
12962 [(use (match_operand:MODEF 0 "register_operand" ""))
12963 (use (match_operand:MODEF 1 "general_operand" ""))
12964 (use (match_operand:MODEF 2 "general_operand" ""))]
12965 "TARGET_USE_FANCY_MATH_387"
12967 rtx (*gen_truncxf) (rtx, rtx);
12969 rtx label = gen_label_rtx ();
12971 rtx op1 = gen_reg_rtx (XFmode);
12972 rtx op2 = gen_reg_rtx (XFmode);
12974 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
12975 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
12977 emit_label (label);
12978 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
12979 ix86_emit_fp_unordered_jump (label);
12980 LABEL_NUSES (label) = 1;
12982 /* Truncate the result properly for strict SSE math. */
12983 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12984 && !TARGET_MIX_SSE_I387)
12985 gen_truncxf = gen_truncxf<mode>2;
12987 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
12989 emit_insn (gen_truncxf (operands[0], op1));
12993 (define_insn "fprem1xf4_i387"
12994 [(set (match_operand:XF 0 "register_operand" "=f")
12995 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
12996 (match_operand:XF 3 "register_operand" "1")]
12998 (set (match_operand:XF 1 "register_operand" "=u")
12999 (unspec:XF [(match_dup 2) (match_dup 3)]
13001 (set (reg:CCFP FPSR_REG)
13002 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13004 "TARGET_USE_FANCY_MATH_387"
13006 [(set_attr "type" "fpspc")
13007 (set_attr "mode" "XF")])
13009 (define_expand "remainderxf3"
13010 [(use (match_operand:XF 0 "register_operand" ""))
13011 (use (match_operand:XF 1 "general_operand" ""))
13012 (use (match_operand:XF 2 "general_operand" ""))]
13013 "TARGET_USE_FANCY_MATH_387"
13015 rtx label = gen_label_rtx ();
13017 rtx op1 = gen_reg_rtx (XFmode);
13018 rtx op2 = gen_reg_rtx (XFmode);
13020 emit_move_insn (op2, operands[2]);
13021 emit_move_insn (op1, operands[1]);
13023 emit_label (label);
13024 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13025 ix86_emit_fp_unordered_jump (label);
13026 LABEL_NUSES (label) = 1;
13028 emit_move_insn (operands[0], op1);
13032 (define_expand "remainder<mode>3"
13033 [(use (match_operand:MODEF 0 "register_operand" ""))
13034 (use (match_operand:MODEF 1 "general_operand" ""))
13035 (use (match_operand:MODEF 2 "general_operand" ""))]
13036 "TARGET_USE_FANCY_MATH_387"
13038 rtx (*gen_truncxf) (rtx, rtx);
13040 rtx label = gen_label_rtx ();
13042 rtx op1 = gen_reg_rtx (XFmode);
13043 rtx op2 = gen_reg_rtx (XFmode);
13045 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13046 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13048 emit_label (label);
13050 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13051 ix86_emit_fp_unordered_jump (label);
13052 LABEL_NUSES (label) = 1;
13054 /* Truncate the result properly for strict SSE math. */
13055 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13056 && !TARGET_MIX_SSE_I387)
13057 gen_truncxf = gen_truncxf<mode>2;
13059 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13061 emit_insn (gen_truncxf (operands[0], op1));
13065 (define_insn "*sinxf2_i387"
13066 [(set (match_operand:XF 0 "register_operand" "=f")
13067 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13068 "TARGET_USE_FANCY_MATH_387
13069 && flag_unsafe_math_optimizations"
13071 [(set_attr "type" "fpspc")
13072 (set_attr "mode" "XF")])
13074 (define_insn "*sin_extend<mode>xf2_i387"
13075 [(set (match_operand:XF 0 "register_operand" "=f")
13076 (unspec:XF [(float_extend:XF
13077 (match_operand:MODEF 1 "register_operand" "0"))]
13079 "TARGET_USE_FANCY_MATH_387
13080 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13081 || TARGET_MIX_SSE_I387)
13082 && flag_unsafe_math_optimizations"
13084 [(set_attr "type" "fpspc")
13085 (set_attr "mode" "XF")])
13087 (define_insn "*cosxf2_i387"
13088 [(set (match_operand:XF 0 "register_operand" "=f")
13089 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13090 "TARGET_USE_FANCY_MATH_387
13091 && flag_unsafe_math_optimizations"
13093 [(set_attr "type" "fpspc")
13094 (set_attr "mode" "XF")])
13096 (define_insn "*cos_extend<mode>xf2_i387"
13097 [(set (match_operand:XF 0 "register_operand" "=f")
13098 (unspec:XF [(float_extend:XF
13099 (match_operand:MODEF 1 "register_operand" "0"))]
13101 "TARGET_USE_FANCY_MATH_387
13102 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13103 || TARGET_MIX_SSE_I387)
13104 && flag_unsafe_math_optimizations"
13106 [(set_attr "type" "fpspc")
13107 (set_attr "mode" "XF")])
13109 ;; When sincos pattern is defined, sin and cos builtin functions will be
13110 ;; expanded to sincos pattern with one of its outputs left unused.
13111 ;; CSE pass will figure out if two sincos patterns can be combined,
13112 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13113 ;; depending on the unused output.
13115 (define_insn "sincosxf3"
13116 [(set (match_operand:XF 0 "register_operand" "=f")
13117 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13118 UNSPEC_SINCOS_COS))
13119 (set (match_operand:XF 1 "register_operand" "=u")
13120 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13121 "TARGET_USE_FANCY_MATH_387
13122 && flag_unsafe_math_optimizations"
13124 [(set_attr "type" "fpspc")
13125 (set_attr "mode" "XF")])
13128 [(set (match_operand:XF 0 "register_operand" "")
13129 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13130 UNSPEC_SINCOS_COS))
13131 (set (match_operand:XF 1 "register_operand" "")
13132 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13133 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13134 && !(reload_completed || reload_in_progress)"
13135 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13138 [(set (match_operand:XF 0 "register_operand" "")
13139 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13140 UNSPEC_SINCOS_COS))
13141 (set (match_operand:XF 1 "register_operand" "")
13142 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13143 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13144 && !(reload_completed || reload_in_progress)"
13145 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13147 (define_insn "sincos_extend<mode>xf3_i387"
13148 [(set (match_operand:XF 0 "register_operand" "=f")
13149 (unspec:XF [(float_extend:XF
13150 (match_operand:MODEF 2 "register_operand" "0"))]
13151 UNSPEC_SINCOS_COS))
13152 (set (match_operand:XF 1 "register_operand" "=u")
13153 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13154 "TARGET_USE_FANCY_MATH_387
13155 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13156 || TARGET_MIX_SSE_I387)
13157 && flag_unsafe_math_optimizations"
13159 [(set_attr "type" "fpspc")
13160 (set_attr "mode" "XF")])
13163 [(set (match_operand:XF 0 "register_operand" "")
13164 (unspec:XF [(float_extend:XF
13165 (match_operand:MODEF 2 "register_operand" ""))]
13166 UNSPEC_SINCOS_COS))
13167 (set (match_operand:XF 1 "register_operand" "")
13168 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13169 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13170 && !(reload_completed || reload_in_progress)"
13171 [(set (match_dup 1)
13172 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13175 [(set (match_operand:XF 0 "register_operand" "")
13176 (unspec:XF [(float_extend:XF
13177 (match_operand:MODEF 2 "register_operand" ""))]
13178 UNSPEC_SINCOS_COS))
13179 (set (match_operand:XF 1 "register_operand" "")
13180 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13181 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13182 && !(reload_completed || reload_in_progress)"
13183 [(set (match_dup 0)
13184 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13186 (define_expand "sincos<mode>3"
13187 [(use (match_operand:MODEF 0 "register_operand" ""))
13188 (use (match_operand:MODEF 1 "register_operand" ""))
13189 (use (match_operand:MODEF 2 "register_operand" ""))]
13190 "TARGET_USE_FANCY_MATH_387
13191 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13192 || TARGET_MIX_SSE_I387)
13193 && flag_unsafe_math_optimizations"
13195 rtx op0 = gen_reg_rtx (XFmode);
13196 rtx op1 = gen_reg_rtx (XFmode);
13198 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13199 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13200 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13204 (define_insn "fptanxf4_i387"
13205 [(set (match_operand:XF 0 "register_operand" "=f")
13206 (match_operand:XF 3 "const_double_operand" "F"))
13207 (set (match_operand:XF 1 "register_operand" "=u")
13208 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13210 "TARGET_USE_FANCY_MATH_387
13211 && flag_unsafe_math_optimizations
13212 && standard_80387_constant_p (operands[3]) == 2"
13214 [(set_attr "type" "fpspc")
13215 (set_attr "mode" "XF")])
13217 (define_insn "fptan_extend<mode>xf4_i387"
13218 [(set (match_operand:MODEF 0 "register_operand" "=f")
13219 (match_operand:MODEF 3 "const_double_operand" "F"))
13220 (set (match_operand:XF 1 "register_operand" "=u")
13221 (unspec:XF [(float_extend:XF
13222 (match_operand:MODEF 2 "register_operand" "0"))]
13224 "TARGET_USE_FANCY_MATH_387
13225 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13226 || TARGET_MIX_SSE_I387)
13227 && flag_unsafe_math_optimizations
13228 && standard_80387_constant_p (operands[3]) == 2"
13230 [(set_attr "type" "fpspc")
13231 (set_attr "mode" "XF")])
13233 (define_expand "tanxf2"
13234 [(use (match_operand:XF 0 "register_operand" ""))
13235 (use (match_operand:XF 1 "register_operand" ""))]
13236 "TARGET_USE_FANCY_MATH_387
13237 && flag_unsafe_math_optimizations"
13239 rtx one = gen_reg_rtx (XFmode);
13240 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13242 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13246 (define_expand "tan<mode>2"
13247 [(use (match_operand:MODEF 0 "register_operand" ""))
13248 (use (match_operand:MODEF 1 "register_operand" ""))]
13249 "TARGET_USE_FANCY_MATH_387
13250 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13251 || TARGET_MIX_SSE_I387)
13252 && flag_unsafe_math_optimizations"
13254 rtx op0 = gen_reg_rtx (XFmode);
13256 rtx one = gen_reg_rtx (<MODE>mode);
13257 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13259 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13260 operands[1], op2));
13261 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13265 (define_insn "*fpatanxf3_i387"
13266 [(set (match_operand:XF 0 "register_operand" "=f")
13267 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13268 (match_operand:XF 2 "register_operand" "u")]
13270 (clobber (match_scratch:XF 3 "=2"))]
13271 "TARGET_USE_FANCY_MATH_387
13272 && flag_unsafe_math_optimizations"
13274 [(set_attr "type" "fpspc")
13275 (set_attr "mode" "XF")])
13277 (define_insn "fpatan_extend<mode>xf3_i387"
13278 [(set (match_operand:XF 0 "register_operand" "=f")
13279 (unspec:XF [(float_extend:XF
13280 (match_operand:MODEF 1 "register_operand" "0"))
13282 (match_operand:MODEF 2 "register_operand" "u"))]
13284 (clobber (match_scratch:XF 3 "=2"))]
13285 "TARGET_USE_FANCY_MATH_387
13286 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13287 || TARGET_MIX_SSE_I387)
13288 && flag_unsafe_math_optimizations"
13290 [(set_attr "type" "fpspc")
13291 (set_attr "mode" "XF")])
13293 (define_expand "atan2xf3"
13294 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13295 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13296 (match_operand:XF 1 "register_operand" "")]
13298 (clobber (match_scratch:XF 3 ""))])]
13299 "TARGET_USE_FANCY_MATH_387
13300 && flag_unsafe_math_optimizations")
13302 (define_expand "atan2<mode>3"
13303 [(use (match_operand:MODEF 0 "register_operand" ""))
13304 (use (match_operand:MODEF 1 "register_operand" ""))
13305 (use (match_operand:MODEF 2 "register_operand" ""))]
13306 "TARGET_USE_FANCY_MATH_387
13307 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13308 || TARGET_MIX_SSE_I387)
13309 && flag_unsafe_math_optimizations"
13311 rtx op0 = gen_reg_rtx (XFmode);
13313 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13314 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13318 (define_expand "atanxf2"
13319 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13320 (unspec:XF [(match_dup 2)
13321 (match_operand:XF 1 "register_operand" "")]
13323 (clobber (match_scratch:XF 3 ""))])]
13324 "TARGET_USE_FANCY_MATH_387
13325 && flag_unsafe_math_optimizations"
13327 operands[2] = gen_reg_rtx (XFmode);
13328 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13331 (define_expand "atan<mode>2"
13332 [(use (match_operand:MODEF 0 "register_operand" ""))
13333 (use (match_operand:MODEF 1 "register_operand" ""))]
13334 "TARGET_USE_FANCY_MATH_387
13335 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13336 || TARGET_MIX_SSE_I387)
13337 && flag_unsafe_math_optimizations"
13339 rtx op0 = gen_reg_rtx (XFmode);
13341 rtx op2 = gen_reg_rtx (<MODE>mode);
13342 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13344 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13345 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13349 (define_expand "asinxf2"
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 5) (match_dup 1)]
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 "asin<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_asinxf2 (op0, op1));
13389 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13393 (define_expand "acosxf2"
13394 [(set (match_dup 2)
13395 (mult:XF (match_operand:XF 1 "register_operand" "")
13397 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13398 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13399 (parallel [(set (match_operand:XF 0 "register_operand" "")
13400 (unspec:XF [(match_dup 1) (match_dup 5)]
13402 (clobber (match_scratch:XF 6 ""))])]
13403 "TARGET_USE_FANCY_MATH_387
13404 && flag_unsafe_math_optimizations"
13408 if (optimize_insn_for_size_p ())
13411 for (i = 2; i < 6; i++)
13412 operands[i] = gen_reg_rtx (XFmode);
13414 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13417 (define_expand "acos<mode>2"
13418 [(use (match_operand:MODEF 0 "register_operand" ""))
13419 (use (match_operand:MODEF 1 "general_operand" ""))]
13420 "TARGET_USE_FANCY_MATH_387
13421 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13422 || TARGET_MIX_SSE_I387)
13423 && flag_unsafe_math_optimizations"
13425 rtx op0 = gen_reg_rtx (XFmode);
13426 rtx op1 = gen_reg_rtx (XFmode);
13428 if (optimize_insn_for_size_p ())
13431 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13432 emit_insn (gen_acosxf2 (op0, op1));
13433 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13437 (define_insn "fyl2xxf3_i387"
13438 [(set (match_operand:XF 0 "register_operand" "=f")
13439 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13440 (match_operand:XF 2 "register_operand" "u")]
13442 (clobber (match_scratch:XF 3 "=2"))]
13443 "TARGET_USE_FANCY_MATH_387
13444 && flag_unsafe_math_optimizations"
13446 [(set_attr "type" "fpspc")
13447 (set_attr "mode" "XF")])
13449 (define_insn "fyl2x_extend<mode>xf3_i387"
13450 [(set (match_operand:XF 0 "register_operand" "=f")
13451 (unspec:XF [(float_extend:XF
13452 (match_operand:MODEF 1 "register_operand" "0"))
13453 (match_operand:XF 2 "register_operand" "u")]
13455 (clobber (match_scratch:XF 3 "=2"))]
13456 "TARGET_USE_FANCY_MATH_387
13457 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13458 || TARGET_MIX_SSE_I387)
13459 && flag_unsafe_math_optimizations"
13461 [(set_attr "type" "fpspc")
13462 (set_attr "mode" "XF")])
13464 (define_expand "logxf2"
13465 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13466 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13467 (match_dup 2)] UNSPEC_FYL2X))
13468 (clobber (match_scratch:XF 3 ""))])]
13469 "TARGET_USE_FANCY_MATH_387
13470 && flag_unsafe_math_optimizations"
13472 operands[2] = gen_reg_rtx (XFmode);
13473 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13476 (define_expand "log<mode>2"
13477 [(use (match_operand:MODEF 0 "register_operand" ""))
13478 (use (match_operand:MODEF 1 "register_operand" ""))]
13479 "TARGET_USE_FANCY_MATH_387
13480 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13481 || TARGET_MIX_SSE_I387)
13482 && flag_unsafe_math_optimizations"
13484 rtx op0 = gen_reg_rtx (XFmode);
13486 rtx op2 = gen_reg_rtx (XFmode);
13487 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13489 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13490 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13494 (define_expand "log10xf2"
13495 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13496 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13497 (match_dup 2)] UNSPEC_FYL2X))
13498 (clobber (match_scratch:XF 3 ""))])]
13499 "TARGET_USE_FANCY_MATH_387
13500 && flag_unsafe_math_optimizations"
13502 operands[2] = gen_reg_rtx (XFmode);
13503 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13506 (define_expand "log10<mode>2"
13507 [(use (match_operand:MODEF 0 "register_operand" ""))
13508 (use (match_operand:MODEF 1 "register_operand" ""))]
13509 "TARGET_USE_FANCY_MATH_387
13510 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13511 || TARGET_MIX_SSE_I387)
13512 && flag_unsafe_math_optimizations"
13514 rtx op0 = gen_reg_rtx (XFmode);
13516 rtx op2 = gen_reg_rtx (XFmode);
13517 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13519 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13520 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13524 (define_expand "log2xf2"
13525 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13526 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13527 (match_dup 2)] UNSPEC_FYL2X))
13528 (clobber (match_scratch:XF 3 ""))])]
13529 "TARGET_USE_FANCY_MATH_387
13530 && flag_unsafe_math_optimizations"
13532 operands[2] = gen_reg_rtx (XFmode);
13533 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13536 (define_expand "log2<mode>2"
13537 [(use (match_operand:MODEF 0 "register_operand" ""))
13538 (use (match_operand:MODEF 1 "register_operand" ""))]
13539 "TARGET_USE_FANCY_MATH_387
13540 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13541 || TARGET_MIX_SSE_I387)
13542 && flag_unsafe_math_optimizations"
13544 rtx op0 = gen_reg_rtx (XFmode);
13546 rtx op2 = gen_reg_rtx (XFmode);
13547 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13549 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13550 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13554 (define_insn "fyl2xp1xf3_i387"
13555 [(set (match_operand:XF 0 "register_operand" "=f")
13556 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13557 (match_operand:XF 2 "register_operand" "u")]
13559 (clobber (match_scratch:XF 3 "=2"))]
13560 "TARGET_USE_FANCY_MATH_387
13561 && flag_unsafe_math_optimizations"
13563 [(set_attr "type" "fpspc")
13564 (set_attr "mode" "XF")])
13566 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13567 [(set (match_operand:XF 0 "register_operand" "=f")
13568 (unspec:XF [(float_extend:XF
13569 (match_operand:MODEF 1 "register_operand" "0"))
13570 (match_operand:XF 2 "register_operand" "u")]
13572 (clobber (match_scratch:XF 3 "=2"))]
13573 "TARGET_USE_FANCY_MATH_387
13574 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13575 || TARGET_MIX_SSE_I387)
13576 && flag_unsafe_math_optimizations"
13578 [(set_attr "type" "fpspc")
13579 (set_attr "mode" "XF")])
13581 (define_expand "log1pxf2"
13582 [(use (match_operand:XF 0 "register_operand" ""))
13583 (use (match_operand:XF 1 "register_operand" ""))]
13584 "TARGET_USE_FANCY_MATH_387
13585 && flag_unsafe_math_optimizations"
13587 if (optimize_insn_for_size_p ())
13590 ix86_emit_i387_log1p (operands[0], operands[1]);
13594 (define_expand "log1p<mode>2"
13595 [(use (match_operand:MODEF 0 "register_operand" ""))
13596 (use (match_operand:MODEF 1 "register_operand" ""))]
13597 "TARGET_USE_FANCY_MATH_387
13598 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13599 || TARGET_MIX_SSE_I387)
13600 && flag_unsafe_math_optimizations"
13604 if (optimize_insn_for_size_p ())
13607 op0 = gen_reg_rtx (XFmode);
13609 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13611 ix86_emit_i387_log1p (op0, operands[1]);
13612 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13616 (define_insn "fxtractxf3_i387"
13617 [(set (match_operand:XF 0 "register_operand" "=f")
13618 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13619 UNSPEC_XTRACT_FRACT))
13620 (set (match_operand:XF 1 "register_operand" "=u")
13621 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13622 "TARGET_USE_FANCY_MATH_387
13623 && flag_unsafe_math_optimizations"
13625 [(set_attr "type" "fpspc")
13626 (set_attr "mode" "XF")])
13628 (define_insn "fxtract_extend<mode>xf3_i387"
13629 [(set (match_operand:XF 0 "register_operand" "=f")
13630 (unspec:XF [(float_extend:XF
13631 (match_operand:MODEF 2 "register_operand" "0"))]
13632 UNSPEC_XTRACT_FRACT))
13633 (set (match_operand:XF 1 "register_operand" "=u")
13634 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13635 "TARGET_USE_FANCY_MATH_387
13636 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13637 || TARGET_MIX_SSE_I387)
13638 && flag_unsafe_math_optimizations"
13640 [(set_attr "type" "fpspc")
13641 (set_attr "mode" "XF")])
13643 (define_expand "logbxf2"
13644 [(parallel [(set (match_dup 2)
13645 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13646 UNSPEC_XTRACT_FRACT))
13647 (set (match_operand:XF 0 "register_operand" "")
13648 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13649 "TARGET_USE_FANCY_MATH_387
13650 && flag_unsafe_math_optimizations"
13651 "operands[2] = gen_reg_rtx (XFmode);")
13653 (define_expand "logb<mode>2"
13654 [(use (match_operand:MODEF 0 "register_operand" ""))
13655 (use (match_operand:MODEF 1 "register_operand" ""))]
13656 "TARGET_USE_FANCY_MATH_387
13657 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13658 || TARGET_MIX_SSE_I387)
13659 && flag_unsafe_math_optimizations"
13661 rtx op0 = gen_reg_rtx (XFmode);
13662 rtx op1 = gen_reg_rtx (XFmode);
13664 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13665 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13669 (define_expand "ilogbxf2"
13670 [(use (match_operand:SI 0 "register_operand" ""))
13671 (use (match_operand:XF 1 "register_operand" ""))]
13672 "TARGET_USE_FANCY_MATH_387
13673 && flag_unsafe_math_optimizations"
13677 if (optimize_insn_for_size_p ())
13680 op0 = gen_reg_rtx (XFmode);
13681 op1 = gen_reg_rtx (XFmode);
13683 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13684 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13688 (define_expand "ilogb<mode>2"
13689 [(use (match_operand:SI 0 "register_operand" ""))
13690 (use (match_operand:MODEF 1 "register_operand" ""))]
13691 "TARGET_USE_FANCY_MATH_387
13692 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13693 || TARGET_MIX_SSE_I387)
13694 && flag_unsafe_math_optimizations"
13698 if (optimize_insn_for_size_p ())
13701 op0 = gen_reg_rtx (XFmode);
13702 op1 = gen_reg_rtx (XFmode);
13704 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13705 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13709 (define_insn "*f2xm1xf2_i387"
13710 [(set (match_operand:XF 0 "register_operand" "=f")
13711 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13713 "TARGET_USE_FANCY_MATH_387
13714 && flag_unsafe_math_optimizations"
13716 [(set_attr "type" "fpspc")
13717 (set_attr "mode" "XF")])
13719 (define_insn "*fscalexf4_i387"
13720 [(set (match_operand:XF 0 "register_operand" "=f")
13721 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13722 (match_operand:XF 3 "register_operand" "1")]
13723 UNSPEC_FSCALE_FRACT))
13724 (set (match_operand:XF 1 "register_operand" "=u")
13725 (unspec:XF [(match_dup 2) (match_dup 3)]
13726 UNSPEC_FSCALE_EXP))]
13727 "TARGET_USE_FANCY_MATH_387
13728 && flag_unsafe_math_optimizations"
13730 [(set_attr "type" "fpspc")
13731 (set_attr "mode" "XF")])
13733 (define_expand "expNcorexf3"
13734 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13735 (match_operand:XF 2 "register_operand" "")))
13736 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13737 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13738 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13739 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
13740 (parallel [(set (match_operand:XF 0 "register_operand" "")
13741 (unspec:XF [(match_dup 8) (match_dup 4)]
13742 UNSPEC_FSCALE_FRACT))
13744 (unspec:XF [(match_dup 8) (match_dup 4)]
13745 UNSPEC_FSCALE_EXP))])]
13746 "TARGET_USE_FANCY_MATH_387
13747 && flag_unsafe_math_optimizations"
13751 if (optimize_insn_for_size_p ())
13754 for (i = 3; i < 10; i++)
13755 operands[i] = gen_reg_rtx (XFmode);
13757 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
13760 (define_expand "expxf2"
13761 [(use (match_operand:XF 0 "register_operand" ""))
13762 (use (match_operand:XF 1 "register_operand" ""))]
13763 "TARGET_USE_FANCY_MATH_387
13764 && flag_unsafe_math_optimizations"
13768 if (optimize_insn_for_size_p ())
13771 op2 = gen_reg_rtx (XFmode);
13772 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
13774 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13778 (define_expand "exp<mode>2"
13779 [(use (match_operand:MODEF 0 "register_operand" ""))
13780 (use (match_operand:MODEF 1 "general_operand" ""))]
13781 "TARGET_USE_FANCY_MATH_387
13782 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13783 || TARGET_MIX_SSE_I387)
13784 && flag_unsafe_math_optimizations"
13788 if (optimize_insn_for_size_p ())
13791 op0 = gen_reg_rtx (XFmode);
13792 op1 = gen_reg_rtx (XFmode);
13794 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13795 emit_insn (gen_expxf2 (op0, op1));
13796 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13800 (define_expand "exp10xf2"
13801 [(use (match_operand:XF 0 "register_operand" ""))
13802 (use (match_operand:XF 1 "register_operand" ""))]
13803 "TARGET_USE_FANCY_MATH_387
13804 && flag_unsafe_math_optimizations"
13808 if (optimize_insn_for_size_p ())
13811 op2 = gen_reg_rtx (XFmode);
13812 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
13814 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13818 (define_expand "exp10<mode>2"
13819 [(use (match_operand:MODEF 0 "register_operand" ""))
13820 (use (match_operand:MODEF 1 "general_operand" ""))]
13821 "TARGET_USE_FANCY_MATH_387
13822 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13823 || TARGET_MIX_SSE_I387)
13824 && flag_unsafe_math_optimizations"
13828 if (optimize_insn_for_size_p ())
13831 op0 = gen_reg_rtx (XFmode);
13832 op1 = gen_reg_rtx (XFmode);
13834 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13835 emit_insn (gen_exp10xf2 (op0, op1));
13836 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13840 (define_expand "exp2xf2"
13841 [(use (match_operand:XF 0 "register_operand" ""))
13842 (use (match_operand:XF 1 "register_operand" ""))]
13843 "TARGET_USE_FANCY_MATH_387
13844 && flag_unsafe_math_optimizations"
13848 if (optimize_insn_for_size_p ())
13851 op2 = gen_reg_rtx (XFmode);
13852 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13854 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13858 (define_expand "exp2<mode>2"
13859 [(use (match_operand:MODEF 0 "register_operand" ""))
13860 (use (match_operand:MODEF 1 "general_operand" ""))]
13861 "TARGET_USE_FANCY_MATH_387
13862 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13863 || TARGET_MIX_SSE_I387)
13864 && flag_unsafe_math_optimizations"
13868 if (optimize_insn_for_size_p ())
13871 op0 = gen_reg_rtx (XFmode);
13872 op1 = gen_reg_rtx (XFmode);
13874 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13875 emit_insn (gen_exp2xf2 (op0, op1));
13876 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13880 (define_expand "expm1xf2"
13881 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13883 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13884 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13885 (set (match_dup 9) (float_extend:XF (match_dup 13)))
13886 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13887 (parallel [(set (match_dup 7)
13888 (unspec:XF [(match_dup 6) (match_dup 4)]
13889 UNSPEC_FSCALE_FRACT))
13891 (unspec:XF [(match_dup 6) (match_dup 4)]
13892 UNSPEC_FSCALE_EXP))])
13893 (parallel [(set (match_dup 10)
13894 (unspec:XF [(match_dup 9) (match_dup 8)]
13895 UNSPEC_FSCALE_FRACT))
13896 (set (match_dup 11)
13897 (unspec:XF [(match_dup 9) (match_dup 8)]
13898 UNSPEC_FSCALE_EXP))])
13899 (set (match_dup 12) (minus:XF (match_dup 10)
13900 (float_extend:XF (match_dup 13))))
13901 (set (match_operand:XF 0 "register_operand" "")
13902 (plus:XF (match_dup 12) (match_dup 7)))]
13903 "TARGET_USE_FANCY_MATH_387
13904 && flag_unsafe_math_optimizations"
13908 if (optimize_insn_for_size_p ())
13911 for (i = 2; i < 13; i++)
13912 operands[i] = gen_reg_rtx (XFmode);
13915 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
13917 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
13920 (define_expand "expm1<mode>2"
13921 [(use (match_operand:MODEF 0 "register_operand" ""))
13922 (use (match_operand:MODEF 1 "general_operand" ""))]
13923 "TARGET_USE_FANCY_MATH_387
13924 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13925 || TARGET_MIX_SSE_I387)
13926 && flag_unsafe_math_optimizations"
13930 if (optimize_insn_for_size_p ())
13933 op0 = gen_reg_rtx (XFmode);
13934 op1 = gen_reg_rtx (XFmode);
13936 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13937 emit_insn (gen_expm1xf2 (op0, op1));
13938 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13942 (define_expand "ldexpxf3"
13943 [(set (match_dup 3)
13944 (float:XF (match_operand:SI 2 "register_operand" "")))
13945 (parallel [(set (match_operand:XF 0 " register_operand" "")
13946 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13948 UNSPEC_FSCALE_FRACT))
13950 (unspec:XF [(match_dup 1) (match_dup 3)]
13951 UNSPEC_FSCALE_EXP))])]
13952 "TARGET_USE_FANCY_MATH_387
13953 && flag_unsafe_math_optimizations"
13955 if (optimize_insn_for_size_p ())
13958 operands[3] = gen_reg_rtx (XFmode);
13959 operands[4] = gen_reg_rtx (XFmode);
13962 (define_expand "ldexp<mode>3"
13963 [(use (match_operand:MODEF 0 "register_operand" ""))
13964 (use (match_operand:MODEF 1 "general_operand" ""))
13965 (use (match_operand:SI 2 "register_operand" ""))]
13966 "TARGET_USE_FANCY_MATH_387
13967 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13968 || TARGET_MIX_SSE_I387)
13969 && flag_unsafe_math_optimizations"
13973 if (optimize_insn_for_size_p ())
13976 op0 = gen_reg_rtx (XFmode);
13977 op1 = gen_reg_rtx (XFmode);
13979 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13980 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
13981 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13985 (define_expand "scalbxf3"
13986 [(parallel [(set (match_operand:XF 0 " register_operand" "")
13987 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13988 (match_operand:XF 2 "register_operand" "")]
13989 UNSPEC_FSCALE_FRACT))
13991 (unspec:XF [(match_dup 1) (match_dup 2)]
13992 UNSPEC_FSCALE_EXP))])]
13993 "TARGET_USE_FANCY_MATH_387
13994 && flag_unsafe_math_optimizations"
13996 if (optimize_insn_for_size_p ())
13999 operands[3] = gen_reg_rtx (XFmode);
14002 (define_expand "scalb<mode>3"
14003 [(use (match_operand:MODEF 0 "register_operand" ""))
14004 (use (match_operand:MODEF 1 "general_operand" ""))
14005 (use (match_operand:MODEF 2 "general_operand" ""))]
14006 "TARGET_USE_FANCY_MATH_387
14007 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14008 || TARGET_MIX_SSE_I387)
14009 && flag_unsafe_math_optimizations"
14013 if (optimize_insn_for_size_p ())
14016 op0 = gen_reg_rtx (XFmode);
14017 op1 = gen_reg_rtx (XFmode);
14018 op2 = gen_reg_rtx (XFmode);
14020 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14021 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14022 emit_insn (gen_scalbxf3 (op0, op1, op2));
14023 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14027 (define_expand "significandxf2"
14028 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14029 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14030 UNSPEC_XTRACT_FRACT))
14032 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14033 "TARGET_USE_FANCY_MATH_387
14034 && flag_unsafe_math_optimizations"
14035 "operands[2] = gen_reg_rtx (XFmode);")
14037 (define_expand "significand<mode>2"
14038 [(use (match_operand:MODEF 0 "register_operand" ""))
14039 (use (match_operand:MODEF 1 "register_operand" ""))]
14040 "TARGET_USE_FANCY_MATH_387
14041 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14042 || TARGET_MIX_SSE_I387)
14043 && flag_unsafe_math_optimizations"
14045 rtx op0 = gen_reg_rtx (XFmode);
14046 rtx op1 = gen_reg_rtx (XFmode);
14048 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14049 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14054 (define_insn "sse4_1_round<mode>2"
14055 [(set (match_operand:MODEF 0 "register_operand" "=x")
14056 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14057 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14060 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14061 [(set_attr "type" "ssecvt")
14062 (set_attr "prefix_extra" "1")
14063 (set_attr "prefix" "maybe_vex")
14064 (set_attr "mode" "<MODE>")])
14066 (define_insn "rintxf2"
14067 [(set (match_operand:XF 0 "register_operand" "=f")
14068 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14070 "TARGET_USE_FANCY_MATH_387
14071 && flag_unsafe_math_optimizations"
14073 [(set_attr "type" "fpspc")
14074 (set_attr "mode" "XF")])
14076 (define_expand "rint<mode>2"
14077 [(use (match_operand:MODEF 0 "register_operand" ""))
14078 (use (match_operand:MODEF 1 "register_operand" ""))]
14079 "(TARGET_USE_FANCY_MATH_387
14080 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14081 || TARGET_MIX_SSE_I387)
14082 && flag_unsafe_math_optimizations)
14083 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14084 && !flag_trapping_math)"
14086 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14087 && !flag_trapping_math)
14089 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14092 emit_insn (gen_sse4_1_round<mode>2
14093 (operands[0], operands[1], GEN_INT (0x04)));
14095 ix86_expand_rint (operand0, operand1);
14099 rtx op0 = gen_reg_rtx (XFmode);
14100 rtx op1 = gen_reg_rtx (XFmode);
14102 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14103 emit_insn (gen_rintxf2 (op0, op1));
14105 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14110 (define_expand "round<mode>2"
14111 [(match_operand:MODEF 0 "register_operand" "")
14112 (match_operand:MODEF 1 "nonimmediate_operand" "")]
14113 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14114 && !flag_trapping_math && !flag_rounding_math"
14116 if (optimize_insn_for_size_p ())
14118 if (TARGET_64BIT || (<MODE>mode != DFmode))
14119 ix86_expand_round (operand0, operand1);
14121 ix86_expand_rounddf_32 (operand0, operand1);
14125 (define_insn_and_split "*fistdi2_1"
14126 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14127 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14129 "TARGET_USE_FANCY_MATH_387
14130 && can_create_pseudo_p ()"
14135 if (memory_operand (operands[0], VOIDmode))
14136 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14139 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14140 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14145 [(set_attr "type" "fpspc")
14146 (set_attr "mode" "DI")])
14148 (define_insn "fistdi2"
14149 [(set (match_operand:DI 0 "memory_operand" "=m")
14150 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14152 (clobber (match_scratch:XF 2 "=&1f"))]
14153 "TARGET_USE_FANCY_MATH_387"
14154 "* return output_fix_trunc (insn, operands, 0);"
14155 [(set_attr "type" "fpspc")
14156 (set_attr "mode" "DI")])
14158 (define_insn "fistdi2_with_temp"
14159 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14160 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14162 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14163 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14164 "TARGET_USE_FANCY_MATH_387"
14166 [(set_attr "type" "fpspc")
14167 (set_attr "mode" "DI")])
14170 [(set (match_operand:DI 0 "register_operand" "")
14171 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14173 (clobber (match_operand:DI 2 "memory_operand" ""))
14174 (clobber (match_scratch 3 ""))]
14176 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14177 (clobber (match_dup 3))])
14178 (set (match_dup 0) (match_dup 2))])
14181 [(set (match_operand:DI 0 "memory_operand" "")
14182 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14184 (clobber (match_operand:DI 2 "memory_operand" ""))
14185 (clobber (match_scratch 3 ""))]
14187 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14188 (clobber (match_dup 3))])])
14190 (define_insn_and_split "*fist<mode>2_1"
14191 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14192 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14194 "TARGET_USE_FANCY_MATH_387
14195 && can_create_pseudo_p ()"
14200 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14201 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14205 [(set_attr "type" "fpspc")
14206 (set_attr "mode" "<MODE>")])
14208 (define_insn "fist<mode>2"
14209 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14210 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14212 "TARGET_USE_FANCY_MATH_387"
14213 "* return output_fix_trunc (insn, operands, 0);"
14214 [(set_attr "type" "fpspc")
14215 (set_attr "mode" "<MODE>")])
14217 (define_insn "fist<mode>2_with_temp"
14218 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14219 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14221 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14222 "TARGET_USE_FANCY_MATH_387"
14224 [(set_attr "type" "fpspc")
14225 (set_attr "mode" "<MODE>")])
14228 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14229 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14231 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14233 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14234 (set (match_dup 0) (match_dup 2))])
14237 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14238 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14240 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14242 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))])
14244 (define_expand "lrintxf<mode>2"
14245 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14246 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14248 "TARGET_USE_FANCY_MATH_387")
14250 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14251 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14252 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14253 UNSPEC_FIX_NOTRUNC))]
14254 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14255 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)")
14257 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14258 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14259 (match_operand:MODEF 1 "register_operand" "")]
14260 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14261 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14262 && !flag_trapping_math && !flag_rounding_math"
14264 if (optimize_insn_for_size_p ())
14266 ix86_expand_lround (operand0, operand1);
14270 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14271 (define_insn_and_split "frndintxf2_floor"
14272 [(set (match_operand:XF 0 "register_operand" "")
14273 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14274 UNSPEC_FRNDINT_FLOOR))
14275 (clobber (reg:CC FLAGS_REG))]
14276 "TARGET_USE_FANCY_MATH_387
14277 && flag_unsafe_math_optimizations
14278 && can_create_pseudo_p ()"
14283 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14285 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14286 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14288 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14289 operands[2], operands[3]));
14292 [(set_attr "type" "frndint")
14293 (set_attr "i387_cw" "floor")
14294 (set_attr "mode" "XF")])
14296 (define_insn "frndintxf2_floor_i387"
14297 [(set (match_operand:XF 0 "register_operand" "=f")
14298 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14299 UNSPEC_FRNDINT_FLOOR))
14300 (use (match_operand:HI 2 "memory_operand" "m"))
14301 (use (match_operand:HI 3 "memory_operand" "m"))]
14302 "TARGET_USE_FANCY_MATH_387
14303 && flag_unsafe_math_optimizations"
14304 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14305 [(set_attr "type" "frndint")
14306 (set_attr "i387_cw" "floor")
14307 (set_attr "mode" "XF")])
14309 (define_expand "floorxf2"
14310 [(use (match_operand:XF 0 "register_operand" ""))
14311 (use (match_operand:XF 1 "register_operand" ""))]
14312 "TARGET_USE_FANCY_MATH_387
14313 && flag_unsafe_math_optimizations"
14315 if (optimize_insn_for_size_p ())
14317 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14321 (define_expand "floor<mode>2"
14322 [(use (match_operand:MODEF 0 "register_operand" ""))
14323 (use (match_operand:MODEF 1 "register_operand" ""))]
14324 "(TARGET_USE_FANCY_MATH_387
14325 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14326 || TARGET_MIX_SSE_I387)
14327 && flag_unsafe_math_optimizations)
14328 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14329 && !flag_trapping_math)"
14331 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14332 && !flag_trapping_math
14333 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14335 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14338 emit_insn (gen_sse4_1_round<mode>2
14339 (operands[0], operands[1], GEN_INT (0x01)));
14340 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14341 ix86_expand_floorceil (operand0, operand1, true);
14343 ix86_expand_floorceildf_32 (operand0, operand1, true);
14349 if (optimize_insn_for_size_p ())
14352 op0 = gen_reg_rtx (XFmode);
14353 op1 = gen_reg_rtx (XFmode);
14354 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14355 emit_insn (gen_frndintxf2_floor (op0, op1));
14357 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14362 (define_insn_and_split "*fist<mode>2_floor_1"
14363 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14364 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14365 UNSPEC_FIST_FLOOR))
14366 (clobber (reg:CC FLAGS_REG))]
14367 "TARGET_USE_FANCY_MATH_387
14368 && flag_unsafe_math_optimizations
14369 && can_create_pseudo_p ()"
14374 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14376 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14377 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14378 if (memory_operand (operands[0], VOIDmode))
14379 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14380 operands[2], operands[3]));
14383 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14384 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14385 operands[2], operands[3],
14390 [(set_attr "type" "fistp")
14391 (set_attr "i387_cw" "floor")
14392 (set_attr "mode" "<MODE>")])
14394 (define_insn "fistdi2_floor"
14395 [(set (match_operand:DI 0 "memory_operand" "=m")
14396 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14397 UNSPEC_FIST_FLOOR))
14398 (use (match_operand:HI 2 "memory_operand" "m"))
14399 (use (match_operand:HI 3 "memory_operand" "m"))
14400 (clobber (match_scratch:XF 4 "=&1f"))]
14401 "TARGET_USE_FANCY_MATH_387
14402 && flag_unsafe_math_optimizations"
14403 "* return output_fix_trunc (insn, operands, 0);"
14404 [(set_attr "type" "fistp")
14405 (set_attr "i387_cw" "floor")
14406 (set_attr "mode" "DI")])
14408 (define_insn "fistdi2_floor_with_temp"
14409 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14410 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14411 UNSPEC_FIST_FLOOR))
14412 (use (match_operand:HI 2 "memory_operand" "m,m"))
14413 (use (match_operand:HI 3 "memory_operand" "m,m"))
14414 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14415 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14416 "TARGET_USE_FANCY_MATH_387
14417 && flag_unsafe_math_optimizations"
14419 [(set_attr "type" "fistp")
14420 (set_attr "i387_cw" "floor")
14421 (set_attr "mode" "DI")])
14424 [(set (match_operand:DI 0 "register_operand" "")
14425 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14426 UNSPEC_FIST_FLOOR))
14427 (use (match_operand:HI 2 "memory_operand" ""))
14428 (use (match_operand:HI 3 "memory_operand" ""))
14429 (clobber (match_operand:DI 4 "memory_operand" ""))
14430 (clobber (match_scratch 5 ""))]
14432 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14433 (use (match_dup 2))
14434 (use (match_dup 3))
14435 (clobber (match_dup 5))])
14436 (set (match_dup 0) (match_dup 4))])
14439 [(set (match_operand:DI 0 "memory_operand" "")
14440 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14441 UNSPEC_FIST_FLOOR))
14442 (use (match_operand:HI 2 "memory_operand" ""))
14443 (use (match_operand:HI 3 "memory_operand" ""))
14444 (clobber (match_operand:DI 4 "memory_operand" ""))
14445 (clobber (match_scratch 5 ""))]
14447 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14448 (use (match_dup 2))
14449 (use (match_dup 3))
14450 (clobber (match_dup 5))])])
14452 (define_insn "fist<mode>2_floor"
14453 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14454 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14455 UNSPEC_FIST_FLOOR))
14456 (use (match_operand:HI 2 "memory_operand" "m"))
14457 (use (match_operand:HI 3 "memory_operand" "m"))]
14458 "TARGET_USE_FANCY_MATH_387
14459 && flag_unsafe_math_optimizations"
14460 "* return output_fix_trunc (insn, operands, 0);"
14461 [(set_attr "type" "fistp")
14462 (set_attr "i387_cw" "floor")
14463 (set_attr "mode" "<MODE>")])
14465 (define_insn "fist<mode>2_floor_with_temp"
14466 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14467 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14468 UNSPEC_FIST_FLOOR))
14469 (use (match_operand:HI 2 "memory_operand" "m,m"))
14470 (use (match_operand:HI 3 "memory_operand" "m,m"))
14471 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14472 "TARGET_USE_FANCY_MATH_387
14473 && flag_unsafe_math_optimizations"
14475 [(set_attr "type" "fistp")
14476 (set_attr "i387_cw" "floor")
14477 (set_attr "mode" "<MODE>")])
14480 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14481 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14482 UNSPEC_FIST_FLOOR))
14483 (use (match_operand:HI 2 "memory_operand" ""))
14484 (use (match_operand:HI 3 "memory_operand" ""))
14485 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14487 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14488 UNSPEC_FIST_FLOOR))
14489 (use (match_dup 2))
14490 (use (match_dup 3))])
14491 (set (match_dup 0) (match_dup 4))])
14494 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14495 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14496 UNSPEC_FIST_FLOOR))
14497 (use (match_operand:HI 2 "memory_operand" ""))
14498 (use (match_operand:HI 3 "memory_operand" ""))
14499 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14501 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14502 UNSPEC_FIST_FLOOR))
14503 (use (match_dup 2))
14504 (use (match_dup 3))])])
14506 (define_expand "lfloorxf<mode>2"
14507 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14508 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14509 UNSPEC_FIST_FLOOR))
14510 (clobber (reg:CC FLAGS_REG))])]
14511 "TARGET_USE_FANCY_MATH_387
14512 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14513 && flag_unsafe_math_optimizations")
14515 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14516 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14517 (match_operand:MODEF 1 "register_operand" "")]
14518 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14519 && !flag_trapping_math"
14521 if (TARGET_64BIT && optimize_insn_for_size_p ())
14523 ix86_expand_lfloorceil (operand0, operand1, true);
14527 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14528 (define_insn_and_split "frndintxf2_ceil"
14529 [(set (match_operand:XF 0 "register_operand" "")
14530 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14531 UNSPEC_FRNDINT_CEIL))
14532 (clobber (reg:CC FLAGS_REG))]
14533 "TARGET_USE_FANCY_MATH_387
14534 && flag_unsafe_math_optimizations
14535 && can_create_pseudo_p ()"
14540 ix86_optimize_mode_switching[I387_CEIL] = 1;
14542 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14543 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14545 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14546 operands[2], operands[3]));
14549 [(set_attr "type" "frndint")
14550 (set_attr "i387_cw" "ceil")
14551 (set_attr "mode" "XF")])
14553 (define_insn "frndintxf2_ceil_i387"
14554 [(set (match_operand:XF 0 "register_operand" "=f")
14555 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14556 UNSPEC_FRNDINT_CEIL))
14557 (use (match_operand:HI 2 "memory_operand" "m"))
14558 (use (match_operand:HI 3 "memory_operand" "m"))]
14559 "TARGET_USE_FANCY_MATH_387
14560 && flag_unsafe_math_optimizations"
14561 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14562 [(set_attr "type" "frndint")
14563 (set_attr "i387_cw" "ceil")
14564 (set_attr "mode" "XF")])
14566 (define_expand "ceilxf2"
14567 [(use (match_operand:XF 0 "register_operand" ""))
14568 (use (match_operand:XF 1 "register_operand" ""))]
14569 "TARGET_USE_FANCY_MATH_387
14570 && flag_unsafe_math_optimizations"
14572 if (optimize_insn_for_size_p ())
14574 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
14578 (define_expand "ceil<mode>2"
14579 [(use (match_operand:MODEF 0 "register_operand" ""))
14580 (use (match_operand:MODEF 1 "register_operand" ""))]
14581 "(TARGET_USE_FANCY_MATH_387
14582 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14583 || TARGET_MIX_SSE_I387)
14584 && flag_unsafe_math_optimizations)
14585 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14586 && !flag_trapping_math)"
14588 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14589 && !flag_trapping_math
14590 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14593 emit_insn (gen_sse4_1_round<mode>2
14594 (operands[0], operands[1], GEN_INT (0x02)));
14595 else if (optimize_insn_for_size_p ())
14597 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14598 ix86_expand_floorceil (operand0, operand1, false);
14600 ix86_expand_floorceildf_32 (operand0, operand1, false);
14606 if (optimize_insn_for_size_p ())
14609 op0 = gen_reg_rtx (XFmode);
14610 op1 = gen_reg_rtx (XFmode);
14611 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14612 emit_insn (gen_frndintxf2_ceil (op0, op1));
14614 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14619 (define_insn_and_split "*fist<mode>2_ceil_1"
14620 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14621 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14623 (clobber (reg:CC FLAGS_REG))]
14624 "TARGET_USE_FANCY_MATH_387
14625 && flag_unsafe_math_optimizations
14626 && can_create_pseudo_p ()"
14631 ix86_optimize_mode_switching[I387_CEIL] = 1;
14633 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14634 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14635 if (memory_operand (operands[0], VOIDmode))
14636 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
14637 operands[2], operands[3]));
14640 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14641 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
14642 operands[2], operands[3],
14647 [(set_attr "type" "fistp")
14648 (set_attr "i387_cw" "ceil")
14649 (set_attr "mode" "<MODE>")])
14651 (define_insn "fistdi2_ceil"
14652 [(set (match_operand:DI 0 "memory_operand" "=m")
14653 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14655 (use (match_operand:HI 2 "memory_operand" "m"))
14656 (use (match_operand:HI 3 "memory_operand" "m"))
14657 (clobber (match_scratch:XF 4 "=&1f"))]
14658 "TARGET_USE_FANCY_MATH_387
14659 && flag_unsafe_math_optimizations"
14660 "* return output_fix_trunc (insn, operands, 0);"
14661 [(set_attr "type" "fistp")
14662 (set_attr "i387_cw" "ceil")
14663 (set_attr "mode" "DI")])
14665 (define_insn "fistdi2_ceil_with_temp"
14666 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14667 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14669 (use (match_operand:HI 2 "memory_operand" "m,m"))
14670 (use (match_operand:HI 3 "memory_operand" "m,m"))
14671 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14672 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14673 "TARGET_USE_FANCY_MATH_387
14674 && flag_unsafe_math_optimizations"
14676 [(set_attr "type" "fistp")
14677 (set_attr "i387_cw" "ceil")
14678 (set_attr "mode" "DI")])
14681 [(set (match_operand:DI 0 "register_operand" "")
14682 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14684 (use (match_operand:HI 2 "memory_operand" ""))
14685 (use (match_operand:HI 3 "memory_operand" ""))
14686 (clobber (match_operand:DI 4 "memory_operand" ""))
14687 (clobber (match_scratch 5 ""))]
14689 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14690 (use (match_dup 2))
14691 (use (match_dup 3))
14692 (clobber (match_dup 5))])
14693 (set (match_dup 0) (match_dup 4))])
14696 [(set (match_operand:DI 0 "memory_operand" "")
14697 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14699 (use (match_operand:HI 2 "memory_operand" ""))
14700 (use (match_operand:HI 3 "memory_operand" ""))
14701 (clobber (match_operand:DI 4 "memory_operand" ""))
14702 (clobber (match_scratch 5 ""))]
14704 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14705 (use (match_dup 2))
14706 (use (match_dup 3))
14707 (clobber (match_dup 5))])])
14709 (define_insn "fist<mode>2_ceil"
14710 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14711 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14713 (use (match_operand:HI 2 "memory_operand" "m"))
14714 (use (match_operand:HI 3 "memory_operand" "m"))]
14715 "TARGET_USE_FANCY_MATH_387
14716 && flag_unsafe_math_optimizations"
14717 "* return output_fix_trunc (insn, operands, 0);"
14718 [(set_attr "type" "fistp")
14719 (set_attr "i387_cw" "ceil")
14720 (set_attr "mode" "<MODE>")])
14722 (define_insn "fist<mode>2_ceil_with_temp"
14723 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14724 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14726 (use (match_operand:HI 2 "memory_operand" "m,m"))
14727 (use (match_operand:HI 3 "memory_operand" "m,m"))
14728 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14729 "TARGET_USE_FANCY_MATH_387
14730 && flag_unsafe_math_optimizations"
14732 [(set_attr "type" "fistp")
14733 (set_attr "i387_cw" "ceil")
14734 (set_attr "mode" "<MODE>")])
14737 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14738 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14740 (use (match_operand:HI 2 "memory_operand" ""))
14741 (use (match_operand:HI 3 "memory_operand" ""))
14742 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14744 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14746 (use (match_dup 2))
14747 (use (match_dup 3))])
14748 (set (match_dup 0) (match_dup 4))])
14751 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14752 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14754 (use (match_operand:HI 2 "memory_operand" ""))
14755 (use (match_operand:HI 3 "memory_operand" ""))
14756 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14758 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14760 (use (match_dup 2))
14761 (use (match_dup 3))])])
14763 (define_expand "lceilxf<mode>2"
14764 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14765 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14767 (clobber (reg:CC FLAGS_REG))])]
14768 "TARGET_USE_FANCY_MATH_387
14769 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14770 && flag_unsafe_math_optimizations")
14772 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
14773 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14774 (match_operand:MODEF 1 "register_operand" "")]
14775 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14776 && !flag_trapping_math"
14778 ix86_expand_lfloorceil (operand0, operand1, false);
14782 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14783 (define_insn_and_split "frndintxf2_trunc"
14784 [(set (match_operand:XF 0 "register_operand" "")
14785 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14786 UNSPEC_FRNDINT_TRUNC))
14787 (clobber (reg:CC FLAGS_REG))]
14788 "TARGET_USE_FANCY_MATH_387
14789 && flag_unsafe_math_optimizations
14790 && can_create_pseudo_p ()"
14795 ix86_optimize_mode_switching[I387_TRUNC] = 1;
14797 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14798 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
14800 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
14801 operands[2], operands[3]));
14804 [(set_attr "type" "frndint")
14805 (set_attr "i387_cw" "trunc")
14806 (set_attr "mode" "XF")])
14808 (define_insn "frndintxf2_trunc_i387"
14809 [(set (match_operand:XF 0 "register_operand" "=f")
14810 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14811 UNSPEC_FRNDINT_TRUNC))
14812 (use (match_operand:HI 2 "memory_operand" "m"))
14813 (use (match_operand:HI 3 "memory_operand" "m"))]
14814 "TARGET_USE_FANCY_MATH_387
14815 && flag_unsafe_math_optimizations"
14816 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14817 [(set_attr "type" "frndint")
14818 (set_attr "i387_cw" "trunc")
14819 (set_attr "mode" "XF")])
14821 (define_expand "btruncxf2"
14822 [(use (match_operand:XF 0 "register_operand" ""))
14823 (use (match_operand:XF 1 "register_operand" ""))]
14824 "TARGET_USE_FANCY_MATH_387
14825 && flag_unsafe_math_optimizations"
14827 if (optimize_insn_for_size_p ())
14829 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
14833 (define_expand "btrunc<mode>2"
14834 [(use (match_operand:MODEF 0 "register_operand" ""))
14835 (use (match_operand:MODEF 1 "register_operand" ""))]
14836 "(TARGET_USE_FANCY_MATH_387
14837 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14838 || TARGET_MIX_SSE_I387)
14839 && flag_unsafe_math_optimizations)
14840 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14841 && !flag_trapping_math)"
14843 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14844 && !flag_trapping_math
14845 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14848 emit_insn (gen_sse4_1_round<mode>2
14849 (operands[0], operands[1], GEN_INT (0x03)));
14850 else if (optimize_insn_for_size_p ())
14852 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14853 ix86_expand_trunc (operand0, operand1);
14855 ix86_expand_truncdf_32 (operand0, operand1);
14861 if (optimize_insn_for_size_p ())
14864 op0 = gen_reg_rtx (XFmode);
14865 op1 = gen_reg_rtx (XFmode);
14866 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14867 emit_insn (gen_frndintxf2_trunc (op0, op1));
14869 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14874 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14875 (define_insn_and_split "frndintxf2_mask_pm"
14876 [(set (match_operand:XF 0 "register_operand" "")
14877 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14878 UNSPEC_FRNDINT_MASK_PM))
14879 (clobber (reg:CC FLAGS_REG))]
14880 "TARGET_USE_FANCY_MATH_387
14881 && flag_unsafe_math_optimizations
14882 && can_create_pseudo_p ()"
14887 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
14889 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14890 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
14892 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
14893 operands[2], operands[3]));
14896 [(set_attr "type" "frndint")
14897 (set_attr "i387_cw" "mask_pm")
14898 (set_attr "mode" "XF")])
14900 (define_insn "frndintxf2_mask_pm_i387"
14901 [(set (match_operand:XF 0 "register_operand" "=f")
14902 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14903 UNSPEC_FRNDINT_MASK_PM))
14904 (use (match_operand:HI 2 "memory_operand" "m"))
14905 (use (match_operand:HI 3 "memory_operand" "m"))]
14906 "TARGET_USE_FANCY_MATH_387
14907 && flag_unsafe_math_optimizations"
14908 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
14909 [(set_attr "type" "frndint")
14910 (set_attr "i387_cw" "mask_pm")
14911 (set_attr "mode" "XF")])
14913 (define_expand "nearbyintxf2"
14914 [(use (match_operand:XF 0 "register_operand" ""))
14915 (use (match_operand:XF 1 "register_operand" ""))]
14916 "TARGET_USE_FANCY_MATH_387
14917 && flag_unsafe_math_optimizations"
14919 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
14923 (define_expand "nearbyint<mode>2"
14924 [(use (match_operand:MODEF 0 "register_operand" ""))
14925 (use (match_operand:MODEF 1 "register_operand" ""))]
14926 "TARGET_USE_FANCY_MATH_387
14927 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14928 || TARGET_MIX_SSE_I387)
14929 && flag_unsafe_math_optimizations"
14931 rtx op0 = gen_reg_rtx (XFmode);
14932 rtx op1 = gen_reg_rtx (XFmode);
14934 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14935 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
14937 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14941 (define_insn "fxam<mode>2_i387"
14942 [(set (match_operand:HI 0 "register_operand" "=a")
14944 [(match_operand:X87MODEF 1 "register_operand" "f")]
14946 "TARGET_USE_FANCY_MATH_387"
14947 "fxam\n\tfnstsw\t%0"
14948 [(set_attr "type" "multi")
14949 (set_attr "length" "4")
14950 (set_attr "unit" "i387")
14951 (set_attr "mode" "<MODE>")])
14953 (define_insn_and_split "fxam<mode>2_i387_with_temp"
14954 [(set (match_operand:HI 0 "register_operand" "")
14956 [(match_operand:MODEF 1 "memory_operand" "")]
14958 "TARGET_USE_FANCY_MATH_387
14959 && can_create_pseudo_p ()"
14962 [(set (match_dup 2)(match_dup 1))
14964 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
14966 operands[2] = gen_reg_rtx (<MODE>mode);
14968 MEM_VOLATILE_P (operands[1]) = 1;
14970 [(set_attr "type" "multi")
14971 (set_attr "unit" "i387")
14972 (set_attr "mode" "<MODE>")])
14974 (define_expand "isinfxf2"
14975 [(use (match_operand:SI 0 "register_operand" ""))
14976 (use (match_operand:XF 1 "register_operand" ""))]
14977 "TARGET_USE_FANCY_MATH_387
14978 && TARGET_C99_FUNCTIONS"
14980 rtx mask = GEN_INT (0x45);
14981 rtx val = GEN_INT (0x05);
14985 rtx scratch = gen_reg_rtx (HImode);
14986 rtx res = gen_reg_rtx (QImode);
14988 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
14990 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
14991 emit_insn (gen_cmpqi_ext_3 (scratch, val));
14992 cond = gen_rtx_fmt_ee (EQ, QImode,
14993 gen_rtx_REG (CCmode, FLAGS_REG),
14995 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
14996 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15000 (define_expand "isinf<mode>2"
15001 [(use (match_operand:SI 0 "register_operand" ""))
15002 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15003 "TARGET_USE_FANCY_MATH_387
15004 && TARGET_C99_FUNCTIONS
15005 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15007 rtx mask = GEN_INT (0x45);
15008 rtx val = GEN_INT (0x05);
15012 rtx scratch = gen_reg_rtx (HImode);
15013 rtx res = gen_reg_rtx (QImode);
15015 /* Remove excess precision by forcing value through memory. */
15016 if (memory_operand (operands[1], VOIDmode))
15017 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15020 enum ix86_stack_slot slot = (virtuals_instantiated
15023 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15025 emit_move_insn (temp, operands[1]);
15026 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15029 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15030 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15031 cond = gen_rtx_fmt_ee (EQ, QImode,
15032 gen_rtx_REG (CCmode, FLAGS_REG),
15034 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15035 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15039 (define_expand "signbitxf2"
15040 [(use (match_operand:SI 0 "register_operand" ""))
15041 (use (match_operand:XF 1 "register_operand" ""))]
15042 "TARGET_USE_FANCY_MATH_387"
15044 rtx scratch = gen_reg_rtx (HImode);
15046 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15047 emit_insn (gen_andsi3 (operands[0],
15048 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15052 (define_insn "movmsk_df"
15053 [(set (match_operand:SI 0 "register_operand" "=r")
15055 [(match_operand:DF 1 "register_operand" "x")]
15057 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15058 "%vmovmskpd\t{%1, %0|%0, %1}"
15059 [(set_attr "type" "ssemov")
15060 (set_attr "prefix" "maybe_vex")
15061 (set_attr "mode" "DF")])
15063 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15064 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15065 (define_expand "signbitdf2"
15066 [(use (match_operand:SI 0 "register_operand" ""))
15067 (use (match_operand:DF 1 "register_operand" ""))]
15068 "TARGET_USE_FANCY_MATH_387
15069 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15071 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15073 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15074 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15078 rtx scratch = gen_reg_rtx (HImode);
15080 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15081 emit_insn (gen_andsi3 (operands[0],
15082 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15087 (define_expand "signbitsf2"
15088 [(use (match_operand:SI 0 "register_operand" ""))
15089 (use (match_operand:SF 1 "register_operand" ""))]
15090 "TARGET_USE_FANCY_MATH_387
15091 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15093 rtx scratch = gen_reg_rtx (HImode);
15095 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15096 emit_insn (gen_andsi3 (operands[0],
15097 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15101 ;; Block operation instructions
15104 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15107 [(set_attr "length" "1")
15108 (set_attr "length_immediate" "0")
15109 (set_attr "modrm" "0")])
15111 (define_expand "movmemsi"
15112 [(use (match_operand:BLK 0 "memory_operand" ""))
15113 (use (match_operand:BLK 1 "memory_operand" ""))
15114 (use (match_operand:SI 2 "nonmemory_operand" ""))
15115 (use (match_operand:SI 3 "const_int_operand" ""))
15116 (use (match_operand:SI 4 "const_int_operand" ""))
15117 (use (match_operand:SI 5 "const_int_operand" ""))]
15120 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15121 operands[4], operands[5]))
15127 (define_expand "movmemdi"
15128 [(use (match_operand:BLK 0 "memory_operand" ""))
15129 (use (match_operand:BLK 1 "memory_operand" ""))
15130 (use (match_operand:DI 2 "nonmemory_operand" ""))
15131 (use (match_operand:DI 3 "const_int_operand" ""))
15132 (use (match_operand:SI 4 "const_int_operand" ""))
15133 (use (match_operand:SI 5 "const_int_operand" ""))]
15136 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15137 operands[4], operands[5]))
15143 ;; Most CPUs don't like single string operations
15144 ;; Handle this case here to simplify previous expander.
15146 (define_expand "strmov"
15147 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15148 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15149 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15150 (clobber (reg:CC FLAGS_REG))])
15151 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15152 (clobber (reg:CC FLAGS_REG))])]
15155 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15157 /* If .md ever supports :P for Pmode, these can be directly
15158 in the pattern above. */
15159 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15160 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15162 /* Can't use this if the user has appropriated esi or edi. */
15163 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15164 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15166 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15167 operands[2], operands[3],
15168 operands[5], operands[6]));
15172 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15175 (define_expand "strmov_singleop"
15176 [(parallel [(set (match_operand 1 "memory_operand" "")
15177 (match_operand 3 "memory_operand" ""))
15178 (set (match_operand 0 "register_operand" "")
15179 (match_operand 4 "" ""))
15180 (set (match_operand 2 "register_operand" "")
15181 (match_operand 5 "" ""))])]
15183 "ix86_current_function_needs_cld = 1;")
15185 (define_insn "*strmovdi_rex_1"
15186 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15187 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15188 (set (match_operand:DI 0 "register_operand" "=D")
15189 (plus:DI (match_dup 2)
15191 (set (match_operand:DI 1 "register_operand" "=S")
15192 (plus:DI (match_dup 3)
15196 [(set_attr "type" "str")
15197 (set_attr "mode" "DI")
15198 (set_attr "memory" "both")])
15200 (define_insn "*strmovsi_1"
15201 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
15202 (mem:SI (match_operand:SI 3 "register_operand" "1")))
15203 (set (match_operand:SI 0 "register_operand" "=D")
15204 (plus:SI (match_dup 2)
15206 (set (match_operand:SI 1 "register_operand" "=S")
15207 (plus:SI (match_dup 3)
15211 [(set_attr "type" "str")
15212 (set_attr "mode" "SI")
15213 (set_attr "memory" "both")])
15215 (define_insn "*strmovsi_rex_1"
15216 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
15217 (mem:SI (match_operand:DI 3 "register_operand" "1")))
15218 (set (match_operand:DI 0 "register_operand" "=D")
15219 (plus:DI (match_dup 2)
15221 (set (match_operand:DI 1 "register_operand" "=S")
15222 (plus:DI (match_dup 3)
15226 [(set_attr "type" "str")
15227 (set_attr "mode" "SI")
15228 (set_attr "memory" "both")])
15230 (define_insn "*strmovhi_1"
15231 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
15232 (mem:HI (match_operand:SI 3 "register_operand" "1")))
15233 (set (match_operand:SI 0 "register_operand" "=D")
15234 (plus:SI (match_dup 2)
15236 (set (match_operand:SI 1 "register_operand" "=S")
15237 (plus:SI (match_dup 3)
15241 [(set_attr "type" "str")
15242 (set_attr "memory" "both")
15243 (set_attr "mode" "HI")])
15245 (define_insn "*strmovhi_rex_1"
15246 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
15247 (mem:HI (match_operand:DI 3 "register_operand" "1")))
15248 (set (match_operand:DI 0 "register_operand" "=D")
15249 (plus:DI (match_dup 2)
15251 (set (match_operand:DI 1 "register_operand" "=S")
15252 (plus:DI (match_dup 3)
15256 [(set_attr "type" "str")
15257 (set_attr "memory" "both")
15258 (set_attr "mode" "HI")])
15260 (define_insn "*strmovqi_1"
15261 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
15262 (mem:QI (match_operand:SI 3 "register_operand" "1")))
15263 (set (match_operand:SI 0 "register_operand" "=D")
15264 (plus:SI (match_dup 2)
15266 (set (match_operand:SI 1 "register_operand" "=S")
15267 (plus:SI (match_dup 3)
15271 [(set_attr "type" "str")
15272 (set_attr "memory" "both")
15273 (set_attr "mode" "QI")])
15275 (define_insn "*strmovqi_rex_1"
15276 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
15277 (mem:QI (match_operand:DI 3 "register_operand" "1")))
15278 (set (match_operand:DI 0 "register_operand" "=D")
15279 (plus:DI (match_dup 2)
15281 (set (match_operand:DI 1 "register_operand" "=S")
15282 (plus:DI (match_dup 3)
15286 [(set_attr "type" "str")
15287 (set_attr "memory" "both")
15288 (set_attr "prefix_rex" "0")
15289 (set_attr "mode" "QI")])
15291 (define_expand "rep_mov"
15292 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15293 (set (match_operand 0 "register_operand" "")
15294 (match_operand 5 "" ""))
15295 (set (match_operand 2 "register_operand" "")
15296 (match_operand 6 "" ""))
15297 (set (match_operand 1 "memory_operand" "")
15298 (match_operand 3 "memory_operand" ""))
15299 (use (match_dup 4))])]
15301 "ix86_current_function_needs_cld = 1;")
15303 (define_insn "*rep_movdi_rex64"
15304 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15305 (set (match_operand:DI 0 "register_operand" "=D")
15306 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15308 (match_operand:DI 3 "register_operand" "0")))
15309 (set (match_operand:DI 1 "register_operand" "=S")
15310 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15311 (match_operand:DI 4 "register_operand" "1")))
15312 (set (mem:BLK (match_dup 3))
15313 (mem:BLK (match_dup 4)))
15314 (use (match_dup 5))]
15317 [(set_attr "type" "str")
15318 (set_attr "prefix_rep" "1")
15319 (set_attr "memory" "both")
15320 (set_attr "mode" "DI")])
15322 (define_insn "*rep_movsi"
15323 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15324 (set (match_operand:SI 0 "register_operand" "=D")
15325 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
15327 (match_operand:SI 3 "register_operand" "0")))
15328 (set (match_operand:SI 1 "register_operand" "=S")
15329 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
15330 (match_operand:SI 4 "register_operand" "1")))
15331 (set (mem:BLK (match_dup 3))
15332 (mem:BLK (match_dup 4)))
15333 (use (match_dup 5))]
15335 "rep{%;} movs{l|d}"
15336 [(set_attr "type" "str")
15337 (set_attr "prefix_rep" "1")
15338 (set_attr "memory" "both")
15339 (set_attr "mode" "SI")])
15341 (define_insn "*rep_movsi_rex64"
15342 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15343 (set (match_operand:DI 0 "register_operand" "=D")
15344 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15346 (match_operand:DI 3 "register_operand" "0")))
15347 (set (match_operand:DI 1 "register_operand" "=S")
15348 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
15349 (match_operand:DI 4 "register_operand" "1")))
15350 (set (mem:BLK (match_dup 3))
15351 (mem:BLK (match_dup 4)))
15352 (use (match_dup 5))]
15354 "rep{%;} movs{l|d}"
15355 [(set_attr "type" "str")
15356 (set_attr "prefix_rep" "1")
15357 (set_attr "memory" "both")
15358 (set_attr "mode" "SI")])
15360 (define_insn "*rep_movqi"
15361 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15362 (set (match_operand:SI 0 "register_operand" "=D")
15363 (plus:SI (match_operand:SI 3 "register_operand" "0")
15364 (match_operand:SI 5 "register_operand" "2")))
15365 (set (match_operand:SI 1 "register_operand" "=S")
15366 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
15367 (set (mem:BLK (match_dup 3))
15368 (mem:BLK (match_dup 4)))
15369 (use (match_dup 5))]
15372 [(set_attr "type" "str")
15373 (set_attr "prefix_rep" "1")
15374 (set_attr "memory" "both")
15375 (set_attr "mode" "SI")])
15377 (define_insn "*rep_movqi_rex64"
15378 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15379 (set (match_operand:DI 0 "register_operand" "=D")
15380 (plus:DI (match_operand:DI 3 "register_operand" "0")
15381 (match_operand:DI 5 "register_operand" "2")))
15382 (set (match_operand:DI 1 "register_operand" "=S")
15383 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
15384 (set (mem:BLK (match_dup 3))
15385 (mem:BLK (match_dup 4)))
15386 (use (match_dup 5))]
15389 [(set_attr "type" "str")
15390 (set_attr "prefix_rep" "1")
15391 (set_attr "memory" "both")
15392 (set_attr "mode" "SI")])
15394 (define_expand "setmemsi"
15395 [(use (match_operand:BLK 0 "memory_operand" ""))
15396 (use (match_operand:SI 1 "nonmemory_operand" ""))
15397 (use (match_operand 2 "const_int_operand" ""))
15398 (use (match_operand 3 "const_int_operand" ""))
15399 (use (match_operand:SI 4 "const_int_operand" ""))
15400 (use (match_operand:SI 5 "const_int_operand" ""))]
15403 if (ix86_expand_setmem (operands[0], operands[1],
15404 operands[2], operands[3],
15405 operands[4], operands[5]))
15411 (define_expand "setmemdi"
15412 [(use (match_operand:BLK 0 "memory_operand" ""))
15413 (use (match_operand:DI 1 "nonmemory_operand" ""))
15414 (use (match_operand 2 "const_int_operand" ""))
15415 (use (match_operand 3 "const_int_operand" ""))
15416 (use (match_operand 4 "const_int_operand" ""))
15417 (use (match_operand 5 "const_int_operand" ""))]
15420 if (ix86_expand_setmem (operands[0], operands[1],
15421 operands[2], operands[3],
15422 operands[4], operands[5]))
15428 ;; Most CPUs don't like single string operations
15429 ;; Handle this case here to simplify previous expander.
15431 (define_expand "strset"
15432 [(set (match_operand 1 "memory_operand" "")
15433 (match_operand 2 "register_operand" ""))
15434 (parallel [(set (match_operand 0 "register_operand" "")
15436 (clobber (reg:CC FLAGS_REG))])]
15439 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15440 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15442 /* If .md ever supports :P for Pmode, this can be directly
15443 in the pattern above. */
15444 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15445 GEN_INT (GET_MODE_SIZE (GET_MODE
15447 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15449 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15455 (define_expand "strset_singleop"
15456 [(parallel [(set (match_operand 1 "memory_operand" "")
15457 (match_operand 2 "register_operand" ""))
15458 (set (match_operand 0 "register_operand" "")
15459 (match_operand 3 "" ""))])]
15461 "ix86_current_function_needs_cld = 1;")
15463 (define_insn "*strsetdi_rex_1"
15464 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15465 (match_operand:DI 2 "register_operand" "a"))
15466 (set (match_operand:DI 0 "register_operand" "=D")
15467 (plus:DI (match_dup 1)
15471 [(set_attr "type" "str")
15472 (set_attr "memory" "store")
15473 (set_attr "mode" "DI")])
15475 (define_insn "*strsetsi_1"
15476 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
15477 (match_operand:SI 2 "register_operand" "a"))
15478 (set (match_operand:SI 0 "register_operand" "=D")
15479 (plus:SI (match_dup 1)
15483 [(set_attr "type" "str")
15484 (set_attr "memory" "store")
15485 (set_attr "mode" "SI")])
15487 (define_insn "*strsetsi_rex_1"
15488 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15489 (match_operand:SI 2 "register_operand" "a"))
15490 (set (match_operand:DI 0 "register_operand" "=D")
15491 (plus:DI (match_dup 1)
15495 [(set_attr "type" "str")
15496 (set_attr "memory" "store")
15497 (set_attr "mode" "SI")])
15499 (define_insn "*strsethi_1"
15500 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
15501 (match_operand:HI 2 "register_operand" "a"))
15502 (set (match_operand:SI 0 "register_operand" "=D")
15503 (plus:SI (match_dup 1)
15507 [(set_attr "type" "str")
15508 (set_attr "memory" "store")
15509 (set_attr "mode" "HI")])
15511 (define_insn "*strsethi_rex_1"
15512 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
15513 (match_operand:HI 2 "register_operand" "a"))
15514 (set (match_operand:DI 0 "register_operand" "=D")
15515 (plus:DI (match_dup 1)
15519 [(set_attr "type" "str")
15520 (set_attr "memory" "store")
15521 (set_attr "mode" "HI")])
15523 (define_insn "*strsetqi_1"
15524 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
15525 (match_operand:QI 2 "register_operand" "a"))
15526 (set (match_operand:SI 0 "register_operand" "=D")
15527 (plus:SI (match_dup 1)
15531 [(set_attr "type" "str")
15532 (set_attr "memory" "store")
15533 (set_attr "mode" "QI")])
15535 (define_insn "*strsetqi_rex_1"
15536 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
15537 (match_operand:QI 2 "register_operand" "a"))
15538 (set (match_operand:DI 0 "register_operand" "=D")
15539 (plus:DI (match_dup 1)
15543 [(set_attr "type" "str")
15544 (set_attr "memory" "store")
15545 (set_attr "prefix_rex" "0")
15546 (set_attr "mode" "QI")])
15548 (define_expand "rep_stos"
15549 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15550 (set (match_operand 0 "register_operand" "")
15551 (match_operand 4 "" ""))
15552 (set (match_operand 2 "memory_operand" "") (const_int 0))
15553 (use (match_operand 3 "register_operand" ""))
15554 (use (match_dup 1))])]
15556 "ix86_current_function_needs_cld = 1;")
15558 (define_insn "*rep_stosdi_rex64"
15559 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15560 (set (match_operand:DI 0 "register_operand" "=D")
15561 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15563 (match_operand:DI 3 "register_operand" "0")))
15564 (set (mem:BLK (match_dup 3))
15566 (use (match_operand:DI 2 "register_operand" "a"))
15567 (use (match_dup 4))]
15570 [(set_attr "type" "str")
15571 (set_attr "prefix_rep" "1")
15572 (set_attr "memory" "store")
15573 (set_attr "mode" "DI")])
15575 (define_insn "*rep_stossi"
15576 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15577 (set (match_operand:SI 0 "register_operand" "=D")
15578 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
15580 (match_operand:SI 3 "register_operand" "0")))
15581 (set (mem:BLK (match_dup 3))
15583 (use (match_operand:SI 2 "register_operand" "a"))
15584 (use (match_dup 4))]
15586 "rep{%;} stos{l|d}"
15587 [(set_attr "type" "str")
15588 (set_attr "prefix_rep" "1")
15589 (set_attr "memory" "store")
15590 (set_attr "mode" "SI")])
15592 (define_insn "*rep_stossi_rex64"
15593 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15594 (set (match_operand:DI 0 "register_operand" "=D")
15595 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15597 (match_operand:DI 3 "register_operand" "0")))
15598 (set (mem:BLK (match_dup 3))
15600 (use (match_operand:SI 2 "register_operand" "a"))
15601 (use (match_dup 4))]
15603 "rep{%;} stos{l|d}"
15604 [(set_attr "type" "str")
15605 (set_attr "prefix_rep" "1")
15606 (set_attr "memory" "store")
15607 (set_attr "mode" "SI")])
15609 (define_insn "*rep_stosqi"
15610 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15611 (set (match_operand:SI 0 "register_operand" "=D")
15612 (plus:SI (match_operand:SI 3 "register_operand" "0")
15613 (match_operand:SI 4 "register_operand" "1")))
15614 (set (mem:BLK (match_dup 3))
15616 (use (match_operand:QI 2 "register_operand" "a"))
15617 (use (match_dup 4))]
15620 [(set_attr "type" "str")
15621 (set_attr "prefix_rep" "1")
15622 (set_attr "memory" "store")
15623 (set_attr "mode" "QI")])
15625 (define_insn "*rep_stosqi_rex64"
15626 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15627 (set (match_operand:DI 0 "register_operand" "=D")
15628 (plus:DI (match_operand:DI 3 "register_operand" "0")
15629 (match_operand:DI 4 "register_operand" "1")))
15630 (set (mem:BLK (match_dup 3))
15632 (use (match_operand:QI 2 "register_operand" "a"))
15633 (use (match_dup 4))]
15636 [(set_attr "type" "str")
15637 (set_attr "prefix_rep" "1")
15638 (set_attr "memory" "store")
15639 (set_attr "prefix_rex" "0")
15640 (set_attr "mode" "QI")])
15642 (define_expand "cmpstrnsi"
15643 [(set (match_operand:SI 0 "register_operand" "")
15644 (compare:SI (match_operand:BLK 1 "general_operand" "")
15645 (match_operand:BLK 2 "general_operand" "")))
15646 (use (match_operand 3 "general_operand" ""))
15647 (use (match_operand 4 "immediate_operand" ""))]
15650 rtx addr1, addr2, out, outlow, count, countreg, align;
15652 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15655 /* Can't use this if the user has appropriated esi or edi. */
15656 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15661 out = gen_reg_rtx (SImode);
15663 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15664 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15665 if (addr1 != XEXP (operands[1], 0))
15666 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15667 if (addr2 != XEXP (operands[2], 0))
15668 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15670 count = operands[3];
15671 countreg = ix86_zero_extend_to_Pmode (count);
15673 /* %%% Iff we are testing strict equality, we can use known alignment
15674 to good advantage. This may be possible with combine, particularly
15675 once cc0 is dead. */
15676 align = operands[4];
15678 if (CONST_INT_P (count))
15680 if (INTVAL (count) == 0)
15682 emit_move_insn (operands[0], const0_rtx);
15685 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15686 operands[1], operands[2]));
15690 rtx (*gen_cmp) (rtx, rtx);
15692 gen_cmp = (TARGET_64BIT
15693 ? gen_cmpdi_1 : gen_cmpsi_1);
15695 emit_insn (gen_cmp (countreg, countreg));
15696 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15697 operands[1], operands[2]));
15700 outlow = gen_lowpart (QImode, out);
15701 emit_insn (gen_cmpintqi (outlow));
15702 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15704 if (operands[0] != out)
15705 emit_move_insn (operands[0], out);
15710 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15712 (define_expand "cmpintqi"
15713 [(set (match_dup 1)
15714 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15716 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15717 (parallel [(set (match_operand:QI 0 "register_operand" "")
15718 (minus:QI (match_dup 1)
15720 (clobber (reg:CC FLAGS_REG))])]
15722 "operands[1] = gen_reg_rtx (QImode);
15723 operands[2] = gen_reg_rtx (QImode);")
15725 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15726 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
15728 (define_expand "cmpstrnqi_nz_1"
15729 [(parallel [(set (reg:CC FLAGS_REG)
15730 (compare:CC (match_operand 4 "memory_operand" "")
15731 (match_operand 5 "memory_operand" "")))
15732 (use (match_operand 2 "register_operand" ""))
15733 (use (match_operand:SI 3 "immediate_operand" ""))
15734 (clobber (match_operand 0 "register_operand" ""))
15735 (clobber (match_operand 1 "register_operand" ""))
15736 (clobber (match_dup 2))])]
15738 "ix86_current_function_needs_cld = 1;")
15740 (define_insn "*cmpstrnqi_nz_1"
15741 [(set (reg:CC FLAGS_REG)
15742 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15743 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
15744 (use (match_operand:SI 6 "register_operand" "2"))
15745 (use (match_operand:SI 3 "immediate_operand" "i"))
15746 (clobber (match_operand:SI 0 "register_operand" "=S"))
15747 (clobber (match_operand:SI 1 "register_operand" "=D"))
15748 (clobber (match_operand:SI 2 "register_operand" "=c"))]
15751 [(set_attr "type" "str")
15752 (set_attr "mode" "QI")
15753 (set_attr "prefix_rep" "1")])
15755 (define_insn "*cmpstrnqi_nz_rex_1"
15756 [(set (reg:CC FLAGS_REG)
15757 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15758 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
15759 (use (match_operand:DI 6 "register_operand" "2"))
15760 (use (match_operand:SI 3 "immediate_operand" "i"))
15761 (clobber (match_operand:DI 0 "register_operand" "=S"))
15762 (clobber (match_operand:DI 1 "register_operand" "=D"))
15763 (clobber (match_operand:DI 2 "register_operand" "=c"))]
15766 [(set_attr "type" "str")
15767 (set_attr "mode" "QI")
15768 (set_attr "prefix_rex" "0")
15769 (set_attr "prefix_rep" "1")])
15771 ;; The same, but the count is not known to not be zero.
15773 (define_expand "cmpstrnqi_1"
15774 [(parallel [(set (reg:CC FLAGS_REG)
15775 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
15777 (compare:CC (match_operand 4 "memory_operand" "")
15778 (match_operand 5 "memory_operand" ""))
15780 (use (match_operand:SI 3 "immediate_operand" ""))
15781 (use (reg:CC FLAGS_REG))
15782 (clobber (match_operand 0 "register_operand" ""))
15783 (clobber (match_operand 1 "register_operand" ""))
15784 (clobber (match_dup 2))])]
15786 "ix86_current_function_needs_cld = 1;")
15788 (define_insn "*cmpstrnqi_1"
15789 [(set (reg:CC FLAGS_REG)
15790 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
15792 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15793 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
15795 (use (match_operand:SI 3 "immediate_operand" "i"))
15796 (use (reg:CC FLAGS_REG))
15797 (clobber (match_operand:SI 0 "register_operand" "=S"))
15798 (clobber (match_operand:SI 1 "register_operand" "=D"))
15799 (clobber (match_operand:SI 2 "register_operand" "=c"))]
15802 [(set_attr "type" "str")
15803 (set_attr "mode" "QI")
15804 (set_attr "prefix_rep" "1")])
15806 (define_insn "*cmpstrnqi_rex_1"
15807 [(set (reg:CC FLAGS_REG)
15808 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
15810 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15811 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
15813 (use (match_operand:SI 3 "immediate_operand" "i"))
15814 (use (reg:CC FLAGS_REG))
15815 (clobber (match_operand:DI 0 "register_operand" "=S"))
15816 (clobber (match_operand:DI 1 "register_operand" "=D"))
15817 (clobber (match_operand:DI 2 "register_operand" "=c"))]
15820 [(set_attr "type" "str")
15821 (set_attr "mode" "QI")
15822 (set_attr "prefix_rex" "0")
15823 (set_attr "prefix_rep" "1")])
15825 (define_expand "strlensi"
15826 [(set (match_operand:SI 0 "register_operand" "")
15827 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
15828 (match_operand:QI 2 "immediate_operand" "")
15829 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
15832 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15838 (define_expand "strlendi"
15839 [(set (match_operand:DI 0 "register_operand" "")
15840 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
15841 (match_operand:QI 2 "immediate_operand" "")
15842 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
15845 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15851 (define_expand "strlenqi_1"
15852 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
15853 (clobber (match_operand 1 "register_operand" ""))
15854 (clobber (reg:CC FLAGS_REG))])]
15856 "ix86_current_function_needs_cld = 1;")
15858 (define_insn "*strlenqi_1"
15859 [(set (match_operand:SI 0 "register_operand" "=&c")
15860 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
15861 (match_operand:QI 2 "register_operand" "a")
15862 (match_operand:SI 3 "immediate_operand" "i")
15863 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
15864 (clobber (match_operand:SI 1 "register_operand" "=D"))
15865 (clobber (reg:CC FLAGS_REG))]
15868 [(set_attr "type" "str")
15869 (set_attr "mode" "QI")
15870 (set_attr "prefix_rep" "1")])
15872 (define_insn "*strlenqi_rex_1"
15873 [(set (match_operand:DI 0 "register_operand" "=&c")
15874 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
15875 (match_operand:QI 2 "register_operand" "a")
15876 (match_operand:DI 3 "immediate_operand" "i")
15877 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
15878 (clobber (match_operand:DI 1 "register_operand" "=D"))
15879 (clobber (reg:CC FLAGS_REG))]
15882 [(set_attr "type" "str")
15883 (set_attr "mode" "QI")
15884 (set_attr "prefix_rex" "0")
15885 (set_attr "prefix_rep" "1")])
15887 ;; Peephole optimizations to clean up after cmpstrn*. This should be
15888 ;; handled in combine, but it is not currently up to the task.
15889 ;; When used for their truth value, the cmpstrn* expanders generate
15898 ;; The intermediate three instructions are unnecessary.
15900 ;; This one handles cmpstrn*_nz_1...
15903 (set (reg:CC FLAGS_REG)
15904 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15905 (mem:BLK (match_operand 5 "register_operand" ""))))
15906 (use (match_operand 6 "register_operand" ""))
15907 (use (match_operand:SI 3 "immediate_operand" ""))
15908 (clobber (match_operand 0 "register_operand" ""))
15909 (clobber (match_operand 1 "register_operand" ""))
15910 (clobber (match_operand 2 "register_operand" ""))])
15911 (set (match_operand:QI 7 "register_operand" "")
15912 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15913 (set (match_operand:QI 8 "register_operand" "")
15914 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15915 (set (reg FLAGS_REG)
15916 (compare (match_dup 7) (match_dup 8)))
15918 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15920 (set (reg:CC FLAGS_REG)
15921 (compare:CC (mem:BLK (match_dup 4))
15922 (mem:BLK (match_dup 5))))
15923 (use (match_dup 6))
15924 (use (match_dup 3))
15925 (clobber (match_dup 0))
15926 (clobber (match_dup 1))
15927 (clobber (match_dup 2))])])
15929 ;; ...and this one handles cmpstrn*_1.
15932 (set (reg:CC FLAGS_REG)
15933 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
15935 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15936 (mem:BLK (match_operand 5 "register_operand" "")))
15938 (use (match_operand:SI 3 "immediate_operand" ""))
15939 (use (reg:CC FLAGS_REG))
15940 (clobber (match_operand 0 "register_operand" ""))
15941 (clobber (match_operand 1 "register_operand" ""))
15942 (clobber (match_operand 2 "register_operand" ""))])
15943 (set (match_operand:QI 7 "register_operand" "")
15944 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15945 (set (match_operand:QI 8 "register_operand" "")
15946 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15947 (set (reg FLAGS_REG)
15948 (compare (match_dup 7) (match_dup 8)))
15950 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15952 (set (reg:CC FLAGS_REG)
15953 (if_then_else:CC (ne (match_dup 6)
15955 (compare:CC (mem:BLK (match_dup 4))
15956 (mem:BLK (match_dup 5)))
15958 (use (match_dup 3))
15959 (use (reg:CC FLAGS_REG))
15960 (clobber (match_dup 0))
15961 (clobber (match_dup 1))
15962 (clobber (match_dup 2))])])
15964 ;; Conditional move instructions.
15966 (define_expand "mov<mode>cc"
15967 [(set (match_operand:SWIM 0 "register_operand" "")
15968 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
15969 (match_operand:SWIM 2 "general_operand" "")
15970 (match_operand:SWIM 3 "general_operand" "")))]
15972 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
15974 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
15975 ;; the register first winds up with `sbbl $0,reg', which is also weird.
15976 ;; So just document what we're doing explicitly.
15978 (define_expand "x86_mov<mode>cc_0_m1"
15980 [(set (match_operand:SWI48 0 "register_operand" "")
15981 (if_then_else:SWI48
15982 (match_operator:SWI48 2 "ix86_carry_flag_operator"
15983 [(match_operand 1 "flags_reg_operand" "")
15987 (clobber (reg:CC FLAGS_REG))])])
15989 (define_insn "*x86_mov<mode>cc_0_m1"
15990 [(set (match_operand:SWI48 0 "register_operand" "=r")
15991 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15992 [(reg FLAGS_REG) (const_int 0)])
15995 (clobber (reg:CC FLAGS_REG))]
15997 "sbb{<imodesuffix>}\t%0, %0"
15998 ; Since we don't have the proper number of operands for an alu insn,
15999 ; fill in all the blanks.
16000 [(set_attr "type" "alu")
16001 (set_attr "use_carry" "1")
16002 (set_attr "pent_pair" "pu")
16003 (set_attr "memory" "none")
16004 (set_attr "imm_disp" "false")
16005 (set_attr "mode" "<MODE>")
16006 (set_attr "length_immediate" "0")])
16008 (define_insn "*x86_mov<mode>cc_0_m1_se"
16009 [(set (match_operand:SWI48 0 "register_operand" "=r")
16010 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16011 [(reg FLAGS_REG) (const_int 0)])
16014 (clobber (reg:CC FLAGS_REG))]
16016 "sbb{<imodesuffix>}\t%0, %0"
16017 [(set_attr "type" "alu")
16018 (set_attr "use_carry" "1")
16019 (set_attr "pent_pair" "pu")
16020 (set_attr "memory" "none")
16021 (set_attr "imm_disp" "false")
16022 (set_attr "mode" "<MODE>")
16023 (set_attr "length_immediate" "0")])
16025 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16026 [(set (match_operand:SWI48 0 "register_operand" "=r")
16027 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16028 [(reg FLAGS_REG) (const_int 0)])))]
16030 "sbb{<imodesuffix>}\t%0, %0"
16031 [(set_attr "type" "alu")
16032 (set_attr "use_carry" "1")
16033 (set_attr "pent_pair" "pu")
16034 (set_attr "memory" "none")
16035 (set_attr "imm_disp" "false")
16036 (set_attr "mode" "<MODE>")
16037 (set_attr "length_immediate" "0")])
16039 (define_insn "*mov<mode>cc_noc"
16040 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16041 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16042 [(reg FLAGS_REG) (const_int 0)])
16043 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16044 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16045 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16047 cmov%O2%C1\t{%2, %0|%0, %2}
16048 cmov%O2%c1\t{%3, %0|%0, %3}"
16049 [(set_attr "type" "icmov")
16050 (set_attr "mode" "<MODE>")])
16052 (define_insn_and_split "*movqicc_noc"
16053 [(set (match_operand:QI 0 "register_operand" "=r,r")
16054 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16055 [(match_operand 4 "flags_reg_operand" "")
16057 (match_operand:QI 2 "register_operand" "r,0")
16058 (match_operand:QI 3 "register_operand" "0,r")))]
16059 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16061 "&& reload_completed"
16062 [(set (match_dup 0)
16063 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16066 "operands[0] = gen_lowpart (SImode, operands[0]);
16067 operands[2] = gen_lowpart (SImode, operands[2]);
16068 operands[3] = gen_lowpart (SImode, operands[3]);"
16069 [(set_attr "type" "icmov")
16070 (set_attr "mode" "SI")])
16072 (define_expand "mov<mode>cc"
16073 [(set (match_operand:X87MODEF 0 "register_operand" "")
16074 (if_then_else:X87MODEF
16075 (match_operand 1 "ix86_fp_comparison_operator" "")
16076 (match_operand:X87MODEF 2 "register_operand" "")
16077 (match_operand:X87MODEF 3 "register_operand" "")))]
16078 "(TARGET_80387 && TARGET_CMOVE)
16079 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16080 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16082 (define_insn "*movsfcc_1_387"
16083 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16084 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16085 [(reg FLAGS_REG) (const_int 0)])
16086 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16087 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16088 "TARGET_80387 && TARGET_CMOVE
16089 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16091 fcmov%F1\t{%2, %0|%0, %2}
16092 fcmov%f1\t{%3, %0|%0, %3}
16093 cmov%O2%C1\t{%2, %0|%0, %2}
16094 cmov%O2%c1\t{%3, %0|%0, %3}"
16095 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16096 (set_attr "mode" "SF,SF,SI,SI")])
16098 (define_insn "*movdfcc_1"
16099 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16100 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16101 [(reg FLAGS_REG) (const_int 0)])
16102 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16103 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16104 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16105 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16107 fcmov%F1\t{%2, %0|%0, %2}
16108 fcmov%f1\t{%3, %0|%0, %3}
16111 [(set_attr "type" "fcmov,fcmov,multi,multi")
16112 (set_attr "mode" "DF")])
16114 (define_insn "*movdfcc_1_rex64"
16115 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16116 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16117 [(reg FLAGS_REG) (const_int 0)])
16118 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16119 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16120 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16121 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16123 fcmov%F1\t{%2, %0|%0, %2}
16124 fcmov%f1\t{%3, %0|%0, %3}
16125 cmov%O2%C1\t{%2, %0|%0, %2}
16126 cmov%O2%c1\t{%3, %0|%0, %3}"
16127 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16128 (set_attr "mode" "DF")])
16131 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16132 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16133 [(match_operand 4 "flags_reg_operand" "")
16135 (match_operand:DF 2 "nonimmediate_operand" "")
16136 (match_operand:DF 3 "nonimmediate_operand" "")))]
16137 "!TARGET_64BIT && reload_completed"
16138 [(set (match_dup 2)
16139 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16143 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16147 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16148 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16151 (define_insn "*movxfcc_1"
16152 [(set (match_operand:XF 0 "register_operand" "=f,f")
16153 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16154 [(reg FLAGS_REG) (const_int 0)])
16155 (match_operand:XF 2 "register_operand" "f,0")
16156 (match_operand:XF 3 "register_operand" "0,f")))]
16157 "TARGET_80387 && TARGET_CMOVE"
16159 fcmov%F1\t{%2, %0|%0, %2}
16160 fcmov%f1\t{%3, %0|%0, %3}"
16161 [(set_attr "type" "fcmov")
16162 (set_attr "mode" "XF")])
16164 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16165 ;; the scalar versions to have only XMM registers as operands.
16167 ;; XOP conditional move
16168 (define_insn "*xop_pcmov_<mode>"
16169 [(set (match_operand:MODEF 0 "register_operand" "=x")
16170 (if_then_else:MODEF
16171 (match_operand:MODEF 1 "register_operand" "x")
16172 (match_operand:MODEF 2 "register_operand" "x")
16173 (match_operand:MODEF 3 "register_operand" "x")))]
16175 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16176 [(set_attr "type" "sse4arg")])
16178 ;; These versions of the min/max patterns are intentionally ignorant of
16179 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16180 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16181 ;; are undefined in this condition, we're certain this is correct.
16183 (define_insn "*avx_<code><mode>3"
16184 [(set (match_operand:MODEF 0 "register_operand" "=x")
16186 (match_operand:MODEF 1 "nonimmediate_operand" "%x")
16187 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16188 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16189 "v<maxmin_float>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16190 [(set_attr "type" "sseadd")
16191 (set_attr "prefix" "vex")
16192 (set_attr "mode" "<MODE>")])
16194 (define_insn "<code><mode>3"
16195 [(set (match_operand:MODEF 0 "register_operand" "=x")
16197 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
16198 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16199 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16200 "<maxmin_float>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
16201 [(set_attr "type" "sseadd")
16202 (set_attr "mode" "<MODE>")])
16204 ;; These versions of the min/max patterns implement exactly the operations
16205 ;; min = (op1 < op2 ? op1 : op2)
16206 ;; max = (!(op1 < op2) ? op1 : op2)
16207 ;; Their operands are not commutative, and thus they may be used in the
16208 ;; presence of -0.0 and NaN.
16210 (define_insn "*avx_ieee_smin<mode>3"
16211 [(set (match_operand:MODEF 0 "register_operand" "=x")
16213 [(match_operand:MODEF 1 "register_operand" "x")
16214 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16216 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16217 "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16218 [(set_attr "type" "sseadd")
16219 (set_attr "prefix" "vex")
16220 (set_attr "mode" "<MODE>")])
16222 (define_insn "*ieee_smin<mode>3"
16223 [(set (match_operand:MODEF 0 "register_operand" "=x")
16225 [(match_operand:MODEF 1 "register_operand" "0")
16226 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16228 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16229 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
16230 [(set_attr "type" "sseadd")
16231 (set_attr "mode" "<MODE>")])
16233 (define_insn "*avx_ieee_smax<mode>3"
16234 [(set (match_operand:MODEF 0 "register_operand" "=x")
16236 [(match_operand:MODEF 1 "register_operand" "0")
16237 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16239 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16240 "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16241 [(set_attr "type" "sseadd")
16242 (set_attr "prefix" "vex")
16243 (set_attr "mode" "<MODE>")])
16245 (define_insn "*ieee_smax<mode>3"
16246 [(set (match_operand:MODEF 0 "register_operand" "=x")
16248 [(match_operand:MODEF 1 "register_operand" "0")
16249 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16251 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16252 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
16253 [(set_attr "type" "sseadd")
16254 (set_attr "mode" "<MODE>")])
16256 ;; Make two stack loads independent:
16258 ;; fld %st(0) -> fld bb
16259 ;; fmul bb fmul %st(1), %st
16261 ;; Actually we only match the last two instructions for simplicity.
16263 [(set (match_operand 0 "fp_register_operand" "")
16264 (match_operand 1 "fp_register_operand" ""))
16266 (match_operator 2 "binary_fp_operator"
16268 (match_operand 3 "memory_operand" "")]))]
16269 "REGNO (operands[0]) != REGNO (operands[1])"
16270 [(set (match_dup 0) (match_dup 3))
16271 (set (match_dup 0) (match_dup 4))]
16273 ;; The % modifier is not operational anymore in peephole2's, so we have to
16274 ;; swap the operands manually in the case of addition and multiplication.
16275 "if (COMMUTATIVE_ARITH_P (operands[2]))
16276 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16277 GET_MODE (operands[2]),
16278 operands[0], operands[1]);
16280 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16281 GET_MODE (operands[2]),
16282 operands[1], operands[0]);")
16284 ;; Conditional addition patterns
16285 (define_expand "add<mode>cc"
16286 [(match_operand:SWI 0 "register_operand" "")
16287 (match_operand 1 "ordered_comparison_operator" "")
16288 (match_operand:SWI 2 "register_operand" "")
16289 (match_operand:SWI 3 "const_int_operand" "")]
16291 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16293 ;; Misc patterns (?)
16295 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16296 ;; Otherwise there will be nothing to keep
16298 ;; [(set (reg ebp) (reg esp))]
16299 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16300 ;; (clobber (eflags)]
16301 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16303 ;; in proper program order.
16305 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16306 [(set (match_operand:P 0 "register_operand" "=r,r")
16307 (plus:P (match_operand:P 1 "register_operand" "0,r")
16308 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16309 (clobber (reg:CC FLAGS_REG))
16310 (clobber (mem:BLK (scratch)))]
16313 switch (get_attr_type (insn))
16316 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16319 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16320 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16321 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16323 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16326 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16327 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16330 [(set (attr "type")
16331 (cond [(and (eq_attr "alternative" "0")
16332 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16333 (const_string "alu")
16334 (match_operand:<MODE> 2 "const0_operand" "")
16335 (const_string "imov")
16337 (const_string "lea")))
16338 (set (attr "length_immediate")
16339 (cond [(eq_attr "type" "imov")
16341 (and (eq_attr "type" "alu")
16342 (match_operand 2 "const128_operand" ""))
16345 (const_string "*")))
16346 (set_attr "mode" "<MODE>")])
16348 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16349 [(set (match_operand:P 0 "register_operand" "=r")
16350 (minus:P (match_operand:P 1 "register_operand" "0")
16351 (match_operand:P 2 "register_operand" "r")))
16352 (clobber (reg:CC FLAGS_REG))
16353 (clobber (mem:BLK (scratch)))]
16355 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16356 [(set_attr "type" "alu")
16357 (set_attr "mode" "<MODE>")])
16359 (define_insn "allocate_stack_worker_probe_<mode>"
16360 [(set (match_operand:P 0 "register_operand" "=a")
16361 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16362 UNSPECV_STACK_PROBE))
16363 (clobber (reg:CC FLAGS_REG))]
16364 "ix86_target_stack_probe ()"
16365 "call\t___chkstk_ms"
16366 [(set_attr "type" "multi")
16367 (set_attr "length" "5")])
16369 (define_expand "allocate_stack"
16370 [(match_operand 0 "register_operand" "")
16371 (match_operand 1 "general_operand" "")]
16372 "ix86_target_stack_probe ()"
16376 #ifndef CHECK_STACK_LIMIT
16377 #define CHECK_STACK_LIMIT 0
16380 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16381 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16383 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16384 stack_pointer_rtx, 0, OPTAB_DIRECT);
16385 if (x != stack_pointer_rtx)
16386 emit_move_insn (stack_pointer_rtx, x);
16390 x = copy_to_mode_reg (Pmode, operands[1]);
16392 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16394 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16395 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16396 stack_pointer_rtx, 0, OPTAB_DIRECT);
16397 if (x != stack_pointer_rtx)
16398 emit_move_insn (stack_pointer_rtx, x);
16401 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16405 ;; Use IOR for stack probes, this is shorter.
16406 (define_expand "probe_stack"
16407 [(match_operand 0 "memory_operand" "")]
16410 rtx (*gen_ior3) (rtx, rtx, rtx);
16412 gen_ior3 = (GET_MODE (operands[0]) == DImode
16413 ? gen_iordi3 : gen_iorsi3);
16415 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16419 (define_insn "adjust_stack_and_probe<mode>"
16420 [(set (match_operand:P 0 "register_operand" "=r")
16421 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16422 UNSPECV_PROBE_STACK_RANGE))
16423 (set (reg:P SP_REG)
16424 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16425 (clobber (reg:CC FLAGS_REG))
16426 (clobber (mem:BLK (scratch)))]
16428 "* return output_adjust_stack_and_probe (operands[0]);"
16429 [(set_attr "type" "multi")])
16431 (define_insn "probe_stack_range<mode>"
16432 [(set (match_operand:P 0 "register_operand" "=r")
16433 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16434 (match_operand:P 2 "const_int_operand" "n")]
16435 UNSPECV_PROBE_STACK_RANGE))
16436 (clobber (reg:CC FLAGS_REG))]
16438 "* return output_probe_stack_range (operands[0], operands[2]);"
16439 [(set_attr "type" "multi")])
16441 (define_expand "builtin_setjmp_receiver"
16442 [(label_ref (match_operand 0 "" ""))]
16443 "!TARGET_64BIT && flag_pic"
16449 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16450 rtx label_rtx = gen_label_rtx ();
16451 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16452 xops[0] = xops[1] = picreg;
16453 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16454 ix86_expand_binary_operator (MINUS, SImode, xops);
16458 emit_insn (gen_set_got (pic_offset_table_rtx));
16462 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16465 [(set (match_operand 0 "register_operand" "")
16466 (match_operator 3 "promotable_binary_operator"
16467 [(match_operand 1 "register_operand" "")
16468 (match_operand 2 "aligned_operand" "")]))
16469 (clobber (reg:CC FLAGS_REG))]
16470 "! TARGET_PARTIAL_REG_STALL && reload_completed
16471 && ((GET_MODE (operands[0]) == HImode
16472 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16473 /* ??? next two lines just !satisfies_constraint_K (...) */
16474 || !CONST_INT_P (operands[2])
16475 || satisfies_constraint_K (operands[2])))
16476 || (GET_MODE (operands[0]) == QImode
16477 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16478 [(parallel [(set (match_dup 0)
16479 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16480 (clobber (reg:CC FLAGS_REG))])]
16481 "operands[0] = gen_lowpart (SImode, operands[0]);
16482 operands[1] = gen_lowpart (SImode, operands[1]);
16483 if (GET_CODE (operands[3]) != ASHIFT)
16484 operands[2] = gen_lowpart (SImode, operands[2]);
16485 PUT_MODE (operands[3], SImode);")
16487 ; Promote the QImode tests, as i386 has encoding of the AND
16488 ; instruction with 32-bit sign-extended immediate and thus the
16489 ; instruction size is unchanged, except in the %eax case for
16490 ; which it is increased by one byte, hence the ! optimize_size.
16492 [(set (match_operand 0 "flags_reg_operand" "")
16493 (match_operator 2 "compare_operator"
16494 [(and (match_operand 3 "aligned_operand" "")
16495 (match_operand 4 "const_int_operand" ""))
16497 (set (match_operand 1 "register_operand" "")
16498 (and (match_dup 3) (match_dup 4)))]
16499 "! TARGET_PARTIAL_REG_STALL && reload_completed
16500 && optimize_insn_for_speed_p ()
16501 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16502 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16503 /* Ensure that the operand will remain sign-extended immediate. */
16504 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16505 [(parallel [(set (match_dup 0)
16506 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16509 (and:SI (match_dup 3) (match_dup 4)))])]
16512 = gen_int_mode (INTVAL (operands[4])
16513 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16514 operands[1] = gen_lowpart (SImode, operands[1]);
16515 operands[3] = gen_lowpart (SImode, operands[3]);
16518 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16519 ; the TEST instruction with 32-bit sign-extended immediate and thus
16520 ; the instruction size would at least double, which is not what we
16521 ; want even with ! optimize_size.
16523 [(set (match_operand 0 "flags_reg_operand" "")
16524 (match_operator 1 "compare_operator"
16525 [(and (match_operand:HI 2 "aligned_operand" "")
16526 (match_operand:HI 3 "const_int_operand" ""))
16528 "! TARGET_PARTIAL_REG_STALL && reload_completed
16529 && ! TARGET_FAST_PREFIX
16530 && optimize_insn_for_speed_p ()
16531 /* Ensure that the operand will remain sign-extended immediate. */
16532 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16533 [(set (match_dup 0)
16534 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16538 = gen_int_mode (INTVAL (operands[3])
16539 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16540 operands[2] = gen_lowpart (SImode, operands[2]);
16544 [(set (match_operand 0 "register_operand" "")
16545 (neg (match_operand 1 "register_operand" "")))
16546 (clobber (reg:CC FLAGS_REG))]
16547 "! TARGET_PARTIAL_REG_STALL && reload_completed
16548 && (GET_MODE (operands[0]) == HImode
16549 || (GET_MODE (operands[0]) == QImode
16550 && (TARGET_PROMOTE_QImode
16551 || optimize_insn_for_size_p ())))"
16552 [(parallel [(set (match_dup 0)
16553 (neg:SI (match_dup 1)))
16554 (clobber (reg:CC FLAGS_REG))])]
16555 "operands[0] = gen_lowpart (SImode, operands[0]);
16556 operands[1] = gen_lowpart (SImode, operands[1]);")
16559 [(set (match_operand 0 "register_operand" "")
16560 (not (match_operand 1 "register_operand" "")))]
16561 "! TARGET_PARTIAL_REG_STALL && reload_completed
16562 && (GET_MODE (operands[0]) == HImode
16563 || (GET_MODE (operands[0]) == QImode
16564 && (TARGET_PROMOTE_QImode
16565 || optimize_insn_for_size_p ())))"
16566 [(set (match_dup 0)
16567 (not:SI (match_dup 1)))]
16568 "operands[0] = gen_lowpart (SImode, operands[0]);
16569 operands[1] = gen_lowpart (SImode, operands[1]);")
16572 [(set (match_operand 0 "register_operand" "")
16573 (if_then_else (match_operator 1 "ordered_comparison_operator"
16574 [(reg FLAGS_REG) (const_int 0)])
16575 (match_operand 2 "register_operand" "")
16576 (match_operand 3 "register_operand" "")))]
16577 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16578 && (GET_MODE (operands[0]) == HImode
16579 || (GET_MODE (operands[0]) == QImode
16580 && (TARGET_PROMOTE_QImode
16581 || optimize_insn_for_size_p ())))"
16582 [(set (match_dup 0)
16583 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16584 "operands[0] = gen_lowpart (SImode, operands[0]);
16585 operands[2] = gen_lowpart (SImode, operands[2]);
16586 operands[3] = gen_lowpart (SImode, operands[3]);")
16588 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16589 ;; transform a complex memory operation into two memory to register operations.
16591 ;; Don't push memory operands
16593 [(set (match_operand:SWI 0 "push_operand" "")
16594 (match_operand:SWI 1 "memory_operand" ""))
16595 (match_scratch:SWI 2 "<r>")]
16596 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16597 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16598 [(set (match_dup 2) (match_dup 1))
16599 (set (match_dup 0) (match_dup 2))])
16601 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16604 [(set (match_operand:SF 0 "push_operand" "")
16605 (match_operand:SF 1 "memory_operand" ""))
16606 (match_scratch:SF 2 "r")]
16607 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16608 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16609 [(set (match_dup 2) (match_dup 1))
16610 (set (match_dup 0) (match_dup 2))])
16612 ;; Don't move an immediate directly to memory when the instruction
16615 [(match_scratch:SWI124 1 "<r>")
16616 (set (match_operand:SWI124 0 "memory_operand" "")
16618 "optimize_insn_for_speed_p ()
16619 && !TARGET_USE_MOV0
16620 && TARGET_SPLIT_LONG_MOVES
16621 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16622 && peep2_regno_dead_p (0, FLAGS_REG)"
16623 [(parallel [(set (match_dup 2) (const_int 0))
16624 (clobber (reg:CC FLAGS_REG))])
16625 (set (match_dup 0) (match_dup 1))]
16626 "operands[2] = gen_lowpart (SImode, operands[1]);")
16629 [(match_scratch:SWI124 2 "<r>")
16630 (set (match_operand:SWI124 0 "memory_operand" "")
16631 (match_operand:SWI124 1 "immediate_operand" ""))]
16632 "optimize_insn_for_speed_p ()
16633 && TARGET_SPLIT_LONG_MOVES
16634 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16635 [(set (match_dup 2) (match_dup 1))
16636 (set (match_dup 0) (match_dup 2))])
16638 ;; Don't compare memory with zero, load and use a test instead.
16640 [(set (match_operand 0 "flags_reg_operand" "")
16641 (match_operator 1 "compare_operator"
16642 [(match_operand:SI 2 "memory_operand" "")
16644 (match_scratch:SI 3 "r")]
16645 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16646 [(set (match_dup 3) (match_dup 2))
16647 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16649 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16650 ;; Don't split NOTs with a displacement operand, because resulting XOR
16651 ;; will not be pairable anyway.
16653 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16654 ;; represented using a modRM byte. The XOR replacement is long decoded,
16655 ;; so this split helps here as well.
16657 ;; Note: Can't do this as a regular split because we can't get proper
16658 ;; lifetime information then.
16661 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16662 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16663 "optimize_insn_for_speed_p ()
16664 && ((TARGET_NOT_UNPAIRABLE
16665 && (!MEM_P (operands[0])
16666 || !memory_displacement_operand (operands[0], <MODE>mode)))
16667 || (TARGET_NOT_VECTORMODE
16668 && long_memory_operand (operands[0], <MODE>mode)))
16669 && peep2_regno_dead_p (0, FLAGS_REG)"
16670 [(parallel [(set (match_dup 0)
16671 (xor:SWI124 (match_dup 1) (const_int -1)))
16672 (clobber (reg:CC FLAGS_REG))])])
16674 ;; Non pairable "test imm, reg" instructions can be translated to
16675 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16676 ;; byte opcode instead of two, have a short form for byte operands),
16677 ;; so do it for other CPUs as well. Given that the value was dead,
16678 ;; this should not create any new dependencies. Pass on the sub-word
16679 ;; versions if we're concerned about partial register stalls.
16682 [(set (match_operand 0 "flags_reg_operand" "")
16683 (match_operator 1 "compare_operator"
16684 [(and:SI (match_operand:SI 2 "register_operand" "")
16685 (match_operand:SI 3 "immediate_operand" ""))
16687 "ix86_match_ccmode (insn, CCNOmode)
16688 && (true_regnum (operands[2]) != AX_REG
16689 || satisfies_constraint_K (operands[3]))
16690 && peep2_reg_dead_p (1, operands[2])"
16692 [(set (match_dup 0)
16693 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16696 (and:SI (match_dup 2) (match_dup 3)))])])
16698 ;; We don't need to handle HImode case, because it will be promoted to SImode
16699 ;; on ! TARGET_PARTIAL_REG_STALL
16702 [(set (match_operand 0 "flags_reg_operand" "")
16703 (match_operator 1 "compare_operator"
16704 [(and:QI (match_operand:QI 2 "register_operand" "")
16705 (match_operand:QI 3 "immediate_operand" ""))
16707 "! TARGET_PARTIAL_REG_STALL
16708 && ix86_match_ccmode (insn, CCNOmode)
16709 && true_regnum (operands[2]) != AX_REG
16710 && peep2_reg_dead_p (1, operands[2])"
16712 [(set (match_dup 0)
16713 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16716 (and:QI (match_dup 2) (match_dup 3)))])])
16719 [(set (match_operand 0 "flags_reg_operand" "")
16720 (match_operator 1 "compare_operator"
16723 (match_operand 2 "ext_register_operand" "")
16726 (match_operand 3 "const_int_operand" ""))
16728 "! TARGET_PARTIAL_REG_STALL
16729 && ix86_match_ccmode (insn, CCNOmode)
16730 && true_regnum (operands[2]) != AX_REG
16731 && peep2_reg_dead_p (1, operands[2])"
16732 [(parallel [(set (match_dup 0)
16741 (set (zero_extract:SI (match_dup 2)
16749 (match_dup 3)))])])
16751 ;; Don't do logical operations with memory inputs.
16753 [(match_scratch:SI 2 "r")
16754 (parallel [(set (match_operand:SI 0 "register_operand" "")
16755 (match_operator:SI 3 "arith_or_logical_operator"
16757 (match_operand:SI 1 "memory_operand" "")]))
16758 (clobber (reg:CC FLAGS_REG))])]
16759 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16760 [(set (match_dup 2) (match_dup 1))
16761 (parallel [(set (match_dup 0)
16762 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16763 (clobber (reg:CC FLAGS_REG))])])
16766 [(match_scratch:SI 2 "r")
16767 (parallel [(set (match_operand:SI 0 "register_operand" "")
16768 (match_operator:SI 3 "arith_or_logical_operator"
16769 [(match_operand:SI 1 "memory_operand" "")
16771 (clobber (reg:CC FLAGS_REG))])]
16772 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16773 [(set (match_dup 2) (match_dup 1))
16774 (parallel [(set (match_dup 0)
16775 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16776 (clobber (reg:CC FLAGS_REG))])])
16778 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
16779 ;; refers to the destination of the load!
16782 [(set (match_operand:SI 0 "register_operand" "")
16783 (match_operand:SI 1 "register_operand" ""))
16784 (parallel [(set (match_dup 0)
16785 (match_operator:SI 3 "commutative_operator"
16787 (match_operand:SI 2 "memory_operand" "")]))
16788 (clobber (reg:CC FLAGS_REG))])]
16789 "REGNO (operands[0]) != REGNO (operands[1])
16790 && GENERAL_REGNO_P (REGNO (operands[0]))
16791 && GENERAL_REGNO_P (REGNO (operands[1]))"
16792 [(set (match_dup 0) (match_dup 4))
16793 (parallel [(set (match_dup 0)
16794 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16795 (clobber (reg:CC FLAGS_REG))])]
16796 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
16799 [(set (match_operand 0 "register_operand" "")
16800 (match_operand 1 "register_operand" ""))
16802 (match_operator 3 "commutative_operator"
16804 (match_operand 2 "memory_operand" "")]))]
16805 "REGNO (operands[0]) != REGNO (operands[1])
16806 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
16807 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
16808 [(set (match_dup 0) (match_dup 2))
16810 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
16812 ; Don't do logical operations with memory outputs
16814 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16815 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
16816 ; the same decoder scheduling characteristics as the original.
16819 [(match_scratch:SI 2 "r")
16820 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16821 (match_operator:SI 3 "arith_or_logical_operator"
16823 (match_operand:SI 1 "nonmemory_operand" "")]))
16824 (clobber (reg:CC FLAGS_REG))])]
16825 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16826 /* Do not split stack checking probes. */
16827 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16828 [(set (match_dup 2) (match_dup 0))
16829 (parallel [(set (match_dup 2)
16830 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16831 (clobber (reg:CC FLAGS_REG))])
16832 (set (match_dup 0) (match_dup 2))])
16835 [(match_scratch:SI 2 "r")
16836 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16837 (match_operator:SI 3 "arith_or_logical_operator"
16838 [(match_operand:SI 1 "nonmemory_operand" "")
16840 (clobber (reg:CC FLAGS_REG))])]
16841 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16842 /* Do not split stack checking probes. */
16843 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16844 [(set (match_dup 2) (match_dup 0))
16845 (parallel [(set (match_dup 2)
16846 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16847 (clobber (reg:CC FLAGS_REG))])
16848 (set (match_dup 0) (match_dup 2))])
16850 ;; Attempt to always use XOR for zeroing registers.
16852 [(set (match_operand 0 "register_operand" "")
16853 (match_operand 1 "const0_operand" ""))]
16854 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
16855 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16856 && GENERAL_REG_P (operands[0])
16857 && peep2_regno_dead_p (0, FLAGS_REG)"
16858 [(parallel [(set (match_dup 0) (const_int 0))
16859 (clobber (reg:CC FLAGS_REG))])]
16860 "operands[0] = gen_lowpart (word_mode, operands[0]);")
16863 [(set (strict_low_part (match_operand 0 "register_operand" ""))
16865 "(GET_MODE (operands[0]) == QImode
16866 || GET_MODE (operands[0]) == HImode)
16867 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16868 && peep2_regno_dead_p (0, FLAGS_REG)"
16869 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
16870 (clobber (reg:CC FLAGS_REG))])])
16872 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
16874 [(set (match_operand:SWI248 0 "register_operand" "")
16876 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
16877 && peep2_regno_dead_p (0, FLAGS_REG)"
16878 [(parallel [(set (match_dup 0) (const_int -1))
16879 (clobber (reg:CC FLAGS_REG))])]
16881 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
16882 operands[0] = gen_lowpart (SImode, operands[0]);
16885 ;; Attempt to convert simple lea to add/shift.
16886 ;; These can be created by move expanders.
16889 [(set (match_operand:SWI48 0 "register_operand" "")
16890 (plus:SWI48 (match_dup 0)
16891 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
16892 "peep2_regno_dead_p (0, FLAGS_REG)"
16893 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
16894 (clobber (reg:CC FLAGS_REG))])])
16897 [(set (match_operand:SI 0 "register_operand" "")
16898 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
16899 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
16901 && peep2_regno_dead_p (0, FLAGS_REG)
16902 && REGNO (operands[0]) == REGNO (operands[1])"
16903 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
16904 (clobber (reg:CC FLAGS_REG))])]
16905 "operands[2] = gen_lowpart (SImode, operands[2]);")
16908 [(set (match_operand:SWI48 0 "register_operand" "")
16909 (mult:SWI48 (match_dup 0)
16910 (match_operand:SWI48 1 "const_int_operand" "")))]
16911 "exact_log2 (INTVAL (operands[1])) >= 0
16912 && peep2_regno_dead_p (0, FLAGS_REG)"
16913 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
16914 (clobber (reg:CC FLAGS_REG))])]
16915 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
16918 [(set (match_operand:SI 0 "register_operand" "")
16919 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
16920 (match_operand:DI 2 "const_int_operand" "")) 0))]
16922 && exact_log2 (INTVAL (operands[2])) >= 0
16923 && REGNO (operands[0]) == REGNO (operands[1])
16924 && peep2_regno_dead_p (0, FLAGS_REG)"
16925 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
16926 (clobber (reg:CC FLAGS_REG))])]
16927 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
16929 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
16930 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
16931 ;; On many CPUs it is also faster, since special hardware to avoid esp
16932 ;; dependencies is present.
16934 ;; While some of these conversions may be done using splitters, we use
16935 ;; peepholes in order to allow combine_stack_adjustments pass to see
16936 ;; nonobfuscated RTL.
16938 ;; Convert prologue esp subtractions to push.
16939 ;; We need register to push. In order to keep verify_flow_info happy we have
16941 ;; - use scratch and clobber it in order to avoid dependencies
16942 ;; - use already live register
16943 ;; We can't use the second way right now, since there is no reliable way how to
16944 ;; verify that given register is live. First choice will also most likely in
16945 ;; fewer dependencies. On the place of esp adjustments it is very likely that
16946 ;; call clobbered registers are dead. We may want to use base pointer as an
16947 ;; alternative when no register is available later.
16950 [(match_scratch:P 1 "r")
16951 (parallel [(set (reg:P SP_REG)
16952 (plus:P (reg:P SP_REG)
16953 (match_operand:P 0 "const_int_operand" "")))
16954 (clobber (reg:CC FLAGS_REG))
16955 (clobber (mem:BLK (scratch)))])]
16956 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16957 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
16958 [(clobber (match_dup 1))
16959 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16960 (clobber (mem:BLK (scratch)))])])
16963 [(match_scratch:P 1 "r")
16964 (parallel [(set (reg:P SP_REG)
16965 (plus:P (reg:P SP_REG)
16966 (match_operand:P 0 "const_int_operand" "")))
16967 (clobber (reg:CC FLAGS_REG))
16968 (clobber (mem:BLK (scratch)))])]
16969 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16970 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
16971 [(clobber (match_dup 1))
16972 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16973 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16974 (clobber (mem:BLK (scratch)))])])
16976 ;; Convert esp subtractions to push.
16978 [(match_scratch:P 1 "r")
16979 (parallel [(set (reg:P SP_REG)
16980 (plus:P (reg:P SP_REG)
16981 (match_operand:P 0 "const_int_operand" "")))
16982 (clobber (reg:CC FLAGS_REG))])]
16983 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16984 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
16985 [(clobber (match_dup 1))
16986 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
16989 [(match_scratch:P 1 "r")
16990 (parallel [(set (reg:P SP_REG)
16991 (plus:P (reg:P SP_REG)
16992 (match_operand:P 0 "const_int_operand" "")))
16993 (clobber (reg:CC FLAGS_REG))])]
16994 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16995 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
16996 [(clobber (match_dup 1))
16997 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16998 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17000 ;; Convert epilogue deallocator to pop.
17002 [(match_scratch:P 1 "r")
17003 (parallel [(set (reg:P SP_REG)
17004 (plus:P (reg:P SP_REG)
17005 (match_operand:P 0 "const_int_operand" "")))
17006 (clobber (reg:CC FLAGS_REG))
17007 (clobber (mem:BLK (scratch)))])]
17008 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17009 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17010 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17011 (clobber (mem:BLK (scratch)))])])
17013 ;; Two pops case is tricky, since pop causes dependency
17014 ;; on destination register. We use two registers if available.
17016 [(match_scratch:P 1 "r")
17017 (match_scratch:P 2 "r")
17018 (parallel [(set (reg:P SP_REG)
17019 (plus:P (reg:P SP_REG)
17020 (match_operand:P 0 "const_int_operand" "")))
17021 (clobber (reg:CC FLAGS_REG))
17022 (clobber (mem:BLK (scratch)))])]
17023 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17024 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17025 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17026 (clobber (mem:BLK (scratch)))])
17027 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17030 [(match_scratch:P 1 "r")
17031 (parallel [(set (reg:P SP_REG)
17032 (plus:P (reg:P SP_REG)
17033 (match_operand:P 0 "const_int_operand" "")))
17034 (clobber (reg:CC FLAGS_REG))
17035 (clobber (mem:BLK (scratch)))])]
17036 "optimize_insn_for_size_p ()
17037 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17038 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17039 (clobber (mem:BLK (scratch)))])
17040 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17042 ;; Convert esp additions to pop.
17044 [(match_scratch:P 1 "r")
17045 (parallel [(set (reg:P SP_REG)
17046 (plus:P (reg:P SP_REG)
17047 (match_operand:P 0 "const_int_operand" "")))
17048 (clobber (reg:CC FLAGS_REG))])]
17049 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17050 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17052 ;; Two pops case is tricky, since pop causes dependency
17053 ;; on destination register. We use two registers if available.
17055 [(match_scratch:P 1 "r")
17056 (match_scratch:P 2 "r")
17057 (parallel [(set (reg:P SP_REG)
17058 (plus:P (reg:P SP_REG)
17059 (match_operand:P 0 "const_int_operand" "")))
17060 (clobber (reg:CC FLAGS_REG))])]
17061 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17062 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17063 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17066 [(match_scratch:P 1 "r")
17067 (parallel [(set (reg:P SP_REG)
17068 (plus:P (reg:P SP_REG)
17069 (match_operand:P 0 "const_int_operand" "")))
17070 (clobber (reg:CC FLAGS_REG))])]
17071 "optimize_insn_for_size_p ()
17072 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17073 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17074 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17076 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17077 ;; required and register dies. Similarly for 128 to -128.
17079 [(set (match_operand 0 "flags_reg_operand" "")
17080 (match_operator 1 "compare_operator"
17081 [(match_operand 2 "register_operand" "")
17082 (match_operand 3 "const_int_operand" "")]))]
17083 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17084 && incdec_operand (operands[3], GET_MODE (operands[3])))
17085 || (!TARGET_FUSE_CMP_AND_BRANCH
17086 && INTVAL (operands[3]) == 128))
17087 && ix86_match_ccmode (insn, CCGCmode)
17088 && peep2_reg_dead_p (1, operands[2])"
17089 [(parallel [(set (match_dup 0)
17090 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17091 (clobber (match_dup 2))])])
17093 ;; Convert imul by three, five and nine into lea
17096 [(set (match_operand:SWI48 0 "register_operand" "")
17097 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17098 (match_operand:SWI48 2 "const_int_operand" "")))
17099 (clobber (reg:CC FLAGS_REG))])]
17100 "INTVAL (operands[2]) == 3
17101 || INTVAL (operands[2]) == 5
17102 || INTVAL (operands[2]) == 9"
17103 [(set (match_dup 0)
17104 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17106 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17110 [(set (match_operand:SWI48 0 "register_operand" "")
17111 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17112 (match_operand:SWI48 2 "const_int_operand" "")))
17113 (clobber (reg:CC FLAGS_REG))])]
17114 "optimize_insn_for_speed_p ()
17115 && (INTVAL (operands[2]) == 3
17116 || INTVAL (operands[2]) == 5
17117 || INTVAL (operands[2]) == 9)"
17118 [(set (match_dup 0) (match_dup 1))
17120 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17122 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17124 ;; imul $32bit_imm, mem, reg is vector decoded, while
17125 ;; imul $32bit_imm, reg, reg is direct decoded.
17127 [(match_scratch:SWI48 3 "r")
17128 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17129 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17130 (match_operand:SWI48 2 "immediate_operand" "")))
17131 (clobber (reg:CC FLAGS_REG))])]
17132 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17133 && !satisfies_constraint_K (operands[2])"
17134 [(set (match_dup 3) (match_dup 1))
17135 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17136 (clobber (reg:CC FLAGS_REG))])])
17139 [(match_scratch:SI 3 "r")
17140 (parallel [(set (match_operand:DI 0 "register_operand" "")
17142 (mult:SI (match_operand:SI 1 "memory_operand" "")
17143 (match_operand:SI 2 "immediate_operand" ""))))
17144 (clobber (reg:CC FLAGS_REG))])]
17146 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17147 && !satisfies_constraint_K (operands[2])"
17148 [(set (match_dup 3) (match_dup 1))
17149 (parallel [(set (match_dup 0)
17150 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17151 (clobber (reg:CC FLAGS_REG))])])
17153 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17154 ;; Convert it into imul reg, reg
17155 ;; It would be better to force assembler to encode instruction using long
17156 ;; immediate, but there is apparently no way to do so.
17158 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17160 (match_operand:SWI248 1 "nonimmediate_operand" "")
17161 (match_operand:SWI248 2 "const_int_operand" "")))
17162 (clobber (reg:CC FLAGS_REG))])
17163 (match_scratch:SWI248 3 "r")]
17164 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17165 && satisfies_constraint_K (operands[2])"
17166 [(set (match_dup 3) (match_dup 2))
17167 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17168 (clobber (reg:CC FLAGS_REG))])]
17170 if (!rtx_equal_p (operands[0], operands[1]))
17171 emit_move_insn (operands[0], operands[1]);
17174 ;; After splitting up read-modify operations, array accesses with memory
17175 ;; operands might end up in form:
17177 ;; movl 4(%esp), %edx
17179 ;; instead of pre-splitting:
17181 ;; addl 4(%esp), %eax
17183 ;; movl 4(%esp), %edx
17184 ;; leal (%edx,%eax,4), %eax
17187 [(match_scratch:P 5 "r")
17188 (parallel [(set (match_operand 0 "register_operand" "")
17189 (ashift (match_operand 1 "register_operand" "")
17190 (match_operand 2 "const_int_operand" "")))
17191 (clobber (reg:CC FLAGS_REG))])
17192 (parallel [(set (match_operand 3 "register_operand" "")
17193 (plus (match_dup 0)
17194 (match_operand 4 "x86_64_general_operand" "")))
17195 (clobber (reg:CC FLAGS_REG))])]
17196 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
17197 /* Validate MODE for lea. */
17198 && ((!TARGET_PARTIAL_REG_STALL
17199 && (GET_MODE (operands[0]) == QImode
17200 || GET_MODE (operands[0]) == HImode))
17201 || GET_MODE (operands[0]) == SImode
17202 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17203 && (rtx_equal_p (operands[0], operands[3])
17204 || peep2_reg_dead_p (2, operands[0]))
17205 /* We reorder load and the shift. */
17206 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17207 [(set (match_dup 5) (match_dup 4))
17208 (set (match_dup 0) (match_dup 1))]
17210 enum machine_mode mode = GET_MODE (operands[1]) == DImode ? DImode : SImode;
17211 int scale = 1 << INTVAL (operands[2]);
17212 rtx index = gen_lowpart (Pmode, operands[1]);
17213 rtx base = gen_lowpart (Pmode, operands[5]);
17214 rtx dest = gen_lowpart (mode, operands[3]);
17216 operands[1] = gen_rtx_PLUS (Pmode, base,
17217 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17218 operands[5] = base;
17221 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17222 operands[5] = gen_rtx_SUBREG (mode, operands[5], 0);
17224 operands[0] = dest;
17227 ;; Call-value patterns last so that the wildcard operand does not
17228 ;; disrupt insn-recog's switch tables.
17230 (define_insn "*call_value_pop_0"
17231 [(set (match_operand 0 "" "")
17232 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17233 (match_operand:SI 2 "" "")))
17234 (set (reg:SI SP_REG)
17235 (plus:SI (reg:SI SP_REG)
17236 (match_operand:SI 3 "immediate_operand" "")))]
17239 if (SIBLING_CALL_P (insn))
17242 return "call\t%P1";
17244 [(set_attr "type" "callv")])
17246 (define_insn "*call_value_pop_1"
17247 [(set (match_operand 0 "" "")
17248 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17249 (match_operand:SI 2 "" "")))
17250 (set (reg:SI SP_REG)
17251 (plus:SI (reg:SI SP_REG)
17252 (match_operand:SI 3 "immediate_operand" "i")))]
17253 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17255 if (constant_call_address_operand (operands[1], Pmode))
17256 return "call\t%P1";
17257 return "call\t%A1";
17259 [(set_attr "type" "callv")])
17261 (define_insn "*sibcall_value_pop_1"
17262 [(set (match_operand 0 "" "")
17263 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17264 (match_operand:SI 2 "" "")))
17265 (set (reg:SI SP_REG)
17266 (plus:SI (reg:SI SP_REG)
17267 (match_operand:SI 3 "immediate_operand" "i,i")))]
17268 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17272 [(set_attr "type" "callv")])
17274 (define_insn "*call_value_0"
17275 [(set (match_operand 0 "" "")
17276 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17277 (match_operand:SI 2 "" "")))]
17280 if (SIBLING_CALL_P (insn))
17283 return "call\t%P1";
17285 [(set_attr "type" "callv")])
17287 (define_insn "*call_value_0_rex64"
17288 [(set (match_operand 0 "" "")
17289 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17290 (match_operand:DI 2 "const_int_operand" "")))]
17293 if (SIBLING_CALL_P (insn))
17296 return "call\t%P1";
17298 [(set_attr "type" "callv")])
17300 (define_insn "*call_value_0_rex64_ms_sysv"
17301 [(set (match_operand 0 "" "")
17302 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17303 (match_operand:DI 2 "const_int_operand" "")))
17304 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17305 (clobber (reg:TI XMM6_REG))
17306 (clobber (reg:TI XMM7_REG))
17307 (clobber (reg:TI XMM8_REG))
17308 (clobber (reg:TI XMM9_REG))
17309 (clobber (reg:TI XMM10_REG))
17310 (clobber (reg:TI XMM11_REG))
17311 (clobber (reg:TI XMM12_REG))
17312 (clobber (reg:TI XMM13_REG))
17313 (clobber (reg:TI XMM14_REG))
17314 (clobber (reg:TI XMM15_REG))
17315 (clobber (reg:DI SI_REG))
17316 (clobber (reg:DI DI_REG))]
17317 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17319 if (SIBLING_CALL_P (insn))
17322 return "call\t%P1";
17324 [(set_attr "type" "callv")])
17326 (define_insn "*call_value_1"
17327 [(set (match_operand 0 "" "")
17328 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17329 (match_operand:SI 2 "" "")))]
17330 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17332 if (constant_call_address_operand (operands[1], Pmode))
17333 return "call\t%P1";
17334 return "call\t%A1";
17336 [(set_attr "type" "callv")])
17338 (define_insn "*sibcall_value_1"
17339 [(set (match_operand 0 "" "")
17340 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17341 (match_operand:SI 2 "" "")))]
17342 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17346 [(set_attr "type" "callv")])
17348 (define_insn "*call_value_1_rex64"
17349 [(set (match_operand 0 "" "")
17350 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17351 (match_operand:DI 2 "" "")))]
17352 "TARGET_64BIT && !SIBLING_CALL_P (insn)
17353 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17355 if (constant_call_address_operand (operands[1], Pmode))
17356 return "call\t%P1";
17357 return "call\t%A1";
17359 [(set_attr "type" "callv")])
17361 (define_insn "*call_value_1_rex64_ms_sysv"
17362 [(set (match_operand 0 "" "")
17363 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17364 (match_operand:DI 2 "" "")))
17365 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17366 (clobber (reg:TI XMM6_REG))
17367 (clobber (reg:TI XMM7_REG))
17368 (clobber (reg:TI XMM8_REG))
17369 (clobber (reg:TI XMM9_REG))
17370 (clobber (reg:TI XMM10_REG))
17371 (clobber (reg:TI XMM11_REG))
17372 (clobber (reg:TI XMM12_REG))
17373 (clobber (reg:TI XMM13_REG))
17374 (clobber (reg:TI XMM14_REG))
17375 (clobber (reg:TI XMM15_REG))
17376 (clobber (reg:DI SI_REG))
17377 (clobber (reg:DI DI_REG))]
17378 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17380 if (constant_call_address_operand (operands[1], Pmode))
17381 return "call\t%P1";
17382 return "call\t%A1";
17384 [(set_attr "type" "callv")])
17386 (define_insn "*call_value_1_rex64_large"
17387 [(set (match_operand 0 "" "")
17388 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17389 (match_operand:DI 2 "" "")))]
17390 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17392 [(set_attr "type" "callv")])
17394 (define_insn "*sibcall_value_1_rex64"
17395 [(set (match_operand 0 "" "")
17396 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17397 (match_operand:DI 2 "" "")))]
17398 "TARGET_64BIT && SIBLING_CALL_P (insn)"
17402 [(set_attr "type" "callv")])
17404 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17405 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17406 ;; caught for use by garbage collectors and the like. Using an insn that
17407 ;; maps to SIGILL makes it more likely the program will rightfully die.
17408 ;; Keeping with tradition, "6" is in honor of #UD.
17409 (define_insn "trap"
17410 [(trap_if (const_int 1) (const_int 6))]
17412 { return ASM_SHORT "0x0b0f"; }
17413 [(set_attr "length" "2")])
17415 (define_expand "prefetch"
17416 [(prefetch (match_operand 0 "address_operand" "")
17417 (match_operand:SI 1 "const_int_operand" "")
17418 (match_operand:SI 2 "const_int_operand" ""))]
17419 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17421 int rw = INTVAL (operands[1]);
17422 int locality = INTVAL (operands[2]);
17424 gcc_assert (rw == 0 || rw == 1);
17425 gcc_assert (locality >= 0 && locality <= 3);
17426 gcc_assert (GET_MODE (operands[0]) == Pmode
17427 || GET_MODE (operands[0]) == VOIDmode);
17429 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17430 supported by SSE counterpart or the SSE prefetch is not available
17431 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17433 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17434 operands[2] = GEN_INT (3);
17436 operands[1] = const0_rtx;
17439 (define_insn "*prefetch_sse_<mode>"
17440 [(prefetch (match_operand:P 0 "address_operand" "p")
17442 (match_operand:SI 1 "const_int_operand" ""))]
17443 "TARGET_PREFETCH_SSE"
17445 static const char * const patterns[4] = {
17446 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17449 int locality = INTVAL (operands[1]);
17450 gcc_assert (locality >= 0 && locality <= 3);
17452 return patterns[locality];
17454 [(set_attr "type" "sse")
17455 (set_attr "atom_sse_attr" "prefetch")
17456 (set (attr "length_address")
17457 (symbol_ref "memory_address_length (operands[0])"))
17458 (set_attr "memory" "none")])
17460 (define_insn "*prefetch_3dnow_<mode>"
17461 [(prefetch (match_operand:P 0 "address_operand" "p")
17462 (match_operand:SI 1 "const_int_operand" "n")
17466 if (INTVAL (operands[1]) == 0)
17467 return "prefetch\t%a0";
17469 return "prefetchw\t%a0";
17471 [(set_attr "type" "mmx")
17472 (set (attr "length_address")
17473 (symbol_ref "memory_address_length (operands[0])"))
17474 (set_attr "memory" "none")])
17476 (define_expand "stack_protect_set"
17477 [(match_operand 0 "memory_operand" "")
17478 (match_operand 1 "memory_operand" "")]
17481 rtx (*insn)(rtx, rtx);
17483 #ifdef TARGET_THREAD_SSP_OFFSET
17484 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17485 insn = (TARGET_64BIT
17486 ? gen_stack_tls_protect_set_di
17487 : gen_stack_tls_protect_set_si);
17489 insn = (TARGET_64BIT
17490 ? gen_stack_protect_set_di
17491 : gen_stack_protect_set_si);
17494 emit_insn (insn (operands[0], operands[1]));
17498 (define_insn "stack_protect_set_<mode>"
17499 [(set (match_operand:P 0 "memory_operand" "=m")
17500 (unspec:P [(match_operand:P 1 "memory_operand" "m")] UNSPEC_SP_SET))
17501 (set (match_scratch:P 2 "=&r") (const_int 0))
17502 (clobber (reg:CC FLAGS_REG))]
17504 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17505 [(set_attr "type" "multi")])
17507 (define_insn "stack_tls_protect_set_<mode>"
17508 [(set (match_operand:P 0 "memory_operand" "=m")
17509 (unspec:P [(match_operand:P 1 "const_int_operand" "i")]
17510 UNSPEC_SP_TLS_SET))
17511 (set (match_scratch:P 2 "=&r") (const_int 0))
17512 (clobber (reg:CC FLAGS_REG))]
17514 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17515 [(set_attr "type" "multi")])
17517 (define_expand "stack_protect_test"
17518 [(match_operand 0 "memory_operand" "")
17519 (match_operand 1 "memory_operand" "")
17520 (match_operand 2 "" "")]
17523 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17525 rtx (*insn)(rtx, rtx, rtx);
17527 #ifdef TARGET_THREAD_SSP_OFFSET
17528 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17529 insn = (TARGET_64BIT
17530 ? gen_stack_tls_protect_test_di
17531 : gen_stack_tls_protect_test_si);
17533 insn = (TARGET_64BIT
17534 ? gen_stack_protect_test_di
17535 : gen_stack_protect_test_si);
17538 emit_insn (insn (flags, operands[0], operands[1]));
17540 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17541 flags, const0_rtx, operands[2]));
17545 (define_insn "stack_protect_test_<mode>"
17546 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17547 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17548 (match_operand:P 2 "memory_operand" "m")]
17550 (clobber (match_scratch:P 3 "=&r"))]
17552 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17553 [(set_attr "type" "multi")])
17555 (define_insn "stack_tls_protect_test_<mode>"
17556 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17557 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17558 (match_operand:P 2 "const_int_operand" "i")]
17559 UNSPEC_SP_TLS_TEST))
17560 (clobber (match_scratch:P 3 "=r"))]
17562 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17563 [(set_attr "type" "multi")])
17565 (define_insn "sse4_2_crc32<mode>"
17566 [(set (match_operand:SI 0 "register_operand" "=r")
17568 [(match_operand:SI 1 "register_operand" "0")
17569 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17571 "TARGET_SSE4_2 || TARGET_CRC32"
17572 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17573 [(set_attr "type" "sselog1")
17574 (set_attr "prefix_rep" "1")
17575 (set_attr "prefix_extra" "1")
17576 (set (attr "prefix_data16")
17577 (if_then_else (match_operand:HI 2 "" "")
17579 (const_string "*")))
17580 (set (attr "prefix_rex")
17581 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17583 (const_string "*")))
17584 (set_attr "mode" "SI")])
17586 (define_insn "sse4_2_crc32di"
17587 [(set (match_operand:DI 0 "register_operand" "=r")
17589 [(match_operand:DI 1 "register_operand" "0")
17590 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17592 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17593 "crc32{q}\t{%2, %0|%0, %2}"
17594 [(set_attr "type" "sselog1")
17595 (set_attr "prefix_rep" "1")
17596 (set_attr "prefix_extra" "1")
17597 (set_attr "mode" "DI")])
17599 (define_expand "rdpmc"
17600 [(match_operand:DI 0 "register_operand" "")
17601 (match_operand:SI 1 "register_operand" "")]
17604 rtx reg = gen_reg_rtx (DImode);
17607 /* Force operand 1 into ECX. */
17608 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17609 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17610 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17615 rtvec vec = rtvec_alloc (2);
17616 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17617 rtx upper = gen_reg_rtx (DImode);
17618 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17619 gen_rtvec (1, const0_rtx),
17621 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17622 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17624 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17625 NULL, 1, OPTAB_DIRECT);
17626 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17630 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17631 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17635 (define_insn "*rdpmc"
17636 [(set (match_operand:DI 0 "register_operand" "=A")
17637 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17641 [(set_attr "type" "other")
17642 (set_attr "length" "2")])
17644 (define_insn "*rdpmc_rex64"
17645 [(set (match_operand:DI 0 "register_operand" "=a")
17646 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17648 (set (match_operand:DI 1 "register_operand" "=d")
17649 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17652 [(set_attr "type" "other")
17653 (set_attr "length" "2")])
17655 (define_expand "rdtsc"
17656 [(set (match_operand:DI 0 "register_operand" "")
17657 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17662 rtvec vec = rtvec_alloc (2);
17663 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17664 rtx upper = gen_reg_rtx (DImode);
17665 rtx lower = gen_reg_rtx (DImode);
17666 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17667 gen_rtvec (1, const0_rtx),
17669 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17670 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17672 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17673 NULL, 1, OPTAB_DIRECT);
17674 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17676 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17681 (define_insn "*rdtsc"
17682 [(set (match_operand:DI 0 "register_operand" "=A")
17683 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17686 [(set_attr "type" "other")
17687 (set_attr "length" "2")])
17689 (define_insn "*rdtsc_rex64"
17690 [(set (match_operand:DI 0 "register_operand" "=a")
17691 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17692 (set (match_operand:DI 1 "register_operand" "=d")
17693 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17696 [(set_attr "type" "other")
17697 (set_attr "length" "2")])
17699 (define_expand "rdtscp"
17700 [(match_operand:DI 0 "register_operand" "")
17701 (match_operand:SI 1 "memory_operand" "")]
17704 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17705 gen_rtvec (1, const0_rtx),
17707 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17708 gen_rtvec (1, const0_rtx),
17710 rtx reg = gen_reg_rtx (DImode);
17711 rtx tmp = gen_reg_rtx (SImode);
17715 rtvec vec = rtvec_alloc (3);
17716 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17717 rtx upper = gen_reg_rtx (DImode);
17718 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17719 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17720 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17722 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17723 NULL, 1, OPTAB_DIRECT);
17724 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17729 rtvec vec = rtvec_alloc (2);
17730 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17731 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17732 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17735 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17736 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17740 (define_insn "*rdtscp"
17741 [(set (match_operand:DI 0 "register_operand" "=A")
17742 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17743 (set (match_operand:SI 1 "register_operand" "=c")
17744 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17747 [(set_attr "type" "other")
17748 (set_attr "length" "3")])
17750 (define_insn "*rdtscp_rex64"
17751 [(set (match_operand:DI 0 "register_operand" "=a")
17752 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17753 (set (match_operand:DI 1 "register_operand" "=d")
17754 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17755 (set (match_operand:SI 2 "register_operand" "=c")
17756 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17759 [(set_attr "type" "other")
17760 (set_attr "length" "3")])
17762 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17764 ;; LWP instructions
17766 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17768 (define_expand "lwp_llwpcb"
17769 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17770 UNSPECV_LLWP_INTRINSIC)]
17773 (define_insn "*lwp_llwpcb<mode>1"
17774 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17775 UNSPECV_LLWP_INTRINSIC)]
17778 [(set_attr "type" "lwp")
17779 (set_attr "mode" "<MODE>")
17780 (set_attr "length" "5")])
17782 (define_expand "lwp_slwpcb"
17783 [(set (match_operand 0 "register_operand" "=r")
17784 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17788 emit_insn (gen_lwp_slwpcbdi (operands[0]));
17790 emit_insn (gen_lwp_slwpcbsi (operands[0]));
17794 (define_insn "lwp_slwpcb<mode>"
17795 [(set (match_operand:P 0 "register_operand" "=r")
17796 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17799 [(set_attr "type" "lwp")
17800 (set_attr "mode" "<MODE>")
17801 (set_attr "length" "5")])
17803 (define_expand "lwp_lwpval<mode>3"
17804 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
17805 (match_operand:SI 2 "nonimmediate_operand" "rm")
17806 (match_operand:SI 3 "const_int_operand" "i")]
17807 UNSPECV_LWPVAL_INTRINSIC)]
17809 "/* Avoid unused variable warning. */
17812 (define_insn "*lwp_lwpval<mode>3_1"
17813 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
17814 (match_operand:SI 1 "nonimmediate_operand" "rm")
17815 (match_operand:SI 2 "const_int_operand" "i")]
17816 UNSPECV_LWPVAL_INTRINSIC)]
17818 "lwpval\t{%2, %1, %0|%0, %1, %2}"
17819 [(set_attr "type" "lwp")
17820 (set_attr "mode" "<MODE>")
17821 (set (attr "length")
17822 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17824 (define_expand "lwp_lwpins<mode>3"
17825 [(set (reg:CCC FLAGS_REG)
17826 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
17827 (match_operand:SI 2 "nonimmediate_operand" "rm")
17828 (match_operand:SI 3 "const_int_operand" "i")]
17829 UNSPECV_LWPINS_INTRINSIC))
17830 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
17831 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
17834 (define_insn "*lwp_lwpins<mode>3_1"
17835 [(set (reg:CCC FLAGS_REG)
17836 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
17837 (match_operand:SI 1 "nonimmediate_operand" "rm")
17838 (match_operand:SI 2 "const_int_operand" "i")]
17839 UNSPECV_LWPINS_INTRINSIC))]
17841 "lwpins\t{%2, %1, %0|%0, %1, %2}"
17842 [(set_attr "type" "lwp")
17843 (set_attr "mode" "<MODE>")
17844 (set (attr "length")
17845 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17847 (define_insn "rdfsbase<mode>"
17848 [(set (match_operand:SWI48 0 "register_operand" "=r")
17849 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
17850 "TARGET_64BIT && TARGET_FSGSBASE"
17852 [(set_attr "type" "other")
17853 (set_attr "prefix_extra" "2")])
17855 (define_insn "rdgsbase<mode>"
17856 [(set (match_operand:SWI48 0 "register_operand" "=r")
17857 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
17858 "TARGET_64BIT && TARGET_FSGSBASE"
17860 [(set_attr "type" "other")
17861 (set_attr "prefix_extra" "2")])
17863 (define_insn "wrfsbase<mode>"
17864 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17866 "TARGET_64BIT && TARGET_FSGSBASE"
17868 [(set_attr "type" "other")
17869 (set_attr "prefix_extra" "2")])
17871 (define_insn "wrgsbase<mode>"
17872 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17874 "TARGET_64BIT && TARGET_FSGSBASE"
17876 [(set_attr "type" "other")
17877 (set_attr "prefix_extra" "2")])
17879 (define_expand "rdrand<mode>"
17880 [(set (match_operand:SWI248 0 "register_operand" "=r")
17881 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))]
17884 rtx retry_label, insn, ccc;
17886 retry_label = gen_label_rtx ();
17888 emit_label (retry_label);
17890 /* Generate rdrand. */
17891 emit_insn (gen_rdrand<mode>_1 (operands[0]));
17893 /* Retry if the carry flag isn't valid. */
17894 ccc = gen_rtx_REG (CCCmode, FLAGS_REG);
17895 ccc = gen_rtx_EQ (VOIDmode, ccc, const0_rtx);
17896 ccc = gen_rtx_IF_THEN_ELSE (VOIDmode, ccc, pc_rtx,
17897 gen_rtx_LABEL_REF (VOIDmode, retry_label));
17898 insn = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, ccc));
17899 JUMP_LABEL (insn) = retry_label;
17904 (define_insn "rdrand<mode>_1"
17905 [(set (match_operand:SWI248 0 "register_operand" "=r")
17906 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))]
17909 [(set_attr "type" "other")
17910 (set_attr "prefix_extra" "1")])
17914 (include "sync.md")