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
95 ;; Other random patterns
104 UNSPEC_LD_MPIC ; load_macho_picbase
107 ;; For SSE/MMX support:
125 UNSPEC_MS_TO_SYSV_CALL
127 ;; Generic math support
129 UNSPEC_IEEE_MIN ; not commutative
130 UNSPEC_IEEE_MAX ; not commutative
132 ;; x87 Floating point
148 UNSPEC_FRNDINT_MASK_PM
152 ;; x87 Double output FP
184 ;; For SSE4.1 support
194 ;; For SSE4.2 support
200 UNSPEC_FMA4_INTRINSIC
203 UNSPEC_XOP_UNSIGNED_CMP
214 UNSPEC_AESKEYGENASSIST
216 ;; For PCLMUL support
232 (define_c_enum "unspecv" [
235 UNSPECV_PROBE_STACK_RANGE
254 UNSPECV_LLWP_INTRINSIC
255 UNSPECV_SLWP_INTRINSIC
256 UNSPECV_LWPVAL_INTRINSIC
257 UNSPECV_LWPINS_INTRINSIC
265 ;; Constants to represent pcomtrue/pcomfalse variants
275 ;; Constants used in the XOP pperm instruction
277 [(PPERM_SRC 0x00) /* copy source */
278 (PPERM_INVERT 0x20) /* invert source */
279 (PPERM_REVERSE 0x40) /* bit reverse source */
280 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
281 (PPERM_ZERO 0x80) /* all 0's */
282 (PPERM_ONES 0xa0) /* all 1's */
283 (PPERM_SIGN 0xc0) /* propagate sign bit */
284 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
285 (PPERM_SRC1 0x00) /* use first source byte */
286 (PPERM_SRC2 0x10) /* use second source byte */
289 ;; Registers by name.
342 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
345 ;; In C guard expressions, put expressions which may be compile-time
346 ;; constants first. This allows for better optimization. For
347 ;; example, write "TARGET_64BIT && reload_completed", not
348 ;; "reload_completed && TARGET_64BIT".
352 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,atom,
353 generic64,amdfam10,bdver1"
354 (const (symbol_ref "ix86_schedule")))
356 ;; A basic instruction type. Refinements due to arguments to be
357 ;; provided in other attributes.
360 alu,alu1,negnot,imov,imovx,lea,
361 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
362 icmp,test,ibr,setcc,icmov,
363 push,pop,call,callv,leave,
365 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
366 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
367 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
368 ssemuladd,sse4arg,lwp,
369 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
370 (const_string "other"))
372 ;; Main data type used by the insn
374 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
375 (const_string "unknown"))
377 ;; The CPU unit operations uses.
378 (define_attr "unit" "integer,i387,sse,mmx,unknown"
379 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
380 (const_string "i387")
381 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
382 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
383 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
385 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
387 (eq_attr "type" "other")
388 (const_string "unknown")]
389 (const_string "integer")))
391 ;; The (bounding maximum) length of an instruction immediate.
392 (define_attr "length_immediate" ""
393 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
396 (eq_attr "unit" "i387,sse,mmx")
398 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
400 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
401 (eq_attr "type" "imov,test")
402 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
403 (eq_attr "type" "call")
404 (if_then_else (match_operand 0 "constant_call_address_operand" "")
407 (eq_attr "type" "callv")
408 (if_then_else (match_operand 1 "constant_call_address_operand" "")
411 ;; We don't know the size before shorten_branches. Expect
412 ;; the instruction to fit for better scheduling.
413 (eq_attr "type" "ibr")
416 (symbol_ref "/* Update immediate_length and other attributes! */
417 gcc_unreachable (),1")))
419 ;; The (bounding maximum) length of an instruction address.
420 (define_attr "length_address" ""
421 (cond [(eq_attr "type" "str,other,multi,fxch")
423 (and (eq_attr "type" "call")
424 (match_operand 0 "constant_call_address_operand" ""))
426 (and (eq_attr "type" "callv")
427 (match_operand 1 "constant_call_address_operand" ""))
430 (symbol_ref "ix86_attr_length_address_default (insn)")))
432 ;; Set when length prefix is used.
433 (define_attr "prefix_data16" ""
434 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
436 (eq_attr "mode" "HI")
438 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
443 ;; Set when string REP prefix is used.
444 (define_attr "prefix_rep" ""
445 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
447 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
452 ;; Set when 0f opcode prefix is used.
453 (define_attr "prefix_0f" ""
455 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
456 (eq_attr "unit" "sse,mmx"))
460 ;; Set when REX opcode prefix is used.
461 (define_attr "prefix_rex" ""
462 (cond [(ne (symbol_ref "!TARGET_64BIT") (const_int 0))
464 (and (eq_attr "mode" "DI")
465 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
466 (eq_attr "unit" "!mmx")))
468 (and (eq_attr "mode" "QI")
469 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
472 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
475 (and (eq_attr "type" "imovx")
476 (match_operand:QI 1 "ext_QIreg_operand" ""))
481 ;; There are also additional prefixes in 3DNOW, SSSE3.
482 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
483 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
484 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
485 (define_attr "prefix_extra" ""
486 (cond [(eq_attr "type" "ssemuladd,sse4arg")
488 (eq_attr "type" "sseiadd1,ssecvt1")
493 ;; Prefix used: original, VEX or maybe VEX.
494 (define_attr "prefix" "orig,vex,maybe_vex"
495 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
497 (const_string "orig")))
499 ;; VEX W bit is used.
500 (define_attr "prefix_vex_w" "" (const_int 0))
502 ;; The length of VEX prefix
503 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
504 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
505 ;; still prefix_0f 1, with prefix_extra 1.
506 (define_attr "length_vex" ""
507 (if_then_else (and (eq_attr "prefix_0f" "1")
508 (eq_attr "prefix_extra" "0"))
509 (if_then_else (eq_attr "prefix_vex_w" "1")
510 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
511 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
512 (if_then_else (eq_attr "prefix_vex_w" "1")
513 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
514 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
516 ;; Set when modrm byte is used.
517 (define_attr "modrm" ""
518 (cond [(eq_attr "type" "str,leave")
520 (eq_attr "unit" "i387")
522 (and (eq_attr "type" "incdec")
523 (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
524 (ior (match_operand:SI 1 "register_operand" "")
525 (match_operand:HI 1 "register_operand" ""))))
527 (and (eq_attr "type" "push")
528 (not (match_operand 1 "memory_operand" "")))
530 (and (eq_attr "type" "pop")
531 (not (match_operand 0 "memory_operand" "")))
533 (and (eq_attr "type" "imov")
534 (and (not (eq_attr "mode" "DI"))
535 (ior (and (match_operand 0 "register_operand" "")
536 (match_operand 1 "immediate_operand" ""))
537 (ior (and (match_operand 0 "ax_reg_operand" "")
538 (match_operand 1 "memory_displacement_only_operand" ""))
539 (and (match_operand 0 "memory_displacement_only_operand" "")
540 (match_operand 1 "ax_reg_operand" ""))))))
542 (and (eq_attr "type" "call")
543 (match_operand 0 "constant_call_address_operand" ""))
545 (and (eq_attr "type" "callv")
546 (match_operand 1 "constant_call_address_operand" ""))
548 (and (eq_attr "type" "alu,alu1,icmp,test")
549 (match_operand 0 "ax_reg_operand" ""))
550 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
554 ;; The (bounding maximum) length of an instruction in bytes.
555 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
556 ;; Later we may want to split them and compute proper length as for
558 (define_attr "length" ""
559 (cond [(eq_attr "type" "other,multi,fistp,frndint")
561 (eq_attr "type" "fcmp")
563 (eq_attr "unit" "i387")
565 (plus (attr "prefix_data16")
566 (attr "length_address")))
567 (ior (eq_attr "prefix" "vex")
568 (and (eq_attr "prefix" "maybe_vex")
569 (ne (symbol_ref "TARGET_AVX") (const_int 0))))
570 (plus (attr "length_vex")
571 (plus (attr "length_immediate")
573 (attr "length_address"))))]
574 (plus (plus (attr "modrm")
575 (plus (attr "prefix_0f")
576 (plus (attr "prefix_rex")
577 (plus (attr "prefix_extra")
579 (plus (attr "prefix_rep")
580 (plus (attr "prefix_data16")
581 (plus (attr "length_immediate")
582 (attr "length_address")))))))
584 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
585 ;; `store' if there is a simple memory reference therein, or `unknown'
586 ;; if the instruction is complex.
588 (define_attr "memory" "none,load,store,both,unknown"
589 (cond [(eq_attr "type" "other,multi,str,lwp")
590 (const_string "unknown")
591 (eq_attr "type" "lea,fcmov,fpspc")
592 (const_string "none")
593 (eq_attr "type" "fistp,leave")
594 (const_string "both")
595 (eq_attr "type" "frndint")
596 (const_string "load")
597 (eq_attr "type" "push")
598 (if_then_else (match_operand 1 "memory_operand" "")
599 (const_string "both")
600 (const_string "store"))
601 (eq_attr "type" "pop")
602 (if_then_else (match_operand 0 "memory_operand" "")
603 (const_string "both")
604 (const_string "load"))
605 (eq_attr "type" "setcc")
606 (if_then_else (match_operand 0 "memory_operand" "")
607 (const_string "store")
608 (const_string "none"))
609 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
610 (if_then_else (ior (match_operand 0 "memory_operand" "")
611 (match_operand 1 "memory_operand" ""))
612 (const_string "load")
613 (const_string "none"))
614 (eq_attr "type" "ibr")
615 (if_then_else (match_operand 0 "memory_operand" "")
616 (const_string "load")
617 (const_string "none"))
618 (eq_attr "type" "call")
619 (if_then_else (match_operand 0 "constant_call_address_operand" "")
620 (const_string "none")
621 (const_string "load"))
622 (eq_attr "type" "callv")
623 (if_then_else (match_operand 1 "constant_call_address_operand" "")
624 (const_string "none")
625 (const_string "load"))
626 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
627 (match_operand 1 "memory_operand" ""))
628 (const_string "both")
629 (and (match_operand 0 "memory_operand" "")
630 (match_operand 1 "memory_operand" ""))
631 (const_string "both")
632 (match_operand 0 "memory_operand" "")
633 (const_string "store")
634 (match_operand 1 "memory_operand" "")
635 (const_string "load")
637 "!alu1,negnot,ishift1,
638 imov,imovx,icmp,test,bitmanip,
640 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
641 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
642 (match_operand 2 "memory_operand" ""))
643 (const_string "load")
644 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
645 (match_operand 3 "memory_operand" ""))
646 (const_string "load")
648 (const_string "none")))
650 ;; Indicates if an instruction has both an immediate and a displacement.
652 (define_attr "imm_disp" "false,true,unknown"
653 (cond [(eq_attr "type" "other,multi")
654 (const_string "unknown")
655 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
656 (and (match_operand 0 "memory_displacement_operand" "")
657 (match_operand 1 "immediate_operand" "")))
658 (const_string "true")
659 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
660 (and (match_operand 0 "memory_displacement_operand" "")
661 (match_operand 2 "immediate_operand" "")))
662 (const_string "true")
664 (const_string "false")))
666 ;; Indicates if an FP operation has an integer source.
668 (define_attr "fp_int_src" "false,true"
669 (const_string "false"))
671 ;; Defines rounding mode of an FP operation.
673 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
674 (const_string "any"))
676 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
677 (define_attr "use_carry" "0,1" (const_string "0"))
679 ;; Define attribute to indicate unaligned ssemov insns
680 (define_attr "movu" "0,1" (const_string "0"))
682 ;; Describe a user's asm statement.
683 (define_asm_attributes
684 [(set_attr "length" "128")
685 (set_attr "type" "multi")])
687 (define_code_iterator plusminus [plus minus])
689 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
691 ;; Base name for define_insn
692 (define_code_attr plusminus_insn
693 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
694 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
696 ;; Base name for insn mnemonic.
697 (define_code_attr plusminus_mnemonic
698 [(plus "add") (ss_plus "adds") (us_plus "addus")
699 (minus "sub") (ss_minus "subs") (us_minus "subus")])
700 (define_code_attr plusminus_carry_mnemonic
701 [(plus "adc") (minus "sbb")])
703 ;; Mark commutative operators as such in constraints.
704 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
705 (minus "") (ss_minus "") (us_minus "")])
707 ;; Mapping of signed max and min
708 (define_code_iterator smaxmin [smax smin])
710 ;; Mapping of unsigned max and min
711 (define_code_iterator umaxmin [umax umin])
713 ;; Mapping of signed/unsigned max and min
714 (define_code_iterator maxmin [smax smin 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>" "")))]
986 (define_insn "*cmp<mode>_ccno_1"
987 [(set (reg FLAGS_REG)
988 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
989 (match_operand:SWI 1 "const0_operand" "")))]
990 "ix86_match_ccmode (insn, CCNOmode)"
992 test{<imodesuffix>}\t%0, %0
993 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
994 [(set_attr "type" "test,icmp")
995 (set_attr "length_immediate" "0,1")
996 (set_attr "mode" "<MODE>")])
998 (define_insn "*cmp<mode>_1"
999 [(set (reg FLAGS_REG)
1000 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1001 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1002 "ix86_match_ccmode (insn, CCmode)"
1003 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1004 [(set_attr "type" "icmp")
1005 (set_attr "mode" "<MODE>")])
1007 (define_insn "*cmp<mode>_minus_1"
1008 [(set (reg FLAGS_REG)
1010 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1011 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1013 "ix86_match_ccmode (insn, CCGOCmode)"
1014 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1015 [(set_attr "type" "icmp")
1016 (set_attr "mode" "<MODE>")])
1018 (define_insn "*cmpqi_ext_1"
1019 [(set (reg FLAGS_REG)
1021 (match_operand:QI 0 "general_operand" "Qm")
1024 (match_operand 1 "ext_register_operand" "Q")
1026 (const_int 8)) 0)))]
1027 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1028 "cmp{b}\t{%h1, %0|%0, %h1}"
1029 [(set_attr "type" "icmp")
1030 (set_attr "mode" "QI")])
1032 (define_insn "*cmpqi_ext_1_rex64"
1033 [(set (reg FLAGS_REG)
1035 (match_operand:QI 0 "register_operand" "Q")
1038 (match_operand 1 "ext_register_operand" "Q")
1040 (const_int 8)) 0)))]
1041 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1042 "cmp{b}\t{%h1, %0|%0, %h1}"
1043 [(set_attr "type" "icmp")
1044 (set_attr "mode" "QI")])
1046 (define_insn "*cmpqi_ext_2"
1047 [(set (reg FLAGS_REG)
1051 (match_operand 0 "ext_register_operand" "Q")
1054 (match_operand:QI 1 "const0_operand" "")))]
1055 "ix86_match_ccmode (insn, CCNOmode)"
1057 [(set_attr "type" "test")
1058 (set_attr "length_immediate" "0")
1059 (set_attr "mode" "QI")])
1061 (define_expand "cmpqi_ext_3"
1062 [(set (reg:CC FLAGS_REG)
1066 (match_operand 0 "ext_register_operand" "")
1069 (match_operand:QI 1 "immediate_operand" "")))]
1073 (define_insn "*cmpqi_ext_3_insn"
1074 [(set (reg FLAGS_REG)
1078 (match_operand 0 "ext_register_operand" "Q")
1081 (match_operand:QI 1 "general_operand" "Qmn")))]
1082 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1083 "cmp{b}\t{%1, %h0|%h0, %1}"
1084 [(set_attr "type" "icmp")
1085 (set_attr "modrm" "1")
1086 (set_attr "mode" "QI")])
1088 (define_insn "*cmpqi_ext_3_insn_rex64"
1089 [(set (reg FLAGS_REG)
1093 (match_operand 0 "ext_register_operand" "Q")
1096 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1097 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1098 "cmp{b}\t{%1, %h0|%h0, %1}"
1099 [(set_attr "type" "icmp")
1100 (set_attr "modrm" "1")
1101 (set_attr "mode" "QI")])
1103 (define_insn "*cmpqi_ext_4"
1104 [(set (reg FLAGS_REG)
1108 (match_operand 0 "ext_register_operand" "Q")
1113 (match_operand 1 "ext_register_operand" "Q")
1115 (const_int 8)) 0)))]
1116 "ix86_match_ccmode (insn, CCmode)"
1117 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1118 [(set_attr "type" "icmp")
1119 (set_attr "mode" "QI")])
1121 ;; These implement float point compares.
1122 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1123 ;; which would allow mix and match FP modes on the compares. Which is what
1124 ;; the old patterns did, but with many more of them.
1126 (define_expand "cbranchxf4"
1127 [(set (reg:CC FLAGS_REG)
1128 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1129 (match_operand:XF 2 "nonmemory_operand" "")))
1130 (set (pc) (if_then_else
1131 (match_operator 0 "ix86_fp_comparison_operator"
1134 (label_ref (match_operand 3 "" ""))
1138 ix86_expand_branch (GET_CODE (operands[0]),
1139 operands[1], operands[2], operands[3]);
1143 (define_expand "cstorexf4"
1144 [(set (reg:CC FLAGS_REG)
1145 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1146 (match_operand:XF 3 "nonmemory_operand" "")))
1147 (set (match_operand:QI 0 "register_operand" "")
1148 (match_operator 1 "ix86_fp_comparison_operator"
1153 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1154 operands[2], operands[3]);
1158 (define_expand "cbranch<mode>4"
1159 [(set (reg:CC FLAGS_REG)
1160 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1161 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1162 (set (pc) (if_then_else
1163 (match_operator 0 "ix86_fp_comparison_operator"
1166 (label_ref (match_operand 3 "" ""))
1168 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1170 ix86_expand_branch (GET_CODE (operands[0]),
1171 operands[1], operands[2], operands[3]);
1175 (define_expand "cstore<mode>4"
1176 [(set (reg:CC FLAGS_REG)
1177 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1178 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1179 (set (match_operand:QI 0 "register_operand" "")
1180 (match_operator 1 "ix86_fp_comparison_operator"
1183 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1185 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1186 operands[2], operands[3]);
1190 (define_expand "cbranchcc4"
1191 [(set (pc) (if_then_else
1192 (match_operator 0 "comparison_operator"
1193 [(match_operand 1 "flags_reg_operand" "")
1194 (match_operand 2 "const0_operand" "")])
1195 (label_ref (match_operand 3 "" ""))
1199 ix86_expand_branch (GET_CODE (operands[0]),
1200 operands[1], operands[2], operands[3]);
1204 (define_expand "cstorecc4"
1205 [(set (match_operand:QI 0 "register_operand" "")
1206 (match_operator 1 "comparison_operator"
1207 [(match_operand 2 "flags_reg_operand" "")
1208 (match_operand 3 "const0_operand" "")]))]
1211 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1212 operands[2], operands[3]);
1217 ;; FP compares, step 1:
1218 ;; Set the FP condition codes.
1220 ;; CCFPmode compare with exceptions
1221 ;; CCFPUmode compare with no exceptions
1223 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1224 ;; used to manage the reg stack popping would not be preserved.
1226 (define_insn "*cmpfp_0"
1227 [(set (match_operand:HI 0 "register_operand" "=a")
1230 (match_operand 1 "register_operand" "f")
1231 (match_operand 2 "const0_operand" ""))]
1233 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1234 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1235 "* return output_fp_compare (insn, operands, 0, 0);"
1236 [(set_attr "type" "multi")
1237 (set_attr "unit" "i387")
1239 (cond [(match_operand:SF 1 "" "")
1241 (match_operand:DF 1 "" "")
1244 (const_string "XF")))])
1246 (define_insn_and_split "*cmpfp_0_cc"
1247 [(set (reg:CCFP FLAGS_REG)
1249 (match_operand 1 "register_operand" "f")
1250 (match_operand 2 "const0_operand" "")))
1251 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1252 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1253 && TARGET_SAHF && !TARGET_CMOVE
1254 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1256 "&& reload_completed"
1259 [(compare:CCFP (match_dup 1)(match_dup 2))]
1261 (set (reg:CC FLAGS_REG)
1262 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1264 [(set_attr "type" "multi")
1265 (set_attr "unit" "i387")
1267 (cond [(match_operand:SF 1 "" "")
1269 (match_operand:DF 1 "" "")
1272 (const_string "XF")))])
1274 (define_insn "*cmpfp_xf"
1275 [(set (match_operand:HI 0 "register_operand" "=a")
1278 (match_operand:XF 1 "register_operand" "f")
1279 (match_operand:XF 2 "register_operand" "f"))]
1282 "* return output_fp_compare (insn, operands, 0, 0);"
1283 [(set_attr "type" "multi")
1284 (set_attr "unit" "i387")
1285 (set_attr "mode" "XF")])
1287 (define_insn_and_split "*cmpfp_xf_cc"
1288 [(set (reg:CCFP FLAGS_REG)
1290 (match_operand:XF 1 "register_operand" "f")
1291 (match_operand:XF 2 "register_operand" "f")))
1292 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1294 && TARGET_SAHF && !TARGET_CMOVE"
1296 "&& reload_completed"
1299 [(compare:CCFP (match_dup 1)(match_dup 2))]
1301 (set (reg:CC FLAGS_REG)
1302 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1304 [(set_attr "type" "multi")
1305 (set_attr "unit" "i387")
1306 (set_attr "mode" "XF")])
1308 (define_insn "*cmpfp_<mode>"
1309 [(set (match_operand:HI 0 "register_operand" "=a")
1312 (match_operand:MODEF 1 "register_operand" "f")
1313 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1316 "* return output_fp_compare (insn, operands, 0, 0);"
1317 [(set_attr "type" "multi")
1318 (set_attr "unit" "i387")
1319 (set_attr "mode" "<MODE>")])
1321 (define_insn_and_split "*cmpfp_<mode>_cc"
1322 [(set (reg:CCFP FLAGS_REG)
1324 (match_operand:MODEF 1 "register_operand" "f")
1325 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1326 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1328 && TARGET_SAHF && !TARGET_CMOVE"
1330 "&& reload_completed"
1333 [(compare:CCFP (match_dup 1)(match_dup 2))]
1335 (set (reg:CC FLAGS_REG)
1336 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1338 [(set_attr "type" "multi")
1339 (set_attr "unit" "i387")
1340 (set_attr "mode" "<MODE>")])
1342 (define_insn "*cmpfp_u"
1343 [(set (match_operand:HI 0 "register_operand" "=a")
1346 (match_operand 1 "register_operand" "f")
1347 (match_operand 2 "register_operand" "f"))]
1349 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1350 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1351 "* return output_fp_compare (insn, operands, 0, 1);"
1352 [(set_attr "type" "multi")
1353 (set_attr "unit" "i387")
1355 (cond [(match_operand:SF 1 "" "")
1357 (match_operand:DF 1 "" "")
1360 (const_string "XF")))])
1362 (define_insn_and_split "*cmpfp_u_cc"
1363 [(set (reg:CCFPU FLAGS_REG)
1365 (match_operand 1 "register_operand" "f")
1366 (match_operand 2 "register_operand" "f")))
1367 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1368 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1369 && TARGET_SAHF && !TARGET_CMOVE
1370 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1372 "&& reload_completed"
1375 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1377 (set (reg:CC FLAGS_REG)
1378 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1380 [(set_attr "type" "multi")
1381 (set_attr "unit" "i387")
1383 (cond [(match_operand:SF 1 "" "")
1385 (match_operand:DF 1 "" "")
1388 (const_string "XF")))])
1390 (define_insn "*cmpfp_<mode>"
1391 [(set (match_operand:HI 0 "register_operand" "=a")
1394 (match_operand 1 "register_operand" "f")
1395 (match_operator 3 "float_operator"
1396 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1398 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1399 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1400 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1401 "* return output_fp_compare (insn, operands, 0, 0);"
1402 [(set_attr "type" "multi")
1403 (set_attr "unit" "i387")
1404 (set_attr "fp_int_src" "true")
1405 (set_attr "mode" "<MODE>")])
1407 (define_insn_and_split "*cmpfp_<mode>_cc"
1408 [(set (reg:CCFP FLAGS_REG)
1410 (match_operand 1 "register_operand" "f")
1411 (match_operator 3 "float_operator"
1412 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1413 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1414 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1415 && TARGET_SAHF && !TARGET_CMOVE
1416 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1417 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1419 "&& reload_completed"
1424 (match_op_dup 3 [(match_dup 2)]))]
1426 (set (reg:CC FLAGS_REG)
1427 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1429 [(set_attr "type" "multi")
1430 (set_attr "unit" "i387")
1431 (set_attr "fp_int_src" "true")
1432 (set_attr "mode" "<MODE>")])
1434 ;; FP compares, step 2
1435 ;; Move the fpsw to ax.
1437 (define_insn "x86_fnstsw_1"
1438 [(set (match_operand:HI 0 "register_operand" "=a")
1439 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1442 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1443 (set_attr "mode" "SI")
1444 (set_attr "unit" "i387")])
1446 ;; FP compares, step 3
1447 ;; Get ax into flags, general case.
1449 (define_insn "x86_sahf_1"
1450 [(set (reg:CC FLAGS_REG)
1451 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1455 #ifndef HAVE_AS_IX86_SAHF
1457 return ASM_BYTE "0x9e";
1462 [(set_attr "length" "1")
1463 (set_attr "athlon_decode" "vector")
1464 (set_attr "amdfam10_decode" "direct")
1465 (set_attr "mode" "SI")])
1467 ;; Pentium Pro can do steps 1 through 3 in one go.
1468 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1469 (define_insn "*cmpfp_i_mixed"
1470 [(set (reg:CCFP FLAGS_REG)
1471 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1472 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1473 "TARGET_MIX_SSE_I387
1474 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1475 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1476 "* return output_fp_compare (insn, operands, 1, 0);"
1477 [(set_attr "type" "fcmp,ssecomi")
1478 (set_attr "prefix" "orig,maybe_vex")
1480 (if_then_else (match_operand:SF 1 "" "")
1482 (const_string "DF")))
1483 (set (attr "prefix_rep")
1484 (if_then_else (eq_attr "type" "ssecomi")
1486 (const_string "*")))
1487 (set (attr "prefix_data16")
1488 (cond [(eq_attr "type" "fcmp")
1490 (eq_attr "mode" "DF")
1493 (const_string "0")))
1494 (set_attr "athlon_decode" "vector")
1495 (set_attr "amdfam10_decode" "direct")])
1497 (define_insn "*cmpfp_i_sse"
1498 [(set (reg:CCFP FLAGS_REG)
1499 (compare:CCFP (match_operand 0 "register_operand" "x")
1500 (match_operand 1 "nonimmediate_operand" "xm")))]
1502 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1503 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1504 "* return output_fp_compare (insn, operands, 1, 0);"
1505 [(set_attr "type" "ssecomi")
1506 (set_attr "prefix" "maybe_vex")
1508 (if_then_else (match_operand:SF 1 "" "")
1510 (const_string "DF")))
1511 (set_attr "prefix_rep" "0")
1512 (set (attr "prefix_data16")
1513 (if_then_else (eq_attr "mode" "DF")
1515 (const_string "0")))
1516 (set_attr "athlon_decode" "vector")
1517 (set_attr "amdfam10_decode" "direct")])
1519 (define_insn "*cmpfp_i_i387"
1520 [(set (reg:CCFP FLAGS_REG)
1521 (compare:CCFP (match_operand 0 "register_operand" "f")
1522 (match_operand 1 "register_operand" "f")))]
1523 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1525 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1526 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1527 "* return output_fp_compare (insn, operands, 1, 0);"
1528 [(set_attr "type" "fcmp")
1530 (cond [(match_operand:SF 1 "" "")
1532 (match_operand:DF 1 "" "")
1535 (const_string "XF")))
1536 (set_attr "athlon_decode" "vector")
1537 (set_attr "amdfam10_decode" "direct")])
1539 (define_insn "*cmpfp_iu_mixed"
1540 [(set (reg:CCFPU FLAGS_REG)
1541 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1542 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1543 "TARGET_MIX_SSE_I387
1544 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1545 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1546 "* return output_fp_compare (insn, operands, 1, 1);"
1547 [(set_attr "type" "fcmp,ssecomi")
1548 (set_attr "prefix" "orig,maybe_vex")
1550 (if_then_else (match_operand:SF 1 "" "")
1552 (const_string "DF")))
1553 (set (attr "prefix_rep")
1554 (if_then_else (eq_attr "type" "ssecomi")
1556 (const_string "*")))
1557 (set (attr "prefix_data16")
1558 (cond [(eq_attr "type" "fcmp")
1560 (eq_attr "mode" "DF")
1563 (const_string "0")))
1564 (set_attr "athlon_decode" "vector")
1565 (set_attr "amdfam10_decode" "direct")])
1567 (define_insn "*cmpfp_iu_sse"
1568 [(set (reg:CCFPU FLAGS_REG)
1569 (compare:CCFPU (match_operand 0 "register_operand" "x")
1570 (match_operand 1 "nonimmediate_operand" "xm")))]
1572 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1573 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1574 "* return output_fp_compare (insn, operands, 1, 1);"
1575 [(set_attr "type" "ssecomi")
1576 (set_attr "prefix" "maybe_vex")
1578 (if_then_else (match_operand:SF 1 "" "")
1580 (const_string "DF")))
1581 (set_attr "prefix_rep" "0")
1582 (set (attr "prefix_data16")
1583 (if_then_else (eq_attr "mode" "DF")
1585 (const_string "0")))
1586 (set_attr "athlon_decode" "vector")
1587 (set_attr "amdfam10_decode" "direct")])
1589 (define_insn "*cmpfp_iu_387"
1590 [(set (reg:CCFPU FLAGS_REG)
1591 (compare:CCFPU (match_operand 0 "register_operand" "f")
1592 (match_operand 1 "register_operand" "f")))]
1593 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1595 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1596 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1597 "* return output_fp_compare (insn, operands, 1, 1);"
1598 [(set_attr "type" "fcmp")
1600 (cond [(match_operand:SF 1 "" "")
1602 (match_operand:DF 1 "" "")
1605 (const_string "XF")))
1606 (set_attr "athlon_decode" "vector")
1607 (set_attr "amdfam10_decode" "direct")])
1609 ;; Push/pop instructions.
1611 (define_insn "*pushdi2_rex64"
1612 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1613 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1618 [(set_attr "type" "push,multi")
1619 (set_attr "mode" "DI")])
1621 ;; Convert impossible pushes of immediate to existing instructions.
1622 ;; First try to get scratch register and go through it. In case this
1623 ;; fails, push sign extended lower part first and then overwrite
1624 ;; upper part by 32bit move.
1626 [(match_scratch:DI 2 "r")
1627 (set (match_operand:DI 0 "push_operand" "")
1628 (match_operand:DI 1 "immediate_operand" ""))]
1629 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1630 && !x86_64_immediate_operand (operands[1], DImode)"
1631 [(set (match_dup 2) (match_dup 1))
1632 (set (match_dup 0) (match_dup 2))])
1634 ;; We need to define this as both peepholer and splitter for case
1635 ;; peephole2 pass is not run.
1636 ;; "&& 1" is needed to keep it from matching the previous pattern.
1638 [(set (match_operand:DI 0 "push_operand" "")
1639 (match_operand:DI 1 "immediate_operand" ""))]
1640 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1641 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1642 [(set (match_dup 0) (match_dup 1))
1643 (set (match_dup 2) (match_dup 3))]
1645 split_di (&operands[1], 1, &operands[2], &operands[3]);
1647 operands[1] = gen_lowpart (DImode, operands[2]);
1648 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1653 [(set (match_operand:DI 0 "push_operand" "")
1654 (match_operand:DI 1 "immediate_operand" ""))]
1655 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1656 ? epilogue_completed : reload_completed)
1657 && !symbolic_operand (operands[1], DImode)
1658 && !x86_64_immediate_operand (operands[1], DImode)"
1659 [(set (match_dup 0) (match_dup 1))
1660 (set (match_dup 2) (match_dup 3))]
1662 split_di (&operands[1], 1, &operands[2], &operands[3]);
1664 operands[1] = gen_lowpart (DImode, operands[2]);
1665 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1669 (define_insn "*pushdi2"
1670 [(set (match_operand:DI 0 "push_operand" "=<")
1671 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1676 [(set (match_operand:DI 0 "push_operand" "")
1677 (match_operand:DI 1 "general_operand" ""))]
1678 "!TARGET_64BIT && reload_completed
1679 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1681 "ix86_split_long_move (operands); DONE;")
1683 (define_insn "*pushsi2"
1684 [(set (match_operand:SI 0 "push_operand" "=<")
1685 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1688 [(set_attr "type" "push")
1689 (set_attr "mode" "SI")])
1691 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1692 ;; "push a byte/word". But actually we use pushl, which has the effect
1693 ;; of rounding the amount pushed up to a word.
1695 ;; For TARGET_64BIT we always round up to 8 bytes.
1696 (define_insn "*push<mode>2_rex64"
1697 [(set (match_operand:SWI124 0 "push_operand" "=X")
1698 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1701 [(set_attr "type" "push")
1702 (set_attr "mode" "DI")])
1704 (define_insn "*push<mode>2"
1705 [(set (match_operand:SWI12 0 "push_operand" "=X")
1706 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1709 [(set_attr "type" "push")
1710 (set_attr "mode" "SI")])
1712 (define_insn "*push<mode>2_prologue"
1713 [(set (match_operand:P 0 "push_operand" "=<")
1714 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1715 (clobber (mem:BLK (scratch)))]
1717 "push{<imodesuffix>}\t%1"
1718 [(set_attr "type" "push")
1719 (set_attr "mode" "<MODE>")])
1721 (define_insn "*pop<mode>1"
1722 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1723 (match_operand:P 1 "pop_operand" ">"))]
1725 "pop{<imodesuffix>}\t%0"
1726 [(set_attr "type" "pop")
1727 (set_attr "mode" "<MODE>")])
1729 (define_insn "*pop<mode>1_epilogue"
1730 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1731 (match_operand:P 1 "pop_operand" ">"))
1732 (clobber (mem:BLK (scratch)))]
1734 "pop{<imodesuffix>}\t%0"
1735 [(set_attr "type" "pop")
1736 (set_attr "mode" "<MODE>")])
1738 ;; Move instructions.
1740 (define_expand "movoi"
1741 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1742 (match_operand:OI 1 "general_operand" ""))]
1744 "ix86_expand_move (OImode, operands); DONE;")
1746 (define_expand "movti"
1747 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1748 (match_operand:TI 1 "nonimmediate_operand" ""))]
1749 "TARGET_64BIT || TARGET_SSE"
1752 ix86_expand_move (TImode, operands);
1753 else if (push_operand (operands[0], TImode))
1754 ix86_expand_push (TImode, operands[1]);
1756 ix86_expand_vector_move (TImode, operands);
1760 ;; This expands to what emit_move_complex would generate if we didn't
1761 ;; have a movti pattern. Having this avoids problems with reload on
1762 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1763 ;; to have around all the time.
1764 (define_expand "movcdi"
1765 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1766 (match_operand:CDI 1 "general_operand" ""))]
1769 if (push_operand (operands[0], CDImode))
1770 emit_move_complex_push (CDImode, operands[0], operands[1]);
1772 emit_move_complex_parts (operands[0], operands[1]);
1776 (define_expand "mov<mode>"
1777 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1778 (match_operand:SWI1248x 1 "general_operand" ""))]
1780 "ix86_expand_move (<MODE>mode, operands); DONE;")
1782 (define_insn "*mov<mode>_xor"
1783 [(set (match_operand:SWI48 0 "register_operand" "=r")
1784 (match_operand:SWI48 1 "const0_operand" ""))
1785 (clobber (reg:CC FLAGS_REG))]
1788 [(set_attr "type" "alu1")
1789 (set_attr "mode" "SI")
1790 (set_attr "length_immediate" "0")])
1792 (define_insn "*mov<mode>_or"
1793 [(set (match_operand:SWI48 0 "register_operand" "=r")
1794 (match_operand:SWI48 1 "const_int_operand" ""))
1795 (clobber (reg:CC FLAGS_REG))]
1797 && operands[1] == constm1_rtx"
1798 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1799 [(set_attr "type" "alu1")
1800 (set_attr "mode" "<MODE>")
1801 (set_attr "length_immediate" "1")])
1803 (define_insn "*movoi_internal_avx"
1804 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1805 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1806 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1808 switch (which_alternative)
1811 return "vxorps\t%0, %0, %0";
1814 if (misaligned_operand (operands[0], OImode)
1815 || misaligned_operand (operands[1], OImode))
1816 return "vmovdqu\t{%1, %0|%0, %1}";
1818 return "vmovdqa\t{%1, %0|%0, %1}";
1823 [(set_attr "type" "sselog1,ssemov,ssemov")
1824 (set_attr "prefix" "vex")
1825 (set_attr "mode" "OI")])
1827 (define_insn "*movti_internal_rex64"
1828 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1829 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1830 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1832 switch (which_alternative)
1838 if (get_attr_mode (insn) == MODE_V4SF)
1839 return "%vxorps\t%0, %d0";
1841 return "%vpxor\t%0, %d0";
1844 /* TDmode values are passed as TImode on the stack. Moving them
1845 to stack may result in unaligned memory access. */
1846 if (misaligned_operand (operands[0], TImode)
1847 || misaligned_operand (operands[1], TImode))
1849 if (get_attr_mode (insn) == MODE_V4SF)
1850 return "%vmovups\t{%1, %0|%0, %1}";
1852 return "%vmovdqu\t{%1, %0|%0, %1}";
1856 if (get_attr_mode (insn) == MODE_V4SF)
1857 return "%vmovaps\t{%1, %0|%0, %1}";
1859 return "%vmovdqa\t{%1, %0|%0, %1}";
1865 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1866 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1868 (cond [(eq_attr "alternative" "2,3")
1870 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1872 (const_string "V4SF")
1873 (const_string "TI"))
1874 (eq_attr "alternative" "4")
1876 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1878 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1880 (const_string "V4SF")
1881 (const_string "TI"))]
1882 (const_string "DI")))])
1885 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1886 (match_operand:TI 1 "general_operand" ""))]
1888 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1890 "ix86_split_long_move (operands); DONE;")
1892 (define_insn "*movti_internal_sse"
1893 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1894 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1895 "TARGET_SSE && !TARGET_64BIT
1896 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1898 switch (which_alternative)
1901 if (get_attr_mode (insn) == MODE_V4SF)
1902 return "%vxorps\t%0, %d0";
1904 return "%vpxor\t%0, %d0";
1907 /* TDmode values are passed as TImode on the stack. Moving them
1908 to stack may result in unaligned memory access. */
1909 if (misaligned_operand (operands[0], TImode)
1910 || misaligned_operand (operands[1], TImode))
1912 if (get_attr_mode (insn) == MODE_V4SF)
1913 return "%vmovups\t{%1, %0|%0, %1}";
1915 return "%vmovdqu\t{%1, %0|%0, %1}";
1919 if (get_attr_mode (insn) == MODE_V4SF)
1920 return "%vmovaps\t{%1, %0|%0, %1}";
1922 return "%vmovdqa\t{%1, %0|%0, %1}";
1928 [(set_attr "type" "sselog1,ssemov,ssemov")
1929 (set_attr "prefix" "maybe_vex")
1931 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1932 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1934 (const_string "V4SF")
1935 (and (eq_attr "alternative" "2")
1936 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1938 (const_string "V4SF")]
1939 (const_string "TI")))])
1941 (define_insn "*movdi_internal_rex64"
1942 [(set (match_operand:DI 0 "nonimmediate_operand"
1943 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
1944 (match_operand:DI 1 "general_operand"
1945 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
1946 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1948 switch (get_attr_type (insn))
1951 if (SSE_REG_P (operands[0]))
1952 return "movq2dq\t{%1, %0|%0, %1}";
1954 return "movdq2q\t{%1, %0|%0, %1}";
1959 if (get_attr_mode (insn) == MODE_TI)
1960 return "vmovdqa\t{%1, %0|%0, %1}";
1962 return "vmovq\t{%1, %0|%0, %1}";
1965 if (get_attr_mode (insn) == MODE_TI)
1966 return "movdqa\t{%1, %0|%0, %1}";
1970 /* Moves from and into integer register is done using movd
1971 opcode with REX prefix. */
1972 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1973 return "movd\t{%1, %0|%0, %1}";
1974 return "movq\t{%1, %0|%0, %1}";
1977 return "%vpxor\t%0, %d0";
1980 return "pxor\t%0, %0";
1986 return "lea{q}\t{%a1, %0|%0, %a1}";
1989 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1990 if (get_attr_mode (insn) == MODE_SI)
1991 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1992 else if (which_alternative == 2)
1993 return "movabs{q}\t{%1, %0|%0, %1}";
1995 return "mov{q}\t{%1, %0|%0, %1}";
1999 (cond [(eq_attr "alternative" "5")
2000 (const_string "mmx")
2001 (eq_attr "alternative" "6,7,8,9,10")
2002 (const_string "mmxmov")
2003 (eq_attr "alternative" "11")
2004 (const_string "sselog1")
2005 (eq_attr "alternative" "12,13,14,15,16")
2006 (const_string "ssemov")
2007 (eq_attr "alternative" "17,18")
2008 (const_string "ssecvt")
2009 (eq_attr "alternative" "4")
2010 (const_string "multi")
2011 (match_operand:DI 1 "pic_32bit_operand" "")
2012 (const_string "lea")
2014 (const_string "imov")))
2017 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2019 (const_string "*")))
2020 (set (attr "length_immediate")
2022 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2024 (const_string "*")))
2025 (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2026 (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2027 (set (attr "prefix")
2028 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2029 (const_string "maybe_vex")
2030 (const_string "orig")))
2031 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2033 ;; Convert impossible stores of immediate to existing instructions.
2034 ;; First try to get scratch register and go through it. In case this
2035 ;; fails, move by 32bit parts.
2037 [(match_scratch:DI 2 "r")
2038 (set (match_operand:DI 0 "memory_operand" "")
2039 (match_operand:DI 1 "immediate_operand" ""))]
2040 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2041 && !x86_64_immediate_operand (operands[1], DImode)"
2042 [(set (match_dup 2) (match_dup 1))
2043 (set (match_dup 0) (match_dup 2))])
2045 ;; We need to define this as both peepholer and splitter for case
2046 ;; peephole2 pass is not run.
2047 ;; "&& 1" is needed to keep it from matching the previous pattern.
2049 [(set (match_operand:DI 0 "memory_operand" "")
2050 (match_operand:DI 1 "immediate_operand" ""))]
2051 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2052 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2053 [(set (match_dup 2) (match_dup 3))
2054 (set (match_dup 4) (match_dup 5))]
2055 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2058 [(set (match_operand:DI 0 "memory_operand" "")
2059 (match_operand:DI 1 "immediate_operand" ""))]
2060 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2061 ? epilogue_completed : reload_completed)
2062 && !symbolic_operand (operands[1], DImode)
2063 && !x86_64_immediate_operand (operands[1], DImode)"
2064 [(set (match_dup 2) (match_dup 3))
2065 (set (match_dup 4) (match_dup 5))]
2066 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2068 (define_insn "*movdi_internal"
2069 [(set (match_operand:DI 0 "nonimmediate_operand"
2070 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2071 (match_operand:DI 1 "general_operand"
2072 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2073 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2078 movq\t{%1, %0|%0, %1}
2079 movq\t{%1, %0|%0, %1}
2081 %vmovq\t{%1, %0|%0, %1}
2082 %vmovdqa\t{%1, %0|%0, %1}
2083 %vmovq\t{%1, %0|%0, %1}
2085 movlps\t{%1, %0|%0, %1}
2086 movaps\t{%1, %0|%0, %1}
2087 movlps\t{%1, %0|%0, %1}"
2088 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2089 (set (attr "prefix")
2090 (if_then_else (eq_attr "alternative" "5,6,7,8")
2091 (const_string "vex")
2092 (const_string "orig")))
2093 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2096 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2097 (match_operand:DI 1 "general_operand" ""))]
2098 "!TARGET_64BIT && reload_completed
2099 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2100 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2102 "ix86_split_long_move (operands); DONE;")
2104 (define_insn "*movsi_internal"
2105 [(set (match_operand:SI 0 "nonimmediate_operand"
2106 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2107 (match_operand:SI 1 "general_operand"
2108 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2109 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2111 switch (get_attr_type (insn))
2114 if (get_attr_mode (insn) == MODE_TI)
2115 return "%vpxor\t%0, %d0";
2116 return "%vxorps\t%0, %d0";
2119 switch (get_attr_mode (insn))
2122 return "%vmovdqa\t{%1, %0|%0, %1}";
2124 return "%vmovaps\t{%1, %0|%0, %1}";
2126 return "%vmovd\t{%1, %0|%0, %1}";
2128 return "%vmovss\t{%1, %0|%0, %1}";
2134 return "pxor\t%0, %0";
2137 if (get_attr_mode (insn) == MODE_DI)
2138 return "movq\t{%1, %0|%0, %1}";
2139 return "movd\t{%1, %0|%0, %1}";
2142 return "lea{l}\t{%a1, %0|%0, %a1}";
2145 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2146 return "mov{l}\t{%1, %0|%0, %1}";
2150 (cond [(eq_attr "alternative" "2")
2151 (const_string "mmx")
2152 (eq_attr "alternative" "3,4,5")
2153 (const_string "mmxmov")
2154 (eq_attr "alternative" "6")
2155 (const_string "sselog1")
2156 (eq_attr "alternative" "7,8,9,10,11")
2157 (const_string "ssemov")
2158 (match_operand:DI 1 "pic_32bit_operand" "")
2159 (const_string "lea")
2161 (const_string "imov")))
2162 (set (attr "prefix")
2163 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2164 (const_string "orig")
2165 (const_string "maybe_vex")))
2166 (set (attr "prefix_data16")
2167 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2169 (const_string "*")))
2171 (cond [(eq_attr "alternative" "2,3")
2173 (eq_attr "alternative" "6,7")
2175 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2176 (const_string "V4SF")
2177 (const_string "TI"))
2178 (and (eq_attr "alternative" "8,9,10,11")
2179 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
2182 (const_string "SI")))])
2184 (define_insn "*movhi_internal"
2185 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2186 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2187 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2189 switch (get_attr_type (insn))
2192 /* movzwl is faster than movw on p2 due to partial word stalls,
2193 though not as fast as an aligned movl. */
2194 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2196 if (get_attr_mode (insn) == MODE_SI)
2197 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2199 return "mov{w}\t{%1, %0|%0, %1}";
2203 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2205 (const_string "imov")
2206 (and (eq_attr "alternative" "0")
2207 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2209 (eq (symbol_ref "TARGET_HIMODE_MATH")
2211 (const_string "imov")
2212 (and (eq_attr "alternative" "1,2")
2213 (match_operand:HI 1 "aligned_operand" ""))
2214 (const_string "imov")
2215 (and (ne (symbol_ref "TARGET_MOVX")
2217 (eq_attr "alternative" "0,2"))
2218 (const_string "imovx")
2220 (const_string "imov")))
2222 (cond [(eq_attr "type" "imovx")
2224 (and (eq_attr "alternative" "1,2")
2225 (match_operand:HI 1 "aligned_operand" ""))
2227 (and (eq_attr "alternative" "0")
2228 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2230 (eq (symbol_ref "TARGET_HIMODE_MATH")
2234 (const_string "HI")))])
2236 ;; Situation is quite tricky about when to choose full sized (SImode) move
2237 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2238 ;; partial register dependency machines (such as AMD Athlon), where QImode
2239 ;; moves issue extra dependency and for partial register stalls machines
2240 ;; that don't use QImode patterns (and QImode move cause stall on the next
2243 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2244 ;; register stall machines with, where we use QImode instructions, since
2245 ;; partial register stall can be caused there. Then we use movzx.
2246 (define_insn "*movqi_internal"
2247 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2248 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2249 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2251 switch (get_attr_type (insn))
2254 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2255 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2257 if (get_attr_mode (insn) == MODE_SI)
2258 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2260 return "mov{b}\t{%1, %0|%0, %1}";
2264 (cond [(and (eq_attr "alternative" "5")
2265 (not (match_operand:QI 1 "aligned_operand" "")))
2266 (const_string "imovx")
2267 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2269 (const_string "imov")
2270 (and (eq_attr "alternative" "3")
2271 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2273 (eq (symbol_ref "TARGET_QIMODE_MATH")
2275 (const_string "imov")
2276 (eq_attr "alternative" "3,5")
2277 (const_string "imovx")
2278 (and (ne (symbol_ref "TARGET_MOVX")
2280 (eq_attr "alternative" "2"))
2281 (const_string "imovx")
2283 (const_string "imov")))
2285 (cond [(eq_attr "alternative" "3,4,5")
2287 (eq_attr "alternative" "6")
2289 (eq_attr "type" "imovx")
2291 (and (eq_attr "type" "imov")
2292 (and (eq_attr "alternative" "0,1")
2293 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2295 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2297 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2300 ;; Avoid partial register stalls when not using QImode arithmetic
2301 (and (eq_attr "type" "imov")
2302 (and (eq_attr "alternative" "0,1")
2303 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2305 (eq (symbol_ref "TARGET_QIMODE_MATH")
2309 (const_string "QI")))])
2311 ;; Stores and loads of ax to arbitrary constant address.
2312 ;; We fake an second form of instruction to force reload to load address
2313 ;; into register when rax is not available
2314 (define_insn "*movabs<mode>_1"
2315 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2316 (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2317 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2319 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2320 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2321 [(set_attr "type" "imov")
2322 (set_attr "modrm" "0,*")
2323 (set_attr "length_address" "8,0")
2324 (set_attr "length_immediate" "0,*")
2325 (set_attr "memory" "store")
2326 (set_attr "mode" "<MODE>")])
2328 (define_insn "*movabs<mode>_2"
2329 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2330 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2331 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2333 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2334 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2335 [(set_attr "type" "imov")
2336 (set_attr "modrm" "0,*")
2337 (set_attr "length_address" "8,0")
2338 (set_attr "length_immediate" "0")
2339 (set_attr "memory" "load")
2340 (set_attr "mode" "<MODE>")])
2342 (define_insn "*swap<mode>"
2343 [(set (match_operand:SWI48 0 "register_operand" "+r")
2344 (match_operand:SWI48 1 "register_operand" "+r"))
2348 "xchg{<imodesuffix>}\t%1, %0"
2349 [(set_attr "type" "imov")
2350 (set_attr "mode" "<MODE>")
2351 (set_attr "pent_pair" "np")
2352 (set_attr "athlon_decode" "vector")
2353 (set_attr "amdfam10_decode" "double")])
2355 (define_insn "*swap<mode>_1"
2356 [(set (match_operand:SWI12 0 "register_operand" "+r")
2357 (match_operand:SWI12 1 "register_operand" "+r"))
2360 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2362 [(set_attr "type" "imov")
2363 (set_attr "mode" "SI")
2364 (set_attr "pent_pair" "np")
2365 (set_attr "athlon_decode" "vector")
2366 (set_attr "amdfam10_decode" "double")])
2368 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2369 ;; is disabled for AMDFAM10
2370 (define_insn "*swap<mode>_2"
2371 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2372 (match_operand:SWI12 1 "register_operand" "+<r>"))
2375 "TARGET_PARTIAL_REG_STALL"
2376 "xchg{<imodesuffix>}\t%1, %0"
2377 [(set_attr "type" "imov")
2378 (set_attr "mode" "<MODE>")
2379 (set_attr "pent_pair" "np")
2380 (set_attr "athlon_decode" "vector")])
2382 (define_expand "movstrict<mode>"
2383 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2384 (match_operand:SWI12 1 "general_operand" ""))]
2387 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2389 /* Don't generate memory->memory moves, go through a register */
2390 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2391 operands[1] = force_reg (<MODE>mode, operands[1]);
2394 (define_insn "*movstrict<mode>_1"
2395 [(set (strict_low_part
2396 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2397 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2398 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2399 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2400 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2401 [(set_attr "type" "imov")
2402 (set_attr "mode" "<MODE>")])
2404 (define_insn "*movstrict<mode>_xor"
2405 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2406 (match_operand:SWI12 1 "const0_operand" ""))
2407 (clobber (reg:CC FLAGS_REG))]
2409 "xor{<imodesuffix>}\t%0, %0"
2410 [(set_attr "type" "alu1")
2411 (set_attr "mode" "<MODE>")
2412 (set_attr "length_immediate" "0")])
2414 (define_insn "*mov<mode>_extv_1"
2415 [(set (match_operand:SWI24 0 "register_operand" "=R")
2416 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2420 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2421 [(set_attr "type" "imovx")
2422 (set_attr "mode" "SI")])
2424 (define_insn "*movqi_extv_1_rex64"
2425 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2426 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2431 switch (get_attr_type (insn))
2434 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2436 return "mov{b}\t{%h1, %0|%0, %h1}";
2440 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2441 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2442 (ne (symbol_ref "TARGET_MOVX")
2444 (const_string "imovx")
2445 (const_string "imov")))
2447 (if_then_else (eq_attr "type" "imovx")
2449 (const_string "QI")))])
2451 (define_insn "*movqi_extv_1"
2452 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2453 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2458 switch (get_attr_type (insn))
2461 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2463 return "mov{b}\t{%h1, %0|%0, %h1}";
2467 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2468 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2469 (ne (symbol_ref "TARGET_MOVX")
2471 (const_string "imovx")
2472 (const_string "imov")))
2474 (if_then_else (eq_attr "type" "imovx")
2476 (const_string "QI")))])
2478 (define_insn "*mov<mode>_extzv_1"
2479 [(set (match_operand:SWI48 0 "register_operand" "=R")
2480 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2484 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2485 [(set_attr "type" "imovx")
2486 (set_attr "mode" "SI")])
2488 (define_insn "*movqi_extzv_2_rex64"
2489 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2491 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2496 switch (get_attr_type (insn))
2499 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2501 return "mov{b}\t{%h1, %0|%0, %h1}";
2505 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2506 (ne (symbol_ref "TARGET_MOVX")
2508 (const_string "imovx")
2509 (const_string "imov")))
2511 (if_then_else (eq_attr "type" "imovx")
2513 (const_string "QI")))])
2515 (define_insn "*movqi_extzv_2"
2516 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2518 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2523 switch (get_attr_type (insn))
2526 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2528 return "mov{b}\t{%h1, %0|%0, %h1}";
2532 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2533 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2534 (ne (symbol_ref "TARGET_MOVX")
2536 (const_string "imovx")
2537 (const_string "imov")))
2539 (if_then_else (eq_attr "type" "imovx")
2541 (const_string "QI")))])
2543 (define_expand "mov<mode>_insv_1"
2544 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2547 (match_operand:SWI48 1 "nonmemory_operand" ""))]
2551 (define_insn "*mov<mode>_insv_1_rex64"
2552 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2555 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2557 "mov{b}\t{%b1, %h0|%h0, %b1}"
2558 [(set_attr "type" "imov")
2559 (set_attr "mode" "QI")])
2561 (define_insn "*movsi_insv_1"
2562 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2565 (match_operand:SI 1 "general_operand" "Qmn"))]
2567 "mov{b}\t{%b1, %h0|%h0, %b1}"
2568 [(set_attr "type" "imov")
2569 (set_attr "mode" "QI")])
2571 (define_insn "*movqi_insv_2"
2572 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2575 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2578 "mov{b}\t{%h1, %h0|%h0, %h1}"
2579 [(set_attr "type" "imov")
2580 (set_attr "mode" "QI")])
2582 ;; Floating point push instructions.
2584 (define_insn "*pushtf"
2585 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2586 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2589 /* This insn should be already split before reg-stack. */
2592 [(set_attr "type" "multi")
2593 (set_attr "unit" "sse,*,*")
2594 (set_attr "mode" "TF,SI,SI")])
2597 [(set (match_operand:TF 0 "push_operand" "")
2598 (match_operand:TF 1 "sse_reg_operand" ""))]
2599 "TARGET_SSE2 && reload_completed"
2600 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2601 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2604 [(set (match_operand:TF 0 "push_operand" "")
2605 (match_operand:TF 1 "general_operand" ""))]
2606 "TARGET_SSE2 && reload_completed
2607 && !SSE_REG_P (operands[1])"
2609 "ix86_split_long_move (operands); DONE;")
2611 (define_insn "*pushxf"
2612 [(set (match_operand:XF 0 "push_operand" "=<,<")
2613 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2614 "optimize_function_for_speed_p (cfun)"
2616 /* This insn should be already split before reg-stack. */
2619 [(set_attr "type" "multi")
2620 (set_attr "unit" "i387,*")
2621 (set_attr "mode" "XF,SI")])
2623 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2624 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2625 ;; Pushing using integer instructions is longer except for constants
2626 ;; and direct memory references (assuming that any given constant is pushed
2627 ;; only once, but this ought to be handled elsewhere).
2629 (define_insn "*pushxf_nointeger"
2630 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2631 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2632 "optimize_function_for_size_p (cfun)"
2634 /* This insn should be already split before reg-stack. */
2637 [(set_attr "type" "multi")
2638 (set_attr "unit" "i387,*,*")
2639 (set_attr "mode" "XF,SI,SI")])
2642 [(set (match_operand:XF 0 "push_operand" "")
2643 (match_operand:XF 1 "fp_register_operand" ""))]
2645 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2646 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2647 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2650 [(set (match_operand:XF 0 "push_operand" "")
2651 (match_operand:XF 1 "general_operand" ""))]
2653 && !FP_REG_P (operands[1])"
2655 "ix86_split_long_move (operands); DONE;")
2657 (define_insn "*pushdf"
2658 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2659 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2660 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2662 /* This insn should be already split before reg-stack. */
2665 [(set_attr "type" "multi")
2666 (set_attr "unit" "i387,*,*")
2667 (set_attr "mode" "DF,SI,DF")])
2669 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2670 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2671 ;; On the average, pushdf using integers can be still shorter. Allow this
2672 ;; pattern for optimize_size too.
2674 (define_insn "*pushdf_nointeger"
2675 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2676 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2677 "!(TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES)"
2679 /* This insn should be already split before reg-stack. */
2682 [(set_attr "type" "multi")
2683 (set_attr "unit" "i387,*,*,*")
2684 (set_attr "mode" "DF,SI,SI,DF")])
2686 ;; %%% Kill this when call knows how to work this out.
2688 [(set (match_operand:DF 0 "push_operand" "")
2689 (match_operand:DF 1 "any_fp_register_operand" ""))]
2691 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2692 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2695 [(set (match_operand:DF 0 "push_operand" "")
2696 (match_operand:DF 1 "general_operand" ""))]
2698 && !ANY_FP_REG_P (operands[1])"
2700 "ix86_split_long_move (operands); DONE;")
2702 (define_insn "*pushsf_rex64"
2703 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2704 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2707 /* Anything else should be already split before reg-stack. */
2708 gcc_assert (which_alternative == 1);
2709 return "push{q}\t%q1";
2711 [(set_attr "type" "multi,push,multi")
2712 (set_attr "unit" "i387,*,*")
2713 (set_attr "mode" "SF,DI,SF")])
2715 (define_insn "*pushsf"
2716 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2717 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2720 /* Anything else should be already split before reg-stack. */
2721 gcc_assert (which_alternative == 1);
2722 return "push{l}\t%1";
2724 [(set_attr "type" "multi,push,multi")
2725 (set_attr "unit" "i387,*,*")
2726 (set_attr "mode" "SF,SI,SF")])
2729 [(set (match_operand:SF 0 "push_operand" "")
2730 (match_operand:SF 1 "memory_operand" ""))]
2732 && MEM_P (operands[1])
2733 && (operands[2] = find_constant_src (insn))"
2737 ;; %%% Kill this when call knows how to work this out.
2739 [(set (match_operand:SF 0 "push_operand" "")
2740 (match_operand:SF 1 "any_fp_register_operand" ""))]
2742 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2743 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2744 "operands[2] = GEN_INT (-GET_MODE_SIZE (<MODE>mode));")
2746 ;; Floating point move instructions.
2748 (define_expand "movtf"
2749 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2750 (match_operand:TF 1 "nonimmediate_operand" ""))]
2753 ix86_expand_move (TFmode, operands);
2757 (define_expand "mov<mode>"
2758 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2759 (match_operand:X87MODEF 1 "general_operand" ""))]
2761 "ix86_expand_move (<MODE>mode, operands); DONE;")
2763 (define_insn "*movtf_internal"
2764 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
2765 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
2767 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2769 switch (which_alternative)
2773 if (get_attr_mode (insn) == MODE_V4SF)
2774 return "%vmovaps\t{%1, %0|%0, %1}";
2776 return "%vmovdqa\t{%1, %0|%0, %1}";
2778 if (get_attr_mode (insn) == MODE_V4SF)
2779 return "%vxorps\t%0, %d0";
2781 return "%vpxor\t%0, %d0";
2789 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2790 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2792 (cond [(eq_attr "alternative" "0,2")
2794 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2796 (const_string "V4SF")
2797 (const_string "TI"))
2798 (eq_attr "alternative" "1")
2800 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2802 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2804 (const_string "V4SF")
2805 (const_string "TI"))]
2806 (const_string "DI")))])
2809 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2810 (match_operand:TF 1 "general_operand" ""))]
2812 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
2814 "ix86_split_long_move (operands); DONE;")
2816 (define_insn "*movxf_internal"
2817 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2818 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2819 "optimize_function_for_speed_p (cfun)
2820 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2821 && (reload_in_progress || reload_completed
2822 || GET_CODE (operands[1]) != CONST_DOUBLE
2823 || memory_operand (operands[0], XFmode))"
2825 switch (which_alternative)
2829 return output_387_reg_move (insn, operands);
2832 return standard_80387_constant_opcode (operands[1]);
2841 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2842 (set_attr "mode" "XF,XF,XF,SI,SI")])
2844 ;; Do not use integer registers when optimizing for size
2845 (define_insn "*movxf_internal_nointeger"
2846 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2847 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2848 "optimize_function_for_size_p (cfun)
2849 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2850 && (reload_in_progress || reload_completed
2851 || standard_80387_constant_p (operands[1])
2852 || GET_CODE (operands[1]) != CONST_DOUBLE
2853 || memory_operand (operands[0], XFmode))"
2855 switch (which_alternative)
2859 return output_387_reg_move (insn, operands);
2862 return standard_80387_constant_opcode (operands[1]);
2870 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2871 (set_attr "mode" "XF,XF,XF,SI,SI")])
2874 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2875 (match_operand:XF 1 "general_operand" ""))]
2877 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2878 && ! (FP_REG_P (operands[0]) ||
2879 (GET_CODE (operands[0]) == SUBREG
2880 && FP_REG_P (SUBREG_REG (operands[0]))))
2881 && ! (FP_REG_P (operands[1]) ||
2882 (GET_CODE (operands[1]) == SUBREG
2883 && FP_REG_P (SUBREG_REG (operands[1]))))"
2885 "ix86_split_long_move (operands); DONE;")
2887 (define_insn "*movdf_internal_rex64"
2888 [(set (match_operand:DF 0 "nonimmediate_operand"
2889 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2890 (match_operand:DF 1 "general_operand"
2891 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2892 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2893 && (reload_in_progress || reload_completed
2894 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2895 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2896 && optimize_function_for_size_p (cfun)
2897 && standard_80387_constant_p (operands[1]))
2898 || GET_CODE (operands[1]) != CONST_DOUBLE
2899 || memory_operand (operands[0], DFmode))"
2901 switch (which_alternative)
2905 return output_387_reg_move (insn, operands);
2908 return standard_80387_constant_opcode (operands[1]);
2915 switch (get_attr_mode (insn))
2918 return "%vxorps\t%0, %d0";
2920 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2921 return "%vxorps\t%0, %d0";
2923 return "%vxorpd\t%0, %d0";
2925 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2926 return "%vxorps\t%0, %d0";
2928 return "%vpxor\t%0, %d0";
2935 switch (get_attr_mode (insn))
2938 return "%vmovaps\t{%1, %0|%0, %1}";
2940 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2941 return "%vmovaps\t{%1, %0|%0, %1}";
2943 return "%vmovapd\t{%1, %0|%0, %1}";
2945 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2946 return "%vmovaps\t{%1, %0|%0, %1}";
2948 return "%vmovdqa\t{%1, %0|%0, %1}";
2950 return "%vmovq\t{%1, %0|%0, %1}";
2954 if (REG_P (operands[0]) && REG_P (operands[1]))
2955 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2957 return "vmovsd\t{%1, %0|%0, %1}";
2960 return "movsd\t{%1, %0|%0, %1}";
2962 return "%vmovlpd\t{%1, %d0|%d0, %1}";
2964 return "%vmovlps\t{%1, %d0|%d0, %1}";
2971 return "%vmovd\t{%1, %0|%0, %1}";
2977 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2978 (set (attr "prefix")
2979 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
2980 (const_string "orig")
2981 (const_string "maybe_vex")))
2982 (set (attr "prefix_data16")
2983 (if_then_else (eq_attr "mode" "V1DF")
2985 (const_string "*")))
2987 (cond [(eq_attr "alternative" "0,1,2")
2989 (eq_attr "alternative" "3,4,9,10")
2992 /* For SSE1, we have many fewer alternatives. */
2993 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2994 (cond [(eq_attr "alternative" "5,6")
2995 (const_string "V4SF")
2997 (const_string "V2SF"))
2999 /* xorps is one byte shorter. */
3000 (eq_attr "alternative" "5")
3001 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3003 (const_string "V4SF")
3004 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3008 (const_string "V2DF"))
3010 /* For architectures resolving dependencies on
3011 whole SSE registers use APD move to break dependency
3012 chains, otherwise use short move to avoid extra work.
3014 movaps encodes one byte shorter. */
3015 (eq_attr "alternative" "6")
3017 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3019 (const_string "V4SF")
3020 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3022 (const_string "V2DF")
3024 (const_string "DF"))
3025 /* For architectures resolving dependencies on register
3026 parts we may avoid extra work to zero out upper part
3028 (eq_attr "alternative" "7")
3030 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3032 (const_string "V1DF")
3033 (const_string "DF"))
3035 (const_string "DF")))])
3037 (define_insn "*movdf_internal"
3038 [(set (match_operand:DF 0 "nonimmediate_operand"
3039 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3040 (match_operand:DF 1 "general_operand"
3041 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3042 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3043 && optimize_function_for_speed_p (cfun)
3044 && TARGET_INTEGER_DFMODE_MOVES
3045 && (reload_in_progress || reload_completed
3046 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3047 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3048 && optimize_function_for_size_p (cfun)
3049 && standard_80387_constant_p (operands[1]))
3050 || GET_CODE (operands[1]) != CONST_DOUBLE
3051 || memory_operand (operands[0], DFmode))"
3053 switch (which_alternative)
3057 return output_387_reg_move (insn, operands);
3060 return standard_80387_constant_opcode (operands[1]);
3067 switch (get_attr_mode (insn))
3070 return "xorps\t%0, %0";
3072 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3073 return "xorps\t%0, %0";
3075 return "xorpd\t%0, %0";
3077 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3078 return "xorps\t%0, %0";
3080 return "pxor\t%0, %0";
3087 switch (get_attr_mode (insn))
3090 return "movaps\t{%1, %0|%0, %1}";
3092 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3093 return "movaps\t{%1, %0|%0, %1}";
3095 return "movapd\t{%1, %0|%0, %1}";
3097 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3098 return "movaps\t{%1, %0|%0, %1}";
3100 return "movdqa\t{%1, %0|%0, %1}";
3102 return "movq\t{%1, %0|%0, %1}";
3104 return "movsd\t{%1, %0|%0, %1}";
3106 return "movlpd\t{%1, %0|%0, %1}";
3108 return "movlps\t{%1, %0|%0, %1}";
3117 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3118 (set (attr "prefix_data16")
3119 (if_then_else (eq_attr "mode" "V1DF")
3121 (const_string "*")))
3123 (cond [(eq_attr "alternative" "0,1,2")
3125 (eq_attr "alternative" "3,4")
3128 /* For SSE1, we have many fewer alternatives. */
3129 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3130 (cond [(eq_attr "alternative" "5,6")
3131 (const_string "V4SF")
3133 (const_string "V2SF"))
3135 /* xorps is one byte shorter. */
3136 (eq_attr "alternative" "5")
3137 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3139 (const_string "V4SF")
3140 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3144 (const_string "V2DF"))
3146 /* For architectures resolving dependencies on
3147 whole SSE registers use APD move to break dependency
3148 chains, otherwise use short move to avoid extra work.
3150 movaps encodes one byte shorter. */
3151 (eq_attr "alternative" "6")
3153 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3155 (const_string "V4SF")
3156 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3158 (const_string "V2DF")
3160 (const_string "DF"))
3161 /* For architectures resolving dependencies on register
3162 parts we may avoid extra work to zero out upper part
3164 (eq_attr "alternative" "7")
3166 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3168 (const_string "V1DF")
3169 (const_string "DF"))
3171 (const_string "DF")))])
3173 ;; Moving is usually shorter when only FP registers are used. This separate
3174 ;; movdf pattern avoids the use of integer registers for FP operations
3175 ;; when optimizing for size.
3177 (define_insn "*movdf_internal_nointeger"
3178 [(set (match_operand:DF 0 "nonimmediate_operand"
3179 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
3180 (match_operand:DF 1 "general_operand"
3181 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
3182 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3183 && ((optimize_function_for_size_p (cfun)
3184 || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3185 && (reload_in_progress || reload_completed
3186 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3187 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3188 && optimize_function_for_size_p (cfun)
3189 && !memory_operand (operands[0], DFmode)
3190 && standard_80387_constant_p (operands[1]))
3191 || GET_CODE (operands[1]) != CONST_DOUBLE
3192 || ((optimize_function_for_size_p (cfun)
3193 || !TARGET_MEMORY_MISMATCH_STALL
3194 || reload_in_progress || reload_completed)
3195 && memory_operand (operands[0], DFmode)))"
3197 switch (which_alternative)
3201 return output_387_reg_move (insn, operands);
3204 return standard_80387_constant_opcode (operands[1]);
3211 switch (get_attr_mode (insn))
3214 return "%vxorps\t%0, %d0";
3216 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3217 return "%vxorps\t%0, %d0";
3219 return "%vxorpd\t%0, %d0";
3221 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3222 return "%vxorps\t%0, %d0";
3224 return "%vpxor\t%0, %d0";
3231 switch (get_attr_mode (insn))
3234 return "%vmovaps\t{%1, %0|%0, %1}";
3236 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3237 return "%vmovaps\t{%1, %0|%0, %1}";
3239 return "%vmovapd\t{%1, %0|%0, %1}";
3241 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3242 return "%vmovaps\t{%1, %0|%0, %1}";
3244 return "%vmovdqa\t{%1, %0|%0, %1}";
3246 return "%vmovq\t{%1, %0|%0, %1}";
3250 if (REG_P (operands[0]) && REG_P (operands[1]))
3251 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3253 return "vmovsd\t{%1, %0|%0, %1}";
3256 return "movsd\t{%1, %0|%0, %1}";
3260 if (REG_P (operands[0]))
3261 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3263 return "vmovlpd\t{%1, %0|%0, %1}";
3266 return "movlpd\t{%1, %0|%0, %1}";
3270 if (REG_P (operands[0]))
3271 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3273 return "vmovlps\t{%1, %0|%0, %1}";
3276 return "movlps\t{%1, %0|%0, %1}";
3285 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3286 (set (attr "prefix")
3287 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3288 (const_string "orig")
3289 (const_string "maybe_vex")))
3290 (set (attr "prefix_data16")
3291 (if_then_else (eq_attr "mode" "V1DF")
3293 (const_string "*")))
3295 (cond [(eq_attr "alternative" "0,1,2")
3297 (eq_attr "alternative" "3,4")
3300 /* For SSE1, we have many fewer alternatives. */
3301 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3302 (cond [(eq_attr "alternative" "5,6")
3303 (const_string "V4SF")
3305 (const_string "V2SF"))
3307 /* xorps is one byte shorter. */
3308 (eq_attr "alternative" "5")
3309 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3311 (const_string "V4SF")
3312 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3316 (const_string "V2DF"))
3318 /* For architectures resolving dependencies on
3319 whole SSE registers use APD move to break dependency
3320 chains, otherwise use short move to avoid extra work.
3322 movaps encodes one byte shorter. */
3323 (eq_attr "alternative" "6")
3325 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3327 (const_string "V4SF")
3328 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3330 (const_string "V2DF")
3332 (const_string "DF"))
3333 /* For architectures resolving dependencies on register
3334 parts we may avoid extra work to zero out upper part
3336 (eq_attr "alternative" "7")
3338 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3340 (const_string "V1DF")
3341 (const_string "DF"))
3343 (const_string "DF")))])
3346 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3347 (match_operand:DF 1 "general_operand" ""))]
3349 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3350 && ! (ANY_FP_REG_P (operands[0]) ||
3351 (GET_CODE (operands[0]) == SUBREG
3352 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3353 && ! (ANY_FP_REG_P (operands[1]) ||
3354 (GET_CODE (operands[1]) == SUBREG
3355 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3357 "ix86_split_long_move (operands); DONE;")
3359 (define_insn "*movsf_internal"
3360 [(set (match_operand:SF 0 "nonimmediate_operand"
3361 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3362 (match_operand:SF 1 "general_operand"
3363 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3364 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3365 && (reload_in_progress || reload_completed
3366 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3367 || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
3368 && standard_80387_constant_p (operands[1]))
3369 || GET_CODE (operands[1]) != CONST_DOUBLE
3370 || memory_operand (operands[0], SFmode))"
3372 switch (which_alternative)
3376 return output_387_reg_move (insn, operands);
3379 return standard_80387_constant_opcode (operands[1]);
3383 return "mov{l}\t{%1, %0|%0, %1}";
3385 if (get_attr_mode (insn) == MODE_TI)
3386 return "%vpxor\t%0, %d0";
3388 return "%vxorps\t%0, %d0";
3390 if (get_attr_mode (insn) == MODE_V4SF)
3391 return "%vmovaps\t{%1, %0|%0, %1}";
3393 return "%vmovss\t{%1, %d0|%d0, %1}";
3396 return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
3397 : "vmovss\t{%1, %0|%0, %1}";
3399 return "movss\t{%1, %0|%0, %1}";
3401 return "%vmovss\t{%1, %0|%0, %1}";
3403 case 9: case 10: case 14: case 15:
3404 return "movd\t{%1, %0|%0, %1}";
3406 return "%vmovd\t{%1, %0|%0, %1}";
3409 return "movq\t{%1, %0|%0, %1}";
3415 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3416 (set (attr "prefix")
3417 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3418 (const_string "maybe_vex")
3419 (const_string "orig")))
3421 (cond [(eq_attr "alternative" "3,4,9,10")
3423 (eq_attr "alternative" "5")
3425 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3427 (ne (symbol_ref "TARGET_SSE2")
3429 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3432 (const_string "V4SF"))
3433 /* For architectures resolving dependencies on
3434 whole SSE registers use APS move to break dependency
3435 chains, otherwise use short move to avoid extra work.
3437 Do the same for architectures resolving dependencies on
3438 the parts. While in DF mode it is better to always handle
3439 just register parts, the SF mode is different due to lack
3440 of instructions to load just part of the register. It is
3441 better to maintain the whole registers in single format
3442 to avoid problems on using packed logical operations. */
3443 (eq_attr "alternative" "6")
3445 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3447 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3449 (const_string "V4SF")
3450 (const_string "SF"))
3451 (eq_attr "alternative" "11")
3452 (const_string "DI")]
3453 (const_string "SF")))])
3456 [(set (match_operand 0 "register_operand" "")
3457 (match_operand 1 "memory_operand" ""))]
3459 && MEM_P (operands[1])
3460 && (GET_MODE (operands[0]) == TFmode
3461 || GET_MODE (operands[0]) == XFmode
3462 || GET_MODE (operands[0]) == DFmode
3463 || GET_MODE (operands[0]) == SFmode)
3464 && (operands[2] = find_constant_src (insn))"
3465 [(set (match_dup 0) (match_dup 2))]
3467 rtx c = operands[2];
3468 rtx r = operands[0];
3470 if (GET_CODE (r) == SUBREG)
3475 if (!standard_sse_constant_p (c))
3478 else if (FP_REG_P (r))
3480 if (!standard_80387_constant_p (c))
3483 else if (MMX_REG_P (r))
3488 [(set (match_operand 0 "register_operand" "")
3489 (float_extend (match_operand 1 "memory_operand" "")))]
3491 && MEM_P (operands[1])
3492 && (GET_MODE (operands[0]) == TFmode
3493 || GET_MODE (operands[0]) == XFmode
3494 || GET_MODE (operands[0]) == DFmode
3495 || GET_MODE (operands[0]) == SFmode)
3496 && (operands[2] = find_constant_src (insn))"
3497 [(set (match_dup 0) (match_dup 2))]
3499 rtx c = operands[2];
3500 rtx r = operands[0];
3502 if (GET_CODE (r) == SUBREG)
3507 if (!standard_sse_constant_p (c))
3510 else if (FP_REG_P (r))
3512 if (!standard_80387_constant_p (c))
3515 else if (MMX_REG_P (r))
3519 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3521 [(set (match_operand:X87MODEF 0 "register_operand" "")
3522 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3523 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3524 && (standard_80387_constant_p (operands[1]) == 8
3525 || standard_80387_constant_p (operands[1]) == 9)"
3526 [(set (match_dup 0)(match_dup 1))
3528 (neg:X87MODEF (match_dup 0)))]
3532 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3533 if (real_isnegzero (&r))
3534 operands[1] = CONST0_RTX (<MODE>mode);
3536 operands[1] = CONST1_RTX (<MODE>mode);
3539 (define_insn "swapxf"
3540 [(set (match_operand:XF 0 "register_operand" "+f")
3541 (match_operand:XF 1 "register_operand" "+f"))
3546 if (STACK_TOP_P (operands[0]))
3551 [(set_attr "type" "fxch")
3552 (set_attr "mode" "XF")])
3554 (define_insn "*swap<mode>"
3555 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3556 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3559 "TARGET_80387 || reload_completed"
3561 if (STACK_TOP_P (operands[0]))
3566 [(set_attr "type" "fxch")
3567 (set_attr "mode" "<MODE>")])
3569 ;; Zero extension instructions
3571 (define_expand "zero_extendsidi2"
3572 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3573 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3578 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3583 (define_insn "*zero_extendsidi2_rex64"
3584 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3586 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3589 mov\t{%k1, %k0|%k0, %k1}
3591 movd\t{%1, %0|%0, %1}
3592 movd\t{%1, %0|%0, %1}
3593 %vmovd\t{%1, %0|%0, %1}
3594 %vmovd\t{%1, %0|%0, %1}"
3595 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3596 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3597 (set_attr "prefix_0f" "0,*,*,*,*,*")
3598 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3601 [(set (match_operand:DI 0 "memory_operand" "")
3602 (zero_extend:DI (match_dup 0)))]
3604 [(set (match_dup 4) (const_int 0))]
3605 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3607 ;; %%% Kill me once multi-word ops are sane.
3608 (define_insn "zero_extendsidi2_1"
3609 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3611 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3612 (clobber (reg:CC FLAGS_REG))]
3618 movd\t{%1, %0|%0, %1}
3619 movd\t{%1, %0|%0, %1}
3620 %vmovd\t{%1, %0|%0, %1}
3621 %vmovd\t{%1, %0|%0, %1}"
3622 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3623 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3624 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3627 [(set (match_operand:DI 0 "register_operand" "")
3628 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3629 (clobber (reg:CC FLAGS_REG))]
3630 "!TARGET_64BIT && reload_completed
3631 && true_regnum (operands[0]) == true_regnum (operands[1])"
3632 [(set (match_dup 4) (const_int 0))]
3633 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3636 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3637 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3638 (clobber (reg:CC FLAGS_REG))]
3639 "!TARGET_64BIT && reload_completed
3640 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3641 [(set (match_dup 3) (match_dup 1))
3642 (set (match_dup 4) (const_int 0))]
3643 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3645 (define_insn "zero_extend<mode>di2"
3646 [(set (match_operand:DI 0 "register_operand" "=r")
3648 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3650 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3651 [(set_attr "type" "imovx")
3652 (set_attr "mode" "SI")])
3654 (define_expand "zero_extendhisi2"
3655 [(set (match_operand:SI 0 "register_operand" "")
3656 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3659 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3661 operands[1] = force_reg (HImode, operands[1]);
3662 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3667 (define_insn_and_split "zero_extendhisi2_and"
3668 [(set (match_operand:SI 0 "register_operand" "=r")
3669 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3670 (clobber (reg:CC FLAGS_REG))]
3671 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3673 "&& reload_completed"
3674 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3675 (clobber (reg:CC FLAGS_REG))])]
3677 [(set_attr "type" "alu1")
3678 (set_attr "mode" "SI")])
3680 (define_insn "*zero_extendhisi2_movzwl"
3681 [(set (match_operand:SI 0 "register_operand" "=r")
3682 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3683 "!TARGET_ZERO_EXTEND_WITH_AND
3684 || optimize_function_for_size_p (cfun)"
3685 "movz{wl|x}\t{%1, %0|%0, %1}"
3686 [(set_attr "type" "imovx")
3687 (set_attr "mode" "SI")])
3689 (define_expand "zero_extendqi<mode>2"
3691 [(set (match_operand:SWI24 0 "register_operand" "")
3692 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3693 (clobber (reg:CC FLAGS_REG))])]
3697 (define_insn "*zero_extendqi<mode>2_and"
3698 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3699 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3700 (clobber (reg:CC FLAGS_REG))]
3701 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3703 [(set_attr "type" "alu1")
3704 (set_attr "mode" "<MODE>")])
3706 ;; When source and destination does not overlap, clear destination
3707 ;; first and then do the movb
3709 [(set (match_operand:SWI24 0 "register_operand" "")
3710 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3711 (clobber (reg:CC FLAGS_REG))]
3713 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3714 && ANY_QI_REG_P (operands[0])
3715 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3716 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3717 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3719 operands[2] = gen_lowpart (QImode, operands[0]);
3720 ix86_expand_clear (operands[0]);
3723 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3724 [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3725 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3726 (clobber (reg:CC FLAGS_REG))]
3727 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3729 [(set_attr "type" "imovx,alu1")
3730 (set_attr "mode" "<MODE>")])
3732 ;; For the movzbl case strip only the clobber
3734 [(set (match_operand:SWI24 0 "register_operand" "")
3735 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3736 (clobber (reg:CC FLAGS_REG))]
3738 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3739 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3741 (zero_extend:SWI24 (match_dup 1)))])
3743 ; zero extend to SImode to avoid partial register stalls
3744 (define_insn "*zero_extendqi<mode>2_movzbl"
3745 [(set (match_operand:SWI24 0 "register_operand" "=r")
3746 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3748 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3749 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3750 [(set_attr "type" "imovx")
3751 (set_attr "mode" "SI")])
3753 ;; Rest is handled by single and.
3755 [(set (match_operand:SWI24 0 "register_operand" "")
3756 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3757 (clobber (reg:CC FLAGS_REG))]
3759 && true_regnum (operands[0]) == true_regnum (operands[1])"
3760 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3761 (clobber (reg:CC FLAGS_REG))])])
3763 ;; Sign extension instructions
3765 (define_expand "extendsidi2"
3766 [(set (match_operand:DI 0 "register_operand" "")
3767 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3772 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3777 (define_insn "*extendsidi2_rex64"
3778 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3779 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3783 movs{lq|x}\t{%1, %0|%0, %1}"
3784 [(set_attr "type" "imovx")
3785 (set_attr "mode" "DI")
3786 (set_attr "prefix_0f" "0")
3787 (set_attr "modrm" "0,1")])
3789 (define_insn "extendsidi2_1"
3790 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3791 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3792 (clobber (reg:CC FLAGS_REG))
3793 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3797 ;; Extend to memory case when source register does die.
3799 [(set (match_operand:DI 0 "memory_operand" "")
3800 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3801 (clobber (reg:CC FLAGS_REG))
3802 (clobber (match_operand:SI 2 "register_operand" ""))]
3804 && dead_or_set_p (insn, operands[1])
3805 && !reg_mentioned_p (operands[1], operands[0]))"
3806 [(set (match_dup 3) (match_dup 1))
3807 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3808 (clobber (reg:CC FLAGS_REG))])
3809 (set (match_dup 4) (match_dup 1))]
3810 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3812 ;; Extend to memory case when source register does not die.
3814 [(set (match_operand:DI 0 "memory_operand" "")
3815 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3816 (clobber (reg:CC FLAGS_REG))
3817 (clobber (match_operand:SI 2 "register_operand" ""))]
3821 split_di (&operands[0], 1, &operands[3], &operands[4]);
3823 emit_move_insn (operands[3], operands[1]);
3825 /* Generate a cltd if possible and doing so it profitable. */
3826 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3827 && true_regnum (operands[1]) == AX_REG
3828 && true_regnum (operands[2]) == DX_REG)
3830 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3834 emit_move_insn (operands[2], operands[1]);
3835 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3837 emit_move_insn (operands[4], operands[2]);
3841 ;; Extend to register case. Optimize case where source and destination
3842 ;; registers match and cases where we can use cltd.
3844 [(set (match_operand:DI 0 "register_operand" "")
3845 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3846 (clobber (reg:CC FLAGS_REG))
3847 (clobber (match_scratch:SI 2 ""))]
3851 split_di (&operands[0], 1, &operands[3], &operands[4]);
3853 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3854 emit_move_insn (operands[3], operands[1]);
3856 /* Generate a cltd if possible and doing so it profitable. */
3857 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3858 && true_regnum (operands[3]) == AX_REG
3859 && true_regnum (operands[4]) == DX_REG)
3861 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3865 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3866 emit_move_insn (operands[4], operands[1]);
3868 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3872 (define_insn "extend<mode>di2"
3873 [(set (match_operand:DI 0 "register_operand" "=r")
3875 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3877 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3878 [(set_attr "type" "imovx")
3879 (set_attr "mode" "DI")])
3881 (define_insn "extendhisi2"
3882 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3883 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3886 switch (get_attr_prefix_0f (insn))
3889 return "{cwtl|cwde}";
3891 return "movs{wl|x}\t{%1, %0|%0, %1}";
3894 [(set_attr "type" "imovx")
3895 (set_attr "mode" "SI")
3896 (set (attr "prefix_0f")
3897 ;; movsx is short decodable while cwtl is vector decoded.
3898 (if_then_else (and (eq_attr "cpu" "!k6")
3899 (eq_attr "alternative" "0"))
3901 (const_string "1")))
3903 (if_then_else (eq_attr "prefix_0f" "0")
3905 (const_string "1")))])
3907 (define_insn "*extendhisi2_zext"
3908 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3911 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3914 switch (get_attr_prefix_0f (insn))
3917 return "{cwtl|cwde}";
3919 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3922 [(set_attr "type" "imovx")
3923 (set_attr "mode" "SI")
3924 (set (attr "prefix_0f")
3925 ;; movsx is short decodable while cwtl is vector decoded.
3926 (if_then_else (and (eq_attr "cpu" "!k6")
3927 (eq_attr "alternative" "0"))
3929 (const_string "1")))
3931 (if_then_else (eq_attr "prefix_0f" "0")
3933 (const_string "1")))])
3935 (define_insn "extendqisi2"
3936 [(set (match_operand:SI 0 "register_operand" "=r")
3937 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3939 "movs{bl|x}\t{%1, %0|%0, %1}"
3940 [(set_attr "type" "imovx")
3941 (set_attr "mode" "SI")])
3943 (define_insn "*extendqisi2_zext"
3944 [(set (match_operand:DI 0 "register_operand" "=r")
3946 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3948 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3949 [(set_attr "type" "imovx")
3950 (set_attr "mode" "SI")])
3952 (define_insn "extendqihi2"
3953 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3954 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3957 switch (get_attr_prefix_0f (insn))
3960 return "{cbtw|cbw}";
3962 return "movs{bw|x}\t{%1, %0|%0, %1}";
3965 [(set_attr "type" "imovx")
3966 (set_attr "mode" "HI")
3967 (set (attr "prefix_0f")
3968 ;; movsx is short decodable while cwtl is vector decoded.
3969 (if_then_else (and (eq_attr "cpu" "!k6")
3970 (eq_attr "alternative" "0"))
3972 (const_string "1")))
3974 (if_then_else (eq_attr "prefix_0f" "0")
3976 (const_string "1")))])
3978 ;; Conversions between float and double.
3980 ;; These are all no-ops in the model used for the 80387.
3981 ;; So just emit moves.
3983 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3985 [(set (match_operand:DF 0 "push_operand" "")
3986 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3988 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3989 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3992 [(set (match_operand:XF 0 "push_operand" "")
3993 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3995 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3996 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3997 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3999 (define_expand "extendsfdf2"
4000 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4001 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4002 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4004 /* ??? Needed for compress_float_constant since all fp constants
4005 are LEGITIMATE_CONSTANT_P. */
4006 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4008 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4009 && standard_80387_constant_p (operands[1]) > 0)
4011 operands[1] = simplify_const_unary_operation
4012 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4013 emit_move_insn_1 (operands[0], operands[1]);
4016 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4020 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4022 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4024 We do the conversion post reload to avoid producing of 128bit spills
4025 that might lead to ICE on 32bit target. The sequence unlikely combine
4028 [(set (match_operand:DF 0 "register_operand" "")
4030 (match_operand:SF 1 "nonimmediate_operand" "")))]
4031 "TARGET_USE_VECTOR_FP_CONVERTS
4032 && optimize_insn_for_speed_p ()
4033 && reload_completed && SSE_REG_P (operands[0])"
4038 (parallel [(const_int 0) (const_int 1)]))))]
4040 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4041 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4042 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4043 Try to avoid move when unpacking can be done in source. */
4044 if (REG_P (operands[1]))
4046 /* If it is unsafe to overwrite upper half of source, we need
4047 to move to destination and unpack there. */
4048 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4049 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4050 && true_regnum (operands[0]) != true_regnum (operands[1]))
4052 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4053 emit_move_insn (tmp, operands[1]);
4056 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4057 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4061 emit_insn (gen_vec_setv4sf_0 (operands[3],
4062 CONST0_RTX (V4SFmode), operands[1]));
4065 (define_insn "*extendsfdf2_mixed"
4066 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4068 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4069 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4071 switch (which_alternative)
4075 return output_387_reg_move (insn, operands);
4078 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4084 [(set_attr "type" "fmov,fmov,ssecvt")
4085 (set_attr "prefix" "orig,orig,maybe_vex")
4086 (set_attr "mode" "SF,XF,DF")])
4088 (define_insn "*extendsfdf2_sse"
4089 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4090 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4091 "TARGET_SSE2 && TARGET_SSE_MATH"
4092 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4093 [(set_attr "type" "ssecvt")
4094 (set_attr "prefix" "maybe_vex")
4095 (set_attr "mode" "DF")])
4097 (define_insn "*extendsfdf2_i387"
4098 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4099 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4101 "* return output_387_reg_move (insn, operands);"
4102 [(set_attr "type" "fmov")
4103 (set_attr "mode" "SF,XF")])
4105 (define_expand "extend<mode>xf2"
4106 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4107 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4110 /* ??? Needed for compress_float_constant since all fp constants
4111 are LEGITIMATE_CONSTANT_P. */
4112 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4114 if (standard_80387_constant_p (operands[1]) > 0)
4116 operands[1] = simplify_const_unary_operation
4117 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4118 emit_move_insn_1 (operands[0], operands[1]);
4121 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4125 (define_insn "*extend<mode>xf2_i387"
4126 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4128 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4130 "* return output_387_reg_move (insn, operands);"
4131 [(set_attr "type" "fmov")
4132 (set_attr "mode" "<MODE>,XF")])
4134 ;; %%% This seems bad bad news.
4135 ;; This cannot output into an f-reg because there is no way to be sure
4136 ;; of truncating in that case. Otherwise this is just like a simple move
4137 ;; insn. So we pretend we can output to a reg in order to get better
4138 ;; register preferencing, but we really use a stack slot.
4140 ;; Conversion from DFmode to SFmode.
4142 (define_expand "truncdfsf2"
4143 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4145 (match_operand:DF 1 "nonimmediate_operand" "")))]
4146 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4148 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4150 else if (flag_unsafe_math_optimizations)
4154 enum ix86_stack_slot slot = (virtuals_instantiated
4157 rtx temp = assign_386_stack_local (SFmode, slot);
4158 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4163 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4165 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4167 We do the conversion post reload to avoid producing of 128bit spills
4168 that might lead to ICE on 32bit target. The sequence unlikely combine
4171 [(set (match_operand:SF 0 "register_operand" "")
4173 (match_operand:DF 1 "nonimmediate_operand" "")))]
4174 "TARGET_USE_VECTOR_FP_CONVERTS
4175 && optimize_insn_for_speed_p ()
4176 && reload_completed && SSE_REG_P (operands[0])"
4179 (float_truncate:V2SF
4183 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4184 operands[3] = CONST0_RTX (V2SFmode);
4185 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4186 /* Use movsd for loading from memory, unpcklpd for registers.
4187 Try to avoid move when unpacking can be done in source, or SSE3
4188 movddup is available. */
4189 if (REG_P (operands[1]))
4192 && true_regnum (operands[0]) != true_regnum (operands[1])
4193 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4194 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4196 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4197 emit_move_insn (tmp, operands[1]);
4200 else if (!TARGET_SSE3)
4201 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4202 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4205 emit_insn (gen_sse2_loadlpd (operands[4],
4206 CONST0_RTX (V2DFmode), operands[1]));
4209 (define_expand "truncdfsf2_with_temp"
4210 [(parallel [(set (match_operand:SF 0 "" "")
4211 (float_truncate:SF (match_operand:DF 1 "" "")))
4212 (clobber (match_operand:SF 2 "" ""))])]
4215 (define_insn "*truncdfsf_fast_mixed"
4216 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4218 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4219 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4221 switch (which_alternative)
4224 return output_387_reg_move (insn, operands);
4226 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4231 [(set_attr "type" "fmov,ssecvt")
4232 (set_attr "prefix" "orig,maybe_vex")
4233 (set_attr "mode" "SF")])
4235 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4236 ;; because nothing we do here is unsafe.
4237 (define_insn "*truncdfsf_fast_sse"
4238 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4240 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4241 "TARGET_SSE2 && TARGET_SSE_MATH"
4242 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4243 [(set_attr "type" "ssecvt")
4244 (set_attr "prefix" "maybe_vex")
4245 (set_attr "mode" "SF")])
4247 (define_insn "*truncdfsf_fast_i387"
4248 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4250 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4251 "TARGET_80387 && flag_unsafe_math_optimizations"
4252 "* return output_387_reg_move (insn, operands);"
4253 [(set_attr "type" "fmov")
4254 (set_attr "mode" "SF")])
4256 (define_insn "*truncdfsf_mixed"
4257 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4259 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4260 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4261 "TARGET_MIX_SSE_I387"
4263 switch (which_alternative)
4266 return output_387_reg_move (insn, operands);
4268 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4274 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4275 (set_attr "unit" "*,*,i387,i387,i387")
4276 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4277 (set_attr "mode" "SF")])
4279 (define_insn "*truncdfsf_i387"
4280 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4282 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4283 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4286 switch (which_alternative)
4289 return output_387_reg_move (insn, operands);
4295 [(set_attr "type" "fmov,multi,multi,multi")
4296 (set_attr "unit" "*,i387,i387,i387")
4297 (set_attr "mode" "SF")])
4299 (define_insn "*truncdfsf2_i387_1"
4300 [(set (match_operand:SF 0 "memory_operand" "=m")
4302 (match_operand:DF 1 "register_operand" "f")))]
4304 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4305 && !TARGET_MIX_SSE_I387"
4306 "* return output_387_reg_move (insn, operands);"
4307 [(set_attr "type" "fmov")
4308 (set_attr "mode" "SF")])
4311 [(set (match_operand:SF 0 "register_operand" "")
4313 (match_operand:DF 1 "fp_register_operand" "")))
4314 (clobber (match_operand 2 "" ""))]
4316 [(set (match_dup 2) (match_dup 1))
4317 (set (match_dup 0) (match_dup 2))]
4318 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4320 ;; Conversion from XFmode to {SF,DF}mode
4322 (define_expand "truncxf<mode>2"
4323 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4324 (float_truncate:MODEF
4325 (match_operand:XF 1 "register_operand" "")))
4326 (clobber (match_dup 2))])]
4329 if (flag_unsafe_math_optimizations)
4331 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4332 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4333 if (reg != operands[0])
4334 emit_move_insn (operands[0], reg);
4339 enum ix86_stack_slot slot = (virtuals_instantiated
4342 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4346 (define_insn "*truncxfsf2_mixed"
4347 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4349 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4350 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4353 gcc_assert (!which_alternative);
4354 return output_387_reg_move (insn, operands);
4356 [(set_attr "type" "fmov,multi,multi,multi")
4357 (set_attr "unit" "*,i387,i387,i387")
4358 (set_attr "mode" "SF")])
4360 (define_insn "*truncxfdf2_mixed"
4361 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4363 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4364 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4367 gcc_assert (!which_alternative);
4368 return output_387_reg_move (insn, operands);
4370 [(set_attr "type" "fmov,multi,multi,multi")
4371 (set_attr "unit" "*,i387,i387,i387")
4372 (set_attr "mode" "DF")])
4374 (define_insn "truncxf<mode>2_i387_noop"
4375 [(set (match_operand:MODEF 0 "register_operand" "=f")
4376 (float_truncate:MODEF
4377 (match_operand:XF 1 "register_operand" "f")))]
4378 "TARGET_80387 && flag_unsafe_math_optimizations"
4379 "* return output_387_reg_move (insn, operands);"
4380 [(set_attr "type" "fmov")
4381 (set_attr "mode" "<MODE>")])
4383 (define_insn "*truncxf<mode>2_i387"
4384 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4385 (float_truncate:MODEF
4386 (match_operand:XF 1 "register_operand" "f")))]
4388 "* return output_387_reg_move (insn, operands);"
4389 [(set_attr "type" "fmov")
4390 (set_attr "mode" "<MODE>")])
4393 [(set (match_operand:MODEF 0 "register_operand" "")
4394 (float_truncate:MODEF
4395 (match_operand:XF 1 "register_operand" "")))
4396 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4397 "TARGET_80387 && reload_completed"
4398 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4399 (set (match_dup 0) (match_dup 2))])
4402 [(set (match_operand:MODEF 0 "memory_operand" "")
4403 (float_truncate:MODEF
4404 (match_operand:XF 1 "register_operand" "")))
4405 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4407 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4409 ;; Signed conversion to DImode.
4411 (define_expand "fix_truncxfdi2"
4412 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4413 (fix:DI (match_operand:XF 1 "register_operand" "")))
4414 (clobber (reg:CC FLAGS_REG))])]
4419 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4424 (define_expand "fix_trunc<mode>di2"
4425 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4426 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4427 (clobber (reg:CC FLAGS_REG))])]
4428 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4431 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4433 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4436 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4438 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4439 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4440 if (out != operands[0])
4441 emit_move_insn (operands[0], out);
4446 ;; Signed conversion to SImode.
4448 (define_expand "fix_truncxfsi2"
4449 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4450 (fix:SI (match_operand:XF 1 "register_operand" "")))
4451 (clobber (reg:CC FLAGS_REG))])]
4456 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4461 (define_expand "fix_trunc<mode>si2"
4462 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4463 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4464 (clobber (reg:CC FLAGS_REG))])]
4465 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4468 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4470 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4473 if (SSE_FLOAT_MODE_P (<MODE>mode))
4475 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4476 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4477 if (out != operands[0])
4478 emit_move_insn (operands[0], out);
4483 ;; Signed conversion to HImode.
4485 (define_expand "fix_trunc<mode>hi2"
4486 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4487 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4488 (clobber (reg:CC FLAGS_REG))])]
4490 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4494 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4499 ;; Unsigned conversion to SImode.
4501 (define_expand "fixuns_trunc<mode>si2"
4503 [(set (match_operand:SI 0 "register_operand" "")
4505 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4507 (clobber (match_scratch:<ssevecmode> 3 ""))
4508 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4509 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4511 enum machine_mode mode = <MODE>mode;
4512 enum machine_mode vecmode = <ssevecmode>mode;
4513 REAL_VALUE_TYPE TWO31r;
4516 if (optimize_insn_for_size_p ())
4519 real_ldexp (&TWO31r, &dconst1, 31);
4520 two31 = const_double_from_real_value (TWO31r, mode);
4521 two31 = ix86_build_const_vector (mode, true, two31);
4522 operands[2] = force_reg (vecmode, two31);
4525 (define_insn_and_split "*fixuns_trunc<mode>_1"
4526 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4528 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4529 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4530 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4531 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4532 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4533 && optimize_function_for_speed_p (cfun)"
4535 "&& reload_completed"
4538 ix86_split_convert_uns_si_sse (operands);
4542 ;; Unsigned conversion to HImode.
4543 ;; Without these patterns, we'll try the unsigned SI conversion which
4544 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4546 (define_expand "fixuns_trunc<mode>hi2"
4548 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4549 (set (match_operand:HI 0 "nonimmediate_operand" "")
4550 (subreg:HI (match_dup 2) 0))]
4551 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4552 "operands[2] = gen_reg_rtx (SImode);")
4554 ;; When SSE is available, it is always faster to use it!
4555 (define_insn "fix_trunc<mode>di_sse"
4556 [(set (match_operand:DI 0 "register_operand" "=r,r")
4557 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4558 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4559 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4560 "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4561 [(set_attr "type" "sseicvt")
4562 (set_attr "prefix" "maybe_vex")
4563 (set_attr "prefix_rex" "1")
4564 (set_attr "mode" "<MODE>")
4565 (set_attr "athlon_decode" "double,vector")
4566 (set_attr "amdfam10_decode" "double,double")])
4568 (define_insn "fix_trunc<mode>si_sse"
4569 [(set (match_operand:SI 0 "register_operand" "=r,r")
4570 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4571 "SSE_FLOAT_MODE_P (<MODE>mode)
4572 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4573 "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4574 [(set_attr "type" "sseicvt")
4575 (set_attr "prefix" "maybe_vex")
4576 (set_attr "mode" "<MODE>")
4577 (set_attr "athlon_decode" "double,vector")
4578 (set_attr "amdfam10_decode" "double,double")])
4580 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4582 [(set (match_operand:MODEF 0 "register_operand" "")
4583 (match_operand:MODEF 1 "memory_operand" ""))
4584 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4585 (fix:SSEMODEI24 (match_dup 0)))]
4586 "TARGET_SHORTEN_X87_SSE
4587 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4588 && peep2_reg_dead_p (2, operands[0])"
4589 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))])
4591 ;; Avoid vector decoded forms of the instruction.
4593 [(match_scratch:DF 2 "Y2")
4594 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4595 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4596 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4597 [(set (match_dup 2) (match_dup 1))
4598 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4601 [(match_scratch:SF 2 "x")
4602 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4603 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4604 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4605 [(set (match_dup 2) (match_dup 1))
4606 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4608 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4609 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4610 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4611 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4613 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4614 && (TARGET_64BIT || <MODE>mode != DImode))
4616 && can_create_pseudo_p ()"
4621 if (memory_operand (operands[0], VOIDmode))
4622 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4625 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4626 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4632 [(set_attr "type" "fisttp")
4633 (set_attr "mode" "<MODE>")])
4635 (define_insn "fix_trunc<mode>_i387_fisttp"
4636 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4637 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4638 (clobber (match_scratch:XF 2 "=&1f"))]
4639 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4641 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4642 && (TARGET_64BIT || <MODE>mode != DImode))
4643 && TARGET_SSE_MATH)"
4644 "* return output_fix_trunc (insn, operands, 1);"
4645 [(set_attr "type" "fisttp")
4646 (set_attr "mode" "<MODE>")])
4648 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4649 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4650 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4651 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4652 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4653 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4655 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4656 && (TARGET_64BIT || <MODE>mode != DImode))
4657 && TARGET_SSE_MATH)"
4659 [(set_attr "type" "fisttp")
4660 (set_attr "mode" "<MODE>")])
4663 [(set (match_operand:X87MODEI 0 "register_operand" "")
4664 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4665 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4666 (clobber (match_scratch 3 ""))]
4668 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4669 (clobber (match_dup 3))])
4670 (set (match_dup 0) (match_dup 2))])
4673 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4674 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4675 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4676 (clobber (match_scratch 3 ""))]
4678 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4679 (clobber (match_dup 3))])])
4681 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4682 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4683 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4684 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4685 ;; function in i386.c.
4686 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4687 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4688 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4689 (clobber (reg:CC FLAGS_REG))]
4690 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4692 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4693 && (TARGET_64BIT || <MODE>mode != DImode))
4694 && can_create_pseudo_p ()"
4699 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4701 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4702 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4703 if (memory_operand (operands[0], VOIDmode))
4704 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4705 operands[2], operands[3]));
4708 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4709 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4710 operands[2], operands[3],
4715 [(set_attr "type" "fistp")
4716 (set_attr "i387_cw" "trunc")
4717 (set_attr "mode" "<MODE>")])
4719 (define_insn "fix_truncdi_i387"
4720 [(set (match_operand:DI 0 "memory_operand" "=m")
4721 (fix:DI (match_operand 1 "register_operand" "f")))
4722 (use (match_operand:HI 2 "memory_operand" "m"))
4723 (use (match_operand:HI 3 "memory_operand" "m"))
4724 (clobber (match_scratch:XF 4 "=&1f"))]
4725 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4727 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4728 "* return output_fix_trunc (insn, operands, 0);"
4729 [(set_attr "type" "fistp")
4730 (set_attr "i387_cw" "trunc")
4731 (set_attr "mode" "DI")])
4733 (define_insn "fix_truncdi_i387_with_temp"
4734 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4735 (fix:DI (match_operand 1 "register_operand" "f,f")))
4736 (use (match_operand:HI 2 "memory_operand" "m,m"))
4737 (use (match_operand:HI 3 "memory_operand" "m,m"))
4738 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4739 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4740 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4742 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4744 [(set_attr "type" "fistp")
4745 (set_attr "i387_cw" "trunc")
4746 (set_attr "mode" "DI")])
4749 [(set (match_operand:DI 0 "register_operand" "")
4750 (fix:DI (match_operand 1 "register_operand" "")))
4751 (use (match_operand:HI 2 "memory_operand" ""))
4752 (use (match_operand:HI 3 "memory_operand" ""))
4753 (clobber (match_operand:DI 4 "memory_operand" ""))
4754 (clobber (match_scratch 5 ""))]
4756 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4759 (clobber (match_dup 5))])
4760 (set (match_dup 0) (match_dup 4))])
4763 [(set (match_operand:DI 0 "memory_operand" "")
4764 (fix:DI (match_operand 1 "register_operand" "")))
4765 (use (match_operand:HI 2 "memory_operand" ""))
4766 (use (match_operand:HI 3 "memory_operand" ""))
4767 (clobber (match_operand:DI 4 "memory_operand" ""))
4768 (clobber (match_scratch 5 ""))]
4770 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4773 (clobber (match_dup 5))])])
4775 (define_insn "fix_trunc<mode>_i387"
4776 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4777 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4778 (use (match_operand:HI 2 "memory_operand" "m"))
4779 (use (match_operand:HI 3 "memory_operand" "m"))]
4780 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4782 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4783 "* return output_fix_trunc (insn, operands, 0);"
4784 [(set_attr "type" "fistp")
4785 (set_attr "i387_cw" "trunc")
4786 (set_attr "mode" "<MODE>")])
4788 (define_insn "fix_trunc<mode>_i387_with_temp"
4789 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4790 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4791 (use (match_operand:HI 2 "memory_operand" "m,m"))
4792 (use (match_operand:HI 3 "memory_operand" "m,m"))
4793 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4794 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4796 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4798 [(set_attr "type" "fistp")
4799 (set_attr "i387_cw" "trunc")
4800 (set_attr "mode" "<MODE>")])
4803 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4804 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4805 (use (match_operand:HI 2 "memory_operand" ""))
4806 (use (match_operand:HI 3 "memory_operand" ""))
4807 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4809 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4811 (use (match_dup 3))])
4812 (set (match_dup 0) (match_dup 4))])
4815 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4816 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4817 (use (match_operand:HI 2 "memory_operand" ""))
4818 (use (match_operand:HI 3 "memory_operand" ""))
4819 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4821 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4823 (use (match_dup 3))])])
4825 (define_insn "x86_fnstcw_1"
4826 [(set (match_operand:HI 0 "memory_operand" "=m")
4827 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4830 [(set (attr "length")
4831 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4832 (set_attr "mode" "HI")
4833 (set_attr "unit" "i387")])
4835 (define_insn "x86_fldcw_1"
4836 [(set (reg:HI FPCR_REG)
4837 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4840 [(set (attr "length")
4841 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4842 (set_attr "mode" "HI")
4843 (set_attr "unit" "i387")
4844 (set_attr "athlon_decode" "vector")
4845 (set_attr "amdfam10_decode" "vector")])
4847 ;; Conversion between fixed point and floating point.
4849 ;; Even though we only accept memory inputs, the backend _really_
4850 ;; wants to be able to do this between registers.
4852 (define_expand "floathi<mode>2"
4853 [(set (match_operand:X87MODEF 0 "register_operand" "")
4854 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4856 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4857 || TARGET_MIX_SSE_I387)"
4860 ;; Pre-reload splitter to add memory clobber to the pattern.
4861 (define_insn_and_split "*floathi<mode>2_1"
4862 [(set (match_operand:X87MODEF 0 "register_operand" "")
4863 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4865 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4866 || TARGET_MIX_SSE_I387)
4867 && can_create_pseudo_p ()"
4870 [(parallel [(set (match_dup 0)
4871 (float:X87MODEF (match_dup 1)))
4872 (clobber (match_dup 2))])]
4873 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4875 (define_insn "*floathi<mode>2_i387_with_temp"
4876 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4877 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4878 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4880 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4881 || TARGET_MIX_SSE_I387)"
4883 [(set_attr "type" "fmov,multi")
4884 (set_attr "mode" "<MODE>")
4885 (set_attr "unit" "*,i387")
4886 (set_attr "fp_int_src" "true")])
4888 (define_insn "*floathi<mode>2_i387"
4889 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4890 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4892 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4893 || TARGET_MIX_SSE_I387)"
4895 [(set_attr "type" "fmov")
4896 (set_attr "mode" "<MODE>")
4897 (set_attr "fp_int_src" "true")])
4900 [(set (match_operand:X87MODEF 0 "register_operand" "")
4901 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4902 (clobber (match_operand:HI 2 "memory_operand" ""))]
4904 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4905 || TARGET_MIX_SSE_I387)
4906 && reload_completed"
4907 [(set (match_dup 2) (match_dup 1))
4908 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4911 [(set (match_operand:X87MODEF 0 "register_operand" "")
4912 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4913 (clobber (match_operand:HI 2 "memory_operand" ""))]
4915 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4916 || TARGET_MIX_SSE_I387)
4917 && reload_completed"
4918 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4920 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
4921 [(set (match_operand:X87MODEF 0 "register_operand" "")
4923 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
4925 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4926 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4928 if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4929 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4930 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
4932 rtx reg = gen_reg_rtx (XFmode);
4935 emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
4937 if (<X87MODEF:MODE>mode == SFmode)
4938 insn = gen_truncxfsf2 (operands[0], reg);
4939 else if (<X87MODEF:MODE>mode == DFmode)
4940 insn = gen_truncxfdf2 (operands[0], reg);
4949 ;; Pre-reload splitter to add memory clobber to the pattern.
4950 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
4951 [(set (match_operand:X87MODEF 0 "register_operand" "")
4952 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
4954 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
4955 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4956 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4957 || TARGET_MIX_SSE_I387))
4958 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4959 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4960 && ((<SSEMODEI24:MODE>mode == SImode
4961 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4962 && optimize_function_for_speed_p (cfun)
4963 && flag_trapping_math)
4964 || !(TARGET_INTER_UNIT_CONVERSIONS
4965 || optimize_function_for_size_p (cfun)))))
4966 && can_create_pseudo_p ()"
4969 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4970 (clobber (match_dup 2))])]
4972 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
4974 /* Avoid store forwarding (partial memory) stall penalty
4975 by passing DImode value through XMM registers. */
4976 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
4977 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4978 && optimize_function_for_speed_p (cfun))
4980 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4987 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4988 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4990 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4991 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4992 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4993 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4995 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4996 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4997 (set_attr "unit" "*,i387,*,*,*")
4998 (set_attr "athlon_decode" "*,*,double,direct,double")
4999 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5000 (set_attr "fp_int_src" "true")])
5002 (define_insn "*floatsi<mode>2_vector_mixed"
5003 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5004 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5005 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5006 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5010 [(set_attr "type" "fmov,sseicvt")
5011 (set_attr "mode" "<MODE>,<ssevecmode>")
5012 (set_attr "unit" "i387,*")
5013 (set_attr "athlon_decode" "*,direct")
5014 (set_attr "amdfam10_decode" "*,double")
5015 (set_attr "fp_int_src" "true")])
5017 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5018 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5020 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5021 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5022 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5023 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5025 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5026 (set_attr "mode" "<MODEF:MODE>")
5027 (set_attr "unit" "*,i387,*,*")
5028 (set_attr "athlon_decode" "*,*,double,direct")
5029 (set_attr "amdfam10_decode" "*,*,vector,double")
5030 (set_attr "fp_int_src" "true")])
5033 [(set (match_operand:MODEF 0 "register_operand" "")
5034 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5035 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5036 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5037 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5038 && TARGET_INTER_UNIT_CONVERSIONS
5040 && (SSE_REG_P (operands[0])
5041 || (GET_CODE (operands[0]) == SUBREG
5042 && SSE_REG_P (operands[0])))"
5043 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5046 [(set (match_operand:MODEF 0 "register_operand" "")
5047 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5048 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5049 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5050 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5051 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5053 && (SSE_REG_P (operands[0])
5054 || (GET_CODE (operands[0]) == SUBREG
5055 && SSE_REG_P (operands[0])))"
5056 [(set (match_dup 2) (match_dup 1))
5057 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5059 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5060 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5062 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5063 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5064 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5065 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5068 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5069 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5070 [(set_attr "type" "fmov,sseicvt,sseicvt")
5071 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5072 (set_attr "mode" "<MODEF:MODE>")
5073 (set (attr "prefix_rex")
5075 (and (eq_attr "prefix" "maybe_vex")
5076 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5078 (const_string "*")))
5079 (set_attr "unit" "i387,*,*")
5080 (set_attr "athlon_decode" "*,double,direct")
5081 (set_attr "amdfam10_decode" "*,vector,double")
5082 (set_attr "fp_int_src" "true")])
5084 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5085 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5087 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5088 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5089 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5090 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5093 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5094 [(set_attr "type" "fmov,sseicvt")
5095 (set_attr "prefix" "orig,maybe_vex")
5096 (set_attr "mode" "<MODEF:MODE>")
5097 (set (attr "prefix_rex")
5099 (and (eq_attr "prefix" "maybe_vex")
5100 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5102 (const_string "*")))
5103 (set_attr "athlon_decode" "*,direct")
5104 (set_attr "amdfam10_decode" "*,double")
5105 (set_attr "fp_int_src" "true")])
5107 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5108 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5110 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5111 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5112 "TARGET_SSE2 && TARGET_SSE_MATH
5113 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5115 [(set_attr "type" "sseicvt")
5116 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5117 (set_attr "athlon_decode" "double,direct,double")
5118 (set_attr "amdfam10_decode" "vector,double,double")
5119 (set_attr "fp_int_src" "true")])
5121 (define_insn "*floatsi<mode>2_vector_sse"
5122 [(set (match_operand:MODEF 0 "register_operand" "=x")
5123 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5124 "TARGET_SSE2 && TARGET_SSE_MATH
5125 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5127 [(set_attr "type" "sseicvt")
5128 (set_attr "mode" "<MODE>")
5129 (set_attr "athlon_decode" "direct")
5130 (set_attr "amdfam10_decode" "double")
5131 (set_attr "fp_int_src" "true")])
5134 [(set (match_operand:MODEF 0 "register_operand" "")
5135 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5136 (clobber (match_operand:SI 2 "memory_operand" ""))]
5137 "TARGET_SSE2 && TARGET_SSE_MATH
5138 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5140 && (SSE_REG_P (operands[0])
5141 || (GET_CODE (operands[0]) == SUBREG
5142 && SSE_REG_P (operands[0])))"
5145 rtx op1 = operands[1];
5147 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5149 if (GET_CODE (op1) == SUBREG)
5150 op1 = SUBREG_REG (op1);
5152 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5154 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5155 emit_insn (gen_sse2_loadld (operands[4],
5156 CONST0_RTX (V4SImode), operands[1]));
5158 /* We can ignore possible trapping value in the
5159 high part of SSE register for non-trapping math. */
5160 else if (SSE_REG_P (op1) && !flag_trapping_math)
5161 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5164 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5165 emit_move_insn (operands[2], operands[1]);
5166 emit_insn (gen_sse2_loadld (operands[4],
5167 CONST0_RTX (V4SImode), operands[2]));
5170 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5175 [(set (match_operand:MODEF 0 "register_operand" "")
5176 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5177 (clobber (match_operand:SI 2 "memory_operand" ""))]
5178 "TARGET_SSE2 && TARGET_SSE_MATH
5179 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5181 && (SSE_REG_P (operands[0])
5182 || (GET_CODE (operands[0]) == SUBREG
5183 && SSE_REG_P (operands[0])))"
5186 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5188 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5190 emit_insn (gen_sse2_loadld (operands[4],
5191 CONST0_RTX (V4SImode), operands[1]));
5193 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5198 [(set (match_operand:MODEF 0 "register_operand" "")
5199 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5200 "TARGET_SSE2 && TARGET_SSE_MATH
5201 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5203 && (SSE_REG_P (operands[0])
5204 || (GET_CODE (operands[0]) == SUBREG
5205 && SSE_REG_P (operands[0])))"
5208 rtx op1 = operands[1];
5210 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5212 if (GET_CODE (op1) == SUBREG)
5213 op1 = SUBREG_REG (op1);
5215 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5217 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5218 emit_insn (gen_sse2_loadld (operands[4],
5219 CONST0_RTX (V4SImode), operands[1]));
5221 /* We can ignore possible trapping value in the
5222 high part of SSE register for non-trapping math. */
5223 else if (SSE_REG_P (op1) && !flag_trapping_math)
5224 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5228 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5233 [(set (match_operand:MODEF 0 "register_operand" "")
5234 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5235 "TARGET_SSE2 && TARGET_SSE_MATH
5236 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5238 && (SSE_REG_P (operands[0])
5239 || (GET_CODE (operands[0]) == SUBREG
5240 && SSE_REG_P (operands[0])))"
5243 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5245 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5247 emit_insn (gen_sse2_loadld (operands[4],
5248 CONST0_RTX (V4SImode), operands[1]));
5250 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5254 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5255 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5257 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5258 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5259 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5260 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5262 [(set_attr "type" "sseicvt")
5263 (set_attr "mode" "<MODEF:MODE>")
5264 (set_attr "athlon_decode" "double,direct")
5265 (set_attr "amdfam10_decode" "vector,double")
5266 (set_attr "fp_int_src" "true")])
5268 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5269 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5271 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5272 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5273 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5274 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5275 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5276 [(set_attr "type" "sseicvt")
5277 (set_attr "prefix" "maybe_vex")
5278 (set_attr "mode" "<MODEF:MODE>")
5279 (set (attr "prefix_rex")
5281 (and (eq_attr "prefix" "maybe_vex")
5282 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5284 (const_string "*")))
5285 (set_attr "athlon_decode" "double,direct")
5286 (set_attr "amdfam10_decode" "vector,double")
5287 (set_attr "fp_int_src" "true")])
5290 [(set (match_operand:MODEF 0 "register_operand" "")
5291 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5292 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5293 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5294 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5295 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5297 && (SSE_REG_P (operands[0])
5298 || (GET_CODE (operands[0]) == SUBREG
5299 && SSE_REG_P (operands[0])))"
5300 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5302 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5303 [(set (match_operand:MODEF 0 "register_operand" "=x")
5305 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5306 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5307 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5308 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5309 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5310 [(set_attr "type" "sseicvt")
5311 (set_attr "prefix" "maybe_vex")
5312 (set_attr "mode" "<MODEF:MODE>")
5313 (set (attr "prefix_rex")
5315 (and (eq_attr "prefix" "maybe_vex")
5316 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5318 (const_string "*")))
5319 (set_attr "athlon_decode" "direct")
5320 (set_attr "amdfam10_decode" "double")
5321 (set_attr "fp_int_src" "true")])
5324 [(set (match_operand:MODEF 0 "register_operand" "")
5325 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5326 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5327 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5328 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5329 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5331 && (SSE_REG_P (operands[0])
5332 || (GET_CODE (operands[0]) == SUBREG
5333 && SSE_REG_P (operands[0])))"
5334 [(set (match_dup 2) (match_dup 1))
5335 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5338 [(set (match_operand:MODEF 0 "register_operand" "")
5339 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5340 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5341 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5342 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5344 && (SSE_REG_P (operands[0])
5345 || (GET_CODE (operands[0]) == SUBREG
5346 && SSE_REG_P (operands[0])))"
5347 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5349 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5350 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5352 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5353 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5355 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5359 [(set_attr "type" "fmov,multi")
5360 (set_attr "mode" "<X87MODEF:MODE>")
5361 (set_attr "unit" "*,i387")
5362 (set_attr "fp_int_src" "true")])
5364 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5365 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5367 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5369 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5371 [(set_attr "type" "fmov")
5372 (set_attr "mode" "<X87MODEF:MODE>")
5373 (set_attr "fp_int_src" "true")])
5376 [(set (match_operand:X87MODEF 0 "register_operand" "")
5377 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5378 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5380 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5382 && FP_REG_P (operands[0])"
5383 [(set (match_dup 2) (match_dup 1))
5384 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5387 [(set (match_operand:X87MODEF 0 "register_operand" "")
5388 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5389 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5391 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5393 && FP_REG_P (operands[0])"
5394 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5396 ;; Avoid store forwarding (partial memory) stall penalty
5397 ;; by passing DImode value through XMM registers. */
5399 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5400 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5402 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5403 (clobber (match_scratch:V4SI 3 "=X,x"))
5404 (clobber (match_scratch:V4SI 4 "=X,x"))
5405 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5406 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5407 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5408 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5410 [(set_attr "type" "multi")
5411 (set_attr "mode" "<X87MODEF:MODE>")
5412 (set_attr "unit" "i387")
5413 (set_attr "fp_int_src" "true")])
5416 [(set (match_operand:X87MODEF 0 "register_operand" "")
5417 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5418 (clobber (match_scratch:V4SI 3 ""))
5419 (clobber (match_scratch:V4SI 4 ""))
5420 (clobber (match_operand:DI 2 "memory_operand" ""))]
5421 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5422 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5423 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5425 && FP_REG_P (operands[0])"
5426 [(set (match_dup 2) (match_dup 3))
5427 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5429 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5430 Assemble the 64-bit DImode value in an xmm register. */
5431 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5432 gen_rtx_SUBREG (SImode, operands[1], 0)));
5433 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5434 gen_rtx_SUBREG (SImode, operands[1], 4)));
5435 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5438 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5442 [(set (match_operand:X87MODEF 0 "register_operand" "")
5443 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5444 (clobber (match_scratch:V4SI 3 ""))
5445 (clobber (match_scratch:V4SI 4 ""))
5446 (clobber (match_operand:DI 2 "memory_operand" ""))]
5447 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5448 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5449 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5451 && FP_REG_P (operands[0])"
5452 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5454 ;; Avoid store forwarding (partial memory) stall penalty by extending
5455 ;; SImode value to DImode through XMM register instead of pushing two
5456 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5457 ;; targets benefit from this optimization. Also note that fild
5458 ;; loads from memory only.
5460 (define_insn "*floatunssi<mode>2_1"
5461 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5462 (unsigned_float:X87MODEF
5463 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5464 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5465 (clobber (match_scratch:SI 3 "=X,x"))]
5467 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5470 [(set_attr "type" "multi")
5471 (set_attr "mode" "<MODE>")])
5474 [(set (match_operand:X87MODEF 0 "register_operand" "")
5475 (unsigned_float:X87MODEF
5476 (match_operand:SI 1 "register_operand" "")))
5477 (clobber (match_operand:DI 2 "memory_operand" ""))
5478 (clobber (match_scratch:SI 3 ""))]
5480 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5482 && reload_completed"
5483 [(set (match_dup 2) (match_dup 1))
5485 (float:X87MODEF (match_dup 2)))]
5486 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5489 [(set (match_operand:X87MODEF 0 "register_operand" "")
5490 (unsigned_float:X87MODEF
5491 (match_operand:SI 1 "memory_operand" "")))
5492 (clobber (match_operand:DI 2 "memory_operand" ""))
5493 (clobber (match_scratch:SI 3 ""))]
5495 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5497 && reload_completed"
5498 [(set (match_dup 2) (match_dup 3))
5500 (float:X87MODEF (match_dup 2)))]
5502 emit_move_insn (operands[3], operands[1]);
5503 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5506 (define_expand "floatunssi<mode>2"
5508 [(set (match_operand:X87MODEF 0 "register_operand" "")
5509 (unsigned_float:X87MODEF
5510 (match_operand:SI 1 "nonimmediate_operand" "")))
5511 (clobber (match_dup 2))
5512 (clobber (match_scratch:SI 3 ""))])]
5514 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5516 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5518 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5520 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5525 enum ix86_stack_slot slot = (virtuals_instantiated
5528 operands[2] = assign_386_stack_local (DImode, slot);
5532 (define_expand "floatunsdisf2"
5533 [(use (match_operand:SF 0 "register_operand" ""))
5534 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5535 "TARGET_64BIT && TARGET_SSE_MATH"
5536 "x86_emit_floatuns (operands); DONE;")
5538 (define_expand "floatunsdidf2"
5539 [(use (match_operand:DF 0 "register_operand" ""))
5540 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5541 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5542 && TARGET_SSE2 && TARGET_SSE_MATH"
5545 x86_emit_floatuns (operands);
5547 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5553 (define_expand "add<mode>3"
5554 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5555 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5556 (match_operand:SDWIM 2 "<general_operand>" "")))]
5558 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5560 (define_insn_and_split "*add<dwi>3_doubleword"
5561 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5563 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5564 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5565 (clobber (reg:CC FLAGS_REG))]
5566 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5569 [(parallel [(set (reg:CC FLAGS_REG)
5570 (unspec:CC [(match_dup 1) (match_dup 2)]
5573 (plus:DWIH (match_dup 1) (match_dup 2)))])
5574 (parallel [(set (match_dup 3)
5578 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5580 (clobber (reg:CC FLAGS_REG))])]
5581 "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
5583 (define_insn "*add<mode>3_cc"
5584 [(set (reg:CC FLAGS_REG)
5586 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5587 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5589 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5590 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5591 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5592 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5593 [(set_attr "type" "alu")
5594 (set_attr "mode" "<MODE>")])
5596 (define_insn "addqi3_cc"
5597 [(set (reg:CC FLAGS_REG)
5599 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5600 (match_operand:QI 2 "general_operand" "qn,qm")]
5602 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5603 (plus:QI (match_dup 1) (match_dup 2)))]
5604 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5605 "add{b}\t{%2, %0|%0, %2}"
5606 [(set_attr "type" "alu")
5607 (set_attr "mode" "QI")])
5609 (define_insn "*lea_1"
5610 [(set (match_operand:P 0 "register_operand" "=r")
5611 (match_operand:P 1 "no_seg_address_operand" "p"))]
5613 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5614 [(set_attr "type" "lea")
5615 (set_attr "mode" "<MODE>")])
5617 (define_insn "*lea_2"
5618 [(set (match_operand:SI 0 "register_operand" "=r")
5619 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5621 "lea{l}\t{%a1, %0|%0, %a1}"
5622 [(set_attr "type" "lea")
5623 (set_attr "mode" "SI")])
5625 (define_insn "*lea_2_zext"
5626 [(set (match_operand:DI 0 "register_operand" "=r")
5628 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5630 "lea{l}\t{%a1, %k0|%k0, %a1}"
5631 [(set_attr "type" "lea")
5632 (set_attr "mode" "SI")])
5634 (define_insn "*add<mode>_1"
5635 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5637 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5638 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5639 (clobber (reg:CC FLAGS_REG))]
5640 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5642 switch (get_attr_type (insn))
5648 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5649 if (operands[2] == const1_rtx)
5650 return "inc{<imodesuffix>}\t%0";
5653 gcc_assert (operands[2] == constm1_rtx);
5654 return "dec{<imodesuffix>}\t%0";
5658 /* For most processors, ADD is faster than LEA. This alternative
5659 was added to use ADD as much as possible. */
5660 if (which_alternative == 2)
5663 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5666 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5667 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5668 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5670 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5674 (cond [(eq_attr "alternative" "3")
5675 (const_string "lea")
5676 (match_operand:SWI48 2 "incdec_operand" "")
5677 (const_string "incdec")
5679 (const_string "alu")))
5680 (set (attr "length_immediate")
5682 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5684 (const_string "*")))
5685 (set_attr "mode" "<MODE>")])
5687 ;; It may seem that nonimmediate operand is proper one for operand 1.
5688 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5689 ;; we take care in ix86_binary_operator_ok to not allow two memory
5690 ;; operands so proper swapping will be done in reload. This allow
5691 ;; patterns constructed from addsi_1 to match.
5693 (define_insn "*addsi_1_zext"
5694 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5696 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5697 (match_operand:SI 2 "general_operand" "g,0,li"))))
5698 (clobber (reg:CC FLAGS_REG))]
5699 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5701 switch (get_attr_type (insn))
5707 if (operands[2] == const1_rtx)
5708 return "inc{l}\t%k0";
5711 gcc_assert (operands[2] == constm1_rtx);
5712 return "dec{l}\t%k0";
5716 /* For most processors, ADD is faster than LEA. This alternative
5717 was added to use ADD as much as possible. */
5718 if (which_alternative == 1)
5721 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5724 if (x86_maybe_negate_const_int (&operands[2], SImode))
5725 return "sub{l}\t{%2, %k0|%k0, %2}";
5727 return "add{l}\t{%2, %k0|%k0, %2}";
5731 (cond [(eq_attr "alternative" "2")
5732 (const_string "lea")
5733 (match_operand:SI 2 "incdec_operand" "")
5734 (const_string "incdec")
5736 (const_string "alu")))
5737 (set (attr "length_immediate")
5739 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5741 (const_string "*")))
5742 (set_attr "mode" "SI")])
5744 (define_insn "*addhi_1"
5745 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5746 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5747 (match_operand:HI 2 "general_operand" "rn,rm")))
5748 (clobber (reg:CC FLAGS_REG))]
5749 "TARGET_PARTIAL_REG_STALL
5750 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5752 switch (get_attr_type (insn))
5755 if (operands[2] == const1_rtx)
5756 return "inc{w}\t%0";
5759 gcc_assert (operands[2] == constm1_rtx);
5760 return "dec{w}\t%0";
5764 if (x86_maybe_negate_const_int (&operands[2], HImode))
5765 return "sub{w}\t{%2, %0|%0, %2}";
5767 return "add{w}\t{%2, %0|%0, %2}";
5771 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5772 (const_string "incdec")
5773 (const_string "alu")))
5774 (set (attr "length_immediate")
5776 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5778 (const_string "*")))
5779 (set_attr "mode" "HI")])
5781 (define_insn "*addhi_1_lea"
5782 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r")
5783 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r")
5784 (match_operand:HI 2 "general_operand" "rmn,rn,0,ln")))
5785 (clobber (reg:CC FLAGS_REG))]
5786 "!TARGET_PARTIAL_REG_STALL
5787 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5789 switch (get_attr_type (insn))
5795 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5796 if (operands[2] == const1_rtx)
5797 return "inc{w}\t%0";
5800 gcc_assert (operands[2] == constm1_rtx);
5801 return "dec{w}\t%0";
5805 /* For most processors, ADD is faster than LEA. This alternative
5806 was added to use ADD as much as possible. */
5807 if (which_alternative == 2)
5810 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5813 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5814 if (x86_maybe_negate_const_int (&operands[2], HImode))
5815 return "sub{w}\t{%2, %0|%0, %2}";
5817 return "add{w}\t{%2, %0|%0, %2}";
5821 (cond [(eq_attr "alternative" "3")
5822 (const_string "lea")
5823 (match_operand:HI 2 "incdec_operand" "")
5824 (const_string "incdec")
5826 (const_string "alu")))
5827 (set (attr "length_immediate")
5829 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5831 (const_string "*")))
5832 (set_attr "mode" "HI,HI,HI,SI")])
5834 ;; %%% Potential partial reg stall on alternative 2. What to do?
5835 (define_insn "*addqi_1"
5836 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5837 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5838 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5839 (clobber (reg:CC FLAGS_REG))]
5840 "TARGET_PARTIAL_REG_STALL
5841 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5843 int widen = (which_alternative == 2);
5844 switch (get_attr_type (insn))
5847 if (operands[2] == const1_rtx)
5848 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5851 gcc_assert (operands[2] == constm1_rtx);
5852 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5856 if (x86_maybe_negate_const_int (&operands[2], QImode))
5859 return "sub{l}\t{%2, %k0|%k0, %2}";
5861 return "sub{b}\t{%2, %0|%0, %2}";
5864 return "add{l}\t{%k2, %k0|%k0, %k2}";
5866 return "add{b}\t{%2, %0|%0, %2}";
5870 (if_then_else (match_operand:QI 2 "incdec_operand" "")
5871 (const_string "incdec")
5872 (const_string "alu")))
5873 (set (attr "length_immediate")
5875 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5877 (const_string "*")))
5878 (set_attr "mode" "QI,QI,SI")])
5880 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5881 (define_insn "*addqi_1_lea"
5882 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r")
5883 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r")
5884 (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln")))
5885 (clobber (reg:CC FLAGS_REG))]
5886 "!TARGET_PARTIAL_REG_STALL
5887 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5889 int widen = (which_alternative == 3 || which_alternative == 4);
5891 switch (get_attr_type (insn))
5897 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5898 if (operands[2] == const1_rtx)
5899 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5902 gcc_assert (operands[2] == constm1_rtx);
5903 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5907 /* For most processors, ADD is faster than LEA. These alternatives
5908 were added to use ADD as much as possible. */
5909 if (which_alternative == 2 || which_alternative == 4)
5912 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5915 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5916 if (x86_maybe_negate_const_int (&operands[2], QImode))
5919 return "sub{l}\t{%2, %k0|%k0, %2}";
5921 return "sub{b}\t{%2, %0|%0, %2}";
5924 return "add{l}\t{%k2, %k0|%k0, %k2}";
5926 return "add{b}\t{%2, %0|%0, %2}";
5930 (cond [(eq_attr "alternative" "5")
5931 (const_string "lea")
5932 (match_operand:QI 2 "incdec_operand" "")
5933 (const_string "incdec")
5935 (const_string "alu")))
5936 (set (attr "length_immediate")
5938 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5940 (const_string "*")))
5941 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5943 (define_insn "*addqi_1_slp"
5944 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5945 (plus:QI (match_dup 0)
5946 (match_operand:QI 1 "general_operand" "qn,qnm")))
5947 (clobber (reg:CC FLAGS_REG))]
5948 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5949 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5951 switch (get_attr_type (insn))
5954 if (operands[1] == const1_rtx)
5955 return "inc{b}\t%0";
5958 gcc_assert (operands[1] == constm1_rtx);
5959 return "dec{b}\t%0";
5963 if (x86_maybe_negate_const_int (&operands[1], QImode))
5964 return "sub{b}\t{%1, %0|%0, %1}";
5966 return "add{b}\t{%1, %0|%0, %1}";
5970 (if_then_else (match_operand:QI 1 "incdec_operand" "")
5971 (const_string "incdec")
5972 (const_string "alu1")))
5973 (set (attr "memory")
5974 (if_then_else (match_operand 1 "memory_operand" "")
5975 (const_string "load")
5976 (const_string "none")))
5977 (set_attr "mode" "QI")])
5979 ;; Convert lea to the lea pattern to avoid flags dependency.
5981 [(set (match_operand 0 "register_operand" "")
5982 (plus (match_operand 1 "register_operand" "")
5983 (match_operand 2 "nonmemory_operand" "")))
5984 (clobber (reg:CC FLAGS_REG))]
5985 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5989 enum machine_mode mode = GET_MODE (operands[0]);
5991 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
5992 may confuse gen_lowpart. */
5995 operands[1] = gen_lowpart (Pmode, operands[1]);
5996 operands[2] = gen_lowpart (Pmode, operands[2]);
5999 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6001 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6002 operands[0] = gen_lowpart (SImode, operands[0]);
6004 if (TARGET_64BIT && mode != Pmode)
6005 pat = gen_rtx_SUBREG (SImode, pat, 0);
6007 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6011 ;; Convert lea to the lea pattern to avoid flags dependency.
6012 ;; ??? This pattern handles immediate operands that do not satisfy immediate
6013 ;; operand predicate (LEGITIMATE_CONSTANT_P) in the previous pattern.
6015 [(set (match_operand:DI 0 "register_operand" "")
6016 (plus:DI (match_operand:DI 1 "register_operand" "")
6017 (match_operand:DI 2 "x86_64_immediate_operand" "")))
6018 (clobber (reg:CC FLAGS_REG))]
6019 "TARGET_64BIT && reload_completed
6020 && true_regnum (operands[0]) != true_regnum (operands[1])"
6022 (plus:DI (match_dup 1) (match_dup 2)))])
6024 ;; Convert lea to the lea pattern to avoid flags dependency.
6026 [(set (match_operand:DI 0 "register_operand" "")
6028 (plus:SI (match_operand:SI 1 "register_operand" "")
6029 (match_operand:SI 2 "nonmemory_operand" ""))))
6030 (clobber (reg:CC FLAGS_REG))]
6031 "TARGET_64BIT && reload_completed
6032 && ix86_lea_for_add_ok (insn, operands)"
6034 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6036 operands[1] = gen_lowpart (DImode, operands[1]);
6037 operands[2] = gen_lowpart (DImode, operands[2]);
6040 (define_insn "*add<mode>_2"
6041 [(set (reg FLAGS_REG)
6044 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6045 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
6047 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6048 (plus:SWI (match_dup 1) (match_dup 2)))]
6049 "ix86_match_ccmode (insn, CCGOCmode)
6050 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6052 switch (get_attr_type (insn))
6055 if (operands[2] == const1_rtx)
6056 return "inc{<imodesuffix>}\t%0";
6059 gcc_assert (operands[2] == constm1_rtx);
6060 return "dec{<imodesuffix>}\t%0";
6064 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6065 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6067 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6071 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6072 (const_string "incdec")
6073 (const_string "alu")))
6074 (set (attr "length_immediate")
6076 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6078 (const_string "*")))
6079 (set_attr "mode" "<MODE>")])
6081 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6082 (define_insn "*addsi_2_zext"
6083 [(set (reg FLAGS_REG)
6085 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6086 (match_operand:SI 2 "general_operand" "g"))
6088 (set (match_operand:DI 0 "register_operand" "=r")
6089 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6090 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6091 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6093 switch (get_attr_type (insn))
6096 if (operands[2] == const1_rtx)
6097 return "inc{l}\t%k0";
6100 gcc_assert (operands[2] == constm1_rtx);
6101 return "dec{l}\t%k0";
6105 if (x86_maybe_negate_const_int (&operands[2], SImode))
6106 return "sub{l}\t{%2, %k0|%k0, %2}";
6108 return "add{l}\t{%2, %k0|%k0, %2}";
6112 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6113 (const_string "incdec")
6114 (const_string "alu")))
6115 (set (attr "length_immediate")
6117 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6119 (const_string "*")))
6120 (set_attr "mode" "SI")])
6122 (define_insn "*add<mode>_3"
6123 [(set (reg FLAGS_REG)
6125 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
6126 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
6127 (clobber (match_scratch:SWI 0 "=<r>"))]
6128 "ix86_match_ccmode (insn, CCZmode)
6129 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6131 switch (get_attr_type (insn))
6134 if (operands[2] == const1_rtx)
6135 return "inc{<imodesuffix>}\t%0";
6138 gcc_assert (operands[2] == constm1_rtx);
6139 return "dec{<imodesuffix>}\t%0";
6143 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6144 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6146 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6150 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6151 (const_string "incdec")
6152 (const_string "alu")))
6153 (set (attr "length_immediate")
6155 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6157 (const_string "*")))
6158 (set_attr "mode" "<MODE>")])
6160 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6161 (define_insn "*addsi_3_zext"
6162 [(set (reg FLAGS_REG)
6164 (neg:SI (match_operand:SI 2 "general_operand" "g"))
6165 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6166 (set (match_operand:DI 0 "register_operand" "=r")
6167 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6168 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6169 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6171 switch (get_attr_type (insn))
6174 if (operands[2] == const1_rtx)
6175 return "inc{l}\t%k0";
6178 gcc_assert (operands[2] == constm1_rtx);
6179 return "dec{l}\t%k0";
6183 if (x86_maybe_negate_const_int (&operands[2], SImode))
6184 return "sub{l}\t{%2, %k0|%k0, %2}";
6186 return "add{l}\t{%2, %k0|%k0, %2}";
6190 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6191 (const_string "incdec")
6192 (const_string "alu")))
6193 (set (attr "length_immediate")
6195 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6197 (const_string "*")))
6198 (set_attr "mode" "SI")])
6200 ; For comparisons against 1, -1 and 128, we may generate better code
6201 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6202 ; is matched then. We can't accept general immediate, because for
6203 ; case of overflows, the result is messed up.
6204 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6205 ; only for comparisons not depending on it.
6207 (define_insn "*adddi_4"
6208 [(set (reg FLAGS_REG)
6210 (match_operand:DI 1 "nonimmediate_operand" "0")
6211 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6212 (clobber (match_scratch:DI 0 "=rm"))]
6214 && ix86_match_ccmode (insn, CCGCmode)"
6216 switch (get_attr_type (insn))
6219 if (operands[2] == constm1_rtx)
6220 return "inc{q}\t%0";
6223 gcc_assert (operands[2] == const1_rtx);
6224 return "dec{q}\t%0";
6228 if (x86_maybe_negate_const_int (&operands[2], DImode))
6229 return "add{q}\t{%2, %0|%0, %2}";
6231 return "sub{q}\t{%2, %0|%0, %2}";
6235 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6236 (const_string "incdec")
6237 (const_string "alu")))
6238 (set (attr "length_immediate")
6240 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6242 (const_string "*")))
6243 (set_attr "mode" "DI")])
6245 ; For comparisons against 1, -1 and 128, we may generate better code
6246 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6247 ; is matched then. We can't accept general immediate, because for
6248 ; case of overflows, the result is messed up.
6249 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6250 ; only for comparisons not depending on it.
6252 (define_insn "*add<mode>_4"
6253 [(set (reg FLAGS_REG)
6255 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6256 (match_operand:SWI124 2 "const_int_operand" "n")))
6257 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6258 "ix86_match_ccmode (insn, CCGCmode)"
6260 switch (get_attr_type (insn))
6263 if (operands[2] == constm1_rtx)
6264 return "inc{<imodesuffix>}\t%0";
6267 gcc_assert (operands[2] == const1_rtx);
6268 return "dec{<imodesuffix>}\t%0";
6272 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6273 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6275 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6279 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6280 (const_string "incdec")
6281 (const_string "alu")))
6282 (set (attr "length_immediate")
6284 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6286 (const_string "*")))
6287 (set_attr "mode" "<MODE>")])
6289 (define_insn "*add<mode>_5"
6290 [(set (reg FLAGS_REG)
6293 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6294 (match_operand:SWI 2 "<general_operand>" "<g>"))
6296 (clobber (match_scratch:SWI 0 "=<r>"))]
6297 "ix86_match_ccmode (insn, CCGOCmode)
6298 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6300 switch (get_attr_type (insn))
6303 if (operands[2] == const1_rtx)
6304 return "inc{<imodesuffix>}\t%0";
6307 gcc_assert (operands[2] == constm1_rtx);
6308 return "dec{<imodesuffix>}\t%0";
6312 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6313 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6315 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6319 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6320 (const_string "incdec")
6321 (const_string "alu")))
6322 (set (attr "length_immediate")
6324 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6326 (const_string "*")))
6327 (set_attr "mode" "<MODE>")])
6329 (define_insn "*addqi_ext_1_rex64"
6330 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6335 (match_operand 1 "ext_register_operand" "0")
6338 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6339 (clobber (reg:CC FLAGS_REG))]
6342 switch (get_attr_type (insn))
6345 if (operands[2] == const1_rtx)
6346 return "inc{b}\t%h0";
6349 gcc_assert (operands[2] == constm1_rtx);
6350 return "dec{b}\t%h0";
6354 return "add{b}\t{%2, %h0|%h0, %2}";
6358 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6359 (const_string "incdec")
6360 (const_string "alu")))
6361 (set_attr "modrm" "1")
6362 (set_attr "mode" "QI")])
6364 (define_insn "addqi_ext_1"
6365 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6370 (match_operand 1 "ext_register_operand" "0")
6373 (match_operand:QI 2 "general_operand" "Qmn")))
6374 (clobber (reg:CC FLAGS_REG))]
6377 switch (get_attr_type (insn))
6380 if (operands[2] == const1_rtx)
6381 return "inc{b}\t%h0";
6384 gcc_assert (operands[2] == constm1_rtx);
6385 return "dec{b}\t%h0";
6389 return "add{b}\t{%2, %h0|%h0, %2}";
6393 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6394 (const_string "incdec")
6395 (const_string "alu")))
6396 (set_attr "modrm" "1")
6397 (set_attr "mode" "QI")])
6399 (define_insn "*addqi_ext_2"
6400 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6405 (match_operand 1 "ext_register_operand" "%0")
6409 (match_operand 2 "ext_register_operand" "Q")
6412 (clobber (reg:CC FLAGS_REG))]
6414 "add{b}\t{%h2, %h0|%h0, %h2}"
6415 [(set_attr "type" "alu")
6416 (set_attr "mode" "QI")])
6418 ;; The lea patterns for non-Pmodes needs to be matched by
6419 ;; several insns converted to real lea by splitters.
6421 (define_insn_and_split "*lea_general_1"
6422 [(set (match_operand 0 "register_operand" "=r")
6423 (plus (plus (match_operand 1 "index_register_operand" "l")
6424 (match_operand 2 "register_operand" "r"))
6425 (match_operand 3 "immediate_operand" "i")))]
6426 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6427 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6428 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6429 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6430 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6431 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6432 || GET_MODE (operands[3]) == VOIDmode)"
6434 "&& reload_completed"
6438 operands[0] = gen_lowpart (SImode, operands[0]);
6439 operands[1] = gen_lowpart (Pmode, operands[1]);
6440 operands[2] = gen_lowpart (Pmode, operands[2]);
6441 operands[3] = gen_lowpart (Pmode, operands[3]);
6442 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6444 if (Pmode != SImode)
6445 pat = gen_rtx_SUBREG (SImode, pat, 0);
6446 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6449 [(set_attr "type" "lea")
6450 (set_attr "mode" "SI")])
6452 (define_insn_and_split "*lea_general_1_zext"
6453 [(set (match_operand:DI 0 "register_operand" "=r")
6456 (match_operand:SI 1 "index_register_operand" "l")
6457 (match_operand:SI 2 "register_operand" "r"))
6458 (match_operand:SI 3 "immediate_operand" "i"))))]
6461 "&& reload_completed"
6463 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6465 (match_dup 3)) 0)))]
6467 operands[1] = gen_lowpart (Pmode, operands[1]);
6468 operands[2] = gen_lowpart (Pmode, operands[2]);
6469 operands[3] = gen_lowpart (Pmode, operands[3]);
6471 [(set_attr "type" "lea")
6472 (set_attr "mode" "SI")])
6474 (define_insn_and_split "*lea_general_2"
6475 [(set (match_operand 0 "register_operand" "=r")
6476 (plus (mult (match_operand 1 "index_register_operand" "l")
6477 (match_operand 2 "const248_operand" "i"))
6478 (match_operand 3 "nonmemory_operand" "ri")))]
6479 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6480 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6481 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6482 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6483 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6484 || GET_MODE (operands[3]) == VOIDmode)"
6486 "&& reload_completed"
6490 operands[0] = gen_lowpart (SImode, operands[0]);
6491 operands[1] = gen_lowpart (Pmode, operands[1]);
6492 operands[3] = gen_lowpart (Pmode, operands[3]);
6493 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6495 if (Pmode != SImode)
6496 pat = gen_rtx_SUBREG (SImode, pat, 0);
6497 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6500 [(set_attr "type" "lea")
6501 (set_attr "mode" "SI")])
6503 (define_insn_and_split "*lea_general_2_zext"
6504 [(set (match_operand:DI 0 "register_operand" "=r")
6507 (match_operand:SI 1 "index_register_operand" "l")
6508 (match_operand:SI 2 "const248_operand" "n"))
6509 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6512 "&& reload_completed"
6514 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6516 (match_dup 3)) 0)))]
6518 operands[1] = gen_lowpart (Pmode, operands[1]);
6519 operands[3] = gen_lowpart (Pmode, operands[3]);
6521 [(set_attr "type" "lea")
6522 (set_attr "mode" "SI")])
6524 (define_insn_and_split "*lea_general_3"
6525 [(set (match_operand 0 "register_operand" "=r")
6526 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6527 (match_operand 2 "const248_operand" "i"))
6528 (match_operand 3 "register_operand" "r"))
6529 (match_operand 4 "immediate_operand" "i")))]
6530 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6531 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6532 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6533 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6534 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6536 "&& reload_completed"
6540 operands[0] = gen_lowpart (SImode, operands[0]);
6541 operands[1] = gen_lowpart (Pmode, operands[1]);
6542 operands[3] = gen_lowpart (Pmode, operands[3]);
6543 operands[4] = gen_lowpart (Pmode, operands[4]);
6544 pat = gen_rtx_PLUS (Pmode,
6545 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6549 if (Pmode != SImode)
6550 pat = gen_rtx_SUBREG (SImode, pat, 0);
6551 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6554 [(set_attr "type" "lea")
6555 (set_attr "mode" "SI")])
6557 (define_insn_and_split "*lea_general_3_zext"
6558 [(set (match_operand:DI 0 "register_operand" "=r")
6562 (match_operand:SI 1 "index_register_operand" "l")
6563 (match_operand:SI 2 "const248_operand" "n"))
6564 (match_operand:SI 3 "register_operand" "r"))
6565 (match_operand:SI 4 "immediate_operand" "i"))))]
6568 "&& reload_completed"
6570 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6573 (match_dup 4)) 0)))]
6575 operands[1] = gen_lowpart (Pmode, operands[1]);
6576 operands[3] = gen_lowpart (Pmode, operands[3]);
6577 operands[4] = gen_lowpart (Pmode, operands[4]);
6579 [(set_attr "type" "lea")
6580 (set_attr "mode" "SI")])
6582 ;; Subtract instructions
6584 (define_expand "sub<mode>3"
6585 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6586 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6587 (match_operand:SDWIM 2 "<general_operand>" "")))]
6589 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6591 (define_insn_and_split "*sub<dwi>3_doubleword"
6592 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6594 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6595 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6596 (clobber (reg:CC FLAGS_REG))]
6597 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6600 [(parallel [(set (reg:CC FLAGS_REG)
6601 (compare:CC (match_dup 1) (match_dup 2)))
6603 (minus:DWIH (match_dup 1) (match_dup 2)))])
6604 (parallel [(set (match_dup 3)
6608 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6610 (clobber (reg:CC FLAGS_REG))])]
6611 "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
6613 (define_insn "*sub<mode>_1"
6614 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6616 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6617 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6618 (clobber (reg:CC FLAGS_REG))]
6619 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6620 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6621 [(set_attr "type" "alu")
6622 (set_attr "mode" "<MODE>")])
6624 (define_insn "*subsi_1_zext"
6625 [(set (match_operand:DI 0 "register_operand" "=r")
6627 (minus:SI (match_operand:SI 1 "register_operand" "0")
6628 (match_operand:SI 2 "general_operand" "g"))))
6629 (clobber (reg:CC FLAGS_REG))]
6630 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6631 "sub{l}\t{%2, %k0|%k0, %2}"
6632 [(set_attr "type" "alu")
6633 (set_attr "mode" "SI")])
6635 (define_insn "*subqi_1_slp"
6636 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6637 (minus:QI (match_dup 0)
6638 (match_operand:QI 1 "general_operand" "qn,qm")))
6639 (clobber (reg:CC FLAGS_REG))]
6640 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6641 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6642 "sub{b}\t{%1, %0|%0, %1}"
6643 [(set_attr "type" "alu1")
6644 (set_attr "mode" "QI")])
6646 (define_insn "*sub<mode>_2"
6647 [(set (reg FLAGS_REG)
6650 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6651 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6653 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6654 (minus:SWI (match_dup 1) (match_dup 2)))]
6655 "ix86_match_ccmode (insn, CCGOCmode)
6656 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6657 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6658 [(set_attr "type" "alu")
6659 (set_attr "mode" "<MODE>")])
6661 (define_insn "*subsi_2_zext"
6662 [(set (reg FLAGS_REG)
6664 (minus:SI (match_operand:SI 1 "register_operand" "0")
6665 (match_operand:SI 2 "general_operand" "g"))
6667 (set (match_operand:DI 0 "register_operand" "=r")
6669 (minus:SI (match_dup 1)
6671 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6672 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6673 "sub{l}\t{%2, %k0|%k0, %2}"
6674 [(set_attr "type" "alu")
6675 (set_attr "mode" "SI")])
6677 (define_insn "*sub<mode>_3"
6678 [(set (reg FLAGS_REG)
6679 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6680 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6681 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6682 (minus:SWI (match_dup 1) (match_dup 2)))]
6683 "ix86_match_ccmode (insn, CCmode)
6684 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6685 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6686 [(set_attr "type" "alu")
6687 (set_attr "mode" "<MODE>")])
6689 (define_insn "*subsi_3_zext"
6690 [(set (reg FLAGS_REG)
6691 (compare (match_operand:SI 1 "register_operand" "0")
6692 (match_operand:SI 2 "general_operand" "g")))
6693 (set (match_operand:DI 0 "register_operand" "=r")
6695 (minus:SI (match_dup 1)
6697 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6698 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6699 "sub{l}\t{%2, %1|%1, %2}"
6700 [(set_attr "type" "alu")
6701 (set_attr "mode" "SI")])
6703 ;; Add with carry and subtract with borrow
6705 (define_expand "<plusminus_insn><mode>3_carry"
6707 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6709 (match_operand:SWI 1 "nonimmediate_operand" "")
6710 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6711 [(match_operand 3 "flags_reg_operand" "")
6713 (match_operand:SWI 2 "<general_operand>" ""))))
6714 (clobber (reg:CC FLAGS_REG))])]
6715 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6718 (define_insn "*<plusminus_insn><mode>3_carry"
6719 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6721 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6723 (match_operator 3 "ix86_carry_flag_operator"
6724 [(reg FLAGS_REG) (const_int 0)])
6725 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6726 (clobber (reg:CC FLAGS_REG))]
6727 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6728 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6729 [(set_attr "type" "alu")
6730 (set_attr "use_carry" "1")
6731 (set_attr "pent_pair" "pu")
6732 (set_attr "mode" "<MODE>")])
6734 (define_insn "*addsi3_carry_zext"
6735 [(set (match_operand:DI 0 "register_operand" "=r")
6737 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6738 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6739 [(reg FLAGS_REG) (const_int 0)])
6740 (match_operand:SI 2 "general_operand" "g")))))
6741 (clobber (reg:CC FLAGS_REG))]
6742 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6743 "adc{l}\t{%2, %k0|%k0, %2}"
6744 [(set_attr "type" "alu")
6745 (set_attr "use_carry" "1")
6746 (set_attr "pent_pair" "pu")
6747 (set_attr "mode" "SI")])
6749 (define_insn "*subsi3_carry_zext"
6750 [(set (match_operand:DI 0 "register_operand" "=r")
6752 (minus:SI (match_operand:SI 1 "register_operand" "0")
6753 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6754 [(reg FLAGS_REG) (const_int 0)])
6755 (match_operand:SI 2 "general_operand" "g")))))
6756 (clobber (reg:CC FLAGS_REG))]
6757 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6758 "sbb{l}\t{%2, %k0|%k0, %2}"
6759 [(set_attr "type" "alu")
6760 (set_attr "pent_pair" "pu")
6761 (set_attr "mode" "SI")])
6763 ;; Overflow setting add and subtract instructions
6765 (define_insn "*add<mode>3_cconly_overflow"
6766 [(set (reg:CCC FLAGS_REG)
6769 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6770 (match_operand:SWI 2 "<general_operand>" "<g>"))
6772 (clobber (match_scratch:SWI 0 "=<r>"))]
6773 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6774 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6775 [(set_attr "type" "alu")
6776 (set_attr "mode" "<MODE>")])
6778 (define_insn "*sub<mode>3_cconly_overflow"
6779 [(set (reg:CCC FLAGS_REG)
6782 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6783 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6786 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6787 [(set_attr "type" "icmp")
6788 (set_attr "mode" "<MODE>")])
6790 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6791 [(set (reg:CCC FLAGS_REG)
6794 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6795 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6797 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6798 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6799 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6800 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6801 [(set_attr "type" "alu")
6802 (set_attr "mode" "<MODE>")])
6804 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6805 [(set (reg:CCC FLAGS_REG)
6808 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6809 (match_operand:SI 2 "general_operand" "g"))
6811 (set (match_operand:DI 0 "register_operand" "=r")
6812 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6813 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6814 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6815 [(set_attr "type" "alu")
6816 (set_attr "mode" "SI")])
6818 ;; The patterns that match these are at the end of this file.
6820 (define_expand "<plusminus_insn>xf3"
6821 [(set (match_operand:XF 0 "register_operand" "")
6823 (match_operand:XF 1 "register_operand" "")
6824 (match_operand:XF 2 "register_operand" "")))]
6828 (define_expand "<plusminus_insn><mode>3"
6829 [(set (match_operand:MODEF 0 "register_operand" "")
6831 (match_operand:MODEF 1 "register_operand" "")
6832 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6833 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6834 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
6837 ;; Multiply instructions
6839 (define_expand "mul<mode>3"
6840 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6842 (match_operand:SWIM248 1 "register_operand" "")
6843 (match_operand:SWIM248 2 "<general_operand>" "")))
6844 (clobber (reg:CC FLAGS_REG))])]
6848 (define_expand "mulqi3"
6849 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6851 (match_operand:QI 1 "register_operand" "")
6852 (match_operand:QI 2 "nonimmediate_operand" "")))
6853 (clobber (reg:CC FLAGS_REG))])]
6854 "TARGET_QIMODE_MATH"
6858 ;; IMUL reg32/64, reg32/64, imm8 Direct
6859 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6860 ;; IMUL reg32/64, reg32/64, imm32 Direct
6861 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6862 ;; IMUL reg32/64, reg32/64 Direct
6863 ;; IMUL reg32/64, mem32/64 Direct
6865 (define_insn "*mul<mode>3_1"
6866 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6868 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6869 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6870 (clobber (reg:CC FLAGS_REG))]
6871 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6873 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6874 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6875 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6876 [(set_attr "type" "imul")
6877 (set_attr "prefix_0f" "0,0,1")
6878 (set (attr "athlon_decode")
6879 (cond [(eq_attr "cpu" "athlon")
6880 (const_string "vector")
6881 (eq_attr "alternative" "1")
6882 (const_string "vector")
6883 (and (eq_attr "alternative" "2")
6884 (match_operand 1 "memory_operand" ""))
6885 (const_string "vector")]
6886 (const_string "direct")))
6887 (set (attr "amdfam10_decode")
6888 (cond [(and (eq_attr "alternative" "0,1")
6889 (match_operand 1 "memory_operand" ""))
6890 (const_string "vector")]
6891 (const_string "direct")))
6892 (set_attr "mode" "<MODE>")])
6894 (define_insn "*mulsi3_1_zext"
6895 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6897 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6898 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6899 (clobber (reg:CC FLAGS_REG))]
6901 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6903 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6904 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6905 imul{l}\t{%2, %k0|%k0, %2}"
6906 [(set_attr "type" "imul")
6907 (set_attr "prefix_0f" "0,0,1")
6908 (set (attr "athlon_decode")
6909 (cond [(eq_attr "cpu" "athlon")
6910 (const_string "vector")
6911 (eq_attr "alternative" "1")
6912 (const_string "vector")
6913 (and (eq_attr "alternative" "2")
6914 (match_operand 1 "memory_operand" ""))
6915 (const_string "vector")]
6916 (const_string "direct")))
6917 (set (attr "amdfam10_decode")
6918 (cond [(and (eq_attr "alternative" "0,1")
6919 (match_operand 1 "memory_operand" ""))
6920 (const_string "vector")]
6921 (const_string "direct")))
6922 (set_attr "mode" "SI")])
6925 ;; IMUL reg16, reg16, imm8 VectorPath
6926 ;; IMUL reg16, mem16, imm8 VectorPath
6927 ;; IMUL reg16, reg16, imm16 VectorPath
6928 ;; IMUL reg16, mem16, imm16 VectorPath
6929 ;; IMUL reg16, reg16 Direct
6930 ;; IMUL reg16, mem16 Direct
6932 (define_insn "*mulhi3_1"
6933 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6934 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6935 (match_operand:HI 2 "general_operand" "K,n,mr")))
6936 (clobber (reg:CC FLAGS_REG))]
6938 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6940 imul{w}\t{%2, %1, %0|%0, %1, %2}
6941 imul{w}\t{%2, %1, %0|%0, %1, %2}
6942 imul{w}\t{%2, %0|%0, %2}"
6943 [(set_attr "type" "imul")
6944 (set_attr "prefix_0f" "0,0,1")
6945 (set (attr "athlon_decode")
6946 (cond [(eq_attr "cpu" "athlon")
6947 (const_string "vector")
6948 (eq_attr "alternative" "1,2")
6949 (const_string "vector")]
6950 (const_string "direct")))
6951 (set (attr "amdfam10_decode")
6952 (cond [(eq_attr "alternative" "0,1")
6953 (const_string "vector")]
6954 (const_string "direct")))
6955 (set_attr "mode" "HI")])
6961 (define_insn "*mulqi3_1"
6962 [(set (match_operand:QI 0 "register_operand" "=a")
6963 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6964 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6965 (clobber (reg:CC FLAGS_REG))]
6967 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6969 [(set_attr "type" "imul")
6970 (set_attr "length_immediate" "0")
6971 (set (attr "athlon_decode")
6972 (if_then_else (eq_attr "cpu" "athlon")
6973 (const_string "vector")
6974 (const_string "direct")))
6975 (set_attr "amdfam10_decode" "direct")
6976 (set_attr "mode" "QI")])
6978 (define_expand "<u>mul<mode><dwi>3"
6979 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6982 (match_operand:DWIH 1 "nonimmediate_operand" ""))
6984 (match_operand:DWIH 2 "register_operand" ""))))
6985 (clobber (reg:CC FLAGS_REG))])]
6989 (define_expand "<u>mulqihi3"
6990 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6993 (match_operand:QI 1 "nonimmediate_operand" ""))
6995 (match_operand:QI 2 "register_operand" ""))))
6996 (clobber (reg:CC FLAGS_REG))])]
6997 "TARGET_QIMODE_MATH"
7000 (define_insn "*<u>mul<mode><dwi>3_1"
7001 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7004 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7006 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7007 (clobber (reg:CC FLAGS_REG))]
7008 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7009 "<sgnprefix>mul{<imodesuffix>}\t%2"
7010 [(set_attr "type" "imul")
7011 (set_attr "length_immediate" "0")
7012 (set (attr "athlon_decode")
7013 (if_then_else (eq_attr "cpu" "athlon")
7014 (const_string "vector")
7015 (const_string "double")))
7016 (set_attr "amdfam10_decode" "double")
7017 (set_attr "mode" "<MODE>")])
7019 (define_insn "*<u>mulqihi3_1"
7020 [(set (match_operand:HI 0 "register_operand" "=a")
7023 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7025 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7026 (clobber (reg:CC FLAGS_REG))]
7028 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7029 "<sgnprefix>mul{b}\t%2"
7030 [(set_attr "type" "imul")
7031 (set_attr "length_immediate" "0")
7032 (set (attr "athlon_decode")
7033 (if_then_else (eq_attr "cpu" "athlon")
7034 (const_string "vector")
7035 (const_string "direct")))
7036 (set_attr "amdfam10_decode" "direct")
7037 (set_attr "mode" "QI")])
7039 (define_expand "<s>mul<mode>3_highpart"
7040 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7045 (match_operand:SWI48 1 "nonimmediate_operand" ""))
7047 (match_operand:SWI48 2 "register_operand" "")))
7049 (clobber (match_scratch:SWI48 3 ""))
7050 (clobber (reg:CC FLAGS_REG))])]
7052 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7054 (define_insn "*<s>muldi3_highpart_1"
7055 [(set (match_operand:DI 0 "register_operand" "=d")
7060 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7062 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7064 (clobber (match_scratch:DI 3 "=1"))
7065 (clobber (reg:CC FLAGS_REG))]
7067 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7068 "<sgnprefix>mul{q}\t%2"
7069 [(set_attr "type" "imul")
7070 (set_attr "length_immediate" "0")
7071 (set (attr "athlon_decode")
7072 (if_then_else (eq_attr "cpu" "athlon")
7073 (const_string "vector")
7074 (const_string "double")))
7075 (set_attr "amdfam10_decode" "double")
7076 (set_attr "mode" "DI")])
7078 (define_insn "*<s>mulsi3_highpart_1"
7079 [(set (match_operand:SI 0 "register_operand" "=d")
7084 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7086 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7088 (clobber (match_scratch:SI 3 "=1"))
7089 (clobber (reg:CC FLAGS_REG))]
7090 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7091 "<sgnprefix>mul{l}\t%2"
7092 [(set_attr "type" "imul")
7093 (set_attr "length_immediate" "0")
7094 (set (attr "athlon_decode")
7095 (if_then_else (eq_attr "cpu" "athlon")
7096 (const_string "vector")
7097 (const_string "double")))
7098 (set_attr "amdfam10_decode" "double")
7099 (set_attr "mode" "SI")])
7101 (define_insn "*<s>mulsi3_highpart_zext"
7102 [(set (match_operand:DI 0 "register_operand" "=d")
7103 (zero_extend:DI (truncate:SI
7105 (mult:DI (any_extend:DI
7106 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7108 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7110 (clobber (match_scratch:SI 3 "=1"))
7111 (clobber (reg:CC FLAGS_REG))]
7113 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7114 "<sgnprefix>mul{l}\t%2"
7115 [(set_attr "type" "imul")
7116 (set_attr "length_immediate" "0")
7117 (set (attr "athlon_decode")
7118 (if_then_else (eq_attr "cpu" "athlon")
7119 (const_string "vector")
7120 (const_string "double")))
7121 (set_attr "amdfam10_decode" "double")
7122 (set_attr "mode" "SI")])
7124 ;; The patterns that match these are at the end of this file.
7126 (define_expand "mulxf3"
7127 [(set (match_operand:XF 0 "register_operand" "")
7128 (mult:XF (match_operand:XF 1 "register_operand" "")
7129 (match_operand:XF 2 "register_operand" "")))]
7133 (define_expand "mul<mode>3"
7134 [(set (match_operand:MODEF 0 "register_operand" "")
7135 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7136 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7137 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7138 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7141 ;; Divide instructions
7143 ;; The patterns that match these are at the end of this file.
7145 (define_expand "divxf3"
7146 [(set (match_operand:XF 0 "register_operand" "")
7147 (div:XF (match_operand:XF 1 "register_operand" "")
7148 (match_operand:XF 2 "register_operand" "")))]
7152 (define_expand "divdf3"
7153 [(set (match_operand:DF 0 "register_operand" "")
7154 (div:DF (match_operand:DF 1 "register_operand" "")
7155 (match_operand:DF 2 "nonimmediate_operand" "")))]
7156 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7157 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7160 (define_expand "divsf3"
7161 [(set (match_operand:SF 0 "register_operand" "")
7162 (div:SF (match_operand:SF 1 "register_operand" "")
7163 (match_operand:SF 2 "nonimmediate_operand" "")))]
7164 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7167 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7168 && flag_finite_math_only && !flag_trapping_math
7169 && flag_unsafe_math_optimizations)
7171 ix86_emit_swdivsf (operands[0], operands[1],
7172 operands[2], SFmode);
7177 ;; Divmod instructions.
7179 (define_expand "divmodqi4"
7180 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7182 (match_operand:QI 1 "register_operand" "")
7183 (match_operand:QI 2 "nonimmediate_operand" "")))
7184 (set (match_operand:QI 3 "register_operand" "")
7185 (mod:QI (match_dup 1) (match_dup 2)))
7186 (clobber (reg:CC FLAGS_REG))])]
7187 "TARGET_QIMODE_MATH"
7192 tmp0 = gen_reg_rtx (HImode);
7193 tmp1 = gen_reg_rtx (HImode);
7195 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7197 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7198 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7200 /* Extract remainder from AH. */
7201 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7202 insn = emit_move_insn (operands[3], tmp1);
7204 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7205 set_unique_reg_note (insn, REG_EQUAL, mod);
7207 /* Extract quotient from AL. */
7208 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7210 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7211 set_unique_reg_note (insn, REG_EQUAL, div);
7216 (define_expand "udivmodqi4"
7217 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7219 (match_operand:QI 1 "register_operand" "")
7220 (match_operand:QI 2 "nonimmediate_operand" "")))
7221 (set (match_operand:QI 3 "register_operand" "")
7222 (umod:QI (match_dup 1) (match_dup 2)))
7223 (clobber (reg:CC FLAGS_REG))])]
7224 "TARGET_QIMODE_MATH"
7229 tmp0 = gen_reg_rtx (HImode);
7230 tmp1 = gen_reg_rtx (HImode);
7232 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7234 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7235 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7237 /* Extract remainder from AH. */
7238 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7239 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7240 insn = emit_move_insn (operands[3], tmp1);
7242 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7243 set_unique_reg_note (insn, REG_EQUAL, mod);
7245 /* Extract quotient from AL. */
7246 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7248 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7249 set_unique_reg_note (insn, REG_EQUAL, div);
7254 ;; Divide AX by r/m8, with result stored in
7257 ;; Change div/mod to HImode and extend the second argument to HImode
7258 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7259 ;; combine may fail.
7260 (define_insn "divmodhiqi3"
7261 [(set (match_operand:HI 0 "register_operand" "=a")
7266 (mod:HI (match_operand:HI 1 "register_operand" "0")
7268 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7272 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7273 (clobber (reg:CC FLAGS_REG))]
7274 "TARGET_QIMODE_MATH"
7276 [(set_attr "type" "idiv")
7277 (set_attr "mode" "QI")])
7279 (define_insn "udivmodhiqi3"
7280 [(set (match_operand:HI 0 "register_operand" "=a")
7285 (mod:HI (match_operand:HI 1 "register_operand" "0")
7287 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7291 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7292 (clobber (reg:CC FLAGS_REG))]
7293 "TARGET_QIMODE_MATH"
7295 [(set_attr "type" "idiv")
7296 (set_attr "mode" "QI")])
7298 (define_expand "divmod<mode>4"
7299 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7301 (match_operand:SWIM248 1 "register_operand" "")
7302 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7303 (set (match_operand:SWIM248 3 "register_operand" "")
7304 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7305 (clobber (reg:CC FLAGS_REG))])]
7309 (define_insn_and_split "*divmod<mode>4"
7310 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7311 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7312 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7313 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7314 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7315 (clobber (reg:CC FLAGS_REG))]
7319 [(parallel [(set (match_dup 1)
7320 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7321 (clobber (reg:CC FLAGS_REG))])
7322 (parallel [(set (match_dup 0)
7323 (div:SWIM248 (match_dup 2) (match_dup 3)))
7325 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7327 (clobber (reg:CC FLAGS_REG))])]
7329 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7331 if (<MODE>mode != HImode
7332 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7333 operands[4] = operands[2];
7336 /* Avoid use of cltd in favor of a mov+shift. */
7337 emit_move_insn (operands[1], operands[2]);
7338 operands[4] = operands[1];
7341 [(set_attr "type" "multi")
7342 (set_attr "mode" "<MODE>")])
7344 (define_insn "*divmod<mode>4_noext"
7345 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7346 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7347 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7348 (set (match_operand:SWIM248 1 "register_operand" "=d")
7349 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7350 (use (match_operand:SWIM248 4 "register_operand" "1"))
7351 (clobber (reg:CC FLAGS_REG))]
7353 "idiv{<imodesuffix>}\t%3"
7354 [(set_attr "type" "idiv")
7355 (set_attr "mode" "<MODE>")])
7357 (define_expand "udivmod<mode>4"
7358 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7360 (match_operand:SWIM248 1 "register_operand" "")
7361 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7362 (set (match_operand:SWIM248 3 "register_operand" "")
7363 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7364 (clobber (reg:CC FLAGS_REG))])]
7368 (define_insn_and_split "*udivmod<mode>4"
7369 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7370 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7371 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7372 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7373 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7374 (clobber (reg:CC FLAGS_REG))]
7378 [(set (match_dup 1) (const_int 0))
7379 (parallel [(set (match_dup 0)
7380 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7382 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7384 (clobber (reg:CC FLAGS_REG))])]
7386 [(set_attr "type" "multi")
7387 (set_attr "mode" "<MODE>")])
7389 (define_insn "*udivmod<mode>4_noext"
7390 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7391 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7392 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7393 (set (match_operand:SWIM248 1 "register_operand" "=d")
7394 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7395 (use (match_operand:SWIM248 4 "register_operand" "1"))
7396 (clobber (reg:CC FLAGS_REG))]
7398 "div{<imodesuffix>}\t%3"
7399 [(set_attr "type" "idiv")
7400 (set_attr "mode" "<MODE>")])
7402 ;; We cannot use div/idiv for double division, because it causes
7403 ;; "division by zero" on the overflow and that's not what we expect
7404 ;; from truncate. Because true (non truncating) double division is
7405 ;; never generated, we can't create this insn anyway.
7408 ; [(set (match_operand:SI 0 "register_operand" "=a")
7410 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7412 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7413 ; (set (match_operand:SI 3 "register_operand" "=d")
7415 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7416 ; (clobber (reg:CC FLAGS_REG))]
7418 ; "div{l}\t{%2, %0|%0, %2}"
7419 ; [(set_attr "type" "idiv")])
7421 ;;- Logical AND instructions
7423 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7424 ;; Note that this excludes ah.
7426 (define_expand "testsi_ccno_1"
7427 [(set (reg:CCNO FLAGS_REG)
7429 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7430 (match_operand:SI 1 "nonmemory_operand" ""))
7435 (define_expand "testqi_ccz_1"
7436 [(set (reg:CCZ FLAGS_REG)
7437 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7438 (match_operand:QI 1 "nonmemory_operand" ""))
7443 (define_insn "*testdi_1"
7444 [(set (reg FLAGS_REG)
7447 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7448 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7450 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7451 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7453 test{l}\t{%k1, %k0|%k0, %k1}
7454 test{l}\t{%k1, %k0|%k0, %k1}
7455 test{q}\t{%1, %0|%0, %1}
7456 test{q}\t{%1, %0|%0, %1}
7457 test{q}\t{%1, %0|%0, %1}"
7458 [(set_attr "type" "test")
7459 (set_attr "modrm" "0,1,0,1,1")
7460 (set_attr "mode" "SI,SI,DI,DI,DI")])
7462 (define_insn "*testqi_1_maybe_si"
7463 [(set (reg FLAGS_REG)
7466 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7467 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7469 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7470 && ix86_match_ccmode (insn,
7471 CONST_INT_P (operands[1])
7472 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7474 if (which_alternative == 3)
7476 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7477 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7478 return "test{l}\t{%1, %k0|%k0, %1}";
7480 return "test{b}\t{%1, %0|%0, %1}";
7482 [(set_attr "type" "test")
7483 (set_attr "modrm" "0,1,1,1")
7484 (set_attr "mode" "QI,QI,QI,SI")
7485 (set_attr "pent_pair" "uv,np,uv,np")])
7487 (define_insn "*test<mode>_1"
7488 [(set (reg FLAGS_REG)
7491 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7492 (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7494 "ix86_match_ccmode (insn, CCNOmode)
7495 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7496 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7497 [(set_attr "type" "test")
7498 (set_attr "modrm" "0,1,1")
7499 (set_attr "mode" "<MODE>")
7500 (set_attr "pent_pair" "uv,np,uv")])
7502 (define_expand "testqi_ext_ccno_0"
7503 [(set (reg:CCNO FLAGS_REG)
7507 (match_operand 0 "ext_register_operand" "")
7510 (match_operand 1 "const_int_operand" ""))
7515 (define_insn "*testqi_ext_0"
7516 [(set (reg FLAGS_REG)
7520 (match_operand 0 "ext_register_operand" "Q")
7523 (match_operand 1 "const_int_operand" "n"))
7525 "ix86_match_ccmode (insn, CCNOmode)"
7526 "test{b}\t{%1, %h0|%h0, %1}"
7527 [(set_attr "type" "test")
7528 (set_attr "mode" "QI")
7529 (set_attr "length_immediate" "1")
7530 (set_attr "modrm" "1")
7531 (set_attr "pent_pair" "np")])
7533 (define_insn "*testqi_ext_1_rex64"
7534 [(set (reg FLAGS_REG)
7538 (match_operand 0 "ext_register_operand" "Q")
7542 (match_operand:QI 1 "register_operand" "Q")))
7544 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7545 "test{b}\t{%1, %h0|%h0, %1}"
7546 [(set_attr "type" "test")
7547 (set_attr "mode" "QI")])
7549 (define_insn "*testqi_ext_1"
7550 [(set (reg FLAGS_REG)
7554 (match_operand 0 "ext_register_operand" "Q")
7558 (match_operand:QI 1 "general_operand" "Qm")))
7560 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7561 "test{b}\t{%1, %h0|%h0, %1}"
7562 [(set_attr "type" "test")
7563 (set_attr "mode" "QI")])
7565 (define_insn "*testqi_ext_2"
7566 [(set (reg FLAGS_REG)
7570 (match_operand 0 "ext_register_operand" "Q")
7574 (match_operand 1 "ext_register_operand" "Q")
7578 "ix86_match_ccmode (insn, CCNOmode)"
7579 "test{b}\t{%h1, %h0|%h0, %h1}"
7580 [(set_attr "type" "test")
7581 (set_attr "mode" "QI")])
7583 (define_insn "*testqi_ext_3_rex64"
7584 [(set (reg FLAGS_REG)
7585 (compare (zero_extract:DI
7586 (match_operand 0 "nonimmediate_operand" "rm")
7587 (match_operand:DI 1 "const_int_operand" "")
7588 (match_operand:DI 2 "const_int_operand" ""))
7591 && ix86_match_ccmode (insn, CCNOmode)
7592 && INTVAL (operands[1]) > 0
7593 && INTVAL (operands[2]) >= 0
7594 /* Ensure that resulting mask is zero or sign extended operand. */
7595 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7596 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7597 && INTVAL (operands[1]) > 32))
7598 && (GET_MODE (operands[0]) == SImode
7599 || GET_MODE (operands[0]) == DImode
7600 || GET_MODE (operands[0]) == HImode
7601 || GET_MODE (operands[0]) == QImode)"
7604 ;; Combine likes to form bit extractions for some tests. Humor it.
7605 (define_insn "*testqi_ext_3"
7606 [(set (reg FLAGS_REG)
7607 (compare (zero_extract:SI
7608 (match_operand 0 "nonimmediate_operand" "rm")
7609 (match_operand:SI 1 "const_int_operand" "")
7610 (match_operand:SI 2 "const_int_operand" ""))
7612 "ix86_match_ccmode (insn, CCNOmode)
7613 && INTVAL (operands[1]) > 0
7614 && INTVAL (operands[2]) >= 0
7615 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7616 && (GET_MODE (operands[0]) == SImode
7617 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7618 || GET_MODE (operands[0]) == HImode
7619 || GET_MODE (operands[0]) == QImode)"
7623 [(set (match_operand 0 "flags_reg_operand" "")
7624 (match_operator 1 "compare_operator"
7626 (match_operand 2 "nonimmediate_operand" "")
7627 (match_operand 3 "const_int_operand" "")
7628 (match_operand 4 "const_int_operand" ""))
7630 "ix86_match_ccmode (insn, CCNOmode)"
7631 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7633 rtx val = operands[2];
7634 HOST_WIDE_INT len = INTVAL (operands[3]);
7635 HOST_WIDE_INT pos = INTVAL (operands[4]);
7637 enum machine_mode mode, submode;
7639 mode = GET_MODE (val);
7642 /* ??? Combine likes to put non-volatile mem extractions in QImode
7643 no matter the size of the test. So find a mode that works. */
7644 if (! MEM_VOLATILE_P (val))
7646 mode = smallest_mode_for_size (pos + len, MODE_INT);
7647 val = adjust_address (val, mode, 0);
7650 else if (GET_CODE (val) == SUBREG
7651 && (submode = GET_MODE (SUBREG_REG (val)),
7652 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7653 && pos + len <= GET_MODE_BITSIZE (submode)
7654 && GET_MODE_CLASS (submode) == MODE_INT)
7656 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7658 val = SUBREG_REG (val);
7660 else if (mode == HImode && pos + len <= 8)
7662 /* Small HImode tests can be converted to QImode. */
7664 val = gen_lowpart (QImode, val);
7667 if (len == HOST_BITS_PER_WIDE_INT)
7670 mask = ((HOST_WIDE_INT)1 << len) - 1;
7673 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7676 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7677 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7678 ;; this is relatively important trick.
7679 ;; Do the conversion only post-reload to avoid limiting of the register class
7682 [(set (match_operand 0 "flags_reg_operand" "")
7683 (match_operator 1 "compare_operator"
7684 [(and (match_operand 2 "register_operand" "")
7685 (match_operand 3 "const_int_operand" ""))
7688 && QI_REG_P (operands[2])
7689 && GET_MODE (operands[2]) != QImode
7690 && ((ix86_match_ccmode (insn, CCZmode)
7691 && !(INTVAL (operands[3]) & ~(255 << 8)))
7692 || (ix86_match_ccmode (insn, CCNOmode)
7693 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7696 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7699 "operands[2] = gen_lowpart (SImode, operands[2]);
7700 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7703 [(set (match_operand 0 "flags_reg_operand" "")
7704 (match_operator 1 "compare_operator"
7705 [(and (match_operand 2 "nonimmediate_operand" "")
7706 (match_operand 3 "const_int_operand" ""))
7709 && GET_MODE (operands[2]) != QImode
7710 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7711 && ((ix86_match_ccmode (insn, CCZmode)
7712 && !(INTVAL (operands[3]) & ~255))
7713 || (ix86_match_ccmode (insn, CCNOmode)
7714 && !(INTVAL (operands[3]) & ~127)))"
7716 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7718 "operands[2] = gen_lowpart (QImode, operands[2]);
7719 operands[3] = gen_lowpart (QImode, operands[3]);")
7721 ;; %%% This used to optimize known byte-wide and operations to memory,
7722 ;; and sometimes to QImode registers. If this is considered useful,
7723 ;; it should be done with splitters.
7725 (define_expand "and<mode>3"
7726 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7727 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7728 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7730 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7732 (define_insn "*anddi_1"
7733 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7735 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7736 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7737 (clobber (reg:CC FLAGS_REG))]
7738 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7740 switch (get_attr_type (insn))
7744 enum machine_mode mode;
7746 gcc_assert (CONST_INT_P (operands[2]));
7747 if (INTVAL (operands[2]) == 0xff)
7751 gcc_assert (INTVAL (operands[2]) == 0xffff);
7755 operands[1] = gen_lowpart (mode, operands[1]);
7757 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7759 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7763 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7764 if (get_attr_mode (insn) == MODE_SI)
7765 return "and{l}\t{%k2, %k0|%k0, %k2}";
7767 return "and{q}\t{%2, %0|%0, %2}";
7770 [(set_attr "type" "alu,alu,alu,imovx")
7771 (set_attr "length_immediate" "*,*,*,0")
7772 (set (attr "prefix_rex")
7774 (and (eq_attr "type" "imovx")
7775 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7776 (match_operand 1 "ext_QIreg_nomode_operand" "")))
7778 (const_string "*")))
7779 (set_attr "mode" "SI,DI,DI,SI")])
7781 (define_insn "*andsi_1"
7782 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7783 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7784 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7785 (clobber (reg:CC FLAGS_REG))]
7786 "ix86_binary_operator_ok (AND, SImode, operands)"
7788 switch (get_attr_type (insn))
7792 enum machine_mode mode;
7794 gcc_assert (CONST_INT_P (operands[2]));
7795 if (INTVAL (operands[2]) == 0xff)
7799 gcc_assert (INTVAL (operands[2]) == 0xffff);
7803 operands[1] = gen_lowpart (mode, operands[1]);
7805 return "movz{bl|x}\t{%1, %0|%0, %1}";
7807 return "movz{wl|x}\t{%1, %0|%0, %1}";
7811 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7812 return "and{l}\t{%2, %0|%0, %2}";
7815 [(set_attr "type" "alu,alu,imovx")
7816 (set (attr "prefix_rex")
7818 (and (eq_attr "type" "imovx")
7819 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7820 (match_operand 1 "ext_QIreg_nomode_operand" "")))
7822 (const_string "*")))
7823 (set_attr "length_immediate" "*,*,0")
7824 (set_attr "mode" "SI")])
7826 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7827 (define_insn "*andsi_1_zext"
7828 [(set (match_operand:DI 0 "register_operand" "=r")
7830 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7831 (match_operand:SI 2 "general_operand" "g"))))
7832 (clobber (reg:CC FLAGS_REG))]
7833 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7834 "and{l}\t{%2, %k0|%k0, %2}"
7835 [(set_attr "type" "alu")
7836 (set_attr "mode" "SI")])
7838 (define_insn "*andhi_1"
7839 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7840 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7841 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7842 (clobber (reg:CC FLAGS_REG))]
7843 "ix86_binary_operator_ok (AND, HImode, operands)"
7845 switch (get_attr_type (insn))
7848 gcc_assert (CONST_INT_P (operands[2]));
7849 gcc_assert (INTVAL (operands[2]) == 0xff);
7850 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7853 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7855 return "and{w}\t{%2, %0|%0, %2}";
7858 [(set_attr "type" "alu,alu,imovx")
7859 (set_attr "length_immediate" "*,*,0")
7860 (set (attr "prefix_rex")
7862 (and (eq_attr "type" "imovx")
7863 (match_operand 1 "ext_QIreg_nomode_operand" ""))
7865 (const_string "*")))
7866 (set_attr "mode" "HI,HI,SI")])
7868 ;; %%% Potential partial reg stall on alternative 2. What to do?
7869 (define_insn "*andqi_1"
7870 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7871 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7872 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7873 (clobber (reg:CC FLAGS_REG))]
7874 "ix86_binary_operator_ok (AND, QImode, operands)"
7876 and{b}\t{%2, %0|%0, %2}
7877 and{b}\t{%2, %0|%0, %2}
7878 and{l}\t{%k2, %k0|%k0, %k2}"
7879 [(set_attr "type" "alu")
7880 (set_attr "mode" "QI,QI,SI")])
7882 (define_insn "*andqi_1_slp"
7883 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7884 (and:QI (match_dup 0)
7885 (match_operand:QI 1 "general_operand" "qn,qmn")))
7886 (clobber (reg:CC FLAGS_REG))]
7887 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7888 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7889 "and{b}\t{%1, %0|%0, %1}"
7890 [(set_attr "type" "alu1")
7891 (set_attr "mode" "QI")])
7894 [(set (match_operand 0 "register_operand" "")
7896 (const_int -65536)))
7897 (clobber (reg:CC FLAGS_REG))]
7898 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7899 || optimize_function_for_size_p (cfun)"
7900 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7901 "operands[1] = gen_lowpart (HImode, operands[0]);")
7904 [(set (match_operand 0 "ext_register_operand" "")
7907 (clobber (reg:CC FLAGS_REG))]
7908 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7909 && reload_completed"
7910 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7911 "operands[1] = gen_lowpart (QImode, operands[0]);")
7914 [(set (match_operand 0 "ext_register_operand" "")
7916 (const_int -65281)))
7917 (clobber (reg:CC FLAGS_REG))]
7918 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7919 && reload_completed"
7920 [(parallel [(set (zero_extract:SI (match_dup 0)
7924 (zero_extract:SI (match_dup 0)
7927 (zero_extract:SI (match_dup 0)
7930 (clobber (reg:CC FLAGS_REG))])]
7931 "operands[0] = gen_lowpart (SImode, operands[0]);")
7933 (define_insn "*anddi_2"
7934 [(set (reg FLAGS_REG)
7937 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7938 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7940 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7941 (and:DI (match_dup 1) (match_dup 2)))]
7942 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7943 && ix86_binary_operator_ok (AND, DImode, operands)"
7945 and{l}\t{%k2, %k0|%k0, %k2}
7946 and{q}\t{%2, %0|%0, %2}
7947 and{q}\t{%2, %0|%0, %2}"
7948 [(set_attr "type" "alu")
7949 (set_attr "mode" "SI,DI,DI")])
7951 (define_insn "*andqi_2_maybe_si"
7952 [(set (reg FLAGS_REG)
7954 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7955 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7957 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7958 (and:QI (match_dup 1) (match_dup 2)))]
7959 "ix86_binary_operator_ok (AND, QImode, operands)
7960 && ix86_match_ccmode (insn,
7961 CONST_INT_P (operands[2])
7962 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7964 if (which_alternative == 2)
7966 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7967 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7968 return "and{l}\t{%2, %k0|%k0, %2}";
7970 return "and{b}\t{%2, %0|%0, %2}";
7972 [(set_attr "type" "alu")
7973 (set_attr "mode" "QI,QI,SI")])
7975 (define_insn "*and<mode>_2"
7976 [(set (reg FLAGS_REG)
7977 (compare (and:SWI124
7978 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7979 (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
7981 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7982 (and:SWI124 (match_dup 1) (match_dup 2)))]
7983 "ix86_match_ccmode (insn, CCNOmode)
7984 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7985 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7986 [(set_attr "type" "alu")
7987 (set_attr "mode" "<MODE>")])
7989 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7990 (define_insn "*andsi_2_zext"
7991 [(set (reg FLAGS_REG)
7993 (match_operand:SI 1 "nonimmediate_operand" "%0")
7994 (match_operand:SI 2 "general_operand" "g"))
7996 (set (match_operand:DI 0 "register_operand" "=r")
7997 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7998 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7999 && ix86_binary_operator_ok (AND, SImode, operands)"
8000 "and{l}\t{%2, %k0|%k0, %2}"
8001 [(set_attr "type" "alu")
8002 (set_attr "mode" "SI")])
8004 (define_insn "*andqi_2_slp"
8005 [(set (reg FLAGS_REG)
8007 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8008 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8010 (set (strict_low_part (match_dup 0))
8011 (and:QI (match_dup 0) (match_dup 1)))]
8012 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8013 && ix86_match_ccmode (insn, CCNOmode)
8014 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8015 "and{b}\t{%1, %0|%0, %1}"
8016 [(set_attr "type" "alu1")
8017 (set_attr "mode" "QI")])
8019 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8020 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8021 ;; for a QImode operand, which of course failed.
8022 (define_insn "andqi_ext_0"
8023 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8028 (match_operand 1 "ext_register_operand" "0")
8031 (match_operand 2 "const_int_operand" "n")))
8032 (clobber (reg:CC FLAGS_REG))]
8034 "and{b}\t{%2, %h0|%h0, %2}"
8035 [(set_attr "type" "alu")
8036 (set_attr "length_immediate" "1")
8037 (set_attr "modrm" "1")
8038 (set_attr "mode" "QI")])
8040 ;; Generated by peephole translating test to and. This shows up
8041 ;; often in fp comparisons.
8042 (define_insn "*andqi_ext_0_cc"
8043 [(set (reg FLAGS_REG)
8047 (match_operand 1 "ext_register_operand" "0")
8050 (match_operand 2 "const_int_operand" "n"))
8052 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8061 "ix86_match_ccmode (insn, CCNOmode)"
8062 "and{b}\t{%2, %h0|%h0, %2}"
8063 [(set_attr "type" "alu")
8064 (set_attr "length_immediate" "1")
8065 (set_attr "modrm" "1")
8066 (set_attr "mode" "QI")])
8068 (define_insn "*andqi_ext_1_rex64"
8069 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8074 (match_operand 1 "ext_register_operand" "0")
8078 (match_operand 2 "ext_register_operand" "Q"))))
8079 (clobber (reg:CC FLAGS_REG))]
8081 "and{b}\t{%2, %h0|%h0, %2}"
8082 [(set_attr "type" "alu")
8083 (set_attr "length_immediate" "0")
8084 (set_attr "mode" "QI")])
8086 (define_insn "*andqi_ext_1"
8087 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8092 (match_operand 1 "ext_register_operand" "0")
8096 (match_operand:QI 2 "general_operand" "Qm"))))
8097 (clobber (reg:CC FLAGS_REG))]
8099 "and{b}\t{%2, %h0|%h0, %2}"
8100 [(set_attr "type" "alu")
8101 (set_attr "length_immediate" "0")
8102 (set_attr "mode" "QI")])
8104 (define_insn "*andqi_ext_2"
8105 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8110 (match_operand 1 "ext_register_operand" "%0")
8114 (match_operand 2 "ext_register_operand" "Q")
8117 (clobber (reg:CC FLAGS_REG))]
8119 "and{b}\t{%h2, %h0|%h0, %h2}"
8120 [(set_attr "type" "alu")
8121 (set_attr "length_immediate" "0")
8122 (set_attr "mode" "QI")])
8124 ;; Convert wide AND instructions with immediate operand to shorter QImode
8125 ;; equivalents when possible.
8126 ;; Don't do the splitting with memory operands, since it introduces risk
8127 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8128 ;; for size, but that can (should?) be handled by generic code instead.
8130 [(set (match_operand 0 "register_operand" "")
8131 (and (match_operand 1 "register_operand" "")
8132 (match_operand 2 "const_int_operand" "")))
8133 (clobber (reg:CC FLAGS_REG))]
8135 && QI_REG_P (operands[0])
8136 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8137 && !(~INTVAL (operands[2]) & ~(255 << 8))
8138 && GET_MODE (operands[0]) != QImode"
8139 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8140 (and:SI (zero_extract:SI (match_dup 1)
8141 (const_int 8) (const_int 8))
8143 (clobber (reg:CC FLAGS_REG))])]
8144 "operands[0] = gen_lowpart (SImode, operands[0]);
8145 operands[1] = gen_lowpart (SImode, operands[1]);
8146 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8148 ;; Since AND can be encoded with sign extended immediate, this is only
8149 ;; profitable when 7th bit is not set.
8151 [(set (match_operand 0 "register_operand" "")
8152 (and (match_operand 1 "general_operand" "")
8153 (match_operand 2 "const_int_operand" "")))
8154 (clobber (reg:CC FLAGS_REG))]
8156 && ANY_QI_REG_P (operands[0])
8157 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8158 && !(~INTVAL (operands[2]) & ~255)
8159 && !(INTVAL (operands[2]) & 128)
8160 && GET_MODE (operands[0]) != QImode"
8161 [(parallel [(set (strict_low_part (match_dup 0))
8162 (and:QI (match_dup 1)
8164 (clobber (reg:CC FLAGS_REG))])]
8165 "operands[0] = gen_lowpart (QImode, operands[0]);
8166 operands[1] = gen_lowpart (QImode, operands[1]);
8167 operands[2] = gen_lowpart (QImode, operands[2]);")
8169 ;; Logical inclusive and exclusive OR instructions
8171 ;; %%% This used to optimize known byte-wide and operations to memory.
8172 ;; If this is considered useful, it should be done with splitters.
8174 (define_expand "<code><mode>3"
8175 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8176 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8177 (match_operand:SWIM 2 "<general_operand>" "")))]
8179 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8181 (define_insn "*<code><mode>_1"
8182 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8184 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8185 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8186 (clobber (reg:CC FLAGS_REG))]
8187 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8188 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8189 [(set_attr "type" "alu")
8190 (set_attr "mode" "<MODE>")])
8192 ;; %%% Potential partial reg stall on alternative 2. What to do?
8193 (define_insn "*<code>qi_1"
8194 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8195 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8196 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8197 (clobber (reg:CC FLAGS_REG))]
8198 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8200 <logic>{b}\t{%2, %0|%0, %2}
8201 <logic>{b}\t{%2, %0|%0, %2}
8202 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8203 [(set_attr "type" "alu")
8204 (set_attr "mode" "QI,QI,SI")])
8206 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8207 (define_insn "*<code>si_1_zext"
8208 [(set (match_operand:DI 0 "register_operand" "=r")
8210 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8211 (match_operand:SI 2 "general_operand" "g"))))
8212 (clobber (reg:CC FLAGS_REG))]
8213 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8214 "<logic>{l}\t{%2, %k0|%k0, %2}"
8215 [(set_attr "type" "alu")
8216 (set_attr "mode" "SI")])
8218 (define_insn "*<code>si_1_zext_imm"
8219 [(set (match_operand:DI 0 "register_operand" "=r")
8221 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8222 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8223 (clobber (reg:CC FLAGS_REG))]
8224 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8225 "<logic>{l}\t{%2, %k0|%k0, %2}"
8226 [(set_attr "type" "alu")
8227 (set_attr "mode" "SI")])
8229 (define_insn "*<code>qi_1_slp"
8230 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8231 (any_or:QI (match_dup 0)
8232 (match_operand:QI 1 "general_operand" "qmn,qn")))
8233 (clobber (reg:CC FLAGS_REG))]
8234 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8235 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8236 "<logic>{b}\t{%1, %0|%0, %1}"
8237 [(set_attr "type" "alu1")
8238 (set_attr "mode" "QI")])
8240 (define_insn "*<code><mode>_2"
8241 [(set (reg FLAGS_REG)
8242 (compare (any_or:SWI
8243 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8244 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8246 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8247 (any_or:SWI (match_dup 1) (match_dup 2)))]
8248 "ix86_match_ccmode (insn, CCNOmode)
8249 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8250 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8251 [(set_attr "type" "alu")
8252 (set_attr "mode" "<MODE>")])
8254 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8255 ;; ??? Special case for immediate operand is missing - it is tricky.
8256 (define_insn "*<code>si_2_zext"
8257 [(set (reg FLAGS_REG)
8258 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8259 (match_operand:SI 2 "general_operand" "g"))
8261 (set (match_operand:DI 0 "register_operand" "=r")
8262 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8263 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8264 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8265 "<logic>{l}\t{%2, %k0|%k0, %2}"
8266 [(set_attr "type" "alu")
8267 (set_attr "mode" "SI")])
8269 (define_insn "*<code>si_2_zext_imm"
8270 [(set (reg FLAGS_REG)
8272 (match_operand:SI 1 "nonimmediate_operand" "%0")
8273 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8275 (set (match_operand:DI 0 "register_operand" "=r")
8276 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8277 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8278 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8279 "<logic>{l}\t{%2, %k0|%k0, %2}"
8280 [(set_attr "type" "alu")
8281 (set_attr "mode" "SI")])
8283 (define_insn "*<code>qi_2_slp"
8284 [(set (reg FLAGS_REG)
8285 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8286 (match_operand:QI 1 "general_operand" "qmn,qn"))
8288 (set (strict_low_part (match_dup 0))
8289 (any_or:QI (match_dup 0) (match_dup 1)))]
8290 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8291 && ix86_match_ccmode (insn, CCNOmode)
8292 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8293 "<logic>{b}\t{%1, %0|%0, %1}"
8294 [(set_attr "type" "alu1")
8295 (set_attr "mode" "QI")])
8297 (define_insn "*<code><mode>_3"
8298 [(set (reg FLAGS_REG)
8299 (compare (any_or:SWI
8300 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8301 (match_operand:SWI 2 "<general_operand>" "<g>"))
8303 (clobber (match_scratch:SWI 0 "=<r>"))]
8304 "ix86_match_ccmode (insn, CCNOmode)
8305 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8306 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8307 [(set_attr "type" "alu")
8308 (set_attr "mode" "<MODE>")])
8310 (define_insn "*<code>qi_ext_0"
8311 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8316 (match_operand 1 "ext_register_operand" "0")
8319 (match_operand 2 "const_int_operand" "n")))
8320 (clobber (reg:CC FLAGS_REG))]
8321 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8322 "<logic>{b}\t{%2, %h0|%h0, %2}"
8323 [(set_attr "type" "alu")
8324 (set_attr "length_immediate" "1")
8325 (set_attr "modrm" "1")
8326 (set_attr "mode" "QI")])
8328 (define_insn "*<code>qi_ext_1_rex64"
8329 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8334 (match_operand 1 "ext_register_operand" "0")
8338 (match_operand 2 "ext_register_operand" "Q"))))
8339 (clobber (reg:CC FLAGS_REG))]
8341 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8342 "<logic>{b}\t{%2, %h0|%h0, %2}"
8343 [(set_attr "type" "alu")
8344 (set_attr "length_immediate" "0")
8345 (set_attr "mode" "QI")])
8347 (define_insn "*<code>qi_ext_1"
8348 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8353 (match_operand 1 "ext_register_operand" "0")
8357 (match_operand:QI 2 "general_operand" "Qm"))))
8358 (clobber (reg:CC FLAGS_REG))]
8360 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8361 "<logic>{b}\t{%2, %h0|%h0, %2}"
8362 [(set_attr "type" "alu")
8363 (set_attr "length_immediate" "0")
8364 (set_attr "mode" "QI")])
8366 (define_insn "*<code>qi_ext_2"
8367 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8371 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8374 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8377 (clobber (reg:CC FLAGS_REG))]
8378 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8379 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8380 [(set_attr "type" "alu")
8381 (set_attr "length_immediate" "0")
8382 (set_attr "mode" "QI")])
8385 [(set (match_operand 0 "register_operand" "")
8386 (any_or (match_operand 1 "register_operand" "")
8387 (match_operand 2 "const_int_operand" "")))
8388 (clobber (reg:CC FLAGS_REG))]
8390 && QI_REG_P (operands[0])
8391 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8392 && !(INTVAL (operands[2]) & ~(255 << 8))
8393 && GET_MODE (operands[0]) != QImode"
8394 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8395 (any_or:SI (zero_extract:SI (match_dup 1)
8396 (const_int 8) (const_int 8))
8398 (clobber (reg:CC FLAGS_REG))])]
8399 "operands[0] = gen_lowpart (SImode, operands[0]);
8400 operands[1] = gen_lowpart (SImode, operands[1]);
8401 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8403 ;; Since OR can be encoded with sign extended immediate, this is only
8404 ;; profitable when 7th bit is set.
8406 [(set (match_operand 0 "register_operand" "")
8407 (any_or (match_operand 1 "general_operand" "")
8408 (match_operand 2 "const_int_operand" "")))
8409 (clobber (reg:CC FLAGS_REG))]
8411 && ANY_QI_REG_P (operands[0])
8412 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8413 && !(INTVAL (operands[2]) & ~255)
8414 && (INTVAL (operands[2]) & 128)
8415 && GET_MODE (operands[0]) != QImode"
8416 [(parallel [(set (strict_low_part (match_dup 0))
8417 (any_or:QI (match_dup 1)
8419 (clobber (reg:CC FLAGS_REG))])]
8420 "operands[0] = gen_lowpart (QImode, operands[0]);
8421 operands[1] = gen_lowpart (QImode, operands[1]);
8422 operands[2] = gen_lowpart (QImode, operands[2]);")
8424 (define_expand "xorqi_cc_ext_1"
8426 (set (reg:CCNO FLAGS_REG)
8430 (match_operand 1 "ext_register_operand" "")
8433 (match_operand:QI 2 "general_operand" ""))
8435 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8447 (define_insn "*xorqi_cc_ext_1_rex64"
8448 [(set (reg FLAGS_REG)
8452 (match_operand 1 "ext_register_operand" "0")
8455 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8457 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8466 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8467 "xor{b}\t{%2, %h0|%h0, %2}"
8468 [(set_attr "type" "alu")
8469 (set_attr "modrm" "1")
8470 (set_attr "mode" "QI")])
8472 (define_insn "*xorqi_cc_ext_1"
8473 [(set (reg FLAGS_REG)
8477 (match_operand 1 "ext_register_operand" "0")
8480 (match_operand:QI 2 "general_operand" "qmn"))
8482 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8491 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8492 "xor{b}\t{%2, %h0|%h0, %2}"
8493 [(set_attr "type" "alu")
8494 (set_attr "modrm" "1")
8495 (set_attr "mode" "QI")])
8497 ;; Negation instructions
8499 (define_expand "neg<mode>2"
8500 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8501 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8503 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8505 (define_insn_and_split "*neg<dwi>2_doubleword"
8506 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8507 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8508 (clobber (reg:CC FLAGS_REG))]
8509 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8513 [(set (reg:CCZ FLAGS_REG)
8514 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8515 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8518 (plus:DWIH (match_dup 3)
8519 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8521 (clobber (reg:CC FLAGS_REG))])
8524 (neg:DWIH (match_dup 2)))
8525 (clobber (reg:CC FLAGS_REG))])]
8526 "split_<dwi> (&operands[0], 2, &operands[0], &operands[2]);")
8528 (define_insn "*neg<mode>2_1"
8529 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8530 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8531 (clobber (reg:CC FLAGS_REG))]
8532 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8533 "neg{<imodesuffix>}\t%0"
8534 [(set_attr "type" "negnot")
8535 (set_attr "mode" "<MODE>")])
8537 ;; Combine is quite creative about this pattern.
8538 (define_insn "*negsi2_1_zext"
8539 [(set (match_operand:DI 0 "register_operand" "=r")
8541 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8544 (clobber (reg:CC FLAGS_REG))]
8545 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8547 [(set_attr "type" "negnot")
8548 (set_attr "mode" "SI")])
8550 ;; The problem with neg is that it does not perform (compare x 0),
8551 ;; it really performs (compare 0 x), which leaves us with the zero
8552 ;; flag being the only useful item.
8554 (define_insn "*neg<mode>2_cmpz"
8555 [(set (reg:CCZ FLAGS_REG)
8557 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8559 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8560 (neg:SWI (match_dup 1)))]
8561 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8562 "neg{<imodesuffix>}\t%0"
8563 [(set_attr "type" "negnot")
8564 (set_attr "mode" "<MODE>")])
8566 (define_insn "*negsi2_cmpz_zext"
8567 [(set (reg:CCZ FLAGS_REG)
8571 (match_operand:DI 1 "register_operand" "0")
8575 (set (match_operand:DI 0 "register_operand" "=r")
8576 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8579 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8581 [(set_attr "type" "negnot")
8582 (set_attr "mode" "SI")])
8584 ;; Changing of sign for FP values is doable using integer unit too.
8586 (define_expand "<code><mode>2"
8587 [(set (match_operand:X87MODEF 0 "register_operand" "")
8588 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8589 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8590 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8592 (define_insn "*absneg<mode>2_mixed"
8593 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8594 (match_operator:MODEF 3 "absneg_operator"
8595 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8596 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8597 (clobber (reg:CC FLAGS_REG))]
8598 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8601 (define_insn "*absneg<mode>2_sse"
8602 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8603 (match_operator:MODEF 3 "absneg_operator"
8604 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8605 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8606 (clobber (reg:CC FLAGS_REG))]
8607 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8610 (define_insn "*absneg<mode>2_i387"
8611 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8612 (match_operator:X87MODEF 3 "absneg_operator"
8613 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8614 (use (match_operand 2 "" ""))
8615 (clobber (reg:CC FLAGS_REG))]
8616 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8619 (define_expand "<code>tf2"
8620 [(set (match_operand:TF 0 "register_operand" "")
8621 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8623 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8625 (define_insn "*absnegtf2_sse"
8626 [(set (match_operand:TF 0 "register_operand" "=x,x")
8627 (match_operator:TF 3 "absneg_operator"
8628 [(match_operand:TF 1 "register_operand" "0,x")]))
8629 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8630 (clobber (reg:CC FLAGS_REG))]
8634 ;; Splitters for fp abs and neg.
8637 [(set (match_operand 0 "fp_register_operand" "")
8638 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8639 (use (match_operand 2 "" ""))
8640 (clobber (reg:CC FLAGS_REG))]
8642 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8645 [(set (match_operand 0 "register_operand" "")
8646 (match_operator 3 "absneg_operator"
8647 [(match_operand 1 "register_operand" "")]))
8648 (use (match_operand 2 "nonimmediate_operand" ""))
8649 (clobber (reg:CC FLAGS_REG))]
8650 "reload_completed && SSE_REG_P (operands[0])"
8651 [(set (match_dup 0) (match_dup 3))]
8653 enum machine_mode mode = GET_MODE (operands[0]);
8654 enum machine_mode vmode = GET_MODE (operands[2]);
8657 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8658 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8659 if (operands_match_p (operands[0], operands[2]))
8662 operands[1] = operands[2];
8665 if (GET_CODE (operands[3]) == ABS)
8666 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8668 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8673 [(set (match_operand:SF 0 "register_operand" "")
8674 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8675 (use (match_operand:V4SF 2 "" ""))
8676 (clobber (reg:CC FLAGS_REG))]
8678 [(parallel [(set (match_dup 0) (match_dup 1))
8679 (clobber (reg:CC FLAGS_REG))])]
8682 operands[0] = gen_lowpart (SImode, operands[0]);
8683 if (GET_CODE (operands[1]) == ABS)
8685 tmp = gen_int_mode (0x7fffffff, SImode);
8686 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8690 tmp = gen_int_mode (0x80000000, SImode);
8691 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8697 [(set (match_operand:DF 0 "register_operand" "")
8698 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8699 (use (match_operand 2 "" ""))
8700 (clobber (reg:CC FLAGS_REG))]
8702 [(parallel [(set (match_dup 0) (match_dup 1))
8703 (clobber (reg:CC FLAGS_REG))])]
8708 tmp = gen_lowpart (DImode, operands[0]);
8709 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8712 if (GET_CODE (operands[1]) == ABS)
8715 tmp = gen_rtx_NOT (DImode, tmp);
8719 operands[0] = gen_highpart (SImode, operands[0]);
8720 if (GET_CODE (operands[1]) == ABS)
8722 tmp = gen_int_mode (0x7fffffff, SImode);
8723 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8727 tmp = gen_int_mode (0x80000000, SImode);
8728 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8735 [(set (match_operand:XF 0 "register_operand" "")
8736 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8737 (use (match_operand 2 "" ""))
8738 (clobber (reg:CC FLAGS_REG))]
8740 [(parallel [(set (match_dup 0) (match_dup 1))
8741 (clobber (reg:CC FLAGS_REG))])]
8744 operands[0] = gen_rtx_REG (SImode,
8745 true_regnum (operands[0])
8746 + (TARGET_64BIT ? 1 : 2));
8747 if (GET_CODE (operands[1]) == ABS)
8749 tmp = GEN_INT (0x7fff);
8750 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8754 tmp = GEN_INT (0x8000);
8755 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8760 ;; Conditionalize these after reload. If they match before reload, we
8761 ;; lose the clobber and ability to use integer instructions.
8763 (define_insn "*<code><mode>2_1"
8764 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8765 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8767 && (reload_completed
8768 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8769 "f<absneg_mnemonic>"
8770 [(set_attr "type" "fsgn")
8771 (set_attr "mode" "<MODE>")])
8773 (define_insn "*<code>extendsfdf2"
8774 [(set (match_operand:DF 0 "register_operand" "=f")
8775 (absneg:DF (float_extend:DF
8776 (match_operand:SF 1 "register_operand" "0"))))]
8777 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8778 "f<absneg_mnemonic>"
8779 [(set_attr "type" "fsgn")
8780 (set_attr "mode" "DF")])
8782 (define_insn "*<code>extendsfxf2"
8783 [(set (match_operand:XF 0 "register_operand" "=f")
8784 (absneg:XF (float_extend:XF
8785 (match_operand:SF 1 "register_operand" "0"))))]
8787 "f<absneg_mnemonic>"
8788 [(set_attr "type" "fsgn")
8789 (set_attr "mode" "XF")])
8791 (define_insn "*<code>extenddfxf2"
8792 [(set (match_operand:XF 0 "register_operand" "=f")
8793 (absneg:XF (float_extend:XF
8794 (match_operand:DF 1 "register_operand" "0"))))]
8796 "f<absneg_mnemonic>"
8797 [(set_attr "type" "fsgn")
8798 (set_attr "mode" "XF")])
8800 ;; Copysign instructions
8802 (define_mode_iterator CSGNMODE [SF DF TF])
8803 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8805 (define_expand "copysign<mode>3"
8806 [(match_operand:CSGNMODE 0 "register_operand" "")
8807 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8808 (match_operand:CSGNMODE 2 "register_operand" "")]
8809 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8810 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8811 "ix86_expand_copysign (operands); DONE;")
8813 (define_insn_and_split "copysign<mode>3_const"
8814 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8816 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8817 (match_operand:CSGNMODE 2 "register_operand" "0")
8818 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8820 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8821 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8823 "&& reload_completed"
8825 "ix86_split_copysign_const (operands); DONE;")
8827 (define_insn "copysign<mode>3_var"
8828 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8830 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8831 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8832 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8833 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8835 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8836 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8837 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8841 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8843 [(match_operand:CSGNMODE 2 "register_operand" "")
8844 (match_operand:CSGNMODE 3 "register_operand" "")
8845 (match_operand:<CSGNVMODE> 4 "" "")
8846 (match_operand:<CSGNVMODE> 5 "" "")]
8848 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8849 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8850 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8851 && reload_completed"
8853 "ix86_split_copysign_var (operands); DONE;")
8855 ;; One complement instructions
8857 (define_expand "one_cmpl<mode>2"
8858 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8859 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8861 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8863 (define_insn "*one_cmpl<mode>2_1"
8864 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8865 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8866 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8867 "not{<imodesuffix>}\t%0"
8868 [(set_attr "type" "negnot")
8869 (set_attr "mode" "<MODE>")])
8871 ;; %%% Potential partial reg stall on alternative 1. What to do?
8872 (define_insn "*one_cmplqi2_1"
8873 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8874 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8875 "ix86_unary_operator_ok (NOT, QImode, operands)"
8879 [(set_attr "type" "negnot")
8880 (set_attr "mode" "QI,SI")])
8882 ;; ??? Currently never generated - xor is used instead.
8883 (define_insn "*one_cmplsi2_1_zext"
8884 [(set (match_operand:DI 0 "register_operand" "=r")
8886 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8887 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8889 [(set_attr "type" "negnot")
8890 (set_attr "mode" "SI")])
8892 (define_insn "*one_cmpl<mode>2_2"
8893 [(set (reg FLAGS_REG)
8894 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8896 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8897 (not:SWI (match_dup 1)))]
8898 "ix86_match_ccmode (insn, CCNOmode)
8899 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8901 [(set_attr "type" "alu1")
8902 (set_attr "mode" "<MODE>")])
8905 [(set (match_operand 0 "flags_reg_operand" "")
8906 (match_operator 2 "compare_operator"
8907 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8909 (set (match_operand:SWI 1 "nonimmediate_operand" "")
8910 (not:SWI (match_dup 3)))]
8911 "ix86_match_ccmode (insn, CCNOmode)"
8912 [(parallel [(set (match_dup 0)
8913 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8916 (xor:SWI (match_dup 3) (const_int -1)))])])
8918 ;; ??? Currently never generated - xor is used instead.
8919 (define_insn "*one_cmplsi2_2_zext"
8920 [(set (reg FLAGS_REG)
8921 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8923 (set (match_operand:DI 0 "register_operand" "=r")
8924 (zero_extend:DI (not:SI (match_dup 1))))]
8925 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8926 && ix86_unary_operator_ok (NOT, SImode, operands)"
8928 [(set_attr "type" "alu1")
8929 (set_attr "mode" "SI")])
8932 [(set (match_operand 0 "flags_reg_operand" "")
8933 (match_operator 2 "compare_operator"
8934 [(not:SI (match_operand:SI 3 "register_operand" ""))
8936 (set (match_operand:DI 1 "register_operand" "")
8937 (zero_extend:DI (not:SI (match_dup 3))))]
8938 "ix86_match_ccmode (insn, CCNOmode)"
8939 [(parallel [(set (match_dup 0)
8940 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8943 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8945 ;; Shift instructions
8947 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8948 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8949 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8950 ;; from the assembler input.
8952 ;; This instruction shifts the target reg/mem as usual, but instead of
8953 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8954 ;; is a left shift double, bits are taken from the high order bits of
8955 ;; reg, else if the insn is a shift right double, bits are taken from the
8956 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8957 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8959 ;; Since sh[lr]d does not change the `reg' operand, that is done
8960 ;; separately, making all shifts emit pairs of shift double and normal
8961 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8962 ;; support a 63 bit shift, each shift where the count is in a reg expands
8963 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8965 ;; If the shift count is a constant, we need never emit more than one
8966 ;; shift pair, instead using moves and sign extension for counts greater
8969 (define_expand "ashl<mode>3"
8970 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8971 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8972 (match_operand:QI 2 "nonmemory_operand" "")))]
8974 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8976 (define_insn "*ashl<mode>3_doubleword"
8977 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8978 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8979 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8980 (clobber (reg:CC FLAGS_REG))]
8983 [(set_attr "type" "multi")])
8986 [(set (match_operand:DWI 0 "register_operand" "")
8987 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8988 (match_operand:QI 2 "nonmemory_operand" "")))
8989 (clobber (reg:CC FLAGS_REG))]
8990 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8992 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8994 ;; By default we don't ask for a scratch register, because when DWImode
8995 ;; values are manipulated, registers are already at a premium. But if
8996 ;; we have one handy, we won't turn it away.
8999 [(match_scratch:DWIH 3 "r")
9000 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9002 (match_operand:<DWI> 1 "nonmemory_operand" "")
9003 (match_operand:QI 2 "nonmemory_operand" "")))
9004 (clobber (reg:CC FLAGS_REG))])
9008 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9010 (define_insn "x86_64_shld"
9011 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9012 (ior:DI (ashift:DI (match_dup 0)
9013 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9014 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9015 (minus:QI (const_int 64) (match_dup 2)))))
9016 (clobber (reg:CC FLAGS_REG))]
9018 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9019 [(set_attr "type" "ishift")
9020 (set_attr "prefix_0f" "1")
9021 (set_attr "mode" "DI")
9022 (set_attr "athlon_decode" "vector")
9023 (set_attr "amdfam10_decode" "vector")])
9025 (define_insn "x86_shld"
9026 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9027 (ior:SI (ashift:SI (match_dup 0)
9028 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9029 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9030 (minus:QI (const_int 32) (match_dup 2)))))
9031 (clobber (reg:CC FLAGS_REG))]
9033 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9034 [(set_attr "type" "ishift")
9035 (set_attr "prefix_0f" "1")
9036 (set_attr "mode" "SI")
9037 (set_attr "pent_pair" "np")
9038 (set_attr "athlon_decode" "vector")
9039 (set_attr "amdfam10_decode" "vector")])
9041 (define_expand "x86_shift<mode>_adj_1"
9042 [(set (reg:CCZ FLAGS_REG)
9043 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9046 (set (match_operand:SWI48 0 "register_operand" "")
9047 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9048 (match_operand:SWI48 1 "register_operand" "")
9051 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9052 (match_operand:SWI48 3 "register_operand" "r")
9055 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9057 (define_expand "x86_shift<mode>_adj_2"
9058 [(use (match_operand:SWI48 0 "register_operand" ""))
9059 (use (match_operand:SWI48 1 "register_operand" ""))
9060 (use (match_operand:QI 2 "register_operand" ""))]
9063 rtx label = gen_label_rtx ();
9066 emit_insn (gen_testqi_ccz_1 (operands[2],
9067 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9069 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9070 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9071 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9072 gen_rtx_LABEL_REF (VOIDmode, label),
9074 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9075 JUMP_LABEL (tmp) = label;
9077 emit_move_insn (operands[0], operands[1]);
9078 ix86_expand_clear (operands[1]);
9081 LABEL_NUSES (label) = 1;
9086 (define_insn "*ashl<mode>3_1"
9087 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9088 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9089 (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9090 (clobber (reg:CC FLAGS_REG))]
9091 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9093 switch (get_attr_type (insn))
9099 gcc_assert (operands[2] == const1_rtx);
9100 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9101 return "add{<imodesuffix>}\t%0, %0";
9104 if (operands[2] == const1_rtx
9105 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9106 return "sal{<imodesuffix>}\t%0";
9108 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9112 (cond [(eq_attr "alternative" "1")
9113 (const_string "lea")
9114 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9116 (match_operand 0 "register_operand" ""))
9117 (match_operand 2 "const1_operand" ""))
9118 (const_string "alu")
9120 (const_string "ishift")))
9121 (set (attr "length_immediate")
9123 (ior (eq_attr "type" "alu")
9124 (and (eq_attr "type" "ishift")
9125 (and (match_operand 2 "const1_operand" "")
9126 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9129 (const_string "*")))
9130 (set_attr "mode" "<MODE>")])
9132 (define_insn "*ashlsi3_1_zext"
9133 [(set (match_operand:DI 0 "register_operand" "=r,r")
9135 (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9136 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9137 (clobber (reg:CC FLAGS_REG))]
9138 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9140 switch (get_attr_type (insn))
9146 gcc_assert (operands[2] == const1_rtx);
9147 return "add{l}\t%k0, %k0";
9150 if (operands[2] == const1_rtx
9151 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9152 return "sal{l}\t%k0";
9154 return "sal{l}\t{%2, %k0|%k0, %2}";
9158 (cond [(eq_attr "alternative" "1")
9159 (const_string "lea")
9160 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9162 (match_operand 2 "const1_operand" ""))
9163 (const_string "alu")
9165 (const_string "ishift")))
9166 (set (attr "length_immediate")
9168 (ior (eq_attr "type" "alu")
9169 (and (eq_attr "type" "ishift")
9170 (and (match_operand 2 "const1_operand" "")
9171 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9174 (const_string "*")))
9175 (set_attr "mode" "SI")])
9177 (define_insn "*ashlhi3_1"
9178 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9179 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9180 (match_operand:QI 2 "nonmemory_operand" "cI")))
9181 (clobber (reg:CC FLAGS_REG))]
9182 "TARGET_PARTIAL_REG_STALL
9183 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9185 switch (get_attr_type (insn))
9188 gcc_assert (operands[2] == const1_rtx);
9189 return "add{w}\t%0, %0";
9192 if (operands[2] == const1_rtx
9193 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9194 return "sal{w}\t%0";
9196 return "sal{w}\t{%2, %0|%0, %2}";
9200 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9202 (match_operand 0 "register_operand" ""))
9203 (match_operand 2 "const1_operand" ""))
9204 (const_string "alu")
9206 (const_string "ishift")))
9207 (set (attr "length_immediate")
9209 (ior (eq_attr "type" "alu")
9210 (and (eq_attr "type" "ishift")
9211 (and (match_operand 2 "const1_operand" "")
9212 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9215 (const_string "*")))
9216 (set_attr "mode" "HI")])
9218 (define_insn "*ashlhi3_1_lea"
9219 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9220 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9221 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9222 (clobber (reg:CC FLAGS_REG))]
9223 "!TARGET_PARTIAL_REG_STALL
9224 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9226 switch (get_attr_type (insn))
9232 gcc_assert (operands[2] == const1_rtx);
9233 return "add{w}\t%0, %0";
9236 if (operands[2] == const1_rtx
9237 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9238 return "sal{w}\t%0";
9240 return "sal{w}\t{%2, %0|%0, %2}";
9244 (cond [(eq_attr "alternative" "1")
9245 (const_string "lea")
9246 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9248 (match_operand 0 "register_operand" ""))
9249 (match_operand 2 "const1_operand" ""))
9250 (const_string "alu")
9252 (const_string "ishift")))
9253 (set (attr "length_immediate")
9255 (ior (eq_attr "type" "alu")
9256 (and (eq_attr "type" "ishift")
9257 (and (match_operand 2 "const1_operand" "")
9258 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9261 (const_string "*")))
9262 (set_attr "mode" "HI,SI")])
9264 (define_insn "*ashlqi3_1"
9265 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9266 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9267 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9268 (clobber (reg:CC FLAGS_REG))]
9269 "TARGET_PARTIAL_REG_STALL
9270 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9272 switch (get_attr_type (insn))
9275 gcc_assert (operands[2] == const1_rtx);
9276 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9277 return "add{l}\t%k0, %k0";
9279 return "add{b}\t%0, %0";
9282 if (operands[2] == const1_rtx
9283 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9285 if (get_attr_mode (insn) == MODE_SI)
9286 return "sal{l}\t%k0";
9288 return "sal{b}\t%0";
9292 if (get_attr_mode (insn) == MODE_SI)
9293 return "sal{l}\t{%2, %k0|%k0, %2}";
9295 return "sal{b}\t{%2, %0|%0, %2}";
9300 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9302 (match_operand 0 "register_operand" ""))
9303 (match_operand 2 "const1_operand" ""))
9304 (const_string "alu")
9306 (const_string "ishift")))
9307 (set (attr "length_immediate")
9309 (ior (eq_attr "type" "alu")
9310 (and (eq_attr "type" "ishift")
9311 (and (match_operand 2 "const1_operand" "")
9312 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9315 (const_string "*")))
9316 (set_attr "mode" "QI,SI")])
9318 ;; %%% Potential partial reg stall on alternative 2. What to do?
9319 (define_insn "*ashlqi3_1_lea"
9320 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9321 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9322 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9323 (clobber (reg:CC FLAGS_REG))]
9324 "!TARGET_PARTIAL_REG_STALL
9325 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9327 switch (get_attr_type (insn))
9333 gcc_assert (operands[2] == const1_rtx);
9334 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9335 return "add{l}\t%k0, %k0";
9337 return "add{b}\t%0, %0";
9340 if (operands[2] == const1_rtx
9341 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9343 if (get_attr_mode (insn) == MODE_SI)
9344 return "sal{l}\t%k0";
9346 return "sal{b}\t%0";
9350 if (get_attr_mode (insn) == MODE_SI)
9351 return "sal{l}\t{%2, %k0|%k0, %2}";
9353 return "sal{b}\t{%2, %0|%0, %2}";
9358 (cond [(eq_attr "alternative" "2")
9359 (const_string "lea")
9360 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9362 (match_operand 0 "register_operand" ""))
9363 (match_operand 2 "const1_operand" ""))
9364 (const_string "alu")
9366 (const_string "ishift")))
9367 (set (attr "length_immediate")
9369 (ior (eq_attr "type" "alu")
9370 (and (eq_attr "type" "ishift")
9371 (and (match_operand 2 "const1_operand" "")
9372 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9375 (const_string "*")))
9376 (set_attr "mode" "QI,SI,SI")])
9378 (define_insn "*ashlqi3_1_slp"
9379 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9380 (ashift:QI (match_dup 0)
9381 (match_operand:QI 1 "nonmemory_operand" "cI")))
9382 (clobber (reg:CC FLAGS_REG))]
9383 "(optimize_function_for_size_p (cfun)
9384 || !TARGET_PARTIAL_FLAG_REG_STALL
9385 || (operands[1] == const1_rtx
9387 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9389 switch (get_attr_type (insn))
9392 gcc_assert (operands[1] == const1_rtx);
9393 return "add{b}\t%0, %0";
9396 if (operands[1] == const1_rtx
9397 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9398 return "sal{b}\t%0";
9400 return "sal{b}\t{%1, %0|%0, %1}";
9404 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9406 (match_operand 0 "register_operand" ""))
9407 (match_operand 1 "const1_operand" ""))
9408 (const_string "alu")
9410 (const_string "ishift1")))
9411 (set (attr "length_immediate")
9413 (ior (eq_attr "type" "alu")
9414 (and (eq_attr "type" "ishift1")
9415 (and (match_operand 1 "const1_operand" "")
9416 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9419 (const_string "*")))
9420 (set_attr "mode" "QI")])
9422 ;; Convert lea to the lea pattern to avoid flags dependency.
9424 [(set (match_operand 0 "register_operand" "")
9425 (ashift (match_operand 1 "index_register_operand" "")
9426 (match_operand:QI 2 "const_int_operand" "")))
9427 (clobber (reg:CC FLAGS_REG))]
9429 && true_regnum (operands[0]) != true_regnum (operands[1])"
9433 enum machine_mode mode = GET_MODE (operands[0]);
9436 operands[1] = gen_lowpart (Pmode, operands[1]);
9437 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9439 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9441 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9442 operands[0] = gen_lowpart (SImode, operands[0]);
9444 if (TARGET_64BIT && mode != Pmode)
9445 pat = gen_rtx_SUBREG (SImode, pat, 0);
9447 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9451 ;; Convert lea to the lea pattern to avoid flags dependency.
9453 [(set (match_operand:DI 0 "register_operand" "")
9455 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9456 (match_operand:QI 2 "const_int_operand" ""))))
9457 (clobber (reg:CC FLAGS_REG))]
9458 "TARGET_64BIT && reload_completed
9459 && true_regnum (operands[0]) != true_regnum (operands[1])"
9461 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9463 operands[1] = gen_lowpart (DImode, operands[1]);
9464 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9467 ;; This pattern can't accept a variable shift count, since shifts by
9468 ;; zero don't affect the flags. We assume that shifts by constant
9469 ;; zero are optimized away.
9470 (define_insn "*ashl<mode>3_cmp"
9471 [(set (reg FLAGS_REG)
9473 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9474 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9476 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9477 (ashift:SWI (match_dup 1) (match_dup 2)))]
9478 "(optimize_function_for_size_p (cfun)
9479 || !TARGET_PARTIAL_FLAG_REG_STALL
9480 || (operands[2] == const1_rtx
9482 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9483 && ix86_match_ccmode (insn, CCGOCmode)
9484 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9486 switch (get_attr_type (insn))
9489 gcc_assert (operands[2] == const1_rtx);
9490 return "add{<imodesuffix>}\t%0, %0";
9493 if (operands[2] == const1_rtx
9494 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9495 return "sal{<imodesuffix>}\t%0";
9497 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9501 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9503 (match_operand 0 "register_operand" ""))
9504 (match_operand 2 "const1_operand" ""))
9505 (const_string "alu")
9507 (const_string "ishift")))
9508 (set (attr "length_immediate")
9510 (ior (eq_attr "type" "alu")
9511 (and (eq_attr "type" "ishift")
9512 (and (match_operand 2 "const1_operand" "")
9513 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9516 (const_string "*")))
9517 (set_attr "mode" "<MODE>")])
9519 (define_insn "*ashlsi3_cmp_zext"
9520 [(set (reg FLAGS_REG)
9522 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9523 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9525 (set (match_operand:DI 0 "register_operand" "=r")
9526 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9528 && (optimize_function_for_size_p (cfun)
9529 || !TARGET_PARTIAL_FLAG_REG_STALL
9530 || (operands[2] == const1_rtx
9532 || TARGET_DOUBLE_WITH_ADD)))
9533 && ix86_match_ccmode (insn, CCGOCmode)
9534 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9536 switch (get_attr_type (insn))
9539 gcc_assert (operands[2] == const1_rtx);
9540 return "add{l}\t%k0, %k0";
9543 if (operands[2] == const1_rtx
9544 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9545 return "sal{l}\t%k0";
9547 return "sal{l}\t{%2, %k0|%k0, %2}";
9551 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9553 (match_operand 2 "const1_operand" ""))
9554 (const_string "alu")
9556 (const_string "ishift")))
9557 (set (attr "length_immediate")
9559 (ior (eq_attr "type" "alu")
9560 (and (eq_attr "type" "ishift")
9561 (and (match_operand 2 "const1_operand" "")
9562 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9565 (const_string "*")))
9566 (set_attr "mode" "SI")])
9568 (define_insn "*ashl<mode>3_cconly"
9569 [(set (reg FLAGS_REG)
9571 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9572 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9574 (clobber (match_scratch:SWI 0 "=<r>"))]
9575 "(optimize_function_for_size_p (cfun)
9576 || !TARGET_PARTIAL_FLAG_REG_STALL
9577 || (operands[2] == const1_rtx
9579 || TARGET_DOUBLE_WITH_ADD)))
9580 && ix86_match_ccmode (insn, CCGOCmode)
9581 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9583 switch (get_attr_type (insn))
9586 gcc_assert (operands[2] == const1_rtx);
9587 return "add{<imodesuffix>}\t%0, %0";
9590 if (operands[2] == const1_rtx
9591 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9592 return "sal{<imodesuffix>}\t%0";
9594 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9598 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9600 (match_operand 0 "register_operand" ""))
9601 (match_operand 2 "const1_operand" ""))
9602 (const_string "alu")
9604 (const_string "ishift")))
9605 (set (attr "length_immediate")
9607 (ior (eq_attr "type" "alu")
9608 (and (eq_attr "type" "ishift")
9609 (and (match_operand 2 "const1_operand" "")
9610 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9613 (const_string "*")))
9614 (set_attr "mode" "<MODE>")])
9616 ;; See comment above `ashl<mode>3' about how this works.
9618 (define_expand "<shiftrt_insn><mode>3"
9619 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9620 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9621 (match_operand:QI 2 "nonmemory_operand" "")))]
9623 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9625 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9626 [(set (match_operand:DWI 0 "register_operand" "=r")
9627 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9628 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9629 (clobber (reg:CC FLAGS_REG))]
9632 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9634 "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9635 [(set_attr "type" "multi")])
9637 ;; By default we don't ask for a scratch register, because when DWImode
9638 ;; values are manipulated, registers are already at a premium. But if
9639 ;; we have one handy, we won't turn it away.
9642 [(match_scratch:DWIH 3 "r")
9643 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9645 (match_operand:<DWI> 1 "register_operand" "")
9646 (match_operand:QI 2 "nonmemory_operand" "")))
9647 (clobber (reg:CC FLAGS_REG))])
9651 "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9653 (define_insn "x86_64_shrd"
9654 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9655 (ior:DI (ashiftrt:DI (match_dup 0)
9656 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9657 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9658 (minus:QI (const_int 64) (match_dup 2)))))
9659 (clobber (reg:CC FLAGS_REG))]
9661 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9662 [(set_attr "type" "ishift")
9663 (set_attr "prefix_0f" "1")
9664 (set_attr "mode" "DI")
9665 (set_attr "athlon_decode" "vector")
9666 (set_attr "amdfam10_decode" "vector")])
9668 (define_insn "x86_shrd"
9669 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9670 (ior:SI (ashiftrt:SI (match_dup 0)
9671 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9672 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9673 (minus:QI (const_int 32) (match_dup 2)))))
9674 (clobber (reg:CC FLAGS_REG))]
9676 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9677 [(set_attr "type" "ishift")
9678 (set_attr "prefix_0f" "1")
9679 (set_attr "mode" "SI")
9680 (set_attr "pent_pair" "np")
9681 (set_attr "athlon_decode" "vector")
9682 (set_attr "amdfam10_decode" "vector")])
9684 (define_insn "ashrdi3_cvt"
9685 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9686 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9687 (match_operand:QI 2 "const_int_operand" "")))
9688 (clobber (reg:CC FLAGS_REG))]
9689 "TARGET_64BIT && INTVAL (operands[2]) == 63
9690 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9691 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9694 sar{q}\t{%2, %0|%0, %2}"
9695 [(set_attr "type" "imovx,ishift")
9696 (set_attr "prefix_0f" "0,*")
9697 (set_attr "length_immediate" "0,*")
9698 (set_attr "modrm" "0,1")
9699 (set_attr "mode" "DI")])
9701 (define_insn "ashrsi3_cvt"
9702 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9703 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9704 (match_operand:QI 2 "const_int_operand" "")))
9705 (clobber (reg:CC FLAGS_REG))]
9706 "INTVAL (operands[2]) == 31
9707 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9708 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9711 sar{l}\t{%2, %0|%0, %2}"
9712 [(set_attr "type" "imovx,ishift")
9713 (set_attr "prefix_0f" "0,*")
9714 (set_attr "length_immediate" "0,*")
9715 (set_attr "modrm" "0,1")
9716 (set_attr "mode" "SI")])
9718 (define_insn "*ashrsi3_cvt_zext"
9719 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9721 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9722 (match_operand:QI 2 "const_int_operand" ""))))
9723 (clobber (reg:CC FLAGS_REG))]
9724 "TARGET_64BIT && INTVAL (operands[2]) == 31
9725 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9726 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9729 sar{l}\t{%2, %k0|%k0, %2}"
9730 [(set_attr "type" "imovx,ishift")
9731 (set_attr "prefix_0f" "0,*")
9732 (set_attr "length_immediate" "0,*")
9733 (set_attr "modrm" "0,1")
9734 (set_attr "mode" "SI")])
9736 (define_expand "x86_shift<mode>_adj_3"
9737 [(use (match_operand:SWI48 0 "register_operand" ""))
9738 (use (match_operand:SWI48 1 "register_operand" ""))
9739 (use (match_operand:QI 2 "register_operand" ""))]
9742 rtx label = gen_label_rtx ();
9745 emit_insn (gen_testqi_ccz_1 (operands[2],
9746 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9748 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9749 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9750 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9751 gen_rtx_LABEL_REF (VOIDmode, label),
9753 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9754 JUMP_LABEL (tmp) = label;
9756 emit_move_insn (operands[0], operands[1]);
9757 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9758 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9760 LABEL_NUSES (label) = 1;
9765 (define_insn "*<shiftrt_insn><mode>3_1"
9766 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9767 (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9768 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9769 (clobber (reg:CC FLAGS_REG))]
9770 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9772 if (operands[2] == const1_rtx
9773 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9774 return "<shiftrt>{<imodesuffix>}\t%0";
9776 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9778 [(set_attr "type" "ishift")
9779 (set (attr "length_immediate")
9781 (and (match_operand 2 "const1_operand" "")
9782 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9785 (const_string "*")))
9786 (set_attr "mode" "<MODE>")])
9788 (define_insn "*<shiftrt_insn>si3_1_zext"
9789 [(set (match_operand:DI 0 "register_operand" "=r")
9791 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9792 (match_operand:QI 2 "nonmemory_operand" "cI"))))
9793 (clobber (reg:CC FLAGS_REG))]
9794 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9796 if (operands[2] == const1_rtx
9797 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9798 return "<shiftrt>{l}\t%k0";
9800 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9802 [(set_attr "type" "ishift")
9803 (set (attr "length_immediate")
9805 (and (match_operand 2 "const1_operand" "")
9806 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9809 (const_string "*")))
9810 (set_attr "mode" "SI")])
9812 (define_insn "*<shiftrt_insn>qi3_1_slp"
9813 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9814 (any_shiftrt:QI (match_dup 0)
9815 (match_operand:QI 1 "nonmemory_operand" "cI")))
9816 (clobber (reg:CC FLAGS_REG))]
9817 "(optimize_function_for_size_p (cfun)
9818 || !TARGET_PARTIAL_REG_STALL
9819 || (operands[1] == const1_rtx
9822 if (operands[1] == const1_rtx
9823 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9824 return "<shiftrt>{b}\t%0";
9826 return "<shiftrt>{b}\t{%1, %0|%0, %1}";
9828 [(set_attr "type" "ishift1")
9829 (set (attr "length_immediate")
9831 (and (match_operand 1 "const1_operand" "")
9832 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9835 (const_string "*")))
9836 (set_attr "mode" "QI")])
9838 ;; This pattern can't accept a variable shift count, since shifts by
9839 ;; zero don't affect the flags. We assume that shifts by constant
9840 ;; zero are optimized away.
9841 (define_insn "*<shiftrt_insn><mode>3_cmp"
9842 [(set (reg FLAGS_REG)
9845 (match_operand:SWI 1 "nonimmediate_operand" "0")
9846 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9848 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9849 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9850 "(optimize_function_for_size_p (cfun)
9851 || !TARGET_PARTIAL_FLAG_REG_STALL
9852 || (operands[2] == const1_rtx
9854 && ix86_match_ccmode (insn, CCGOCmode)
9855 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9857 if (operands[2] == const1_rtx
9858 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9859 return "<shiftrt>{<imodesuffix>}\t%0";
9861 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9863 [(set_attr "type" "ishift")
9864 (set (attr "length_immediate")
9866 (and (match_operand 2 "const1_operand" "")
9867 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9870 (const_string "*")))
9871 (set_attr "mode" "<MODE>")])
9873 (define_insn "*<shiftrt_insn>si3_cmp_zext"
9874 [(set (reg FLAGS_REG)
9876 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9877 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9879 (set (match_operand:DI 0 "register_operand" "=r")
9880 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9882 && (optimize_function_for_size_p (cfun)
9883 || !TARGET_PARTIAL_FLAG_REG_STALL
9884 || (operands[2] == const1_rtx
9886 && ix86_match_ccmode (insn, CCGOCmode)
9887 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9889 if (operands[2] == const1_rtx
9890 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9891 return "<shiftrt>{l}\t%k0";
9893 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9895 [(set_attr "type" "ishift")
9896 (set (attr "length_immediate")
9898 (and (match_operand 2 "const1_operand" "")
9899 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9902 (const_string "*")))
9903 (set_attr "mode" "SI")])
9905 (define_insn "*<shiftrt_insn><mode>3_cconly"
9906 [(set (reg FLAGS_REG)
9909 (match_operand:SWI 1 "nonimmediate_operand" "0")
9910 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9912 (clobber (match_scratch:SWI 0 "=<r>"))]
9913 "(optimize_function_for_size_p (cfun)
9914 || !TARGET_PARTIAL_FLAG_REG_STALL
9915 || (operands[2] == const1_rtx
9917 && ix86_match_ccmode (insn, CCGOCmode)
9918 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9920 if (operands[2] == const1_rtx
9921 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9922 return "<shiftrt>{<imodesuffix>}\t%0";
9924 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9926 [(set_attr "type" "ishift")
9927 (set (attr "length_immediate")
9929 (and (match_operand 2 "const1_operand" "")
9930 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9933 (const_string "*")))
9934 (set_attr "mode" "<MODE>")])
9936 ;; Rotate instructions
9938 (define_expand "<rotate_insn>ti3"
9939 [(set (match_operand:TI 0 "register_operand" "")
9940 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
9941 (match_operand:QI 2 "nonmemory_operand" "")))]
9944 if (const_1_to_63_operand (operands[2], VOIDmode))
9945 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
9946 (operands[0], operands[1], operands[2]));
9953 (define_expand "<rotate_insn>di3"
9954 [(set (match_operand:DI 0 "shiftdi_operand" "")
9955 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
9956 (match_operand:QI 2 "nonmemory_operand" "")))]
9960 ix86_expand_binary_operator (<CODE>, DImode, operands);
9961 else if (const_1_to_31_operand (operands[2], VOIDmode))
9962 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
9963 (operands[0], operands[1], operands[2]));
9970 (define_expand "<rotate_insn><mode>3"
9971 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
9972 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
9973 (match_operand:QI 2 "nonmemory_operand" "")))]
9975 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9977 ;; Implement rotation using two double-precision
9978 ;; shift instructions and a scratch register.
9980 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
9981 [(set (match_operand:<DWI> 0 "register_operand" "=r")
9982 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
9983 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
9984 (clobber (reg:CC FLAGS_REG))
9985 (clobber (match_scratch:DWIH 3 "=&r"))]
9989 [(set (match_dup 3) (match_dup 4))
9992 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
9993 (lshiftrt:DWIH (match_dup 5)
9994 (minus:QI (match_dup 6) (match_dup 2)))))
9995 (clobber (reg:CC FLAGS_REG))])
9998 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
9999 (lshiftrt:DWIH (match_dup 3)
10000 (minus:QI (match_dup 6) (match_dup 2)))))
10001 (clobber (reg:CC FLAGS_REG))])]
10003 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10005 split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
10008 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10009 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10010 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10011 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10012 (clobber (reg:CC FLAGS_REG))
10013 (clobber (match_scratch:DWIH 3 "=&r"))]
10017 [(set (match_dup 3) (match_dup 4))
10019 [(set (match_dup 4)
10020 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10021 (ashift:DWIH (match_dup 5)
10022 (minus:QI (match_dup 6) (match_dup 2)))))
10023 (clobber (reg:CC FLAGS_REG))])
10025 [(set (match_dup 5)
10026 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10027 (ashift:DWIH (match_dup 3)
10028 (minus:QI (match_dup 6) (match_dup 2)))))
10029 (clobber (reg:CC FLAGS_REG))])]
10031 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10033 split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
10036 (define_insn "*<rotate_insn><mode>3_1"
10037 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10038 (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10039 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10040 (clobber (reg:CC FLAGS_REG))]
10041 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10043 if (operands[2] == const1_rtx
10044 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10045 return "<rotate>{<imodesuffix>}\t%0";
10047 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10049 [(set_attr "type" "rotate")
10050 (set (attr "length_immediate")
10052 (and (match_operand 2 "const1_operand" "")
10053 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10056 (const_string "*")))
10057 (set_attr "mode" "<MODE>")])
10059 (define_insn "*<rotate_insn>si3_1_zext"
10060 [(set (match_operand:DI 0 "register_operand" "=r")
10062 (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10063 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10064 (clobber (reg:CC FLAGS_REG))]
10065 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10067 if (operands[2] == const1_rtx
10068 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10069 return "<rotate>{l}\t%k0";
10071 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10073 [(set_attr "type" "rotate")
10074 (set (attr "length_immediate")
10076 (and (match_operand 2 "const1_operand" "")
10077 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10080 (const_string "*")))
10081 (set_attr "mode" "SI")])
10083 (define_insn "*<rotate_insn>qi3_1_slp"
10084 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10085 (any_rotate:QI (match_dup 0)
10086 (match_operand:QI 1 "nonmemory_operand" "cI")))
10087 (clobber (reg:CC FLAGS_REG))]
10088 "(optimize_function_for_size_p (cfun)
10089 || !TARGET_PARTIAL_REG_STALL
10090 || (operands[1] == const1_rtx
10091 && TARGET_SHIFT1))"
10093 if (operands[1] == const1_rtx
10094 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10095 return "<rotate>{b}\t%0";
10097 return "<rotate>{b}\t{%1, %0|%0, %1}";
10099 [(set_attr "type" "rotate1")
10100 (set (attr "length_immediate")
10102 (and (match_operand 1 "const1_operand" "")
10103 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10106 (const_string "*")))
10107 (set_attr "mode" "QI")])
10110 [(set (match_operand:HI 0 "register_operand" "")
10111 (any_rotate:HI (match_dup 0) (const_int 8)))
10112 (clobber (reg:CC FLAGS_REG))]
10114 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10115 [(parallel [(set (strict_low_part (match_dup 0))
10116 (bswap:HI (match_dup 0)))
10117 (clobber (reg:CC FLAGS_REG))])])
10119 ;; Bit set / bit test instructions
10121 (define_expand "extv"
10122 [(set (match_operand:SI 0 "register_operand" "")
10123 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10124 (match_operand:SI 2 "const8_operand" "")
10125 (match_operand:SI 3 "const8_operand" "")))]
10128 /* Handle extractions from %ah et al. */
10129 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10132 /* From mips.md: extract_bit_field doesn't verify that our source
10133 matches the predicate, so check it again here. */
10134 if (! ext_register_operand (operands[1], VOIDmode))
10138 (define_expand "extzv"
10139 [(set (match_operand:SI 0 "register_operand" "")
10140 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10141 (match_operand:SI 2 "const8_operand" "")
10142 (match_operand:SI 3 "const8_operand" "")))]
10145 /* Handle extractions from %ah et al. */
10146 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10149 /* From mips.md: extract_bit_field doesn't verify that our source
10150 matches the predicate, so check it again here. */
10151 if (! ext_register_operand (operands[1], VOIDmode))
10155 (define_expand "insv"
10156 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
10157 (match_operand 1 "const8_operand" "")
10158 (match_operand 2 "const8_operand" ""))
10159 (match_operand 3 "register_operand" ""))]
10162 rtx (*gen_mov_insv_1) (rtx, rtx);
10164 /* Handle insertions to %ah et al. */
10165 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10168 /* From mips.md: insert_bit_field doesn't verify that our source
10169 matches the predicate, so check it again here. */
10170 if (! ext_register_operand (operands[0], VOIDmode))
10173 gen_mov_insv_1 = (TARGET_64BIT
10174 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10176 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10180 ;; %%% bts, btr, btc, bt.
10181 ;; In general these instructions are *slow* when applied to memory,
10182 ;; since they enforce atomic operation. When applied to registers,
10183 ;; it depends on the cpu implementation. They're never faster than
10184 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10185 ;; no point. But in 64-bit, we can't hold the relevant immediates
10186 ;; within the instruction itself, so operating on bits in the high
10187 ;; 32-bits of a register becomes easier.
10189 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10190 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10191 ;; negdf respectively, so they can never be disabled entirely.
10193 (define_insn "*btsq"
10194 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10196 (match_operand:DI 1 "const_0_to_63_operand" ""))
10198 (clobber (reg:CC FLAGS_REG))]
10199 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10200 "bts{q}\t{%1, %0|%0, %1}"
10201 [(set_attr "type" "alu1")
10202 (set_attr "prefix_0f" "1")
10203 (set_attr "mode" "DI")])
10205 (define_insn "*btrq"
10206 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10208 (match_operand:DI 1 "const_0_to_63_operand" ""))
10210 (clobber (reg:CC FLAGS_REG))]
10211 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10212 "btr{q}\t{%1, %0|%0, %1}"
10213 [(set_attr "type" "alu1")
10214 (set_attr "prefix_0f" "1")
10215 (set_attr "mode" "DI")])
10217 (define_insn "*btcq"
10218 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10220 (match_operand:DI 1 "const_0_to_63_operand" ""))
10221 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10222 (clobber (reg:CC FLAGS_REG))]
10223 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10224 "btc{q}\t{%1, %0|%0, %1}"
10225 [(set_attr "type" "alu1")
10226 (set_attr "prefix_0f" "1")
10227 (set_attr "mode" "DI")])
10229 ;; Allow Nocona to avoid these instructions if a register is available.
10232 [(match_scratch:DI 2 "r")
10233 (parallel [(set (zero_extract:DI
10234 (match_operand:DI 0 "register_operand" "")
10236 (match_operand:DI 1 "const_0_to_63_operand" ""))
10238 (clobber (reg:CC FLAGS_REG))])]
10239 "TARGET_64BIT && !TARGET_USE_BT"
10242 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10245 if (HOST_BITS_PER_WIDE_INT >= 64)
10246 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10247 else if (i < HOST_BITS_PER_WIDE_INT)
10248 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10250 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10252 op1 = immed_double_const (lo, hi, DImode);
10255 emit_move_insn (operands[2], op1);
10259 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10264 [(match_scratch:DI 2 "r")
10265 (parallel [(set (zero_extract:DI
10266 (match_operand:DI 0 "register_operand" "")
10268 (match_operand:DI 1 "const_0_to_63_operand" ""))
10270 (clobber (reg:CC FLAGS_REG))])]
10271 "TARGET_64BIT && !TARGET_USE_BT"
10274 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10277 if (HOST_BITS_PER_WIDE_INT >= 64)
10278 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10279 else if (i < HOST_BITS_PER_WIDE_INT)
10280 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10282 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10284 op1 = immed_double_const (~lo, ~hi, DImode);
10287 emit_move_insn (operands[2], op1);
10291 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10296 [(match_scratch:DI 2 "r")
10297 (parallel [(set (zero_extract:DI
10298 (match_operand:DI 0 "register_operand" "")
10300 (match_operand:DI 1 "const_0_to_63_operand" ""))
10301 (not:DI (zero_extract:DI
10302 (match_dup 0) (const_int 1) (match_dup 1))))
10303 (clobber (reg:CC FLAGS_REG))])]
10304 "TARGET_64BIT && !TARGET_USE_BT"
10307 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10310 if (HOST_BITS_PER_WIDE_INT >= 64)
10311 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10312 else if (i < HOST_BITS_PER_WIDE_INT)
10313 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10315 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10317 op1 = immed_double_const (lo, hi, DImode);
10320 emit_move_insn (operands[2], op1);
10324 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10328 (define_insn "*bt<mode>"
10329 [(set (reg:CCC FLAGS_REG)
10331 (zero_extract:SWI48
10332 (match_operand:SWI48 0 "register_operand" "r")
10334 (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10336 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10337 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10338 [(set_attr "type" "alu1")
10339 (set_attr "prefix_0f" "1")
10340 (set_attr "mode" "<MODE>")])
10342 ;; Store-flag instructions.
10344 ;; For all sCOND expanders, also expand the compare or test insn that
10345 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10347 (define_insn_and_split "*setcc_di_1"
10348 [(set (match_operand:DI 0 "register_operand" "=q")
10349 (match_operator:DI 1 "ix86_comparison_operator"
10350 [(reg FLAGS_REG) (const_int 0)]))]
10351 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10353 "&& reload_completed"
10354 [(set (match_dup 2) (match_dup 1))
10355 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10357 PUT_MODE (operands[1], QImode);
10358 operands[2] = gen_lowpart (QImode, operands[0]);
10361 (define_insn_and_split "*setcc_si_1_and"
10362 [(set (match_operand:SI 0 "register_operand" "=q")
10363 (match_operator:SI 1 "ix86_comparison_operator"
10364 [(reg FLAGS_REG) (const_int 0)]))
10365 (clobber (reg:CC FLAGS_REG))]
10366 "!TARGET_PARTIAL_REG_STALL
10367 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10369 "&& reload_completed"
10370 [(set (match_dup 2) (match_dup 1))
10371 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10372 (clobber (reg:CC FLAGS_REG))])]
10374 PUT_MODE (operands[1], QImode);
10375 operands[2] = gen_lowpart (QImode, operands[0]);
10378 (define_insn_and_split "*setcc_si_1_movzbl"
10379 [(set (match_operand:SI 0 "register_operand" "=q")
10380 (match_operator:SI 1 "ix86_comparison_operator"
10381 [(reg FLAGS_REG) (const_int 0)]))]
10382 "!TARGET_PARTIAL_REG_STALL
10383 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10385 "&& reload_completed"
10386 [(set (match_dup 2) (match_dup 1))
10387 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10389 PUT_MODE (operands[1], QImode);
10390 operands[2] = gen_lowpart (QImode, operands[0]);
10393 (define_insn "*setcc_qi"
10394 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10395 (match_operator:QI 1 "ix86_comparison_operator"
10396 [(reg FLAGS_REG) (const_int 0)]))]
10399 [(set_attr "type" "setcc")
10400 (set_attr "mode" "QI")])
10402 (define_insn "*setcc_qi_slp"
10403 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10404 (match_operator:QI 1 "ix86_comparison_operator"
10405 [(reg FLAGS_REG) (const_int 0)]))]
10408 [(set_attr "type" "setcc")
10409 (set_attr "mode" "QI")])
10411 ;; In general it is not safe to assume too much about CCmode registers,
10412 ;; so simplify-rtx stops when it sees a second one. Under certain
10413 ;; conditions this is safe on x86, so help combine not create
10420 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10421 (ne:QI (match_operator 1 "ix86_comparison_operator"
10422 [(reg FLAGS_REG) (const_int 0)])
10425 [(set (match_dup 0) (match_dup 1))]
10426 "PUT_MODE (operands[1], QImode);")
10429 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10430 (ne:QI (match_operator 1 "ix86_comparison_operator"
10431 [(reg FLAGS_REG) (const_int 0)])
10434 [(set (match_dup 0) (match_dup 1))]
10435 "PUT_MODE (operands[1], QImode);")
10438 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10439 (eq:QI (match_operator 1 "ix86_comparison_operator"
10440 [(reg FLAGS_REG) (const_int 0)])
10443 [(set (match_dup 0) (match_dup 1))]
10445 rtx new_op1 = copy_rtx (operands[1]);
10446 operands[1] = new_op1;
10447 PUT_MODE (new_op1, QImode);
10448 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10449 GET_MODE (XEXP (new_op1, 0))));
10451 /* Make sure that (a) the CCmode we have for the flags is strong
10452 enough for the reversed compare or (b) we have a valid FP compare. */
10453 if (! ix86_comparison_operator (new_op1, VOIDmode))
10458 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10459 (eq:QI (match_operator 1 "ix86_comparison_operator"
10460 [(reg FLAGS_REG) (const_int 0)])
10463 [(set (match_dup 0) (match_dup 1))]
10465 rtx new_op1 = copy_rtx (operands[1]);
10466 operands[1] = new_op1;
10467 PUT_MODE (new_op1, QImode);
10468 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10469 GET_MODE (XEXP (new_op1, 0))));
10471 /* Make sure that (a) the CCmode we have for the flags is strong
10472 enough for the reversed compare or (b) we have a valid FP compare. */
10473 if (! ix86_comparison_operator (new_op1, VOIDmode))
10477 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10478 ;; subsequent logical operations are used to imitate conditional moves.
10479 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10482 (define_insn "*avx_setcc<mode>"
10483 [(set (match_operand:MODEF 0 "register_operand" "=x")
10484 (match_operator:MODEF 1 "avx_comparison_float_operator"
10485 [(match_operand:MODEF 2 "register_operand" "x")
10486 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10488 "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
10489 [(set_attr "type" "ssecmp")
10490 (set_attr "prefix" "vex")
10491 (set_attr "length_immediate" "1")
10492 (set_attr "mode" "<MODE>")])
10494 (define_insn "*sse_setcc<mode>"
10495 [(set (match_operand:MODEF 0 "register_operand" "=x")
10496 (match_operator:MODEF 1 "sse_comparison_operator"
10497 [(match_operand:MODEF 2 "register_operand" "0")
10498 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10499 "SSE_FLOAT_MODE_P (<MODE>mode)"
10500 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
10501 [(set_attr "type" "ssecmp")
10502 (set_attr "length_immediate" "1")
10503 (set_attr "mode" "<MODE>")])
10505 ;; Basic conditional jump instructions.
10506 ;; We ignore the overflow flag for signed branch instructions.
10508 (define_insn "*jcc_1"
10510 (if_then_else (match_operator 1 "ix86_comparison_operator"
10511 [(reg FLAGS_REG) (const_int 0)])
10512 (label_ref (match_operand 0 "" ""))
10516 [(set_attr "type" "ibr")
10517 (set_attr "modrm" "0")
10518 (set (attr "length")
10519 (if_then_else (and (ge (minus (match_dup 0) (pc))
10521 (lt (minus (match_dup 0) (pc))
10526 (define_insn "*jcc_2"
10528 (if_then_else (match_operator 1 "ix86_comparison_operator"
10529 [(reg FLAGS_REG) (const_int 0)])
10531 (label_ref (match_operand 0 "" ""))))]
10534 [(set_attr "type" "ibr")
10535 (set_attr "modrm" "0")
10536 (set (attr "length")
10537 (if_then_else (and (ge (minus (match_dup 0) (pc))
10539 (lt (minus (match_dup 0) (pc))
10544 ;; In general it is not safe to assume too much about CCmode registers,
10545 ;; so simplify-rtx stops when it sees a second one. Under certain
10546 ;; conditions this is safe on x86, so help combine not create
10554 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10555 [(reg FLAGS_REG) (const_int 0)])
10557 (label_ref (match_operand 1 "" ""))
10561 (if_then_else (match_dup 0)
10562 (label_ref (match_dup 1))
10564 "PUT_MODE (operands[0], VOIDmode);")
10568 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10569 [(reg FLAGS_REG) (const_int 0)])
10571 (label_ref (match_operand 1 "" ""))
10575 (if_then_else (match_dup 0)
10576 (label_ref (match_dup 1))
10579 rtx new_op0 = copy_rtx (operands[0]);
10580 operands[0] = new_op0;
10581 PUT_MODE (new_op0, VOIDmode);
10582 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10583 GET_MODE (XEXP (new_op0, 0))));
10585 /* Make sure that (a) the CCmode we have for the flags is strong
10586 enough for the reversed compare or (b) we have a valid FP compare. */
10587 if (! ix86_comparison_operator (new_op0, VOIDmode))
10591 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10592 ;; pass generates from shift insn with QImode operand. Actually, the mode
10593 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10594 ;; appropriate modulo of the bit offset value.
10596 (define_insn_and_split "*jcc_bt<mode>"
10598 (if_then_else (match_operator 0 "bt_comparison_operator"
10599 [(zero_extract:SWI48
10600 (match_operand:SWI48 1 "register_operand" "r")
10603 (match_operand:QI 2 "register_operand" "r")))
10605 (label_ref (match_operand 3 "" ""))
10607 (clobber (reg:CC FLAGS_REG))]
10608 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10611 [(set (reg:CCC FLAGS_REG)
10613 (zero_extract:SWI48
10619 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10620 (label_ref (match_dup 3))
10623 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10625 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10628 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10629 ;; also for DImode, this is what combine produces.
10630 (define_insn_and_split "*jcc_bt<mode>_mask"
10632 (if_then_else (match_operator 0 "bt_comparison_operator"
10633 [(zero_extract:SWI48
10634 (match_operand:SWI48 1 "register_operand" "r")
10637 (match_operand:SI 2 "register_operand" "r")
10638 (match_operand:SI 3 "const_int_operand" "n")))])
10639 (label_ref (match_operand 4 "" ""))
10641 (clobber (reg:CC FLAGS_REG))]
10642 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10643 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10644 == GET_MODE_BITSIZE (<MODE>mode)-1"
10647 [(set (reg:CCC FLAGS_REG)
10649 (zero_extract:SWI48
10655 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10656 (label_ref (match_dup 4))
10659 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10661 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10664 (define_insn_and_split "*jcc_btsi_1"
10666 (if_then_else (match_operator 0 "bt_comparison_operator"
10669 (match_operand:SI 1 "register_operand" "r")
10670 (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)
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 (SImode, operands[2], QImode, 0);
10693 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10696 ;; avoid useless masking of bit offset operand
10697 (define_insn_and_split "*jcc_btsi_mask_1"
10700 (match_operator 0 "bt_comparison_operator"
10703 (match_operand:SI 1 "register_operand" "r")
10706 (match_operand:SI 2 "register_operand" "r")
10707 (match_operand:SI 3 "const_int_operand" "n")) 0))
10710 (label_ref (match_operand 4 "" ""))
10712 (clobber (reg:CC FLAGS_REG))]
10713 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10714 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10717 [(set (reg:CCC FLAGS_REG)
10725 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10726 (label_ref (match_dup 4))
10728 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10730 ;; Define combination compare-and-branch fp compare instructions to help
10733 (define_insn "*fp_jcc_1_387"
10735 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10736 [(match_operand 1 "register_operand" "f")
10737 (match_operand 2 "nonimmediate_operand" "fm")])
10738 (label_ref (match_operand 3 "" ""))
10740 (clobber (reg:CCFP FPSR_REG))
10741 (clobber (reg:CCFP FLAGS_REG))
10742 (clobber (match_scratch:HI 4 "=a"))]
10744 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10745 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10746 && SELECT_CC_MODE (GET_CODE (operands[0]),
10747 operands[1], operands[2]) == CCFPmode
10751 (define_insn "*fp_jcc_1r_387"
10753 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10754 [(match_operand 1 "register_operand" "f")
10755 (match_operand 2 "nonimmediate_operand" "fm")])
10757 (label_ref (match_operand 3 "" ""))))
10758 (clobber (reg:CCFP FPSR_REG))
10759 (clobber (reg:CCFP FLAGS_REG))
10760 (clobber (match_scratch:HI 4 "=a"))]
10762 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10763 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10764 && SELECT_CC_MODE (GET_CODE (operands[0]),
10765 operands[1], operands[2]) == CCFPmode
10769 (define_insn "*fp_jcc_2_387"
10771 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10772 [(match_operand 1 "register_operand" "f")
10773 (match_operand 2 "register_operand" "f")])
10774 (label_ref (match_operand 3 "" ""))
10776 (clobber (reg:CCFP FPSR_REG))
10777 (clobber (reg:CCFP FLAGS_REG))
10778 (clobber (match_scratch:HI 4 "=a"))]
10779 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10780 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10784 (define_insn "*fp_jcc_2r_387"
10786 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10787 [(match_operand 1 "register_operand" "f")
10788 (match_operand 2 "register_operand" "f")])
10790 (label_ref (match_operand 3 "" ""))))
10791 (clobber (reg:CCFP FPSR_REG))
10792 (clobber (reg:CCFP FLAGS_REG))
10793 (clobber (match_scratch:HI 4 "=a"))]
10794 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10795 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10799 (define_insn "*fp_jcc_3_387"
10801 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10802 [(match_operand 1 "register_operand" "f")
10803 (match_operand 2 "const0_operand" "")])
10804 (label_ref (match_operand 3 "" ""))
10806 (clobber (reg:CCFP FPSR_REG))
10807 (clobber (reg:CCFP FLAGS_REG))
10808 (clobber (match_scratch:HI 4 "=a"))]
10809 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10810 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10811 && SELECT_CC_MODE (GET_CODE (operands[0]),
10812 operands[1], operands[2]) == CCFPmode
10818 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10819 [(match_operand 1 "register_operand" "")
10820 (match_operand 2 "nonimmediate_operand" "")])
10821 (match_operand 3 "" "")
10822 (match_operand 4 "" "")))
10823 (clobber (reg:CCFP FPSR_REG))
10824 (clobber (reg:CCFP FLAGS_REG))]
10828 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10829 operands[3], operands[4], NULL_RTX, NULL_RTX);
10835 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10836 [(match_operand 1 "register_operand" "")
10837 (match_operand 2 "general_operand" "")])
10838 (match_operand 3 "" "")
10839 (match_operand 4 "" "")))
10840 (clobber (reg:CCFP FPSR_REG))
10841 (clobber (reg:CCFP FLAGS_REG))
10842 (clobber (match_scratch:HI 5 "=a"))]
10846 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10847 operands[3], operands[4], operands[5], NULL_RTX);
10851 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
10852 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
10853 ;; with a precedence over other operators and is always put in the first
10854 ;; place. Swap condition and operands to match ficom instruction.
10856 (define_insn "*fp_jcc_4_<mode>_387"
10859 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10860 [(match_operator 1 "float_operator"
10861 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
10862 (match_operand 3 "register_operand" "f,f")])
10863 (label_ref (match_operand 4 "" ""))
10865 (clobber (reg:CCFP FPSR_REG))
10866 (clobber (reg:CCFP FLAGS_REG))
10867 (clobber (match_scratch:HI 5 "=a,a"))]
10868 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
10869 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
10870 && GET_MODE (operands[1]) == GET_MODE (operands[3])
10871 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
10878 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10879 [(match_operator 1 "float_operator"
10880 [(match_operand:X87MODEI12 2 "memory_operand" "")])
10881 (match_operand 3 "register_operand" "")])
10882 (match_operand 4 "" "")
10883 (match_operand 5 "" "")))
10884 (clobber (reg:CCFP FPSR_REG))
10885 (clobber (reg:CCFP FLAGS_REG))
10886 (clobber (match_scratch:HI 6 "=a"))]
10890 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
10892 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10893 operands[3], operands[7],
10894 operands[4], operands[5], operands[6], NULL_RTX);
10898 ;; %%% Kill this when reload knows how to do it.
10902 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10903 [(match_operator 1 "float_operator"
10904 [(match_operand:X87MODEI12 2 "register_operand" "")])
10905 (match_operand 3 "register_operand" "")])
10906 (match_operand 4 "" "")
10907 (match_operand 5 "" "")))
10908 (clobber (reg:CCFP FPSR_REG))
10909 (clobber (reg:CCFP FLAGS_REG))
10910 (clobber (match_scratch:HI 6 "=a"))]
10914 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
10915 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
10917 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10918 operands[3], operands[7],
10919 operands[4], operands[5], operands[6], operands[2]);
10923 ;; Unconditional and other jump instructions
10925 (define_insn "jump"
10927 (label_ref (match_operand 0 "" "")))]
10930 [(set_attr "type" "ibr")
10931 (set (attr "length")
10932 (if_then_else (and (ge (minus (match_dup 0) (pc))
10934 (lt (minus (match_dup 0) (pc))
10938 (set_attr "modrm" "0")])
10940 (define_expand "indirect_jump"
10941 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
10945 (define_insn "*indirect_jump"
10946 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
10949 [(set_attr "type" "ibr")
10950 (set_attr "length_immediate" "0")])
10952 (define_expand "tablejump"
10953 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
10954 (use (label_ref (match_operand 1 "" "")))])]
10957 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
10958 relative. Convert the relative address to an absolute address. */
10962 enum rtx_code code;
10964 /* We can't use @GOTOFF for text labels on VxWorks;
10965 see gotoff_operand. */
10966 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
10970 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
10972 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
10976 op1 = pic_offset_table_rtx;
10981 op0 = pic_offset_table_rtx;
10985 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
10990 (define_insn "*tablejump_1"
10991 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
10992 (use (label_ref (match_operand 1 "" "")))]
10995 [(set_attr "type" "ibr")
10996 (set_attr "length_immediate" "0")])
10998 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11001 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11002 (set (match_operand:QI 1 "register_operand" "")
11003 (match_operator:QI 2 "ix86_comparison_operator"
11004 [(reg FLAGS_REG) (const_int 0)]))
11005 (set (match_operand 3 "q_regs_operand" "")
11006 (zero_extend (match_dup 1)))]
11007 "(peep2_reg_dead_p (3, operands[1])
11008 || operands_match_p (operands[1], operands[3]))
11009 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11010 [(set (match_dup 4) (match_dup 0))
11011 (set (strict_low_part (match_dup 5))
11014 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11015 operands[5] = gen_lowpart (QImode, operands[3]);
11016 ix86_expand_clear (operands[3]);
11019 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11022 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11023 (set (match_operand:QI 1 "register_operand" "")
11024 (match_operator:QI 2 "ix86_comparison_operator"
11025 [(reg FLAGS_REG) (const_int 0)]))
11026 (parallel [(set (match_operand 3 "q_regs_operand" "")
11027 (zero_extend (match_dup 1)))
11028 (clobber (reg:CC FLAGS_REG))])]
11029 "(peep2_reg_dead_p (3, operands[1])
11030 || operands_match_p (operands[1], operands[3]))
11031 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11032 [(set (match_dup 4) (match_dup 0))
11033 (set (strict_low_part (match_dup 5))
11036 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11037 operands[5] = gen_lowpart (QImode, operands[3]);
11038 ix86_expand_clear (operands[3]);
11041 ;; Call instructions.
11043 ;; The predicates normally associated with named expanders are not properly
11044 ;; checked for calls. This is a bug in the generic code, but it isn't that
11045 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11047 ;; P6 processors will jump to the address after the decrement when %esp
11048 ;; is used as a call operand, so they will execute return address as a code.
11049 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11051 ;; Call subroutine returning no value.
11053 (define_expand "call_pop"
11054 [(parallel [(call (match_operand:QI 0 "" "")
11055 (match_operand:SI 1 "" ""))
11056 (set (reg:SI SP_REG)
11057 (plus:SI (reg:SI SP_REG)
11058 (match_operand:SI 3 "" "")))])]
11061 ix86_expand_call (NULL, operands[0], operands[1],
11062 operands[2], operands[3], 0);
11066 (define_insn "*call_pop_0"
11067 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11068 (match_operand:SI 1 "" ""))
11069 (set (reg:SI SP_REG)
11070 (plus:SI (reg:SI SP_REG)
11071 (match_operand:SI 2 "immediate_operand" "")))]
11074 if (SIBLING_CALL_P (insn))
11077 return "call\t%P0";
11079 [(set_attr "type" "call")])
11081 (define_insn "*call_pop_1"
11082 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11083 (match_operand:SI 1 "" ""))
11084 (set (reg:SI SP_REG)
11085 (plus:SI (reg:SI SP_REG)
11086 (match_operand:SI 2 "immediate_operand" "i")))]
11087 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11089 if (constant_call_address_operand (operands[0], Pmode))
11090 return "call\t%P0";
11091 return "call\t%A0";
11093 [(set_attr "type" "call")])
11095 (define_insn "*sibcall_pop_1"
11096 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11097 (match_operand:SI 1 "" ""))
11098 (set (reg:SI SP_REG)
11099 (plus:SI (reg:SI SP_REG)
11100 (match_operand:SI 2 "immediate_operand" "i,i")))]
11101 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11105 [(set_attr "type" "call")])
11107 (define_expand "call"
11108 [(call (match_operand:QI 0 "" "")
11109 (match_operand 1 "" ""))
11110 (use (match_operand 2 "" ""))]
11113 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
11117 (define_expand "sibcall"
11118 [(call (match_operand:QI 0 "" "")
11119 (match_operand 1 "" ""))
11120 (use (match_operand 2 "" ""))]
11123 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
11127 (define_insn "*call_0"
11128 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11129 (match_operand 1 "" ""))]
11132 if (SIBLING_CALL_P (insn))
11135 return "call\t%P0";
11137 [(set_attr "type" "call")])
11139 (define_insn "*call_1"
11140 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11141 (match_operand 1 "" ""))]
11142 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11144 if (constant_call_address_operand (operands[0], Pmode))
11145 return "call\t%P0";
11146 return "call\t%A0";
11148 [(set_attr "type" "call")])
11150 (define_insn "*sibcall_1"
11151 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11152 (match_operand 1 "" ""))]
11153 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11157 [(set_attr "type" "call")])
11159 (define_insn "*call_1_rex64"
11160 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11161 (match_operand 1 "" ""))]
11162 "TARGET_64BIT && !SIBLING_CALL_P (insn)
11163 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11165 if (constant_call_address_operand (operands[0], Pmode))
11166 return "call\t%P0";
11167 return "call\t%A0";
11169 [(set_attr "type" "call")])
11171 (define_insn "*call_1_rex64_ms_sysv"
11172 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11173 (match_operand 1 "" ""))
11174 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11175 (clobber (reg:TI XMM6_REG))
11176 (clobber (reg:TI XMM7_REG))
11177 (clobber (reg:TI XMM8_REG))
11178 (clobber (reg:TI XMM9_REG))
11179 (clobber (reg:TI XMM10_REG))
11180 (clobber (reg:TI XMM11_REG))
11181 (clobber (reg:TI XMM12_REG))
11182 (clobber (reg:TI XMM13_REG))
11183 (clobber (reg:TI XMM14_REG))
11184 (clobber (reg:TI XMM15_REG))
11185 (clobber (reg:DI SI_REG))
11186 (clobber (reg:DI DI_REG))]
11187 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11189 if (constant_call_address_operand (operands[0], Pmode))
11190 return "call\t%P0";
11191 return "call\t%A0";
11193 [(set_attr "type" "call")])
11195 (define_insn "*call_1_rex64_large"
11196 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11197 (match_operand 1 "" ""))]
11198 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11200 [(set_attr "type" "call")])
11202 (define_insn "*sibcall_1_rex64"
11203 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11204 (match_operand 1 "" ""))]
11205 "TARGET_64BIT && SIBLING_CALL_P (insn)"
11209 [(set_attr "type" "call")])
11211 ;; Call subroutine, returning value in operand 0
11212 (define_expand "call_value_pop"
11213 [(parallel [(set (match_operand 0 "" "")
11214 (call (match_operand:QI 1 "" "")
11215 (match_operand:SI 2 "" "")))
11216 (set (reg:SI SP_REG)
11217 (plus:SI (reg:SI SP_REG)
11218 (match_operand:SI 4 "" "")))])]
11221 ix86_expand_call (operands[0], operands[1], operands[2],
11222 operands[3], operands[4], 0);
11226 (define_expand "call_value"
11227 [(set (match_operand 0 "" "")
11228 (call (match_operand:QI 1 "" "")
11229 (match_operand:SI 2 "" "")))
11230 (use (match_operand:SI 3 "" ""))]
11231 ;; Operand 3 is not used on the i386.
11234 ix86_expand_call (operands[0], operands[1], operands[2],
11235 operands[3], NULL, 0);
11239 (define_expand "sibcall_value"
11240 [(set (match_operand 0 "" "")
11241 (call (match_operand:QI 1 "" "")
11242 (match_operand:SI 2 "" "")))
11243 (use (match_operand:SI 3 "" ""))]
11244 ;; Operand 3 is not used on the i386.
11247 ix86_expand_call (operands[0], operands[1], operands[2],
11248 operands[3], NULL, 1);
11252 ;; Call subroutine returning any type.
11254 (define_expand "untyped_call"
11255 [(parallel [(call (match_operand 0 "" "")
11257 (match_operand 1 "" "")
11258 (match_operand 2 "" "")])]
11263 /* In order to give reg-stack an easier job in validating two
11264 coprocessor registers as containing a possible return value,
11265 simply pretend the untyped call returns a complex long double
11268 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11269 and should have the default ABI. */
11271 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11272 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11273 operands[0], const0_rtx,
11274 GEN_INT ((TARGET_64BIT
11275 ? (ix86_abi == SYSV_ABI
11276 ? X86_64_SSE_REGPARM_MAX
11277 : X86_64_MS_SSE_REGPARM_MAX)
11278 : X86_32_SSE_REGPARM_MAX)
11282 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11284 rtx set = XVECEXP (operands[2], 0, i);
11285 emit_move_insn (SET_DEST (set), SET_SRC (set));
11288 /* The optimizer does not know that the call sets the function value
11289 registers we stored in the result block. We avoid problems by
11290 claiming that all hard registers are used and clobbered at this
11292 emit_insn (gen_blockage ());
11297 ;; Prologue and epilogue instructions
11299 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11300 ;; all of memory. This blocks insns from being moved across this point.
11302 (define_insn "blockage"
11303 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11306 [(set_attr "length" "0")])
11308 ;; Do not schedule instructions accessing memory across this point.
11310 (define_expand "memory_blockage"
11311 [(set (match_dup 0)
11312 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11315 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11316 MEM_VOLATILE_P (operands[0]) = 1;
11319 (define_insn "*memory_blockage"
11320 [(set (match_operand:BLK 0 "" "")
11321 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11324 [(set_attr "length" "0")])
11326 ;; As USE insns aren't meaningful after reload, this is used instead
11327 ;; to prevent deleting instructions setting registers for PIC code
11328 (define_insn "prologue_use"
11329 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11332 [(set_attr "length" "0")])
11334 ;; Insn emitted into the body of a function to return from a function.
11335 ;; This is only done if the function's epilogue is known to be simple.
11336 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11338 (define_expand "return"
11340 "ix86_can_use_return_insn_p ()"
11342 if (crtl->args.pops_args)
11344 rtx popc = GEN_INT (crtl->args.pops_args);
11345 emit_jump_insn (gen_return_pop_internal (popc));
11350 (define_insn "return_internal"
11354 [(set_attr "length" "1")
11355 (set_attr "atom_unit" "jeu")
11356 (set_attr "length_immediate" "0")
11357 (set_attr "modrm" "0")])
11359 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11360 ;; instruction Athlon and K8 have.
11362 (define_insn "return_internal_long"
11364 (unspec [(const_int 0)] UNSPEC_REP)]
11367 [(set_attr "length" "2")
11368 (set_attr "atom_unit" "jeu")
11369 (set_attr "length_immediate" "0")
11370 (set_attr "prefix_rep" "1")
11371 (set_attr "modrm" "0")])
11373 (define_insn "return_pop_internal"
11375 (use (match_operand:SI 0 "const_int_operand" ""))]
11378 [(set_attr "length" "3")
11379 (set_attr "atom_unit" "jeu")
11380 (set_attr "length_immediate" "2")
11381 (set_attr "modrm" "0")])
11383 (define_insn "return_indirect_internal"
11385 (use (match_operand:SI 0 "register_operand" "r"))]
11388 [(set_attr "type" "ibr")
11389 (set_attr "length_immediate" "0")])
11395 [(set_attr "length" "1")
11396 (set_attr "length_immediate" "0")
11397 (set_attr "modrm" "0")])
11399 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11400 ;; branch prediction penalty for the third jump in a 16-byte
11404 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11407 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11408 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11410 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11411 The align insn is used to avoid 3 jump instructions in the row to improve
11412 branch prediction and the benefits hardly outweigh the cost of extra 8
11413 nops on the average inserted by full alignment pseudo operation. */
11417 [(set_attr "length" "16")])
11419 (define_expand "prologue"
11422 "ix86_expand_prologue (); DONE;")
11424 (define_insn "set_got"
11425 [(set (match_operand:SI 0 "register_operand" "=r")
11426 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11427 (clobber (reg:CC FLAGS_REG))]
11429 { return output_set_got (operands[0], NULL_RTX); }
11430 [(set_attr "type" "multi")
11431 (set_attr "length" "12")])
11433 (define_insn "set_got_labelled"
11434 [(set (match_operand:SI 0 "register_operand" "=r")
11435 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11437 (clobber (reg:CC FLAGS_REG))]
11439 { return output_set_got (operands[0], operands[1]); }
11440 [(set_attr "type" "multi")
11441 (set_attr "length" "12")])
11443 (define_insn "set_got_rex64"
11444 [(set (match_operand:DI 0 "register_operand" "=r")
11445 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11447 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11448 [(set_attr "type" "lea")
11449 (set_attr "length_address" "4")
11450 (set_attr "mode" "DI")])
11452 (define_insn "set_rip_rex64"
11453 [(set (match_operand:DI 0 "register_operand" "=r")
11454 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11456 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11457 [(set_attr "type" "lea")
11458 (set_attr "length_address" "4")
11459 (set_attr "mode" "DI")])
11461 (define_insn "set_got_offset_rex64"
11462 [(set (match_operand:DI 0 "register_operand" "=r")
11464 [(label_ref (match_operand 1 "" ""))]
11465 UNSPEC_SET_GOT_OFFSET))]
11467 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11468 [(set_attr "type" "imov")
11469 (set_attr "length_immediate" "0")
11470 (set_attr "length_address" "8")
11471 (set_attr "mode" "DI")])
11473 (define_expand "epilogue"
11476 "ix86_expand_epilogue (1); DONE;")
11478 (define_expand "sibcall_epilogue"
11481 "ix86_expand_epilogue (0); DONE;")
11483 (define_expand "eh_return"
11484 [(use (match_operand 0 "register_operand" ""))]
11487 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11489 /* Tricky bit: we write the address of the handler to which we will
11490 be returning into someone else's stack frame, one word below the
11491 stack address we wish to restore. */
11492 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11493 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11494 tmp = gen_rtx_MEM (Pmode, tmp);
11495 emit_move_insn (tmp, ra);
11497 emit_jump_insn (gen_eh_return_internal ());
11502 (define_insn_and_split "eh_return_internal"
11506 "epilogue_completed"
11508 "ix86_expand_epilogue (2); DONE;")
11510 (define_insn "leave"
11511 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11512 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11513 (clobber (mem:BLK (scratch)))]
11516 [(set_attr "type" "leave")])
11518 (define_insn "leave_rex64"
11519 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11520 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11521 (clobber (mem:BLK (scratch)))]
11524 [(set_attr "type" "leave")])
11526 ;; Bit manipulation instructions.
11528 (define_expand "ffs<mode>2"
11529 [(set (match_dup 2) (const_int -1))
11530 (parallel [(set (reg:CCZ FLAGS_REG)
11532 (match_operand:SWI48 1 "nonimmediate_operand" "")
11534 (set (match_operand:SWI48 0 "register_operand" "")
11535 (ctz:SWI48 (match_dup 1)))])
11536 (set (match_dup 0) (if_then_else:SWI48
11537 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11540 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11541 (clobber (reg:CC FLAGS_REG))])]
11544 if (<MODE>mode == SImode && !TARGET_CMOVE)
11546 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11549 operands[2] = gen_reg_rtx (<MODE>mode);
11552 (define_insn_and_split "ffssi2_no_cmove"
11553 [(set (match_operand:SI 0 "register_operand" "=r")
11554 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11555 (clobber (match_scratch:SI 2 "=&q"))
11556 (clobber (reg:CC FLAGS_REG))]
11559 "&& reload_completed"
11560 [(parallel [(set (reg:CCZ FLAGS_REG)
11561 (compare:CCZ (match_dup 1) (const_int 0)))
11562 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11563 (set (strict_low_part (match_dup 3))
11564 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11565 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11566 (clobber (reg:CC FLAGS_REG))])
11567 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11568 (clobber (reg:CC FLAGS_REG))])
11569 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11570 (clobber (reg:CC FLAGS_REG))])]
11572 operands[3] = gen_lowpart (QImode, operands[2]);
11573 ix86_expand_clear (operands[2]);
11576 (define_insn "*ffs<mode>_1"
11577 [(set (reg:CCZ FLAGS_REG)
11578 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11580 (set (match_operand:SWI48 0 "register_operand" "=r")
11581 (ctz:SWI48 (match_dup 1)))]
11583 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11584 [(set_attr "type" "alu1")
11585 (set_attr "prefix_0f" "1")
11586 (set_attr "mode" "<MODE>")])
11588 (define_insn "ctz<mode>2"
11589 [(set (match_operand:SWI48 0 "register_operand" "=r")
11590 (ctz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
11591 (clobber (reg:CC FLAGS_REG))]
11593 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11594 [(set_attr "type" "alu1")
11595 (set_attr "prefix_0f" "1")
11596 (set_attr "mode" "<MODE>")])
11598 (define_expand "clz<mode>2"
11600 [(set (match_operand:SWI248 0 "register_operand" "")
11603 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
11604 (clobber (reg:CC FLAGS_REG))])
11606 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
11607 (clobber (reg:CC FLAGS_REG))])]
11612 emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
11615 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11618 (define_insn "clz<mode>2_abm"
11619 [(set (match_operand:SWI248 0 "register_operand" "=r")
11620 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11621 (clobber (reg:CC FLAGS_REG))]
11623 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11624 [(set_attr "prefix_rep" "1")
11625 (set_attr "type" "bitmanip")
11626 (set_attr "mode" "<MODE>")])
11628 (define_insn "bsr_rex64"
11629 [(set (match_operand:DI 0 "register_operand" "=r")
11630 (minus:DI (const_int 63)
11631 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
11632 (clobber (reg:CC FLAGS_REG))]
11634 "bsr{q}\t{%1, %0|%0, %1}"
11635 [(set_attr "type" "alu1")
11636 (set_attr "prefix_0f" "1")
11637 (set_attr "mode" "DI")])
11640 [(set (match_operand:SI 0 "register_operand" "=r")
11641 (minus:SI (const_int 31)
11642 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
11643 (clobber (reg:CC FLAGS_REG))]
11645 "bsr{l}\t{%1, %0|%0, %1}"
11646 [(set_attr "type" "alu1")
11647 (set_attr "prefix_0f" "1")
11648 (set_attr "mode" "SI")])
11650 (define_insn "*bsrhi"
11651 [(set (match_operand:HI 0 "register_operand" "=r")
11652 (minus:HI (const_int 15)
11653 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
11654 (clobber (reg:CC FLAGS_REG))]
11656 "bsr{w}\t{%1, %0|%0, %1}"
11657 [(set_attr "type" "alu1")
11658 (set_attr "prefix_0f" "1")
11659 (set_attr "mode" "HI")])
11661 (define_insn "popcount<mode>2"
11662 [(set (match_operand:SWI248 0 "register_operand" "=r")
11664 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11665 (clobber (reg:CC FLAGS_REG))]
11669 return "popcnt\t{%1, %0|%0, %1}";
11671 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11674 [(set_attr "prefix_rep" "1")
11675 (set_attr "type" "bitmanip")
11676 (set_attr "mode" "<MODE>")])
11678 (define_insn "*popcount<mode>2_cmp"
11679 [(set (reg FLAGS_REG)
11682 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
11684 (set (match_operand:SWI248 0 "register_operand" "=r")
11685 (popcount:SWI248 (match_dup 1)))]
11686 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
11689 return "popcnt\t{%1, %0|%0, %1}";
11691 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11694 [(set_attr "prefix_rep" "1")
11695 (set_attr "type" "bitmanip")
11696 (set_attr "mode" "<MODE>")])
11698 (define_insn "*popcountsi2_cmp_zext"
11699 [(set (reg FLAGS_REG)
11701 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
11703 (set (match_operand:DI 0 "register_operand" "=r")
11704 (zero_extend:DI(popcount:SI (match_dup 1))))]
11705 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
11708 return "popcnt\t{%1, %0|%0, %1}";
11710 return "popcnt{l}\t{%1, %0|%0, %1}";
11713 [(set_attr "prefix_rep" "1")
11714 (set_attr "type" "bitmanip")
11715 (set_attr "mode" "SI")])
11717 (define_expand "bswap<mode>2"
11718 [(set (match_operand:SWI48 0 "register_operand" "")
11719 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
11722 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
11724 rtx x = operands[0];
11726 emit_move_insn (x, operands[1]);
11727 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
11728 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
11729 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
11734 (define_insn "*bswap<mode>2_movbe"
11735 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
11736 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
11738 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11741 movbe\t{%1, %0|%0, %1}
11742 movbe\t{%1, %0|%0, %1}"
11743 [(set_attr "type" "bitmanip,imov,imov")
11744 (set_attr "modrm" "0,1,1")
11745 (set_attr "prefix_0f" "*,1,1")
11746 (set_attr "prefix_extra" "*,1,1")
11747 (set_attr "mode" "<MODE>")])
11749 (define_insn "*bswap<mode>2_1"
11750 [(set (match_operand:SWI48 0 "register_operand" "=r")
11751 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
11754 [(set_attr "type" "bitmanip")
11755 (set_attr "modrm" "0")
11756 (set_attr "mode" "<MODE>")])
11758 (define_insn "*bswaphi_lowpart_1"
11759 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
11760 (bswap:HI (match_dup 0)))
11761 (clobber (reg:CC FLAGS_REG))]
11762 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
11764 xchg{b}\t{%h0, %b0|%b0, %h0}
11765 rol{w}\t{$8, %0|%0, 8}"
11766 [(set_attr "length" "2,4")
11767 (set_attr "mode" "QI,HI")])
11769 (define_insn "bswaphi_lowpart"
11770 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
11771 (bswap:HI (match_dup 0)))
11772 (clobber (reg:CC FLAGS_REG))]
11774 "rol{w}\t{$8, %0|%0, 8}"
11775 [(set_attr "length" "4")
11776 (set_attr "mode" "HI")])
11778 (define_expand "paritydi2"
11779 [(set (match_operand:DI 0 "register_operand" "")
11780 (parity:DI (match_operand:DI 1 "register_operand" "")))]
11783 rtx scratch = gen_reg_rtx (QImode);
11786 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
11787 NULL_RTX, operands[1]));
11789 cond = gen_rtx_fmt_ee (ORDERED, QImode,
11790 gen_rtx_REG (CCmode, FLAGS_REG),
11792 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
11795 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
11798 rtx tmp = gen_reg_rtx (SImode);
11800 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
11801 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
11806 (define_expand "paritysi2"
11807 [(set (match_operand:SI 0 "register_operand" "")
11808 (parity:SI (match_operand:SI 1 "register_operand" "")))]
11811 rtx scratch = gen_reg_rtx (QImode);
11814 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
11816 cond = gen_rtx_fmt_ee (ORDERED, QImode,
11817 gen_rtx_REG (CCmode, FLAGS_REG),
11819 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
11821 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
11825 (define_insn_and_split "paritydi2_cmp"
11826 [(set (reg:CC FLAGS_REG)
11827 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
11829 (clobber (match_scratch:DI 0 "=r"))
11830 (clobber (match_scratch:SI 1 "=&r"))
11831 (clobber (match_scratch:HI 2 "=Q"))]
11834 "&& reload_completed"
11836 [(set (match_dup 1)
11837 (xor:SI (match_dup 1) (match_dup 4)))
11838 (clobber (reg:CC FLAGS_REG))])
11840 [(set (reg:CC FLAGS_REG)
11841 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
11842 (clobber (match_dup 1))
11843 (clobber (match_dup 2))])]
11845 operands[4] = gen_lowpart (SImode, operands[3]);
11849 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
11850 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
11853 operands[1] = gen_highpart (SImode, operands[3]);
11856 (define_insn_and_split "paritysi2_cmp"
11857 [(set (reg:CC FLAGS_REG)
11858 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
11860 (clobber (match_scratch:SI 0 "=r"))
11861 (clobber (match_scratch:HI 1 "=&Q"))]
11864 "&& reload_completed"
11866 [(set (match_dup 1)
11867 (xor:HI (match_dup 1) (match_dup 3)))
11868 (clobber (reg:CC FLAGS_REG))])
11870 [(set (reg:CC FLAGS_REG)
11871 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
11872 (clobber (match_dup 1))])]
11874 operands[3] = gen_lowpart (HImode, operands[2]);
11876 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
11877 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
11880 (define_insn "*parityhi2_cmp"
11881 [(set (reg:CC FLAGS_REG)
11882 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
11884 (clobber (match_scratch:HI 0 "=Q"))]
11886 "xor{b}\t{%h0, %b0|%b0, %h0}"
11887 [(set_attr "length" "2")
11888 (set_attr "mode" "HI")])
11890 ;; Thread-local storage patterns for ELF.
11892 ;; Note that these code sequences must appear exactly as shown
11893 ;; in order to allow linker relaxation.
11895 (define_insn "*tls_global_dynamic_32_gnu"
11896 [(set (match_operand:SI 0 "register_operand" "=a")
11897 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
11898 (match_operand:SI 2 "tls_symbolic_operand" "")
11899 (match_operand:SI 3 "call_insn_operand" "")]
11901 (clobber (match_scratch:SI 4 "=d"))
11902 (clobber (match_scratch:SI 5 "=c"))
11903 (clobber (reg:CC FLAGS_REG))]
11904 "!TARGET_64BIT && TARGET_GNU_TLS"
11905 "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
11906 [(set_attr "type" "multi")
11907 (set_attr "length" "12")])
11909 (define_expand "tls_global_dynamic_32"
11910 [(parallel [(set (match_operand:SI 0 "register_operand" "")
11913 (match_operand:SI 1 "tls_symbolic_operand" "")
11916 (clobber (match_scratch:SI 4 ""))
11917 (clobber (match_scratch:SI 5 ""))
11918 (clobber (reg:CC FLAGS_REG))])]
11922 operands[2] = pic_offset_table_rtx;
11925 operands[2] = gen_reg_rtx (Pmode);
11926 emit_insn (gen_set_got (operands[2]));
11928 if (TARGET_GNU2_TLS)
11930 emit_insn (gen_tls_dynamic_gnu2_32
11931 (operands[0], operands[1], operands[2]));
11934 operands[3] = ix86_tls_get_addr ();
11937 (define_insn "*tls_global_dynamic_64"
11938 [(set (match_operand:DI 0 "register_operand" "=a")
11939 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
11940 (match_operand:DI 3 "" "")))
11941 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
11944 { 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"; }
11945 [(set_attr "type" "multi")
11946 (set_attr "length" "16")])
11948 (define_expand "tls_global_dynamic_64"
11949 [(parallel [(set (match_operand:DI 0 "register_operand" "")
11950 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
11951 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
11955 if (TARGET_GNU2_TLS)
11957 emit_insn (gen_tls_dynamic_gnu2_64
11958 (operands[0], operands[1]));
11961 operands[2] = ix86_tls_get_addr ();
11964 (define_insn "*tls_local_dynamic_base_32_gnu"
11965 [(set (match_operand:SI 0 "register_operand" "=a")
11966 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
11967 (match_operand:SI 2 "call_insn_operand" "")]
11968 UNSPEC_TLS_LD_BASE))
11969 (clobber (match_scratch:SI 3 "=d"))
11970 (clobber (match_scratch:SI 4 "=c"))
11971 (clobber (reg:CC FLAGS_REG))]
11972 "!TARGET_64BIT && TARGET_GNU_TLS"
11973 "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
11974 [(set_attr "type" "multi")
11975 (set_attr "length" "11")])
11977 (define_expand "tls_local_dynamic_base_32"
11978 [(parallel [(set (match_operand:SI 0 "register_operand" "")
11979 (unspec:SI [(match_dup 1) (match_dup 2)]
11980 UNSPEC_TLS_LD_BASE))
11981 (clobber (match_scratch:SI 3 ""))
11982 (clobber (match_scratch:SI 4 ""))
11983 (clobber (reg:CC FLAGS_REG))])]
11987 operands[1] = pic_offset_table_rtx;
11990 operands[1] = gen_reg_rtx (Pmode);
11991 emit_insn (gen_set_got (operands[1]));
11993 if (TARGET_GNU2_TLS)
11995 emit_insn (gen_tls_dynamic_gnu2_32
11996 (operands[0], ix86_tls_module_base (), operands[1]));
11999 operands[2] = ix86_tls_get_addr ();
12002 (define_insn "*tls_local_dynamic_base_64"
12003 [(set (match_operand:DI 0 "register_operand" "=a")
12004 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
12005 (match_operand:DI 2 "" "")))
12006 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12008 "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
12009 [(set_attr "type" "multi")
12010 (set_attr "length" "12")])
12012 (define_expand "tls_local_dynamic_base_64"
12013 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12014 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
12015 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12018 if (TARGET_GNU2_TLS)
12020 emit_insn (gen_tls_dynamic_gnu2_64
12021 (operands[0], ix86_tls_module_base ()));
12024 operands[1] = ix86_tls_get_addr ();
12027 ;; Local dynamic of a single variable is a lose. Show combine how
12028 ;; to convert that back to global dynamic.
12030 (define_insn_and_split "*tls_local_dynamic_32_once"
12031 [(set (match_operand:SI 0 "register_operand" "=a")
12032 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12033 (match_operand:SI 2 "call_insn_operand" "")]
12034 UNSPEC_TLS_LD_BASE)
12035 (const:SI (unspec:SI
12036 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12038 (clobber (match_scratch:SI 4 "=d"))
12039 (clobber (match_scratch:SI 5 "=c"))
12040 (clobber (reg:CC FLAGS_REG))]
12044 [(parallel [(set (match_dup 0)
12045 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12047 (clobber (match_dup 4))
12048 (clobber (match_dup 5))
12049 (clobber (reg:CC FLAGS_REG))])]
12052 ;; Segment register for the thread base ptr load
12053 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12055 ;; Load and add the thread base pointer from %gs:0.
12056 (define_insn "*load_tp_<mode>"
12057 [(set (match_operand:P 0 "register_operand" "=r")
12058 (unspec:P [(const_int 0)] UNSPEC_TP))]
12060 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12061 [(set_attr "type" "imov")
12062 (set_attr "modrm" "0")
12063 (set_attr "length" "7")
12064 (set_attr "memory" "load")
12065 (set_attr "imm_disp" "false")])
12067 (define_insn "*add_tp_<mode>"
12068 [(set (match_operand:P 0 "register_operand" "=r")
12069 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12070 (match_operand:P 1 "register_operand" "0")))
12071 (clobber (reg:CC FLAGS_REG))]
12073 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12074 [(set_attr "type" "alu")
12075 (set_attr "modrm" "0")
12076 (set_attr "length" "7")
12077 (set_attr "memory" "load")
12078 (set_attr "imm_disp" "false")])
12080 ;; GNU2 TLS patterns can be split.
12082 (define_expand "tls_dynamic_gnu2_32"
12083 [(set (match_dup 3)
12084 (plus:SI (match_operand:SI 2 "register_operand" "")
12086 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12089 [(set (match_operand:SI 0 "register_operand" "")
12090 (unspec:SI [(match_dup 1) (match_dup 3)
12091 (match_dup 2) (reg:SI SP_REG)]
12093 (clobber (reg:CC FLAGS_REG))])]
12094 "!TARGET_64BIT && TARGET_GNU2_TLS"
12096 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12097 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12100 (define_insn "*tls_dynamic_lea_32"
12101 [(set (match_operand:SI 0 "register_operand" "=r")
12102 (plus:SI (match_operand:SI 1 "register_operand" "b")
12104 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12105 UNSPEC_TLSDESC))))]
12106 "!TARGET_64BIT && TARGET_GNU2_TLS"
12107 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12108 [(set_attr "type" "lea")
12109 (set_attr "mode" "SI")
12110 (set_attr "length" "6")
12111 (set_attr "length_address" "4")])
12113 (define_insn "*tls_dynamic_call_32"
12114 [(set (match_operand:SI 0 "register_operand" "=a")
12115 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12116 (match_operand:SI 2 "register_operand" "0")
12117 ;; we have to make sure %ebx still points to the GOT
12118 (match_operand:SI 3 "register_operand" "b")
12121 (clobber (reg:CC FLAGS_REG))]
12122 "!TARGET_64BIT && TARGET_GNU2_TLS"
12123 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12124 [(set_attr "type" "call")
12125 (set_attr "length" "2")
12126 (set_attr "length_address" "0")])
12128 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12129 [(set (match_operand:SI 0 "register_operand" "=&a")
12131 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12132 (match_operand:SI 4 "" "")
12133 (match_operand:SI 2 "register_operand" "b")
12136 (const:SI (unspec:SI
12137 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12139 (clobber (reg:CC FLAGS_REG))]
12140 "!TARGET_64BIT && TARGET_GNU2_TLS"
12143 [(set (match_dup 0) (match_dup 5))]
12145 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12146 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12149 (define_expand "tls_dynamic_gnu2_64"
12150 [(set (match_dup 2)
12151 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12154 [(set (match_operand:DI 0 "register_operand" "")
12155 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12157 (clobber (reg:CC FLAGS_REG))])]
12158 "TARGET_64BIT && TARGET_GNU2_TLS"
12160 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12161 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12164 (define_insn "*tls_dynamic_lea_64"
12165 [(set (match_operand:DI 0 "register_operand" "=r")
12166 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12168 "TARGET_64BIT && TARGET_GNU2_TLS"
12169 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12170 [(set_attr "type" "lea")
12171 (set_attr "mode" "DI")
12172 (set_attr "length" "7")
12173 (set_attr "length_address" "4")])
12175 (define_insn "*tls_dynamic_call_64"
12176 [(set (match_operand:DI 0 "register_operand" "=a")
12177 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12178 (match_operand:DI 2 "register_operand" "0")
12181 (clobber (reg:CC FLAGS_REG))]
12182 "TARGET_64BIT && TARGET_GNU2_TLS"
12183 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12184 [(set_attr "type" "call")
12185 (set_attr "length" "2")
12186 (set_attr "length_address" "0")])
12188 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12189 [(set (match_operand:DI 0 "register_operand" "=&a")
12191 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12192 (match_operand:DI 3 "" "")
12195 (const:DI (unspec:DI
12196 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12198 (clobber (reg:CC FLAGS_REG))]
12199 "TARGET_64BIT && TARGET_GNU2_TLS"
12202 [(set (match_dup 0) (match_dup 4))]
12204 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12205 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12208 ;; These patterns match the binary 387 instructions for addM3, subM3,
12209 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12210 ;; SFmode. The first is the normal insn, the second the same insn but
12211 ;; with one operand a conversion, and the third the same insn but with
12212 ;; the other operand a conversion. The conversion may be SFmode or
12213 ;; SImode if the target mode DFmode, but only SImode if the target mode
12216 ;; Gcc is slightly more smart about handling normal two address instructions
12217 ;; so use special patterns for add and mull.
12219 (define_insn "*fop_<mode>_comm_mixed_avx"
12220 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12221 (match_operator:MODEF 3 "binary_fp_operator"
12222 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12223 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12224 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12225 && COMMUTATIVE_ARITH_P (operands[3])
12226 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12227 "* return output_387_binary_op (insn, operands);"
12228 [(set (attr "type")
12229 (if_then_else (eq_attr "alternative" "1")
12230 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12231 (const_string "ssemul")
12232 (const_string "sseadd"))
12233 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12234 (const_string "fmul")
12235 (const_string "fop"))))
12236 (set_attr "prefix" "orig,maybe_vex")
12237 (set_attr "mode" "<MODE>")])
12239 (define_insn "*fop_<mode>_comm_mixed"
12240 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12241 (match_operator:MODEF 3 "binary_fp_operator"
12242 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
12243 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12244 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12245 && COMMUTATIVE_ARITH_P (operands[3])
12246 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12247 "* return output_387_binary_op (insn, operands);"
12248 [(set (attr "type")
12249 (if_then_else (eq_attr "alternative" "1")
12250 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12251 (const_string "ssemul")
12252 (const_string "sseadd"))
12253 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12254 (const_string "fmul")
12255 (const_string "fop"))))
12256 (set_attr "mode" "<MODE>")])
12258 (define_insn "*fop_<mode>_comm_avx"
12259 [(set (match_operand:MODEF 0 "register_operand" "=x")
12260 (match_operator:MODEF 3 "binary_fp_operator"
12261 [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
12262 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12263 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12264 && COMMUTATIVE_ARITH_P (operands[3])
12265 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12266 "* return output_387_binary_op (insn, operands);"
12267 [(set (attr "type")
12268 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12269 (const_string "ssemul")
12270 (const_string "sseadd")))
12271 (set_attr "prefix" "vex")
12272 (set_attr "mode" "<MODE>")])
12274 (define_insn "*fop_<mode>_comm_sse"
12275 [(set (match_operand:MODEF 0 "register_operand" "=x")
12276 (match_operator:MODEF 3 "binary_fp_operator"
12277 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12278 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12279 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12280 && COMMUTATIVE_ARITH_P (operands[3])
12281 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12282 "* return output_387_binary_op (insn, operands);"
12283 [(set (attr "type")
12284 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12285 (const_string "ssemul")
12286 (const_string "sseadd")))
12287 (set_attr "mode" "<MODE>")])
12289 (define_insn "*fop_<mode>_comm_i387"
12290 [(set (match_operand:MODEF 0 "register_operand" "=f")
12291 (match_operator:MODEF 3 "binary_fp_operator"
12292 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12293 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12294 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12295 && COMMUTATIVE_ARITH_P (operands[3])
12296 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12297 "* return output_387_binary_op (insn, operands);"
12298 [(set (attr "type")
12299 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12300 (const_string "fmul")
12301 (const_string "fop")))
12302 (set_attr "mode" "<MODE>")])
12304 (define_insn "*fop_<mode>_1_mixed_avx"
12305 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12306 (match_operator:MODEF 3 "binary_fp_operator"
12307 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
12308 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12309 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12310 && !COMMUTATIVE_ARITH_P (operands[3])
12311 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12312 "* return output_387_binary_op (insn, operands);"
12313 [(set (attr "type")
12314 (cond [(and (eq_attr "alternative" "2")
12315 (match_operand:MODEF 3 "mult_operator" ""))
12316 (const_string "ssemul")
12317 (and (eq_attr "alternative" "2")
12318 (match_operand:MODEF 3 "div_operator" ""))
12319 (const_string "ssediv")
12320 (eq_attr "alternative" "2")
12321 (const_string "sseadd")
12322 (match_operand:MODEF 3 "mult_operator" "")
12323 (const_string "fmul")
12324 (match_operand:MODEF 3 "div_operator" "")
12325 (const_string "fdiv")
12327 (const_string "fop")))
12328 (set_attr "prefix" "orig,orig,maybe_vex")
12329 (set_attr "mode" "<MODE>")])
12331 (define_insn "*fop_<mode>_1_mixed"
12332 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12333 (match_operator:MODEF 3 "binary_fp_operator"
12334 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
12335 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12336 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12337 && !COMMUTATIVE_ARITH_P (operands[3])
12338 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12339 "* return output_387_binary_op (insn, operands);"
12340 [(set (attr "type")
12341 (cond [(and (eq_attr "alternative" "2")
12342 (match_operand:MODEF 3 "mult_operator" ""))
12343 (const_string "ssemul")
12344 (and (eq_attr "alternative" "2")
12345 (match_operand:MODEF 3 "div_operator" ""))
12346 (const_string "ssediv")
12347 (eq_attr "alternative" "2")
12348 (const_string "sseadd")
12349 (match_operand:MODEF 3 "mult_operator" "")
12350 (const_string "fmul")
12351 (match_operand:MODEF 3 "div_operator" "")
12352 (const_string "fdiv")
12354 (const_string "fop")))
12355 (set_attr "mode" "<MODE>")])
12357 (define_insn "*rcpsf2_sse"
12358 [(set (match_operand:SF 0 "register_operand" "=x")
12359 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12362 "%vrcpss\t{%1, %d0|%d0, %1}"
12363 [(set_attr "type" "sse")
12364 (set_attr "atom_sse_attr" "rcp")
12365 (set_attr "prefix" "maybe_vex")
12366 (set_attr "mode" "SF")])
12368 (define_insn "*fop_<mode>_1_avx"
12369 [(set (match_operand:MODEF 0 "register_operand" "=x")
12370 (match_operator:MODEF 3 "binary_fp_operator"
12371 [(match_operand:MODEF 1 "register_operand" "x")
12372 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12373 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12374 && !COMMUTATIVE_ARITH_P (operands[3])"
12375 "* return output_387_binary_op (insn, operands);"
12376 [(set (attr "type")
12377 (cond [(match_operand:MODEF 3 "mult_operator" "")
12378 (const_string "ssemul")
12379 (match_operand:MODEF 3 "div_operator" "")
12380 (const_string "ssediv")
12382 (const_string "sseadd")))
12383 (set_attr "prefix" "vex")
12384 (set_attr "mode" "<MODE>")])
12386 (define_insn "*fop_<mode>_1_sse"
12387 [(set (match_operand:MODEF 0 "register_operand" "=x")
12388 (match_operator:MODEF 3 "binary_fp_operator"
12389 [(match_operand:MODEF 1 "register_operand" "0")
12390 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12391 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12392 && !COMMUTATIVE_ARITH_P (operands[3])"
12393 "* return output_387_binary_op (insn, operands);"
12394 [(set (attr "type")
12395 (cond [(match_operand:MODEF 3 "mult_operator" "")
12396 (const_string "ssemul")
12397 (match_operand:MODEF 3 "div_operator" "")
12398 (const_string "ssediv")
12400 (const_string "sseadd")))
12401 (set_attr "mode" "<MODE>")])
12403 ;; This pattern is not fully shadowed by the pattern above.
12404 (define_insn "*fop_<mode>_1_i387"
12405 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12406 (match_operator:MODEF 3 "binary_fp_operator"
12407 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12408 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12409 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12410 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12411 && !COMMUTATIVE_ARITH_P (operands[3])
12412 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12413 "* return output_387_binary_op (insn, operands);"
12414 [(set (attr "type")
12415 (cond [(match_operand:MODEF 3 "mult_operator" "")
12416 (const_string "fmul")
12417 (match_operand:MODEF 3 "div_operator" "")
12418 (const_string "fdiv")
12420 (const_string "fop")))
12421 (set_attr "mode" "<MODE>")])
12423 ;; ??? Add SSE splitters for these!
12424 (define_insn "*fop_<MODEF:mode>_2_i387"
12425 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12426 (match_operator:MODEF 3 "binary_fp_operator"
12428 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12429 (match_operand:MODEF 2 "register_operand" "0,0")]))]
12430 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12431 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12432 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12433 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12434 [(set (attr "type")
12435 (cond [(match_operand:MODEF 3 "mult_operator" "")
12436 (const_string "fmul")
12437 (match_operand:MODEF 3 "div_operator" "")
12438 (const_string "fdiv")
12440 (const_string "fop")))
12441 (set_attr "fp_int_src" "true")
12442 (set_attr "mode" "<X87MODEI12:MODE>")])
12444 (define_insn "*fop_<MODEF:mode>_3_i387"
12445 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12446 (match_operator:MODEF 3 "binary_fp_operator"
12447 [(match_operand:MODEF 1 "register_operand" "0,0")
12449 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12450 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12451 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12452 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12453 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12454 [(set (attr "type")
12455 (cond [(match_operand:MODEF 3 "mult_operator" "")
12456 (const_string "fmul")
12457 (match_operand:MODEF 3 "div_operator" "")
12458 (const_string "fdiv")
12460 (const_string "fop")))
12461 (set_attr "fp_int_src" "true")
12462 (set_attr "mode" "<MODE>")])
12464 (define_insn "*fop_df_4_i387"
12465 [(set (match_operand:DF 0 "register_operand" "=f,f")
12466 (match_operator:DF 3 "binary_fp_operator"
12468 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12469 (match_operand:DF 2 "register_operand" "0,f")]))]
12470 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12471 && !(TARGET_SSE2 && TARGET_SSE_MATH)
12472 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12473 "* return output_387_binary_op (insn, operands);"
12474 [(set (attr "type")
12475 (cond [(match_operand:DF 3 "mult_operator" "")
12476 (const_string "fmul")
12477 (match_operand:DF 3 "div_operator" "")
12478 (const_string "fdiv")
12480 (const_string "fop")))
12481 (set_attr "mode" "SF")])
12483 (define_insn "*fop_df_5_i387"
12484 [(set (match_operand:DF 0 "register_operand" "=f,f")
12485 (match_operator:DF 3 "binary_fp_operator"
12486 [(match_operand:DF 1 "register_operand" "0,f")
12488 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12489 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12490 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12491 "* return output_387_binary_op (insn, operands);"
12492 [(set (attr "type")
12493 (cond [(match_operand:DF 3 "mult_operator" "")
12494 (const_string "fmul")
12495 (match_operand:DF 3 "div_operator" "")
12496 (const_string "fdiv")
12498 (const_string "fop")))
12499 (set_attr "mode" "SF")])
12501 (define_insn "*fop_df_6_i387"
12502 [(set (match_operand:DF 0 "register_operand" "=f,f")
12503 (match_operator:DF 3 "binary_fp_operator"
12505 (match_operand:SF 1 "register_operand" "0,f"))
12507 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12508 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12509 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12510 "* return output_387_binary_op (insn, operands);"
12511 [(set (attr "type")
12512 (cond [(match_operand:DF 3 "mult_operator" "")
12513 (const_string "fmul")
12514 (match_operand:DF 3 "div_operator" "")
12515 (const_string "fdiv")
12517 (const_string "fop")))
12518 (set_attr "mode" "SF")])
12520 (define_insn "*fop_xf_comm_i387"
12521 [(set (match_operand:XF 0 "register_operand" "=f")
12522 (match_operator:XF 3 "binary_fp_operator"
12523 [(match_operand:XF 1 "register_operand" "%0")
12524 (match_operand:XF 2 "register_operand" "f")]))]
12526 && COMMUTATIVE_ARITH_P (operands[3])"
12527 "* return output_387_binary_op (insn, operands);"
12528 [(set (attr "type")
12529 (if_then_else (match_operand:XF 3 "mult_operator" "")
12530 (const_string "fmul")
12531 (const_string "fop")))
12532 (set_attr "mode" "XF")])
12534 (define_insn "*fop_xf_1_i387"
12535 [(set (match_operand:XF 0 "register_operand" "=f,f")
12536 (match_operator:XF 3 "binary_fp_operator"
12537 [(match_operand:XF 1 "register_operand" "0,f")
12538 (match_operand:XF 2 "register_operand" "f,0")]))]
12540 && !COMMUTATIVE_ARITH_P (operands[3])"
12541 "* return output_387_binary_op (insn, operands);"
12542 [(set (attr "type")
12543 (cond [(match_operand:XF 3 "mult_operator" "")
12544 (const_string "fmul")
12545 (match_operand:XF 3 "div_operator" "")
12546 (const_string "fdiv")
12548 (const_string "fop")))
12549 (set_attr "mode" "XF")])
12551 (define_insn "*fop_xf_2_i387"
12552 [(set (match_operand:XF 0 "register_operand" "=f,f")
12553 (match_operator:XF 3 "binary_fp_operator"
12555 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12556 (match_operand:XF 2 "register_operand" "0,0")]))]
12557 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12558 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12559 [(set (attr "type")
12560 (cond [(match_operand:XF 3 "mult_operator" "")
12561 (const_string "fmul")
12562 (match_operand:XF 3 "div_operator" "")
12563 (const_string "fdiv")
12565 (const_string "fop")))
12566 (set_attr "fp_int_src" "true")
12567 (set_attr "mode" "<MODE>")])
12569 (define_insn "*fop_xf_3_i387"
12570 [(set (match_operand:XF 0 "register_operand" "=f,f")
12571 (match_operator:XF 3 "binary_fp_operator"
12572 [(match_operand:XF 1 "register_operand" "0,0")
12574 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12575 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12576 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12577 [(set (attr "type")
12578 (cond [(match_operand:XF 3 "mult_operator" "")
12579 (const_string "fmul")
12580 (match_operand:XF 3 "div_operator" "")
12581 (const_string "fdiv")
12583 (const_string "fop")))
12584 (set_attr "fp_int_src" "true")
12585 (set_attr "mode" "<MODE>")])
12587 (define_insn "*fop_xf_4_i387"
12588 [(set (match_operand:XF 0 "register_operand" "=f,f")
12589 (match_operator:XF 3 "binary_fp_operator"
12591 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
12592 (match_operand:XF 2 "register_operand" "0,f")]))]
12594 "* return output_387_binary_op (insn, operands);"
12595 [(set (attr "type")
12596 (cond [(match_operand:XF 3 "mult_operator" "")
12597 (const_string "fmul")
12598 (match_operand:XF 3 "div_operator" "")
12599 (const_string "fdiv")
12601 (const_string "fop")))
12602 (set_attr "mode" "<MODE>")])
12604 (define_insn "*fop_xf_5_i387"
12605 [(set (match_operand:XF 0 "register_operand" "=f,f")
12606 (match_operator:XF 3 "binary_fp_operator"
12607 [(match_operand:XF 1 "register_operand" "0,f")
12609 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12611 "* return output_387_binary_op (insn, operands);"
12612 [(set (attr "type")
12613 (cond [(match_operand:XF 3 "mult_operator" "")
12614 (const_string "fmul")
12615 (match_operand:XF 3 "div_operator" "")
12616 (const_string "fdiv")
12618 (const_string "fop")))
12619 (set_attr "mode" "<MODE>")])
12621 (define_insn "*fop_xf_6_i387"
12622 [(set (match_operand:XF 0 "register_operand" "=f,f")
12623 (match_operator:XF 3 "binary_fp_operator"
12625 (match_operand:MODEF 1 "register_operand" "0,f"))
12627 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12629 "* return output_387_binary_op (insn, operands);"
12630 [(set (attr "type")
12631 (cond [(match_operand:XF 3 "mult_operator" "")
12632 (const_string "fmul")
12633 (match_operand:XF 3 "div_operator" "")
12634 (const_string "fdiv")
12636 (const_string "fop")))
12637 (set_attr "mode" "<MODE>")])
12640 [(set (match_operand 0 "register_operand" "")
12641 (match_operator 3 "binary_fp_operator"
12642 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
12643 (match_operand 2 "register_operand" "")]))]
12645 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12646 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
12649 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
12650 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12651 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12652 gen_rtx_fmt_ee (GET_CODE (operands[3]),
12653 GET_MODE (operands[3]),
12656 ix86_free_from_memory (GET_MODE (operands[1]));
12661 [(set (match_operand 0 "register_operand" "")
12662 (match_operator 3 "binary_fp_operator"
12663 [(match_operand 1 "register_operand" "")
12664 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
12666 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12667 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
12670 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
12671 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12672 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12673 gen_rtx_fmt_ee (GET_CODE (operands[3]),
12674 GET_MODE (operands[3]),
12677 ix86_free_from_memory (GET_MODE (operands[2]));
12681 ;; FPU special functions.
12683 ;; This pattern implements a no-op XFmode truncation for
12684 ;; all fancy i386 XFmode math functions.
12686 (define_insn "truncxf<mode>2_i387_noop_unspec"
12687 [(set (match_operand:MODEF 0 "register_operand" "=f")
12688 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
12689 UNSPEC_TRUNC_NOOP))]
12690 "TARGET_USE_FANCY_MATH_387"
12691 "* return output_387_reg_move (insn, operands);"
12692 [(set_attr "type" "fmov")
12693 (set_attr "mode" "<MODE>")])
12695 (define_insn "sqrtxf2"
12696 [(set (match_operand:XF 0 "register_operand" "=f")
12697 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
12698 "TARGET_USE_FANCY_MATH_387"
12700 [(set_attr "type" "fpspc")
12701 (set_attr "mode" "XF")
12702 (set_attr "athlon_decode" "direct")
12703 (set_attr "amdfam10_decode" "direct")])
12705 (define_insn "sqrt_extend<mode>xf2_i387"
12706 [(set (match_operand:XF 0 "register_operand" "=f")
12709 (match_operand:MODEF 1 "register_operand" "0"))))]
12710 "TARGET_USE_FANCY_MATH_387"
12712 [(set_attr "type" "fpspc")
12713 (set_attr "mode" "XF")
12714 (set_attr "athlon_decode" "direct")
12715 (set_attr "amdfam10_decode" "direct")])
12717 (define_insn "*rsqrtsf2_sse"
12718 [(set (match_operand:SF 0 "register_operand" "=x")
12719 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12722 "%vrsqrtss\t{%1, %d0|%d0, %1}"
12723 [(set_attr "type" "sse")
12724 (set_attr "atom_sse_attr" "rcp")
12725 (set_attr "prefix" "maybe_vex")
12726 (set_attr "mode" "SF")])
12728 (define_expand "rsqrtsf2"
12729 [(set (match_operand:SF 0 "register_operand" "")
12730 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
12734 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
12738 (define_insn "*sqrt<mode>2_sse"
12739 [(set (match_operand:MODEF 0 "register_operand" "=x")
12741 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
12742 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
12743 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
12744 [(set_attr "type" "sse")
12745 (set_attr "atom_sse_attr" "sqrt")
12746 (set_attr "prefix" "maybe_vex")
12747 (set_attr "mode" "<MODE>")
12748 (set_attr "athlon_decode" "*")
12749 (set_attr "amdfam10_decode" "*")])
12751 (define_expand "sqrt<mode>2"
12752 [(set (match_operand:MODEF 0 "register_operand" "")
12754 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
12755 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
12756 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
12758 if (<MODE>mode == SFmode
12759 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
12760 && flag_finite_math_only && !flag_trapping_math
12761 && flag_unsafe_math_optimizations)
12763 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
12767 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
12769 rtx op0 = gen_reg_rtx (XFmode);
12770 rtx op1 = force_reg (<MODE>mode, operands[1]);
12772 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
12773 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
12778 (define_insn "fpremxf4_i387"
12779 [(set (match_operand:XF 0 "register_operand" "=f")
12780 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
12781 (match_operand:XF 3 "register_operand" "1")]
12783 (set (match_operand:XF 1 "register_operand" "=u")
12784 (unspec:XF [(match_dup 2) (match_dup 3)]
12786 (set (reg:CCFP FPSR_REG)
12787 (unspec:CCFP [(match_dup 2) (match_dup 3)]
12789 "TARGET_USE_FANCY_MATH_387"
12791 [(set_attr "type" "fpspc")
12792 (set_attr "mode" "XF")])
12794 (define_expand "fmodxf3"
12795 [(use (match_operand:XF 0 "register_operand" ""))
12796 (use (match_operand:XF 1 "general_operand" ""))
12797 (use (match_operand:XF 2 "general_operand" ""))]
12798 "TARGET_USE_FANCY_MATH_387"
12800 rtx label = gen_label_rtx ();
12802 rtx op1 = gen_reg_rtx (XFmode);
12803 rtx op2 = gen_reg_rtx (XFmode);
12805 emit_move_insn (op2, operands[2]);
12806 emit_move_insn (op1, operands[1]);
12808 emit_label (label);
12809 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
12810 ix86_emit_fp_unordered_jump (label);
12811 LABEL_NUSES (label) = 1;
12813 emit_move_insn (operands[0], op1);
12817 (define_expand "fmod<mode>3"
12818 [(use (match_operand:MODEF 0 "register_operand" ""))
12819 (use (match_operand:MODEF 1 "general_operand" ""))
12820 (use (match_operand:MODEF 2 "general_operand" ""))]
12821 "TARGET_USE_FANCY_MATH_387"
12823 rtx (*gen_truncxf) (rtx, rtx);
12825 rtx label = gen_label_rtx ();
12827 rtx op1 = gen_reg_rtx (XFmode);
12828 rtx op2 = gen_reg_rtx (XFmode);
12830 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
12831 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
12833 emit_label (label);
12834 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
12835 ix86_emit_fp_unordered_jump (label);
12836 LABEL_NUSES (label) = 1;
12838 /* Truncate the result properly for strict SSE math. */
12839 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12840 && !TARGET_MIX_SSE_I387)
12841 gen_truncxf = gen_truncxf<mode>2;
12843 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
12845 emit_insn (gen_truncxf (operands[0], op1));
12849 (define_insn "fprem1xf4_i387"
12850 [(set (match_operand:XF 0 "register_operand" "=f")
12851 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
12852 (match_operand:XF 3 "register_operand" "1")]
12854 (set (match_operand:XF 1 "register_operand" "=u")
12855 (unspec:XF [(match_dup 2) (match_dup 3)]
12857 (set (reg:CCFP FPSR_REG)
12858 (unspec:CCFP [(match_dup 2) (match_dup 3)]
12860 "TARGET_USE_FANCY_MATH_387"
12862 [(set_attr "type" "fpspc")
12863 (set_attr "mode" "XF")])
12865 (define_expand "remainderxf3"
12866 [(use (match_operand:XF 0 "register_operand" ""))
12867 (use (match_operand:XF 1 "general_operand" ""))
12868 (use (match_operand:XF 2 "general_operand" ""))]
12869 "TARGET_USE_FANCY_MATH_387"
12871 rtx label = gen_label_rtx ();
12873 rtx op1 = gen_reg_rtx (XFmode);
12874 rtx op2 = gen_reg_rtx (XFmode);
12876 emit_move_insn (op2, operands[2]);
12877 emit_move_insn (op1, operands[1]);
12879 emit_label (label);
12880 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
12881 ix86_emit_fp_unordered_jump (label);
12882 LABEL_NUSES (label) = 1;
12884 emit_move_insn (operands[0], op1);
12888 (define_expand "remainder<mode>3"
12889 [(use (match_operand:MODEF 0 "register_operand" ""))
12890 (use (match_operand:MODEF 1 "general_operand" ""))
12891 (use (match_operand:MODEF 2 "general_operand" ""))]
12892 "TARGET_USE_FANCY_MATH_387"
12894 rtx (*gen_truncxf) (rtx, rtx);
12896 rtx label = gen_label_rtx ();
12898 rtx op1 = gen_reg_rtx (XFmode);
12899 rtx op2 = gen_reg_rtx (XFmode);
12901 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
12902 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
12904 emit_label (label);
12906 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
12907 ix86_emit_fp_unordered_jump (label);
12908 LABEL_NUSES (label) = 1;
12910 /* Truncate the result properly for strict SSE math. */
12911 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12912 && !TARGET_MIX_SSE_I387)
12913 gen_truncxf = gen_truncxf<mode>2;
12915 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
12917 emit_insn (gen_truncxf (operands[0], op1));
12921 (define_insn "*sinxf2_i387"
12922 [(set (match_operand:XF 0 "register_operand" "=f")
12923 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
12924 "TARGET_USE_FANCY_MATH_387
12925 && flag_unsafe_math_optimizations"
12927 [(set_attr "type" "fpspc")
12928 (set_attr "mode" "XF")])
12930 (define_insn "*sin_extend<mode>xf2_i387"
12931 [(set (match_operand:XF 0 "register_operand" "=f")
12932 (unspec:XF [(float_extend:XF
12933 (match_operand:MODEF 1 "register_operand" "0"))]
12935 "TARGET_USE_FANCY_MATH_387
12936 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12937 || TARGET_MIX_SSE_I387)
12938 && flag_unsafe_math_optimizations"
12940 [(set_attr "type" "fpspc")
12941 (set_attr "mode" "XF")])
12943 (define_insn "*cosxf2_i387"
12944 [(set (match_operand:XF 0 "register_operand" "=f")
12945 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
12946 "TARGET_USE_FANCY_MATH_387
12947 && flag_unsafe_math_optimizations"
12949 [(set_attr "type" "fpspc")
12950 (set_attr "mode" "XF")])
12952 (define_insn "*cos_extend<mode>xf2_i387"
12953 [(set (match_operand:XF 0 "register_operand" "=f")
12954 (unspec:XF [(float_extend:XF
12955 (match_operand:MODEF 1 "register_operand" "0"))]
12957 "TARGET_USE_FANCY_MATH_387
12958 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12959 || TARGET_MIX_SSE_I387)
12960 && flag_unsafe_math_optimizations"
12962 [(set_attr "type" "fpspc")
12963 (set_attr "mode" "XF")])
12965 ;; When sincos pattern is defined, sin and cos builtin functions will be
12966 ;; expanded to sincos pattern with one of its outputs left unused.
12967 ;; CSE pass will figure out if two sincos patterns can be combined,
12968 ;; otherwise sincos pattern will be split back to sin or cos pattern,
12969 ;; depending on the unused output.
12971 (define_insn "sincosxf3"
12972 [(set (match_operand:XF 0 "register_operand" "=f")
12973 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
12974 UNSPEC_SINCOS_COS))
12975 (set (match_operand:XF 1 "register_operand" "=u")
12976 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
12977 "TARGET_USE_FANCY_MATH_387
12978 && flag_unsafe_math_optimizations"
12980 [(set_attr "type" "fpspc")
12981 (set_attr "mode" "XF")])
12984 [(set (match_operand:XF 0 "register_operand" "")
12985 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
12986 UNSPEC_SINCOS_COS))
12987 (set (match_operand:XF 1 "register_operand" "")
12988 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
12989 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
12990 && !(reload_completed || reload_in_progress)"
12991 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
12994 [(set (match_operand:XF 0 "register_operand" "")
12995 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
12996 UNSPEC_SINCOS_COS))
12997 (set (match_operand:XF 1 "register_operand" "")
12998 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
12999 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13000 && !(reload_completed || reload_in_progress)"
13001 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13003 (define_insn "sincos_extend<mode>xf3_i387"
13004 [(set (match_operand:XF 0 "register_operand" "=f")
13005 (unspec:XF [(float_extend:XF
13006 (match_operand:MODEF 2 "register_operand" "0"))]
13007 UNSPEC_SINCOS_COS))
13008 (set (match_operand:XF 1 "register_operand" "=u")
13009 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13010 "TARGET_USE_FANCY_MATH_387
13011 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13012 || TARGET_MIX_SSE_I387)
13013 && flag_unsafe_math_optimizations"
13015 [(set_attr "type" "fpspc")
13016 (set_attr "mode" "XF")])
13019 [(set (match_operand:XF 0 "register_operand" "")
13020 (unspec:XF [(float_extend:XF
13021 (match_operand:MODEF 2 "register_operand" ""))]
13022 UNSPEC_SINCOS_COS))
13023 (set (match_operand:XF 1 "register_operand" "")
13024 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13025 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13026 && !(reload_completed || reload_in_progress)"
13027 [(set (match_dup 1)
13028 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13031 [(set (match_operand:XF 0 "register_operand" "")
13032 (unspec:XF [(float_extend:XF
13033 (match_operand:MODEF 2 "register_operand" ""))]
13034 UNSPEC_SINCOS_COS))
13035 (set (match_operand:XF 1 "register_operand" "")
13036 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13037 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13038 && !(reload_completed || reload_in_progress)"
13039 [(set (match_dup 0)
13040 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13042 (define_expand "sincos<mode>3"
13043 [(use (match_operand:MODEF 0 "register_operand" ""))
13044 (use (match_operand:MODEF 1 "register_operand" ""))
13045 (use (match_operand:MODEF 2 "register_operand" ""))]
13046 "TARGET_USE_FANCY_MATH_387
13047 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13048 || TARGET_MIX_SSE_I387)
13049 && flag_unsafe_math_optimizations"
13051 rtx op0 = gen_reg_rtx (XFmode);
13052 rtx op1 = gen_reg_rtx (XFmode);
13054 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13055 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13056 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13060 (define_insn "fptanxf4_i387"
13061 [(set (match_operand:XF 0 "register_operand" "=f")
13062 (match_operand:XF 3 "const_double_operand" "F"))
13063 (set (match_operand:XF 1 "register_operand" "=u")
13064 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13066 "TARGET_USE_FANCY_MATH_387
13067 && flag_unsafe_math_optimizations
13068 && standard_80387_constant_p (operands[3]) == 2"
13070 [(set_attr "type" "fpspc")
13071 (set_attr "mode" "XF")])
13073 (define_insn "fptan_extend<mode>xf4_i387"
13074 [(set (match_operand:MODEF 0 "register_operand" "=f")
13075 (match_operand:MODEF 3 "const_double_operand" "F"))
13076 (set (match_operand:XF 1 "register_operand" "=u")
13077 (unspec:XF [(float_extend:XF
13078 (match_operand:MODEF 2 "register_operand" "0"))]
13080 "TARGET_USE_FANCY_MATH_387
13081 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13082 || TARGET_MIX_SSE_I387)
13083 && flag_unsafe_math_optimizations
13084 && standard_80387_constant_p (operands[3]) == 2"
13086 [(set_attr "type" "fpspc")
13087 (set_attr "mode" "XF")])
13089 (define_expand "tanxf2"
13090 [(use (match_operand:XF 0 "register_operand" ""))
13091 (use (match_operand:XF 1 "register_operand" ""))]
13092 "TARGET_USE_FANCY_MATH_387
13093 && flag_unsafe_math_optimizations"
13095 rtx one = gen_reg_rtx (XFmode);
13096 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13098 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13102 (define_expand "tan<mode>2"
13103 [(use (match_operand:MODEF 0 "register_operand" ""))
13104 (use (match_operand:MODEF 1 "register_operand" ""))]
13105 "TARGET_USE_FANCY_MATH_387
13106 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13107 || TARGET_MIX_SSE_I387)
13108 && flag_unsafe_math_optimizations"
13110 rtx op0 = gen_reg_rtx (XFmode);
13112 rtx one = gen_reg_rtx (<MODE>mode);
13113 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13115 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13116 operands[1], op2));
13117 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13121 (define_insn "*fpatanxf3_i387"
13122 [(set (match_operand:XF 0 "register_operand" "=f")
13123 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13124 (match_operand:XF 2 "register_operand" "u")]
13126 (clobber (match_scratch:XF 3 "=2"))]
13127 "TARGET_USE_FANCY_MATH_387
13128 && flag_unsafe_math_optimizations"
13130 [(set_attr "type" "fpspc")
13131 (set_attr "mode" "XF")])
13133 (define_insn "fpatan_extend<mode>xf3_i387"
13134 [(set (match_operand:XF 0 "register_operand" "=f")
13135 (unspec:XF [(float_extend:XF
13136 (match_operand:MODEF 1 "register_operand" "0"))
13138 (match_operand:MODEF 2 "register_operand" "u"))]
13140 (clobber (match_scratch:XF 3 "=2"))]
13141 "TARGET_USE_FANCY_MATH_387
13142 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13143 || TARGET_MIX_SSE_I387)
13144 && flag_unsafe_math_optimizations"
13146 [(set_attr "type" "fpspc")
13147 (set_attr "mode" "XF")])
13149 (define_expand "atan2xf3"
13150 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13151 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13152 (match_operand:XF 1 "register_operand" "")]
13154 (clobber (match_scratch:XF 3 ""))])]
13155 "TARGET_USE_FANCY_MATH_387
13156 && flag_unsafe_math_optimizations"
13159 (define_expand "atan2<mode>3"
13160 [(use (match_operand:MODEF 0 "register_operand" ""))
13161 (use (match_operand:MODEF 1 "register_operand" ""))
13162 (use (match_operand:MODEF 2 "register_operand" ""))]
13163 "TARGET_USE_FANCY_MATH_387
13164 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13165 || TARGET_MIX_SSE_I387)
13166 && flag_unsafe_math_optimizations"
13168 rtx op0 = gen_reg_rtx (XFmode);
13170 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13171 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13175 (define_expand "atanxf2"
13176 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13177 (unspec:XF [(match_dup 2)
13178 (match_operand:XF 1 "register_operand" "")]
13180 (clobber (match_scratch:XF 3 ""))])]
13181 "TARGET_USE_FANCY_MATH_387
13182 && flag_unsafe_math_optimizations"
13184 operands[2] = gen_reg_rtx (XFmode);
13185 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13188 (define_expand "atan<mode>2"
13189 [(use (match_operand:MODEF 0 "register_operand" ""))
13190 (use (match_operand:MODEF 1 "register_operand" ""))]
13191 "TARGET_USE_FANCY_MATH_387
13192 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13193 || TARGET_MIX_SSE_I387)
13194 && flag_unsafe_math_optimizations"
13196 rtx op0 = gen_reg_rtx (XFmode);
13198 rtx op2 = gen_reg_rtx (<MODE>mode);
13199 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13201 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13202 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13206 (define_expand "asinxf2"
13207 [(set (match_dup 2)
13208 (mult:XF (match_operand:XF 1 "register_operand" "")
13210 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13211 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13212 (parallel [(set (match_operand:XF 0 "register_operand" "")
13213 (unspec:XF [(match_dup 5) (match_dup 1)]
13215 (clobber (match_scratch:XF 6 ""))])]
13216 "TARGET_USE_FANCY_MATH_387
13217 && flag_unsafe_math_optimizations"
13221 if (optimize_insn_for_size_p ())
13224 for (i = 2; i < 6; i++)
13225 operands[i] = gen_reg_rtx (XFmode);
13227 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13230 (define_expand "asin<mode>2"
13231 [(use (match_operand:MODEF 0 "register_operand" ""))
13232 (use (match_operand:MODEF 1 "general_operand" ""))]
13233 "TARGET_USE_FANCY_MATH_387
13234 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13235 || TARGET_MIX_SSE_I387)
13236 && flag_unsafe_math_optimizations"
13238 rtx op0 = gen_reg_rtx (XFmode);
13239 rtx op1 = gen_reg_rtx (XFmode);
13241 if (optimize_insn_for_size_p ())
13244 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13245 emit_insn (gen_asinxf2 (op0, op1));
13246 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13250 (define_expand "acosxf2"
13251 [(set (match_dup 2)
13252 (mult:XF (match_operand:XF 1 "register_operand" "")
13254 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13255 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13256 (parallel [(set (match_operand:XF 0 "register_operand" "")
13257 (unspec:XF [(match_dup 1) (match_dup 5)]
13259 (clobber (match_scratch:XF 6 ""))])]
13260 "TARGET_USE_FANCY_MATH_387
13261 && flag_unsafe_math_optimizations"
13265 if (optimize_insn_for_size_p ())
13268 for (i = 2; i < 6; i++)
13269 operands[i] = gen_reg_rtx (XFmode);
13271 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13274 (define_expand "acos<mode>2"
13275 [(use (match_operand:MODEF 0 "register_operand" ""))
13276 (use (match_operand:MODEF 1 "general_operand" ""))]
13277 "TARGET_USE_FANCY_MATH_387
13278 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13279 || TARGET_MIX_SSE_I387)
13280 && flag_unsafe_math_optimizations"
13282 rtx op0 = gen_reg_rtx (XFmode);
13283 rtx op1 = gen_reg_rtx (XFmode);
13285 if (optimize_insn_for_size_p ())
13288 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13289 emit_insn (gen_acosxf2 (op0, op1));
13290 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13294 (define_insn "fyl2xxf3_i387"
13295 [(set (match_operand:XF 0 "register_operand" "=f")
13296 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13297 (match_operand:XF 2 "register_operand" "u")]
13299 (clobber (match_scratch:XF 3 "=2"))]
13300 "TARGET_USE_FANCY_MATH_387
13301 && flag_unsafe_math_optimizations"
13303 [(set_attr "type" "fpspc")
13304 (set_attr "mode" "XF")])
13306 (define_insn "fyl2x_extend<mode>xf3_i387"
13307 [(set (match_operand:XF 0 "register_operand" "=f")
13308 (unspec:XF [(float_extend:XF
13309 (match_operand:MODEF 1 "register_operand" "0"))
13310 (match_operand:XF 2 "register_operand" "u")]
13312 (clobber (match_scratch:XF 3 "=2"))]
13313 "TARGET_USE_FANCY_MATH_387
13314 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13315 || TARGET_MIX_SSE_I387)
13316 && flag_unsafe_math_optimizations"
13318 [(set_attr "type" "fpspc")
13319 (set_attr "mode" "XF")])
13321 (define_expand "logxf2"
13322 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13323 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13324 (match_dup 2)] UNSPEC_FYL2X))
13325 (clobber (match_scratch:XF 3 ""))])]
13326 "TARGET_USE_FANCY_MATH_387
13327 && flag_unsafe_math_optimizations"
13329 operands[2] = gen_reg_rtx (XFmode);
13330 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13333 (define_expand "log<mode>2"
13334 [(use (match_operand:MODEF 0 "register_operand" ""))
13335 (use (match_operand:MODEF 1 "register_operand" ""))]
13336 "TARGET_USE_FANCY_MATH_387
13337 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13338 || TARGET_MIX_SSE_I387)
13339 && flag_unsafe_math_optimizations"
13341 rtx op0 = gen_reg_rtx (XFmode);
13343 rtx op2 = gen_reg_rtx (XFmode);
13344 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13346 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13347 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13351 (define_expand "log10xf2"
13352 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13353 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13354 (match_dup 2)] UNSPEC_FYL2X))
13355 (clobber (match_scratch:XF 3 ""))])]
13356 "TARGET_USE_FANCY_MATH_387
13357 && flag_unsafe_math_optimizations"
13359 operands[2] = gen_reg_rtx (XFmode);
13360 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13363 (define_expand "log10<mode>2"
13364 [(use (match_operand:MODEF 0 "register_operand" ""))
13365 (use (match_operand:MODEF 1 "register_operand" ""))]
13366 "TARGET_USE_FANCY_MATH_387
13367 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13368 || TARGET_MIX_SSE_I387)
13369 && flag_unsafe_math_optimizations"
13371 rtx op0 = gen_reg_rtx (XFmode);
13373 rtx op2 = gen_reg_rtx (XFmode);
13374 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13376 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13377 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13381 (define_expand "log2xf2"
13382 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13383 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13384 (match_dup 2)] UNSPEC_FYL2X))
13385 (clobber (match_scratch:XF 3 ""))])]
13386 "TARGET_USE_FANCY_MATH_387
13387 && flag_unsafe_math_optimizations"
13389 operands[2] = gen_reg_rtx (XFmode);
13390 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13393 (define_expand "log2<mode>2"
13394 [(use (match_operand:MODEF 0 "register_operand" ""))
13395 (use (match_operand:MODEF 1 "register_operand" ""))]
13396 "TARGET_USE_FANCY_MATH_387
13397 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13398 || TARGET_MIX_SSE_I387)
13399 && flag_unsafe_math_optimizations"
13401 rtx op0 = gen_reg_rtx (XFmode);
13403 rtx op2 = gen_reg_rtx (XFmode);
13404 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13406 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13407 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13411 (define_insn "fyl2xp1xf3_i387"
13412 [(set (match_operand:XF 0 "register_operand" "=f")
13413 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13414 (match_operand:XF 2 "register_operand" "u")]
13416 (clobber (match_scratch:XF 3 "=2"))]
13417 "TARGET_USE_FANCY_MATH_387
13418 && flag_unsafe_math_optimizations"
13420 [(set_attr "type" "fpspc")
13421 (set_attr "mode" "XF")])
13423 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13424 [(set (match_operand:XF 0 "register_operand" "=f")
13425 (unspec:XF [(float_extend:XF
13426 (match_operand:MODEF 1 "register_operand" "0"))
13427 (match_operand:XF 2 "register_operand" "u")]
13429 (clobber (match_scratch:XF 3 "=2"))]
13430 "TARGET_USE_FANCY_MATH_387
13431 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13432 || TARGET_MIX_SSE_I387)
13433 && flag_unsafe_math_optimizations"
13435 [(set_attr "type" "fpspc")
13436 (set_attr "mode" "XF")])
13438 (define_expand "log1pxf2"
13439 [(use (match_operand:XF 0 "register_operand" ""))
13440 (use (match_operand:XF 1 "register_operand" ""))]
13441 "TARGET_USE_FANCY_MATH_387
13442 && flag_unsafe_math_optimizations"
13444 if (optimize_insn_for_size_p ())
13447 ix86_emit_i387_log1p (operands[0], operands[1]);
13451 (define_expand "log1p<mode>2"
13452 [(use (match_operand:MODEF 0 "register_operand" ""))
13453 (use (match_operand:MODEF 1 "register_operand" ""))]
13454 "TARGET_USE_FANCY_MATH_387
13455 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13456 || TARGET_MIX_SSE_I387)
13457 && flag_unsafe_math_optimizations"
13461 if (optimize_insn_for_size_p ())
13464 op0 = gen_reg_rtx (XFmode);
13466 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13468 ix86_emit_i387_log1p (op0, operands[1]);
13469 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13473 (define_insn "fxtractxf3_i387"
13474 [(set (match_operand:XF 0 "register_operand" "=f")
13475 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13476 UNSPEC_XTRACT_FRACT))
13477 (set (match_operand:XF 1 "register_operand" "=u")
13478 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13479 "TARGET_USE_FANCY_MATH_387
13480 && flag_unsafe_math_optimizations"
13482 [(set_attr "type" "fpspc")
13483 (set_attr "mode" "XF")])
13485 (define_insn "fxtract_extend<mode>xf3_i387"
13486 [(set (match_operand:XF 0 "register_operand" "=f")
13487 (unspec:XF [(float_extend:XF
13488 (match_operand:MODEF 2 "register_operand" "0"))]
13489 UNSPEC_XTRACT_FRACT))
13490 (set (match_operand:XF 1 "register_operand" "=u")
13491 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13492 "TARGET_USE_FANCY_MATH_387
13493 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13494 || TARGET_MIX_SSE_I387)
13495 && flag_unsafe_math_optimizations"
13497 [(set_attr "type" "fpspc")
13498 (set_attr "mode" "XF")])
13500 (define_expand "logbxf2"
13501 [(parallel [(set (match_dup 2)
13502 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13503 UNSPEC_XTRACT_FRACT))
13504 (set (match_operand:XF 0 "register_operand" "")
13505 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13506 "TARGET_USE_FANCY_MATH_387
13507 && flag_unsafe_math_optimizations"
13509 operands[2] = gen_reg_rtx (XFmode);
13512 (define_expand "logb<mode>2"
13513 [(use (match_operand:MODEF 0 "register_operand" ""))
13514 (use (match_operand:MODEF 1 "register_operand" ""))]
13515 "TARGET_USE_FANCY_MATH_387
13516 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13517 || TARGET_MIX_SSE_I387)
13518 && flag_unsafe_math_optimizations"
13520 rtx op0 = gen_reg_rtx (XFmode);
13521 rtx op1 = gen_reg_rtx (XFmode);
13523 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13524 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13528 (define_expand "ilogbxf2"
13529 [(use (match_operand:SI 0 "register_operand" ""))
13530 (use (match_operand:XF 1 "register_operand" ""))]
13531 "TARGET_USE_FANCY_MATH_387
13532 && flag_unsafe_math_optimizations"
13536 if (optimize_insn_for_size_p ())
13539 op0 = gen_reg_rtx (XFmode);
13540 op1 = gen_reg_rtx (XFmode);
13542 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13543 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13547 (define_expand "ilogb<mode>2"
13548 [(use (match_operand:SI 0 "register_operand" ""))
13549 (use (match_operand:MODEF 1 "register_operand" ""))]
13550 "TARGET_USE_FANCY_MATH_387
13551 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13552 || TARGET_MIX_SSE_I387)
13553 && flag_unsafe_math_optimizations"
13557 if (optimize_insn_for_size_p ())
13560 op0 = gen_reg_rtx (XFmode);
13561 op1 = gen_reg_rtx (XFmode);
13563 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13564 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13568 (define_insn "*f2xm1xf2_i387"
13569 [(set (match_operand:XF 0 "register_operand" "=f")
13570 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13572 "TARGET_USE_FANCY_MATH_387
13573 && flag_unsafe_math_optimizations"
13575 [(set_attr "type" "fpspc")
13576 (set_attr "mode" "XF")])
13578 (define_insn "*fscalexf4_i387"
13579 [(set (match_operand:XF 0 "register_operand" "=f")
13580 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13581 (match_operand:XF 3 "register_operand" "1")]
13582 UNSPEC_FSCALE_FRACT))
13583 (set (match_operand:XF 1 "register_operand" "=u")
13584 (unspec:XF [(match_dup 2) (match_dup 3)]
13585 UNSPEC_FSCALE_EXP))]
13586 "TARGET_USE_FANCY_MATH_387
13587 && flag_unsafe_math_optimizations"
13589 [(set_attr "type" "fpspc")
13590 (set_attr "mode" "XF")])
13592 (define_expand "expNcorexf3"
13593 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13594 (match_operand:XF 2 "register_operand" "")))
13595 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13596 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13597 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13598 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
13599 (parallel [(set (match_operand:XF 0 "register_operand" "")
13600 (unspec:XF [(match_dup 8) (match_dup 4)]
13601 UNSPEC_FSCALE_FRACT))
13603 (unspec:XF [(match_dup 8) (match_dup 4)]
13604 UNSPEC_FSCALE_EXP))])]
13605 "TARGET_USE_FANCY_MATH_387
13606 && flag_unsafe_math_optimizations"
13610 if (optimize_insn_for_size_p ())
13613 for (i = 3; i < 10; i++)
13614 operands[i] = gen_reg_rtx (XFmode);
13616 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
13619 (define_expand "expxf2"
13620 [(use (match_operand:XF 0 "register_operand" ""))
13621 (use (match_operand:XF 1 "register_operand" ""))]
13622 "TARGET_USE_FANCY_MATH_387
13623 && flag_unsafe_math_optimizations"
13627 if (optimize_insn_for_size_p ())
13630 op2 = gen_reg_rtx (XFmode);
13631 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
13633 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13637 (define_expand "exp<mode>2"
13638 [(use (match_operand:MODEF 0 "register_operand" ""))
13639 (use (match_operand:MODEF 1 "general_operand" ""))]
13640 "TARGET_USE_FANCY_MATH_387
13641 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13642 || TARGET_MIX_SSE_I387)
13643 && flag_unsafe_math_optimizations"
13647 if (optimize_insn_for_size_p ())
13650 op0 = gen_reg_rtx (XFmode);
13651 op1 = gen_reg_rtx (XFmode);
13653 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13654 emit_insn (gen_expxf2 (op0, op1));
13655 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13659 (define_expand "exp10xf2"
13660 [(use (match_operand:XF 0 "register_operand" ""))
13661 (use (match_operand:XF 1 "register_operand" ""))]
13662 "TARGET_USE_FANCY_MATH_387
13663 && flag_unsafe_math_optimizations"
13667 if (optimize_insn_for_size_p ())
13670 op2 = gen_reg_rtx (XFmode);
13671 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
13673 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13677 (define_expand "exp10<mode>2"
13678 [(use (match_operand:MODEF 0 "register_operand" ""))
13679 (use (match_operand:MODEF 1 "general_operand" ""))]
13680 "TARGET_USE_FANCY_MATH_387
13681 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13682 || TARGET_MIX_SSE_I387)
13683 && flag_unsafe_math_optimizations"
13687 if (optimize_insn_for_size_p ())
13690 op0 = gen_reg_rtx (XFmode);
13691 op1 = gen_reg_rtx (XFmode);
13693 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13694 emit_insn (gen_exp10xf2 (op0, op1));
13695 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13699 (define_expand "exp2xf2"
13700 [(use (match_operand:XF 0 "register_operand" ""))
13701 (use (match_operand:XF 1 "register_operand" ""))]
13702 "TARGET_USE_FANCY_MATH_387
13703 && flag_unsafe_math_optimizations"
13707 if (optimize_insn_for_size_p ())
13710 op2 = gen_reg_rtx (XFmode);
13711 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13713 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13717 (define_expand "exp2<mode>2"
13718 [(use (match_operand:MODEF 0 "register_operand" ""))
13719 (use (match_operand:MODEF 1 "general_operand" ""))]
13720 "TARGET_USE_FANCY_MATH_387
13721 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13722 || TARGET_MIX_SSE_I387)
13723 && flag_unsafe_math_optimizations"
13727 if (optimize_insn_for_size_p ())
13730 op0 = gen_reg_rtx (XFmode);
13731 op1 = gen_reg_rtx (XFmode);
13733 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13734 emit_insn (gen_exp2xf2 (op0, op1));
13735 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13739 (define_expand "expm1xf2"
13740 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13742 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13743 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13744 (set (match_dup 9) (float_extend:XF (match_dup 13)))
13745 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13746 (parallel [(set (match_dup 7)
13747 (unspec:XF [(match_dup 6) (match_dup 4)]
13748 UNSPEC_FSCALE_FRACT))
13750 (unspec:XF [(match_dup 6) (match_dup 4)]
13751 UNSPEC_FSCALE_EXP))])
13752 (parallel [(set (match_dup 10)
13753 (unspec:XF [(match_dup 9) (match_dup 8)]
13754 UNSPEC_FSCALE_FRACT))
13755 (set (match_dup 11)
13756 (unspec:XF [(match_dup 9) (match_dup 8)]
13757 UNSPEC_FSCALE_EXP))])
13758 (set (match_dup 12) (minus:XF (match_dup 10)
13759 (float_extend:XF (match_dup 13))))
13760 (set (match_operand:XF 0 "register_operand" "")
13761 (plus:XF (match_dup 12) (match_dup 7)))]
13762 "TARGET_USE_FANCY_MATH_387
13763 && flag_unsafe_math_optimizations"
13767 if (optimize_insn_for_size_p ())
13770 for (i = 2; i < 13; i++)
13771 operands[i] = gen_reg_rtx (XFmode);
13774 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
13776 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
13779 (define_expand "expm1<mode>2"
13780 [(use (match_operand:MODEF 0 "register_operand" ""))
13781 (use (match_operand:MODEF 1 "general_operand" ""))]
13782 "TARGET_USE_FANCY_MATH_387
13783 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13784 || TARGET_MIX_SSE_I387)
13785 && flag_unsafe_math_optimizations"
13789 if (optimize_insn_for_size_p ())
13792 op0 = gen_reg_rtx (XFmode);
13793 op1 = gen_reg_rtx (XFmode);
13795 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13796 emit_insn (gen_expm1xf2 (op0, op1));
13797 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13801 (define_expand "ldexpxf3"
13802 [(set (match_dup 3)
13803 (float:XF (match_operand:SI 2 "register_operand" "")))
13804 (parallel [(set (match_operand:XF 0 " register_operand" "")
13805 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13807 UNSPEC_FSCALE_FRACT))
13809 (unspec:XF [(match_dup 1) (match_dup 3)]
13810 UNSPEC_FSCALE_EXP))])]
13811 "TARGET_USE_FANCY_MATH_387
13812 && flag_unsafe_math_optimizations"
13814 if (optimize_insn_for_size_p ())
13817 operands[3] = gen_reg_rtx (XFmode);
13818 operands[4] = gen_reg_rtx (XFmode);
13821 (define_expand "ldexp<mode>3"
13822 [(use (match_operand:MODEF 0 "register_operand" ""))
13823 (use (match_operand:MODEF 1 "general_operand" ""))
13824 (use (match_operand:SI 2 "register_operand" ""))]
13825 "TARGET_USE_FANCY_MATH_387
13826 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13827 || TARGET_MIX_SSE_I387)
13828 && flag_unsafe_math_optimizations"
13832 if (optimize_insn_for_size_p ())
13835 op0 = gen_reg_rtx (XFmode);
13836 op1 = gen_reg_rtx (XFmode);
13838 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13839 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
13840 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13844 (define_expand "scalbxf3"
13845 [(parallel [(set (match_operand:XF 0 " register_operand" "")
13846 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13847 (match_operand:XF 2 "register_operand" "")]
13848 UNSPEC_FSCALE_FRACT))
13850 (unspec:XF [(match_dup 1) (match_dup 2)]
13851 UNSPEC_FSCALE_EXP))])]
13852 "TARGET_USE_FANCY_MATH_387
13853 && flag_unsafe_math_optimizations"
13855 if (optimize_insn_for_size_p ())
13858 operands[3] = gen_reg_rtx (XFmode);
13861 (define_expand "scalb<mode>3"
13862 [(use (match_operand:MODEF 0 "register_operand" ""))
13863 (use (match_operand:MODEF 1 "general_operand" ""))
13864 (use (match_operand:MODEF 2 "general_operand" ""))]
13865 "TARGET_USE_FANCY_MATH_387
13866 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13867 || TARGET_MIX_SSE_I387)
13868 && flag_unsafe_math_optimizations"
13872 if (optimize_insn_for_size_p ())
13875 op0 = gen_reg_rtx (XFmode);
13876 op1 = gen_reg_rtx (XFmode);
13877 op2 = gen_reg_rtx (XFmode);
13879 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13880 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13881 emit_insn (gen_scalbxf3 (op0, op1, op2));
13882 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13886 (define_expand "significandxf2"
13887 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13888 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13889 UNSPEC_XTRACT_FRACT))
13891 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13892 "TARGET_USE_FANCY_MATH_387
13893 && flag_unsafe_math_optimizations"
13895 operands[2] = gen_reg_rtx (XFmode);
13898 (define_expand "significand<mode>2"
13899 [(use (match_operand:MODEF 0 "register_operand" ""))
13900 (use (match_operand:MODEF 1 "register_operand" ""))]
13901 "TARGET_USE_FANCY_MATH_387
13902 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13903 || TARGET_MIX_SSE_I387)
13904 && flag_unsafe_math_optimizations"
13906 rtx op0 = gen_reg_rtx (XFmode);
13907 rtx op1 = gen_reg_rtx (XFmode);
13909 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13910 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13915 (define_insn "sse4_1_round<mode>2"
13916 [(set (match_operand:MODEF 0 "register_operand" "=x")
13917 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
13918 (match_operand:SI 2 "const_0_to_15_operand" "n")]
13921 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
13922 [(set_attr "type" "ssecvt")
13923 (set_attr "prefix_extra" "1")
13924 (set_attr "prefix" "maybe_vex")
13925 (set_attr "mode" "<MODE>")])
13927 (define_insn "rintxf2"
13928 [(set (match_operand:XF 0 "register_operand" "=f")
13929 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13931 "TARGET_USE_FANCY_MATH_387
13932 && flag_unsafe_math_optimizations"
13934 [(set_attr "type" "fpspc")
13935 (set_attr "mode" "XF")])
13937 (define_expand "rint<mode>2"
13938 [(use (match_operand:MODEF 0 "register_operand" ""))
13939 (use (match_operand:MODEF 1 "register_operand" ""))]
13940 "(TARGET_USE_FANCY_MATH_387
13941 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13942 || TARGET_MIX_SSE_I387)
13943 && flag_unsafe_math_optimizations)
13944 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13945 && !flag_trapping_math)"
13947 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13948 && !flag_trapping_math)
13950 if (!TARGET_ROUND && optimize_insn_for_size_p ())
13953 emit_insn (gen_sse4_1_round<mode>2
13954 (operands[0], operands[1], GEN_INT (0x04)));
13956 ix86_expand_rint (operand0, operand1);
13960 rtx op0 = gen_reg_rtx (XFmode);
13961 rtx op1 = gen_reg_rtx (XFmode);
13963 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13964 emit_insn (gen_rintxf2 (op0, op1));
13966 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13971 (define_expand "round<mode>2"
13972 [(match_operand:MODEF 0 "register_operand" "")
13973 (match_operand:MODEF 1 "nonimmediate_operand" "")]
13974 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13975 && !flag_trapping_math && !flag_rounding_math"
13977 if (optimize_insn_for_size_p ())
13979 if (TARGET_64BIT || (<MODE>mode != DFmode))
13980 ix86_expand_round (operand0, operand1);
13982 ix86_expand_rounddf_32 (operand0, operand1);
13986 (define_insn_and_split "*fistdi2_1"
13987 [(set (match_operand:DI 0 "nonimmediate_operand" "")
13988 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
13990 "TARGET_USE_FANCY_MATH_387
13991 && can_create_pseudo_p ()"
13996 if (memory_operand (operands[0], VOIDmode))
13997 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14000 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14001 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14006 [(set_attr "type" "fpspc")
14007 (set_attr "mode" "DI")])
14009 (define_insn "fistdi2"
14010 [(set (match_operand:DI 0 "memory_operand" "=m")
14011 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14013 (clobber (match_scratch:XF 2 "=&1f"))]
14014 "TARGET_USE_FANCY_MATH_387"
14015 "* return output_fix_trunc (insn, operands, 0);"
14016 [(set_attr "type" "fpspc")
14017 (set_attr "mode" "DI")])
14019 (define_insn "fistdi2_with_temp"
14020 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14021 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14023 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14024 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14025 "TARGET_USE_FANCY_MATH_387"
14027 [(set_attr "type" "fpspc")
14028 (set_attr "mode" "DI")])
14031 [(set (match_operand:DI 0 "register_operand" "")
14032 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14034 (clobber (match_operand:DI 2 "memory_operand" ""))
14035 (clobber (match_scratch 3 ""))]
14037 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14038 (clobber (match_dup 3))])
14039 (set (match_dup 0) (match_dup 2))])
14042 [(set (match_operand:DI 0 "memory_operand" "")
14043 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14045 (clobber (match_operand:DI 2 "memory_operand" ""))
14046 (clobber (match_scratch 3 ""))]
14048 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14049 (clobber (match_dup 3))])])
14051 (define_insn_and_split "*fist<mode>2_1"
14052 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14053 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14055 "TARGET_USE_FANCY_MATH_387
14056 && can_create_pseudo_p ()"
14061 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14062 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14066 [(set_attr "type" "fpspc")
14067 (set_attr "mode" "<MODE>")])
14069 (define_insn "fist<mode>2"
14070 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14071 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14073 "TARGET_USE_FANCY_MATH_387"
14074 "* return output_fix_trunc (insn, operands, 0);"
14075 [(set_attr "type" "fpspc")
14076 (set_attr "mode" "<MODE>")])
14078 (define_insn "fist<mode>2_with_temp"
14079 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14080 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14082 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14083 "TARGET_USE_FANCY_MATH_387"
14085 [(set_attr "type" "fpspc")
14086 (set_attr "mode" "<MODE>")])
14089 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14090 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14092 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14094 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14095 (set (match_dup 0) (match_dup 2))])
14098 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14099 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14101 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14103 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))])
14105 (define_expand "lrintxf<mode>2"
14106 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14107 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14109 "TARGET_USE_FANCY_MATH_387"
14112 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14113 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14114 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14115 UNSPEC_FIX_NOTRUNC))]
14116 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14117 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
14120 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14121 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14122 (match_operand:MODEF 1 "register_operand" "")]
14123 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14124 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14125 && !flag_trapping_math && !flag_rounding_math"
14127 if (optimize_insn_for_size_p ())
14129 ix86_expand_lround (operand0, operand1);
14133 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14134 (define_insn_and_split "frndintxf2_floor"
14135 [(set (match_operand:XF 0 "register_operand" "")
14136 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14137 UNSPEC_FRNDINT_FLOOR))
14138 (clobber (reg:CC FLAGS_REG))]
14139 "TARGET_USE_FANCY_MATH_387
14140 && flag_unsafe_math_optimizations
14141 && can_create_pseudo_p ()"
14146 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14148 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14149 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14151 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14152 operands[2], operands[3]));
14155 [(set_attr "type" "frndint")
14156 (set_attr "i387_cw" "floor")
14157 (set_attr "mode" "XF")])
14159 (define_insn "frndintxf2_floor_i387"
14160 [(set (match_operand:XF 0 "register_operand" "=f")
14161 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14162 UNSPEC_FRNDINT_FLOOR))
14163 (use (match_operand:HI 2 "memory_operand" "m"))
14164 (use (match_operand:HI 3 "memory_operand" "m"))]
14165 "TARGET_USE_FANCY_MATH_387
14166 && flag_unsafe_math_optimizations"
14167 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14168 [(set_attr "type" "frndint")
14169 (set_attr "i387_cw" "floor")
14170 (set_attr "mode" "XF")])
14172 (define_expand "floorxf2"
14173 [(use (match_operand:XF 0 "register_operand" ""))
14174 (use (match_operand:XF 1 "register_operand" ""))]
14175 "TARGET_USE_FANCY_MATH_387
14176 && flag_unsafe_math_optimizations"
14178 if (optimize_insn_for_size_p ())
14180 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14184 (define_expand "floor<mode>2"
14185 [(use (match_operand:MODEF 0 "register_operand" ""))
14186 (use (match_operand:MODEF 1 "register_operand" ""))]
14187 "(TARGET_USE_FANCY_MATH_387
14188 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14189 || TARGET_MIX_SSE_I387)
14190 && flag_unsafe_math_optimizations)
14191 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14192 && !flag_trapping_math)"
14194 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14195 && !flag_trapping_math
14196 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14198 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14201 emit_insn (gen_sse4_1_round<mode>2
14202 (operands[0], operands[1], GEN_INT (0x01)));
14203 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14204 ix86_expand_floorceil (operand0, operand1, true);
14206 ix86_expand_floorceildf_32 (operand0, operand1, true);
14212 if (optimize_insn_for_size_p ())
14215 op0 = gen_reg_rtx (XFmode);
14216 op1 = gen_reg_rtx (XFmode);
14217 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14218 emit_insn (gen_frndintxf2_floor (op0, op1));
14220 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14225 (define_insn_and_split "*fist<mode>2_floor_1"
14226 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14227 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14228 UNSPEC_FIST_FLOOR))
14229 (clobber (reg:CC FLAGS_REG))]
14230 "TARGET_USE_FANCY_MATH_387
14231 && flag_unsafe_math_optimizations
14232 && can_create_pseudo_p ()"
14237 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14239 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14240 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14241 if (memory_operand (operands[0], VOIDmode))
14242 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14243 operands[2], operands[3]));
14246 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14247 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14248 operands[2], operands[3],
14253 [(set_attr "type" "fistp")
14254 (set_attr "i387_cw" "floor")
14255 (set_attr "mode" "<MODE>")])
14257 (define_insn "fistdi2_floor"
14258 [(set (match_operand:DI 0 "memory_operand" "=m")
14259 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14260 UNSPEC_FIST_FLOOR))
14261 (use (match_operand:HI 2 "memory_operand" "m"))
14262 (use (match_operand:HI 3 "memory_operand" "m"))
14263 (clobber (match_scratch:XF 4 "=&1f"))]
14264 "TARGET_USE_FANCY_MATH_387
14265 && flag_unsafe_math_optimizations"
14266 "* return output_fix_trunc (insn, operands, 0);"
14267 [(set_attr "type" "fistp")
14268 (set_attr "i387_cw" "floor")
14269 (set_attr "mode" "DI")])
14271 (define_insn "fistdi2_floor_with_temp"
14272 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14273 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14274 UNSPEC_FIST_FLOOR))
14275 (use (match_operand:HI 2 "memory_operand" "m,m"))
14276 (use (match_operand:HI 3 "memory_operand" "m,m"))
14277 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14278 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14279 "TARGET_USE_FANCY_MATH_387
14280 && flag_unsafe_math_optimizations"
14282 [(set_attr "type" "fistp")
14283 (set_attr "i387_cw" "floor")
14284 (set_attr "mode" "DI")])
14287 [(set (match_operand:DI 0 "register_operand" "")
14288 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14289 UNSPEC_FIST_FLOOR))
14290 (use (match_operand:HI 2 "memory_operand" ""))
14291 (use (match_operand:HI 3 "memory_operand" ""))
14292 (clobber (match_operand:DI 4 "memory_operand" ""))
14293 (clobber (match_scratch 5 ""))]
14295 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14296 (use (match_dup 2))
14297 (use (match_dup 3))
14298 (clobber (match_dup 5))])
14299 (set (match_dup 0) (match_dup 4))])
14302 [(set (match_operand:DI 0 "memory_operand" "")
14303 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14304 UNSPEC_FIST_FLOOR))
14305 (use (match_operand:HI 2 "memory_operand" ""))
14306 (use (match_operand:HI 3 "memory_operand" ""))
14307 (clobber (match_operand:DI 4 "memory_operand" ""))
14308 (clobber (match_scratch 5 ""))]
14310 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14311 (use (match_dup 2))
14312 (use (match_dup 3))
14313 (clobber (match_dup 5))])])
14315 (define_insn "fist<mode>2_floor"
14316 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14317 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14318 UNSPEC_FIST_FLOOR))
14319 (use (match_operand:HI 2 "memory_operand" "m"))
14320 (use (match_operand:HI 3 "memory_operand" "m"))]
14321 "TARGET_USE_FANCY_MATH_387
14322 && flag_unsafe_math_optimizations"
14323 "* return output_fix_trunc (insn, operands, 0);"
14324 [(set_attr "type" "fistp")
14325 (set_attr "i387_cw" "floor")
14326 (set_attr "mode" "<MODE>")])
14328 (define_insn "fist<mode>2_floor_with_temp"
14329 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14330 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14331 UNSPEC_FIST_FLOOR))
14332 (use (match_operand:HI 2 "memory_operand" "m,m"))
14333 (use (match_operand:HI 3 "memory_operand" "m,m"))
14334 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14335 "TARGET_USE_FANCY_MATH_387
14336 && flag_unsafe_math_optimizations"
14338 [(set_attr "type" "fistp")
14339 (set_attr "i387_cw" "floor")
14340 (set_attr "mode" "<MODE>")])
14343 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14344 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14345 UNSPEC_FIST_FLOOR))
14346 (use (match_operand:HI 2 "memory_operand" ""))
14347 (use (match_operand:HI 3 "memory_operand" ""))
14348 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14350 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14351 UNSPEC_FIST_FLOOR))
14352 (use (match_dup 2))
14353 (use (match_dup 3))])
14354 (set (match_dup 0) (match_dup 4))])
14357 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14358 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14359 UNSPEC_FIST_FLOOR))
14360 (use (match_operand:HI 2 "memory_operand" ""))
14361 (use (match_operand:HI 3 "memory_operand" ""))
14362 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14364 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14365 UNSPEC_FIST_FLOOR))
14366 (use (match_dup 2))
14367 (use (match_dup 3))])])
14369 (define_expand "lfloorxf<mode>2"
14370 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14371 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14372 UNSPEC_FIST_FLOOR))
14373 (clobber (reg:CC FLAGS_REG))])]
14374 "TARGET_USE_FANCY_MATH_387
14375 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14376 && flag_unsafe_math_optimizations"
14379 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14380 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14381 (match_operand:MODEF 1 "register_operand" "")]
14382 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14383 && !flag_trapping_math"
14385 if (TARGET_64BIT && optimize_insn_for_size_p ())
14387 ix86_expand_lfloorceil (operand0, operand1, true);
14391 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14392 (define_insn_and_split "frndintxf2_ceil"
14393 [(set (match_operand:XF 0 "register_operand" "")
14394 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14395 UNSPEC_FRNDINT_CEIL))
14396 (clobber (reg:CC FLAGS_REG))]
14397 "TARGET_USE_FANCY_MATH_387
14398 && flag_unsafe_math_optimizations
14399 && can_create_pseudo_p ()"
14404 ix86_optimize_mode_switching[I387_CEIL] = 1;
14406 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14407 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14409 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14410 operands[2], operands[3]));
14413 [(set_attr "type" "frndint")
14414 (set_attr "i387_cw" "ceil")
14415 (set_attr "mode" "XF")])
14417 (define_insn "frndintxf2_ceil_i387"
14418 [(set (match_operand:XF 0 "register_operand" "=f")
14419 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14420 UNSPEC_FRNDINT_CEIL))
14421 (use (match_operand:HI 2 "memory_operand" "m"))
14422 (use (match_operand:HI 3 "memory_operand" "m"))]
14423 "TARGET_USE_FANCY_MATH_387
14424 && flag_unsafe_math_optimizations"
14425 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14426 [(set_attr "type" "frndint")
14427 (set_attr "i387_cw" "ceil")
14428 (set_attr "mode" "XF")])
14430 (define_expand "ceilxf2"
14431 [(use (match_operand:XF 0 "register_operand" ""))
14432 (use (match_operand:XF 1 "register_operand" ""))]
14433 "TARGET_USE_FANCY_MATH_387
14434 && flag_unsafe_math_optimizations"
14436 if (optimize_insn_for_size_p ())
14438 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
14442 (define_expand "ceil<mode>2"
14443 [(use (match_operand:MODEF 0 "register_operand" ""))
14444 (use (match_operand:MODEF 1 "register_operand" ""))]
14445 "(TARGET_USE_FANCY_MATH_387
14446 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14447 || TARGET_MIX_SSE_I387)
14448 && flag_unsafe_math_optimizations)
14449 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14450 && !flag_trapping_math)"
14452 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14453 && !flag_trapping_math
14454 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14457 emit_insn (gen_sse4_1_round<mode>2
14458 (operands[0], operands[1], GEN_INT (0x02)));
14459 else if (optimize_insn_for_size_p ())
14461 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14462 ix86_expand_floorceil (operand0, operand1, false);
14464 ix86_expand_floorceildf_32 (operand0, operand1, false);
14470 if (optimize_insn_for_size_p ())
14473 op0 = gen_reg_rtx (XFmode);
14474 op1 = gen_reg_rtx (XFmode);
14475 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14476 emit_insn (gen_frndintxf2_ceil (op0, op1));
14478 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14483 (define_insn_and_split "*fist<mode>2_ceil_1"
14484 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14485 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14487 (clobber (reg:CC FLAGS_REG))]
14488 "TARGET_USE_FANCY_MATH_387
14489 && flag_unsafe_math_optimizations
14490 && can_create_pseudo_p ()"
14495 ix86_optimize_mode_switching[I387_CEIL] = 1;
14497 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14498 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14499 if (memory_operand (operands[0], VOIDmode))
14500 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
14501 operands[2], operands[3]));
14504 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14505 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
14506 operands[2], operands[3],
14511 [(set_attr "type" "fistp")
14512 (set_attr "i387_cw" "ceil")
14513 (set_attr "mode" "<MODE>")])
14515 (define_insn "fistdi2_ceil"
14516 [(set (match_operand:DI 0 "memory_operand" "=m")
14517 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14519 (use (match_operand:HI 2 "memory_operand" "m"))
14520 (use (match_operand:HI 3 "memory_operand" "m"))
14521 (clobber (match_scratch:XF 4 "=&1f"))]
14522 "TARGET_USE_FANCY_MATH_387
14523 && flag_unsafe_math_optimizations"
14524 "* return output_fix_trunc (insn, operands, 0);"
14525 [(set_attr "type" "fistp")
14526 (set_attr "i387_cw" "ceil")
14527 (set_attr "mode" "DI")])
14529 (define_insn "fistdi2_ceil_with_temp"
14530 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14531 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14533 (use (match_operand:HI 2 "memory_operand" "m,m"))
14534 (use (match_operand:HI 3 "memory_operand" "m,m"))
14535 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14536 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14537 "TARGET_USE_FANCY_MATH_387
14538 && flag_unsafe_math_optimizations"
14540 [(set_attr "type" "fistp")
14541 (set_attr "i387_cw" "ceil")
14542 (set_attr "mode" "DI")])
14545 [(set (match_operand:DI 0 "register_operand" "")
14546 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14548 (use (match_operand:HI 2 "memory_operand" ""))
14549 (use (match_operand:HI 3 "memory_operand" ""))
14550 (clobber (match_operand:DI 4 "memory_operand" ""))
14551 (clobber (match_scratch 5 ""))]
14553 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14554 (use (match_dup 2))
14555 (use (match_dup 3))
14556 (clobber (match_dup 5))])
14557 (set (match_dup 0) (match_dup 4))])
14560 [(set (match_operand:DI 0 "memory_operand" "")
14561 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14563 (use (match_operand:HI 2 "memory_operand" ""))
14564 (use (match_operand:HI 3 "memory_operand" ""))
14565 (clobber (match_operand:DI 4 "memory_operand" ""))
14566 (clobber (match_scratch 5 ""))]
14568 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14569 (use (match_dup 2))
14570 (use (match_dup 3))
14571 (clobber (match_dup 5))])])
14573 (define_insn "fist<mode>2_ceil"
14574 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14575 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14577 (use (match_operand:HI 2 "memory_operand" "m"))
14578 (use (match_operand:HI 3 "memory_operand" "m"))]
14579 "TARGET_USE_FANCY_MATH_387
14580 && flag_unsafe_math_optimizations"
14581 "* return output_fix_trunc (insn, operands, 0);"
14582 [(set_attr "type" "fistp")
14583 (set_attr "i387_cw" "ceil")
14584 (set_attr "mode" "<MODE>")])
14586 (define_insn "fist<mode>2_ceil_with_temp"
14587 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14588 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14590 (use (match_operand:HI 2 "memory_operand" "m,m"))
14591 (use (match_operand:HI 3 "memory_operand" "m,m"))
14592 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14593 "TARGET_USE_FANCY_MATH_387
14594 && flag_unsafe_math_optimizations"
14596 [(set_attr "type" "fistp")
14597 (set_attr "i387_cw" "ceil")
14598 (set_attr "mode" "<MODE>")])
14601 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14602 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14604 (use (match_operand:HI 2 "memory_operand" ""))
14605 (use (match_operand:HI 3 "memory_operand" ""))
14606 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14608 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14610 (use (match_dup 2))
14611 (use (match_dup 3))])
14612 (set (match_dup 0) (match_dup 4))])
14615 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14616 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14618 (use (match_operand:HI 2 "memory_operand" ""))
14619 (use (match_operand:HI 3 "memory_operand" ""))
14620 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14622 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14624 (use (match_dup 2))
14625 (use (match_dup 3))])])
14627 (define_expand "lceilxf<mode>2"
14628 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14629 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14631 (clobber (reg:CC FLAGS_REG))])]
14632 "TARGET_USE_FANCY_MATH_387
14633 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14634 && flag_unsafe_math_optimizations"
14637 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
14638 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14639 (match_operand:MODEF 1 "register_operand" "")]
14640 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14641 && !flag_trapping_math"
14643 ix86_expand_lfloorceil (operand0, operand1, false);
14647 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14648 (define_insn_and_split "frndintxf2_trunc"
14649 [(set (match_operand:XF 0 "register_operand" "")
14650 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14651 UNSPEC_FRNDINT_TRUNC))
14652 (clobber (reg:CC FLAGS_REG))]
14653 "TARGET_USE_FANCY_MATH_387
14654 && flag_unsafe_math_optimizations
14655 && can_create_pseudo_p ()"
14660 ix86_optimize_mode_switching[I387_TRUNC] = 1;
14662 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14663 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
14665 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
14666 operands[2], operands[3]));
14669 [(set_attr "type" "frndint")
14670 (set_attr "i387_cw" "trunc")
14671 (set_attr "mode" "XF")])
14673 (define_insn "frndintxf2_trunc_i387"
14674 [(set (match_operand:XF 0 "register_operand" "=f")
14675 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14676 UNSPEC_FRNDINT_TRUNC))
14677 (use (match_operand:HI 2 "memory_operand" "m"))
14678 (use (match_operand:HI 3 "memory_operand" "m"))]
14679 "TARGET_USE_FANCY_MATH_387
14680 && flag_unsafe_math_optimizations"
14681 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14682 [(set_attr "type" "frndint")
14683 (set_attr "i387_cw" "trunc")
14684 (set_attr "mode" "XF")])
14686 (define_expand "btruncxf2"
14687 [(use (match_operand:XF 0 "register_operand" ""))
14688 (use (match_operand:XF 1 "register_operand" ""))]
14689 "TARGET_USE_FANCY_MATH_387
14690 && flag_unsafe_math_optimizations"
14692 if (optimize_insn_for_size_p ())
14694 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
14698 (define_expand "btrunc<mode>2"
14699 [(use (match_operand:MODEF 0 "register_operand" ""))
14700 (use (match_operand:MODEF 1 "register_operand" ""))]
14701 "(TARGET_USE_FANCY_MATH_387
14702 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14703 || TARGET_MIX_SSE_I387)
14704 && flag_unsafe_math_optimizations)
14705 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14706 && !flag_trapping_math)"
14708 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14709 && !flag_trapping_math
14710 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14713 emit_insn (gen_sse4_1_round<mode>2
14714 (operands[0], operands[1], GEN_INT (0x03)));
14715 else if (optimize_insn_for_size_p ())
14717 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14718 ix86_expand_trunc (operand0, operand1);
14720 ix86_expand_truncdf_32 (operand0, operand1);
14726 if (optimize_insn_for_size_p ())
14729 op0 = gen_reg_rtx (XFmode);
14730 op1 = gen_reg_rtx (XFmode);
14731 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14732 emit_insn (gen_frndintxf2_trunc (op0, op1));
14734 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14739 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14740 (define_insn_and_split "frndintxf2_mask_pm"
14741 [(set (match_operand:XF 0 "register_operand" "")
14742 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14743 UNSPEC_FRNDINT_MASK_PM))
14744 (clobber (reg:CC FLAGS_REG))]
14745 "TARGET_USE_FANCY_MATH_387
14746 && flag_unsafe_math_optimizations
14747 && can_create_pseudo_p ()"
14752 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
14754 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14755 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
14757 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
14758 operands[2], operands[3]));
14761 [(set_attr "type" "frndint")
14762 (set_attr "i387_cw" "mask_pm")
14763 (set_attr "mode" "XF")])
14765 (define_insn "frndintxf2_mask_pm_i387"
14766 [(set (match_operand:XF 0 "register_operand" "=f")
14767 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14768 UNSPEC_FRNDINT_MASK_PM))
14769 (use (match_operand:HI 2 "memory_operand" "m"))
14770 (use (match_operand:HI 3 "memory_operand" "m"))]
14771 "TARGET_USE_FANCY_MATH_387
14772 && flag_unsafe_math_optimizations"
14773 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
14774 [(set_attr "type" "frndint")
14775 (set_attr "i387_cw" "mask_pm")
14776 (set_attr "mode" "XF")])
14778 (define_expand "nearbyintxf2"
14779 [(use (match_operand:XF 0 "register_operand" ""))
14780 (use (match_operand:XF 1 "register_operand" ""))]
14781 "TARGET_USE_FANCY_MATH_387
14782 && flag_unsafe_math_optimizations"
14784 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
14789 (define_expand "nearbyint<mode>2"
14790 [(use (match_operand:MODEF 0 "register_operand" ""))
14791 (use (match_operand:MODEF 1 "register_operand" ""))]
14792 "TARGET_USE_FANCY_MATH_387
14793 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14794 || TARGET_MIX_SSE_I387)
14795 && flag_unsafe_math_optimizations"
14797 rtx op0 = gen_reg_rtx (XFmode);
14798 rtx op1 = gen_reg_rtx (XFmode);
14800 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14801 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
14803 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14807 (define_insn "fxam<mode>2_i387"
14808 [(set (match_operand:HI 0 "register_operand" "=a")
14810 [(match_operand:X87MODEF 1 "register_operand" "f")]
14812 "TARGET_USE_FANCY_MATH_387"
14813 "fxam\n\tfnstsw\t%0"
14814 [(set_attr "type" "multi")
14815 (set_attr "length" "4")
14816 (set_attr "unit" "i387")
14817 (set_attr "mode" "<MODE>")])
14819 (define_insn_and_split "fxam<mode>2_i387_with_temp"
14820 [(set (match_operand:HI 0 "register_operand" "")
14822 [(match_operand:MODEF 1 "memory_operand" "")]
14824 "TARGET_USE_FANCY_MATH_387
14825 && can_create_pseudo_p ()"
14828 [(set (match_dup 2)(match_dup 1))
14830 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
14832 operands[2] = gen_reg_rtx (<MODE>mode);
14834 MEM_VOLATILE_P (operands[1]) = 1;
14836 [(set_attr "type" "multi")
14837 (set_attr "unit" "i387")
14838 (set_attr "mode" "<MODE>")])
14840 (define_expand "isinfxf2"
14841 [(use (match_operand:SI 0 "register_operand" ""))
14842 (use (match_operand:XF 1 "register_operand" ""))]
14843 "TARGET_USE_FANCY_MATH_387
14844 && TARGET_C99_FUNCTIONS"
14846 rtx mask = GEN_INT (0x45);
14847 rtx val = GEN_INT (0x05);
14851 rtx scratch = gen_reg_rtx (HImode);
14852 rtx res = gen_reg_rtx (QImode);
14854 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
14856 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
14857 emit_insn (gen_cmpqi_ext_3 (scratch, val));
14858 cond = gen_rtx_fmt_ee (EQ, QImode,
14859 gen_rtx_REG (CCmode, FLAGS_REG),
14861 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
14862 emit_insn (gen_zero_extendqisi2 (operands[0], res));
14866 (define_expand "isinf<mode>2"
14867 [(use (match_operand:SI 0 "register_operand" ""))
14868 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
14869 "TARGET_USE_FANCY_MATH_387
14870 && TARGET_C99_FUNCTIONS
14871 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14873 rtx mask = GEN_INT (0x45);
14874 rtx val = GEN_INT (0x05);
14878 rtx scratch = gen_reg_rtx (HImode);
14879 rtx res = gen_reg_rtx (QImode);
14881 /* Remove excess precision by forcing value through memory. */
14882 if (memory_operand (operands[1], VOIDmode))
14883 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
14886 enum ix86_stack_slot slot = (virtuals_instantiated
14889 rtx temp = assign_386_stack_local (<MODE>mode, slot);
14891 emit_move_insn (temp, operands[1]);
14892 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
14895 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
14896 emit_insn (gen_cmpqi_ext_3 (scratch, val));
14897 cond = gen_rtx_fmt_ee (EQ, QImode,
14898 gen_rtx_REG (CCmode, FLAGS_REG),
14900 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
14901 emit_insn (gen_zero_extendqisi2 (operands[0], res));
14905 (define_expand "signbit<mode>2"
14906 [(use (match_operand:SI 0 "register_operand" ""))
14907 (use (match_operand:X87MODEF 1 "register_operand" ""))]
14908 "TARGET_USE_FANCY_MATH_387
14909 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14911 rtx mask = GEN_INT (0x0200);
14913 rtx scratch = gen_reg_rtx (HImode);
14915 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
14916 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
14920 ;; Block operation instructions
14923 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
14926 [(set_attr "length" "1")
14927 (set_attr "length_immediate" "0")
14928 (set_attr "modrm" "0")])
14930 (define_expand "movmemsi"
14931 [(use (match_operand:BLK 0 "memory_operand" ""))
14932 (use (match_operand:BLK 1 "memory_operand" ""))
14933 (use (match_operand:SI 2 "nonmemory_operand" ""))
14934 (use (match_operand:SI 3 "const_int_operand" ""))
14935 (use (match_operand:SI 4 "const_int_operand" ""))
14936 (use (match_operand:SI 5 "const_int_operand" ""))]
14939 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
14940 operands[4], operands[5]))
14946 (define_expand "movmemdi"
14947 [(use (match_operand:BLK 0 "memory_operand" ""))
14948 (use (match_operand:BLK 1 "memory_operand" ""))
14949 (use (match_operand:DI 2 "nonmemory_operand" ""))
14950 (use (match_operand:DI 3 "const_int_operand" ""))
14951 (use (match_operand:SI 4 "const_int_operand" ""))
14952 (use (match_operand:SI 5 "const_int_operand" ""))]
14955 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
14956 operands[4], operands[5]))
14962 ;; Most CPUs don't like single string operations
14963 ;; Handle this case here to simplify previous expander.
14965 (define_expand "strmov"
14966 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
14967 (set (match_operand 1 "memory_operand" "") (match_dup 4))
14968 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
14969 (clobber (reg:CC FLAGS_REG))])
14970 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
14971 (clobber (reg:CC FLAGS_REG))])]
14974 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
14976 /* If .md ever supports :P for Pmode, these can be directly
14977 in the pattern above. */
14978 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
14979 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
14981 /* Can't use this if the user has appropriated esi or edi. */
14982 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
14983 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
14985 emit_insn (gen_strmov_singleop (operands[0], operands[1],
14986 operands[2], operands[3],
14987 operands[5], operands[6]));
14991 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
14994 (define_expand "strmov_singleop"
14995 [(parallel [(set (match_operand 1 "memory_operand" "")
14996 (match_operand 3 "memory_operand" ""))
14997 (set (match_operand 0 "register_operand" "")
14998 (match_operand 4 "" ""))
14999 (set (match_operand 2 "register_operand" "")
15000 (match_operand 5 "" ""))])]
15002 "ix86_current_function_needs_cld = 1;")
15004 (define_insn "*strmovdi_rex_1"
15005 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15006 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15007 (set (match_operand:DI 0 "register_operand" "=D")
15008 (plus:DI (match_dup 2)
15010 (set (match_operand:DI 1 "register_operand" "=S")
15011 (plus:DI (match_dup 3)
15015 [(set_attr "type" "str")
15016 (set_attr "mode" "DI")
15017 (set_attr "memory" "both")])
15019 (define_insn "*strmovsi_1"
15020 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
15021 (mem:SI (match_operand:SI 3 "register_operand" "1")))
15022 (set (match_operand:SI 0 "register_operand" "=D")
15023 (plus:SI (match_dup 2)
15025 (set (match_operand:SI 1 "register_operand" "=S")
15026 (plus:SI (match_dup 3)
15030 [(set_attr "type" "str")
15031 (set_attr "mode" "SI")
15032 (set_attr "memory" "both")])
15034 (define_insn "*strmovsi_rex_1"
15035 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
15036 (mem:SI (match_operand:DI 3 "register_operand" "1")))
15037 (set (match_operand:DI 0 "register_operand" "=D")
15038 (plus:DI (match_dup 2)
15040 (set (match_operand:DI 1 "register_operand" "=S")
15041 (plus:DI (match_dup 3)
15045 [(set_attr "type" "str")
15046 (set_attr "mode" "SI")
15047 (set_attr "memory" "both")])
15049 (define_insn "*strmovhi_1"
15050 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
15051 (mem:HI (match_operand:SI 3 "register_operand" "1")))
15052 (set (match_operand:SI 0 "register_operand" "=D")
15053 (plus:SI (match_dup 2)
15055 (set (match_operand:SI 1 "register_operand" "=S")
15056 (plus:SI (match_dup 3)
15060 [(set_attr "type" "str")
15061 (set_attr "memory" "both")
15062 (set_attr "mode" "HI")])
15064 (define_insn "*strmovhi_rex_1"
15065 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
15066 (mem:HI (match_operand:DI 3 "register_operand" "1")))
15067 (set (match_operand:DI 0 "register_operand" "=D")
15068 (plus:DI (match_dup 2)
15070 (set (match_operand:DI 1 "register_operand" "=S")
15071 (plus:DI (match_dup 3)
15075 [(set_attr "type" "str")
15076 (set_attr "memory" "both")
15077 (set_attr "mode" "HI")])
15079 (define_insn "*strmovqi_1"
15080 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
15081 (mem:QI (match_operand:SI 3 "register_operand" "1")))
15082 (set (match_operand:SI 0 "register_operand" "=D")
15083 (plus:SI (match_dup 2)
15085 (set (match_operand:SI 1 "register_operand" "=S")
15086 (plus:SI (match_dup 3)
15090 [(set_attr "type" "str")
15091 (set_attr "memory" "both")
15092 (set_attr "mode" "QI")])
15094 (define_insn "*strmovqi_rex_1"
15095 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
15096 (mem:QI (match_operand:DI 3 "register_operand" "1")))
15097 (set (match_operand:DI 0 "register_operand" "=D")
15098 (plus:DI (match_dup 2)
15100 (set (match_operand:DI 1 "register_operand" "=S")
15101 (plus:DI (match_dup 3)
15105 [(set_attr "type" "str")
15106 (set_attr "memory" "both")
15107 (set_attr "prefix_rex" "0")
15108 (set_attr "mode" "QI")])
15110 (define_expand "rep_mov"
15111 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15112 (set (match_operand 0 "register_operand" "")
15113 (match_operand 5 "" ""))
15114 (set (match_operand 2 "register_operand" "")
15115 (match_operand 6 "" ""))
15116 (set (match_operand 1 "memory_operand" "")
15117 (match_operand 3 "memory_operand" ""))
15118 (use (match_dup 4))])]
15120 "ix86_current_function_needs_cld = 1;")
15122 (define_insn "*rep_movdi_rex64"
15123 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15124 (set (match_operand:DI 0 "register_operand" "=D")
15125 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15127 (match_operand:DI 3 "register_operand" "0")))
15128 (set (match_operand:DI 1 "register_operand" "=S")
15129 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15130 (match_operand:DI 4 "register_operand" "1")))
15131 (set (mem:BLK (match_dup 3))
15132 (mem:BLK (match_dup 4)))
15133 (use (match_dup 5))]
15136 [(set_attr "type" "str")
15137 (set_attr "prefix_rep" "1")
15138 (set_attr "memory" "both")
15139 (set_attr "mode" "DI")])
15141 (define_insn "*rep_movsi"
15142 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15143 (set (match_operand:SI 0 "register_operand" "=D")
15144 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
15146 (match_operand:SI 3 "register_operand" "0")))
15147 (set (match_operand:SI 1 "register_operand" "=S")
15148 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
15149 (match_operand:SI 4 "register_operand" "1")))
15150 (set (mem:BLK (match_dup 3))
15151 (mem:BLK (match_dup 4)))
15152 (use (match_dup 5))]
15154 "rep{%;} movs{l|d}"
15155 [(set_attr "type" "str")
15156 (set_attr "prefix_rep" "1")
15157 (set_attr "memory" "both")
15158 (set_attr "mode" "SI")])
15160 (define_insn "*rep_movsi_rex64"
15161 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15162 (set (match_operand:DI 0 "register_operand" "=D")
15163 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15165 (match_operand:DI 3 "register_operand" "0")))
15166 (set (match_operand:DI 1 "register_operand" "=S")
15167 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
15168 (match_operand:DI 4 "register_operand" "1")))
15169 (set (mem:BLK (match_dup 3))
15170 (mem:BLK (match_dup 4)))
15171 (use (match_dup 5))]
15173 "rep{%;} movs{l|d}"
15174 [(set_attr "type" "str")
15175 (set_attr "prefix_rep" "1")
15176 (set_attr "memory" "both")
15177 (set_attr "mode" "SI")])
15179 (define_insn "*rep_movqi"
15180 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15181 (set (match_operand:SI 0 "register_operand" "=D")
15182 (plus:SI (match_operand:SI 3 "register_operand" "0")
15183 (match_operand:SI 5 "register_operand" "2")))
15184 (set (match_operand:SI 1 "register_operand" "=S")
15185 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
15186 (set (mem:BLK (match_dup 3))
15187 (mem:BLK (match_dup 4)))
15188 (use (match_dup 5))]
15191 [(set_attr "type" "str")
15192 (set_attr "prefix_rep" "1")
15193 (set_attr "memory" "both")
15194 (set_attr "mode" "SI")])
15196 (define_insn "*rep_movqi_rex64"
15197 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15198 (set (match_operand:DI 0 "register_operand" "=D")
15199 (plus:DI (match_operand:DI 3 "register_operand" "0")
15200 (match_operand:DI 5 "register_operand" "2")))
15201 (set (match_operand:DI 1 "register_operand" "=S")
15202 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
15203 (set (mem:BLK (match_dup 3))
15204 (mem:BLK (match_dup 4)))
15205 (use (match_dup 5))]
15208 [(set_attr "type" "str")
15209 (set_attr "prefix_rep" "1")
15210 (set_attr "memory" "both")
15211 (set_attr "mode" "SI")])
15213 (define_expand "setmemsi"
15214 [(use (match_operand:BLK 0 "memory_operand" ""))
15215 (use (match_operand:SI 1 "nonmemory_operand" ""))
15216 (use (match_operand 2 "const_int_operand" ""))
15217 (use (match_operand 3 "const_int_operand" ""))
15218 (use (match_operand:SI 4 "const_int_operand" ""))
15219 (use (match_operand:SI 5 "const_int_operand" ""))]
15222 if (ix86_expand_setmem (operands[0], operands[1],
15223 operands[2], operands[3],
15224 operands[4], operands[5]))
15230 (define_expand "setmemdi"
15231 [(use (match_operand:BLK 0 "memory_operand" ""))
15232 (use (match_operand:DI 1 "nonmemory_operand" ""))
15233 (use (match_operand 2 "const_int_operand" ""))
15234 (use (match_operand 3 "const_int_operand" ""))
15235 (use (match_operand 4 "const_int_operand" ""))
15236 (use (match_operand 5 "const_int_operand" ""))]
15239 if (ix86_expand_setmem (operands[0], operands[1],
15240 operands[2], operands[3],
15241 operands[4], operands[5]))
15247 ;; Most CPUs don't like single string operations
15248 ;; Handle this case here to simplify previous expander.
15250 (define_expand "strset"
15251 [(set (match_operand 1 "memory_operand" "")
15252 (match_operand 2 "register_operand" ""))
15253 (parallel [(set (match_operand 0 "register_operand" "")
15255 (clobber (reg:CC FLAGS_REG))])]
15258 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15259 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15261 /* If .md ever supports :P for Pmode, this can be directly
15262 in the pattern above. */
15263 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15264 GEN_INT (GET_MODE_SIZE (GET_MODE
15266 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15268 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15274 (define_expand "strset_singleop"
15275 [(parallel [(set (match_operand 1 "memory_operand" "")
15276 (match_operand 2 "register_operand" ""))
15277 (set (match_operand 0 "register_operand" "")
15278 (match_operand 3 "" ""))])]
15280 "ix86_current_function_needs_cld = 1;")
15282 (define_insn "*strsetdi_rex_1"
15283 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15284 (match_operand:DI 2 "register_operand" "a"))
15285 (set (match_operand:DI 0 "register_operand" "=D")
15286 (plus:DI (match_dup 1)
15290 [(set_attr "type" "str")
15291 (set_attr "memory" "store")
15292 (set_attr "mode" "DI")])
15294 (define_insn "*strsetsi_1"
15295 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
15296 (match_operand:SI 2 "register_operand" "a"))
15297 (set (match_operand:SI 0 "register_operand" "=D")
15298 (plus:SI (match_dup 1)
15302 [(set_attr "type" "str")
15303 (set_attr "memory" "store")
15304 (set_attr "mode" "SI")])
15306 (define_insn "*strsetsi_rex_1"
15307 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15308 (match_operand:SI 2 "register_operand" "a"))
15309 (set (match_operand:DI 0 "register_operand" "=D")
15310 (plus:DI (match_dup 1)
15314 [(set_attr "type" "str")
15315 (set_attr "memory" "store")
15316 (set_attr "mode" "SI")])
15318 (define_insn "*strsethi_1"
15319 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
15320 (match_operand:HI 2 "register_operand" "a"))
15321 (set (match_operand:SI 0 "register_operand" "=D")
15322 (plus:SI (match_dup 1)
15326 [(set_attr "type" "str")
15327 (set_attr "memory" "store")
15328 (set_attr "mode" "HI")])
15330 (define_insn "*strsethi_rex_1"
15331 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
15332 (match_operand:HI 2 "register_operand" "a"))
15333 (set (match_operand:DI 0 "register_operand" "=D")
15334 (plus:DI (match_dup 1)
15338 [(set_attr "type" "str")
15339 (set_attr "memory" "store")
15340 (set_attr "mode" "HI")])
15342 (define_insn "*strsetqi_1"
15343 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
15344 (match_operand:QI 2 "register_operand" "a"))
15345 (set (match_operand:SI 0 "register_operand" "=D")
15346 (plus:SI (match_dup 1)
15350 [(set_attr "type" "str")
15351 (set_attr "memory" "store")
15352 (set_attr "mode" "QI")])
15354 (define_insn "*strsetqi_rex_1"
15355 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
15356 (match_operand:QI 2 "register_operand" "a"))
15357 (set (match_operand:DI 0 "register_operand" "=D")
15358 (plus:DI (match_dup 1)
15362 [(set_attr "type" "str")
15363 (set_attr "memory" "store")
15364 (set_attr "prefix_rex" "0")
15365 (set_attr "mode" "QI")])
15367 (define_expand "rep_stos"
15368 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15369 (set (match_operand 0 "register_operand" "")
15370 (match_operand 4 "" ""))
15371 (set (match_operand 2 "memory_operand" "") (const_int 0))
15372 (use (match_operand 3 "register_operand" ""))
15373 (use (match_dup 1))])]
15375 "ix86_current_function_needs_cld = 1;")
15377 (define_insn "*rep_stosdi_rex64"
15378 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15379 (set (match_operand:DI 0 "register_operand" "=D")
15380 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15382 (match_operand:DI 3 "register_operand" "0")))
15383 (set (mem:BLK (match_dup 3))
15385 (use (match_operand:DI 2 "register_operand" "a"))
15386 (use (match_dup 4))]
15389 [(set_attr "type" "str")
15390 (set_attr "prefix_rep" "1")
15391 (set_attr "memory" "store")
15392 (set_attr "mode" "DI")])
15394 (define_insn "*rep_stossi"
15395 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15396 (set (match_operand:SI 0 "register_operand" "=D")
15397 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
15399 (match_operand:SI 3 "register_operand" "0")))
15400 (set (mem:BLK (match_dup 3))
15402 (use (match_operand:SI 2 "register_operand" "a"))
15403 (use (match_dup 4))]
15405 "rep{%;} stos{l|d}"
15406 [(set_attr "type" "str")
15407 (set_attr "prefix_rep" "1")
15408 (set_attr "memory" "store")
15409 (set_attr "mode" "SI")])
15411 (define_insn "*rep_stossi_rex64"
15412 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15413 (set (match_operand:DI 0 "register_operand" "=D")
15414 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15416 (match_operand:DI 3 "register_operand" "0")))
15417 (set (mem:BLK (match_dup 3))
15419 (use (match_operand:SI 2 "register_operand" "a"))
15420 (use (match_dup 4))]
15422 "rep{%;} stos{l|d}"
15423 [(set_attr "type" "str")
15424 (set_attr "prefix_rep" "1")
15425 (set_attr "memory" "store")
15426 (set_attr "mode" "SI")])
15428 (define_insn "*rep_stosqi"
15429 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15430 (set (match_operand:SI 0 "register_operand" "=D")
15431 (plus:SI (match_operand:SI 3 "register_operand" "0")
15432 (match_operand:SI 4 "register_operand" "1")))
15433 (set (mem:BLK (match_dup 3))
15435 (use (match_operand:QI 2 "register_operand" "a"))
15436 (use (match_dup 4))]
15439 [(set_attr "type" "str")
15440 (set_attr "prefix_rep" "1")
15441 (set_attr "memory" "store")
15442 (set_attr "mode" "QI")])
15444 (define_insn "*rep_stosqi_rex64"
15445 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15446 (set (match_operand:DI 0 "register_operand" "=D")
15447 (plus:DI (match_operand:DI 3 "register_operand" "0")
15448 (match_operand:DI 4 "register_operand" "1")))
15449 (set (mem:BLK (match_dup 3))
15451 (use (match_operand:QI 2 "register_operand" "a"))
15452 (use (match_dup 4))]
15455 [(set_attr "type" "str")
15456 (set_attr "prefix_rep" "1")
15457 (set_attr "memory" "store")
15458 (set_attr "prefix_rex" "0")
15459 (set_attr "mode" "QI")])
15461 (define_expand "cmpstrnsi"
15462 [(set (match_operand:SI 0 "register_operand" "")
15463 (compare:SI (match_operand:BLK 1 "general_operand" "")
15464 (match_operand:BLK 2 "general_operand" "")))
15465 (use (match_operand 3 "general_operand" ""))
15466 (use (match_operand 4 "immediate_operand" ""))]
15469 rtx addr1, addr2, out, outlow, count, countreg, align;
15471 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15474 /* Can't use this if the user has appropriated esi or edi. */
15475 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15480 out = gen_reg_rtx (SImode);
15482 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15483 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15484 if (addr1 != XEXP (operands[1], 0))
15485 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15486 if (addr2 != XEXP (operands[2], 0))
15487 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15489 count = operands[3];
15490 countreg = ix86_zero_extend_to_Pmode (count);
15492 /* %%% Iff we are testing strict equality, we can use known alignment
15493 to good advantage. This may be possible with combine, particularly
15494 once cc0 is dead. */
15495 align = operands[4];
15497 if (CONST_INT_P (count))
15499 if (INTVAL (count) == 0)
15501 emit_move_insn (operands[0], const0_rtx);
15504 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15505 operands[1], operands[2]));
15509 rtx (*gen_cmp) (rtx, rtx);
15511 gen_cmp = (TARGET_64BIT
15512 ? gen_cmpdi_1 : gen_cmpsi_1);
15514 emit_insn (gen_cmp (countreg, countreg));
15515 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15516 operands[1], operands[2]));
15519 outlow = gen_lowpart (QImode, out);
15520 emit_insn (gen_cmpintqi (outlow));
15521 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15523 if (operands[0] != out)
15524 emit_move_insn (operands[0], out);
15529 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15531 (define_expand "cmpintqi"
15532 [(set (match_dup 1)
15533 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15535 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15536 (parallel [(set (match_operand:QI 0 "register_operand" "")
15537 (minus:QI (match_dup 1)
15539 (clobber (reg:CC FLAGS_REG))])]
15541 "operands[1] = gen_reg_rtx (QImode);
15542 operands[2] = gen_reg_rtx (QImode);")
15544 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15545 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
15547 (define_expand "cmpstrnqi_nz_1"
15548 [(parallel [(set (reg:CC FLAGS_REG)
15549 (compare:CC (match_operand 4 "memory_operand" "")
15550 (match_operand 5 "memory_operand" "")))
15551 (use (match_operand 2 "register_operand" ""))
15552 (use (match_operand:SI 3 "immediate_operand" ""))
15553 (clobber (match_operand 0 "register_operand" ""))
15554 (clobber (match_operand 1 "register_operand" ""))
15555 (clobber (match_dup 2))])]
15557 "ix86_current_function_needs_cld = 1;")
15559 (define_insn "*cmpstrnqi_nz_1"
15560 [(set (reg:CC FLAGS_REG)
15561 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15562 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
15563 (use (match_operand:SI 6 "register_operand" "2"))
15564 (use (match_operand:SI 3 "immediate_operand" "i"))
15565 (clobber (match_operand:SI 0 "register_operand" "=S"))
15566 (clobber (match_operand:SI 1 "register_operand" "=D"))
15567 (clobber (match_operand:SI 2 "register_operand" "=c"))]
15570 [(set_attr "type" "str")
15571 (set_attr "mode" "QI")
15572 (set_attr "prefix_rep" "1")])
15574 (define_insn "*cmpstrnqi_nz_rex_1"
15575 [(set (reg:CC FLAGS_REG)
15576 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15577 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
15578 (use (match_operand:DI 6 "register_operand" "2"))
15579 (use (match_operand:SI 3 "immediate_operand" "i"))
15580 (clobber (match_operand:DI 0 "register_operand" "=S"))
15581 (clobber (match_operand:DI 1 "register_operand" "=D"))
15582 (clobber (match_operand:DI 2 "register_operand" "=c"))]
15585 [(set_attr "type" "str")
15586 (set_attr "mode" "QI")
15587 (set_attr "prefix_rex" "0")
15588 (set_attr "prefix_rep" "1")])
15590 ;; The same, but the count is not known to not be zero.
15592 (define_expand "cmpstrnqi_1"
15593 [(parallel [(set (reg:CC FLAGS_REG)
15594 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
15596 (compare:CC (match_operand 4 "memory_operand" "")
15597 (match_operand 5 "memory_operand" ""))
15599 (use (match_operand:SI 3 "immediate_operand" ""))
15600 (use (reg:CC FLAGS_REG))
15601 (clobber (match_operand 0 "register_operand" ""))
15602 (clobber (match_operand 1 "register_operand" ""))
15603 (clobber (match_dup 2))])]
15605 "ix86_current_function_needs_cld = 1;")
15607 (define_insn "*cmpstrnqi_1"
15608 [(set (reg:CC FLAGS_REG)
15609 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
15611 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15612 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
15614 (use (match_operand:SI 3 "immediate_operand" "i"))
15615 (use (reg:CC FLAGS_REG))
15616 (clobber (match_operand:SI 0 "register_operand" "=S"))
15617 (clobber (match_operand:SI 1 "register_operand" "=D"))
15618 (clobber (match_operand:SI 2 "register_operand" "=c"))]
15621 [(set_attr "type" "str")
15622 (set_attr "mode" "QI")
15623 (set_attr "prefix_rep" "1")])
15625 (define_insn "*cmpstrnqi_rex_1"
15626 [(set (reg:CC FLAGS_REG)
15627 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
15629 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15630 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
15632 (use (match_operand:SI 3 "immediate_operand" "i"))
15633 (use (reg:CC FLAGS_REG))
15634 (clobber (match_operand:DI 0 "register_operand" "=S"))
15635 (clobber (match_operand:DI 1 "register_operand" "=D"))
15636 (clobber (match_operand:DI 2 "register_operand" "=c"))]
15639 [(set_attr "type" "str")
15640 (set_attr "mode" "QI")
15641 (set_attr "prefix_rex" "0")
15642 (set_attr "prefix_rep" "1")])
15644 (define_expand "strlensi"
15645 [(set (match_operand:SI 0 "register_operand" "")
15646 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
15647 (match_operand:QI 2 "immediate_operand" "")
15648 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
15651 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15657 (define_expand "strlendi"
15658 [(set (match_operand:DI 0 "register_operand" "")
15659 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
15660 (match_operand:QI 2 "immediate_operand" "")
15661 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
15664 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15670 (define_expand "strlenqi_1"
15671 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
15672 (clobber (match_operand 1 "register_operand" ""))
15673 (clobber (reg:CC FLAGS_REG))])]
15675 "ix86_current_function_needs_cld = 1;")
15677 (define_insn "*strlenqi_1"
15678 [(set (match_operand:SI 0 "register_operand" "=&c")
15679 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
15680 (match_operand:QI 2 "register_operand" "a")
15681 (match_operand:SI 3 "immediate_operand" "i")
15682 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
15683 (clobber (match_operand:SI 1 "register_operand" "=D"))
15684 (clobber (reg:CC FLAGS_REG))]
15687 [(set_attr "type" "str")
15688 (set_attr "mode" "QI")
15689 (set_attr "prefix_rep" "1")])
15691 (define_insn "*strlenqi_rex_1"
15692 [(set (match_operand:DI 0 "register_operand" "=&c")
15693 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
15694 (match_operand:QI 2 "register_operand" "a")
15695 (match_operand:DI 3 "immediate_operand" "i")
15696 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
15697 (clobber (match_operand:DI 1 "register_operand" "=D"))
15698 (clobber (reg:CC FLAGS_REG))]
15701 [(set_attr "type" "str")
15702 (set_attr "mode" "QI")
15703 (set_attr "prefix_rex" "0")
15704 (set_attr "prefix_rep" "1")])
15706 ;; Peephole optimizations to clean up after cmpstrn*. This should be
15707 ;; handled in combine, but it is not currently up to the task.
15708 ;; When used for their truth value, the cmpstrn* expanders generate
15717 ;; The intermediate three instructions are unnecessary.
15719 ;; This one handles cmpstrn*_nz_1...
15722 (set (reg:CC FLAGS_REG)
15723 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15724 (mem:BLK (match_operand 5 "register_operand" ""))))
15725 (use (match_operand 6 "register_operand" ""))
15726 (use (match_operand:SI 3 "immediate_operand" ""))
15727 (clobber (match_operand 0 "register_operand" ""))
15728 (clobber (match_operand 1 "register_operand" ""))
15729 (clobber (match_operand 2 "register_operand" ""))])
15730 (set (match_operand:QI 7 "register_operand" "")
15731 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15732 (set (match_operand:QI 8 "register_operand" "")
15733 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15734 (set (reg FLAGS_REG)
15735 (compare (match_dup 7) (match_dup 8)))
15737 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15739 (set (reg:CC FLAGS_REG)
15740 (compare:CC (mem:BLK (match_dup 4))
15741 (mem:BLK (match_dup 5))))
15742 (use (match_dup 6))
15743 (use (match_dup 3))
15744 (clobber (match_dup 0))
15745 (clobber (match_dup 1))
15746 (clobber (match_dup 2))])])
15748 ;; ...and this one handles cmpstrn*_1.
15751 (set (reg:CC FLAGS_REG)
15752 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
15754 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15755 (mem:BLK (match_operand 5 "register_operand" "")))
15757 (use (match_operand:SI 3 "immediate_operand" ""))
15758 (use (reg:CC FLAGS_REG))
15759 (clobber (match_operand 0 "register_operand" ""))
15760 (clobber (match_operand 1 "register_operand" ""))
15761 (clobber (match_operand 2 "register_operand" ""))])
15762 (set (match_operand:QI 7 "register_operand" "")
15763 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15764 (set (match_operand:QI 8 "register_operand" "")
15765 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15766 (set (reg FLAGS_REG)
15767 (compare (match_dup 7) (match_dup 8)))
15769 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15771 (set (reg:CC FLAGS_REG)
15772 (if_then_else:CC (ne (match_dup 6)
15774 (compare:CC (mem:BLK (match_dup 4))
15775 (mem:BLK (match_dup 5)))
15777 (use (match_dup 3))
15778 (use (reg:CC FLAGS_REG))
15779 (clobber (match_dup 0))
15780 (clobber (match_dup 1))
15781 (clobber (match_dup 2))])])
15783 ;; Conditional move instructions.
15785 (define_expand "mov<mode>cc"
15786 [(set (match_operand:SWIM 0 "register_operand" "")
15787 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
15788 (match_operand:SWIM 2 "general_operand" "")
15789 (match_operand:SWIM 3 "general_operand" "")))]
15791 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
15793 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
15794 ;; the register first winds up with `sbbl $0,reg', which is also weird.
15795 ;; So just document what we're doing explicitly.
15797 (define_expand "x86_mov<mode>cc_0_m1"
15799 [(set (match_operand:SWI48 0 "register_operand" "")
15800 (if_then_else:SWI48
15801 (match_operator:SWI48 2 "ix86_carry_flag_operator"
15802 [(match_operand 1 "flags_reg_operand" "")
15806 (clobber (reg:CC FLAGS_REG))])]
15810 (define_insn "*x86_mov<mode>cc_0_m1"
15811 [(set (match_operand:SWI48 0 "register_operand" "=r")
15812 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15813 [(reg FLAGS_REG) (const_int 0)])
15816 (clobber (reg:CC FLAGS_REG))]
15818 "sbb{<imodesuffix>}\t%0, %0"
15819 ; Since we don't have the proper number of operands for an alu insn,
15820 ; fill in all the blanks.
15821 [(set_attr "type" "alu")
15822 (set_attr "use_carry" "1")
15823 (set_attr "pent_pair" "pu")
15824 (set_attr "memory" "none")
15825 (set_attr "imm_disp" "false")
15826 (set_attr "mode" "<MODE>")
15827 (set_attr "length_immediate" "0")])
15829 (define_insn "*x86_mov<mode>cc_0_m1_se"
15830 [(set (match_operand:SWI48 0 "register_operand" "=r")
15831 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15832 [(reg FLAGS_REG) (const_int 0)])
15835 (clobber (reg:CC FLAGS_REG))]
15837 "sbb{<imodesuffix>}\t%0, %0"
15838 [(set_attr "type" "alu")
15839 (set_attr "use_carry" "1")
15840 (set_attr "pent_pair" "pu")
15841 (set_attr "memory" "none")
15842 (set_attr "imm_disp" "false")
15843 (set_attr "mode" "<MODE>")
15844 (set_attr "length_immediate" "0")])
15846 (define_insn "*x86_mov<mode>cc_0_m1_neg"
15847 [(set (match_operand:SWI48 0 "register_operand" "=r")
15848 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15849 [(reg FLAGS_REG) (const_int 0)])))]
15851 "sbb{<imodesuffix>}\t%0, %0"
15852 [(set_attr "type" "alu")
15853 (set_attr "use_carry" "1")
15854 (set_attr "pent_pair" "pu")
15855 (set_attr "memory" "none")
15856 (set_attr "imm_disp" "false")
15857 (set_attr "mode" "<MODE>")
15858 (set_attr "length_immediate" "0")])
15860 (define_insn "*mov<mode>cc_noc"
15861 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
15862 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
15863 [(reg FLAGS_REG) (const_int 0)])
15864 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
15865 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
15866 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
15868 cmov%O2%C1\t{%2, %0|%0, %2}
15869 cmov%O2%c1\t{%3, %0|%0, %3}"
15870 [(set_attr "type" "icmov")
15871 (set_attr "mode" "<MODE>")])
15873 (define_insn_and_split "*movqicc_noc"
15874 [(set (match_operand:QI 0 "register_operand" "=r,r")
15875 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
15876 [(match_operand 4 "flags_reg_operand" "")
15878 (match_operand:QI 2 "register_operand" "r,0")
15879 (match_operand:QI 3 "register_operand" "0,r")))]
15880 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
15882 "&& reload_completed"
15883 [(set (match_dup 0)
15884 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
15887 "operands[0] = gen_lowpart (SImode, operands[0]);
15888 operands[2] = gen_lowpart (SImode, operands[2]);
15889 operands[3] = gen_lowpart (SImode, operands[3]);"
15890 [(set_attr "type" "icmov")
15891 (set_attr "mode" "SI")])
15893 (define_expand "mov<mode>cc"
15894 [(set (match_operand:X87MODEF 0 "register_operand" "")
15895 (if_then_else:X87MODEF
15896 (match_operand 1 "ix86_fp_comparison_operator" "")
15897 (match_operand:X87MODEF 2 "register_operand" "")
15898 (match_operand:X87MODEF 3 "register_operand" "")))]
15899 "(TARGET_80387 && TARGET_CMOVE)
15900 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15901 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
15903 (define_insn "*movsfcc_1_387"
15904 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
15905 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
15906 [(reg FLAGS_REG) (const_int 0)])
15907 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
15908 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
15909 "TARGET_80387 && TARGET_CMOVE
15910 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
15912 fcmov%F1\t{%2, %0|%0, %2}
15913 fcmov%f1\t{%3, %0|%0, %3}
15914 cmov%O2%C1\t{%2, %0|%0, %2}
15915 cmov%O2%c1\t{%3, %0|%0, %3}"
15916 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
15917 (set_attr "mode" "SF,SF,SI,SI")])
15919 (define_insn "*movdfcc_1"
15920 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
15921 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
15922 [(reg FLAGS_REG) (const_int 0)])
15923 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
15924 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
15925 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
15926 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
15928 fcmov%F1\t{%2, %0|%0, %2}
15929 fcmov%f1\t{%3, %0|%0, %3}
15932 [(set_attr "type" "fcmov,fcmov,multi,multi")
15933 (set_attr "mode" "DF")])
15935 (define_insn "*movdfcc_1_rex64"
15936 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
15937 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
15938 [(reg FLAGS_REG) (const_int 0)])
15939 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
15940 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
15941 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
15942 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
15944 fcmov%F1\t{%2, %0|%0, %2}
15945 fcmov%f1\t{%3, %0|%0, %3}
15946 cmov%O2%C1\t{%2, %0|%0, %2}
15947 cmov%O2%c1\t{%3, %0|%0, %3}"
15948 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
15949 (set_attr "mode" "DF")])
15952 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
15953 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
15954 [(match_operand 4 "flags_reg_operand" "")
15956 (match_operand:DF 2 "nonimmediate_operand" "")
15957 (match_operand:DF 3 "nonimmediate_operand" "")))]
15958 "!TARGET_64BIT && reload_completed"
15959 [(set (match_dup 2)
15960 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
15964 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
15968 split_di (&operands[2], 2, &operands[5], &operands[7]);
15969 split_di (&operands[0], 1, &operands[2], &operands[3]);
15972 (define_insn "*movxfcc_1"
15973 [(set (match_operand:XF 0 "register_operand" "=f,f")
15974 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
15975 [(reg FLAGS_REG) (const_int 0)])
15976 (match_operand:XF 2 "register_operand" "f,0")
15977 (match_operand:XF 3 "register_operand" "0,f")))]
15978 "TARGET_80387 && TARGET_CMOVE"
15980 fcmov%F1\t{%2, %0|%0, %2}
15981 fcmov%f1\t{%3, %0|%0, %3}"
15982 [(set_attr "type" "fcmov")
15983 (set_attr "mode" "XF")])
15985 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
15986 ;; the scalar versions to have only XMM registers as operands.
15988 ;; XOP conditional move
15989 (define_insn "*xop_pcmov_<mode>"
15990 [(set (match_operand:MODEF 0 "register_operand" "=x")
15991 (if_then_else:MODEF
15992 (match_operand:MODEF 1 "register_operand" "x")
15993 (match_operand:MODEF 2 "register_operand" "x")
15994 (match_operand:MODEF 3 "register_operand" "x")))]
15996 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
15997 [(set_attr "type" "sse4arg")])
15999 ;; These versions of the min/max patterns are intentionally ignorant of
16000 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16001 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16002 ;; are undefined in this condition, we're certain this is correct.
16004 (define_insn "*avx_<code><mode>3"
16005 [(set (match_operand:MODEF 0 "register_operand" "=x")
16007 (match_operand:MODEF 1 "nonimmediate_operand" "%x")
16008 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16009 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16010 "v<maxmin_float>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16011 [(set_attr "type" "sseadd")
16012 (set_attr "prefix" "vex")
16013 (set_attr "mode" "<MODE>")])
16015 (define_insn "<code><mode>3"
16016 [(set (match_operand:MODEF 0 "register_operand" "=x")
16018 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
16019 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16020 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16021 "<maxmin_float>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
16022 [(set_attr "type" "sseadd")
16023 (set_attr "mode" "<MODE>")])
16025 ;; These versions of the min/max patterns implement exactly the operations
16026 ;; min = (op1 < op2 ? op1 : op2)
16027 ;; max = (!(op1 < op2) ? op1 : op2)
16028 ;; Their operands are not commutative, and thus they may be used in the
16029 ;; presence of -0.0 and NaN.
16031 (define_insn "*avx_ieee_smin<mode>3"
16032 [(set (match_operand:MODEF 0 "register_operand" "=x")
16034 [(match_operand:MODEF 1 "register_operand" "x")
16035 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16037 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16038 "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16039 [(set_attr "type" "sseadd")
16040 (set_attr "prefix" "vex")
16041 (set_attr "mode" "<MODE>")])
16043 (define_insn "*ieee_smin<mode>3"
16044 [(set (match_operand:MODEF 0 "register_operand" "=x")
16046 [(match_operand:MODEF 1 "register_operand" "0")
16047 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16049 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16050 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
16051 [(set_attr "type" "sseadd")
16052 (set_attr "mode" "<MODE>")])
16054 (define_insn "*avx_ieee_smax<mode>3"
16055 [(set (match_operand:MODEF 0 "register_operand" "=x")
16057 [(match_operand:MODEF 1 "register_operand" "0")
16058 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16060 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16061 "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16062 [(set_attr "type" "sseadd")
16063 (set_attr "prefix" "vex")
16064 (set_attr "mode" "<MODE>")])
16066 (define_insn "*ieee_smax<mode>3"
16067 [(set (match_operand:MODEF 0 "register_operand" "=x")
16069 [(match_operand:MODEF 1 "register_operand" "0")
16070 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16072 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16073 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
16074 [(set_attr "type" "sseadd")
16075 (set_attr "mode" "<MODE>")])
16077 ;; Make two stack loads independent:
16079 ;; fld %st(0) -> fld bb
16080 ;; fmul bb fmul %st(1), %st
16082 ;; Actually we only match the last two instructions for simplicity.
16084 [(set (match_operand 0 "fp_register_operand" "")
16085 (match_operand 1 "fp_register_operand" ""))
16087 (match_operator 2 "binary_fp_operator"
16089 (match_operand 3 "memory_operand" "")]))]
16090 "REGNO (operands[0]) != REGNO (operands[1])"
16091 [(set (match_dup 0) (match_dup 3))
16092 (set (match_dup 0) (match_dup 4))]
16094 ;; The % modifier is not operational anymore in peephole2's, so we have to
16095 ;; swap the operands manually in the case of addition and multiplication.
16096 "if (COMMUTATIVE_ARITH_P (operands[2]))
16097 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16098 GET_MODE (operands[2]),
16099 operands[0], operands[1]);
16101 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16102 GET_MODE (operands[2]),
16103 operands[1], operands[0]);")
16105 ;; Conditional addition patterns
16106 (define_expand "add<mode>cc"
16107 [(match_operand:SWI 0 "register_operand" "")
16108 (match_operand 1 "ordered_comparison_operator" "")
16109 (match_operand:SWI 2 "register_operand" "")
16110 (match_operand:SWI 3 "const_int_operand" "")]
16112 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16114 ;; Misc patterns (?)
16116 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16117 ;; Otherwise there will be nothing to keep
16119 ;; [(set (reg ebp) (reg esp))]
16120 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16121 ;; (clobber (eflags)]
16122 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16124 ;; in proper program order.
16126 (define_insn "pro_epilogue_adjust_stack_<mode>_1"
16127 [(set (match_operand:P 0 "register_operand" "=r,r")
16128 (plus:P (match_operand:P 1 "register_operand" "0,r")
16129 (match_operand:P 2 "<immediate_operand>" "<i>,<i>")))
16130 (clobber (reg:CC FLAGS_REG))
16131 (clobber (mem:BLK (scratch)))]
16134 switch (get_attr_type (insn))
16137 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16140 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16141 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16142 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16144 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16147 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16148 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16151 [(set (attr "type")
16152 (cond [(and (eq_attr "alternative" "0")
16153 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16154 (const_string "alu")
16155 (match_operand:<MODE> 2 "const0_operand" "")
16156 (const_string "imov")
16158 (const_string "lea")))
16159 (set (attr "length_immediate")
16160 (cond [(eq_attr "type" "imov")
16162 (and (eq_attr "type" "alu")
16163 (match_operand 2 "const128_operand" ""))
16166 (const_string "*")))
16167 (set_attr "mode" "<MODE>")])
16169 (define_insn "pro_epilogue_adjust_stack_di_2"
16170 [(set (match_operand:DI 0 "register_operand" "=r,r")
16171 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16172 (match_operand:DI 3 "immediate_operand" "i,i")))
16173 (use (match_operand:DI 2 "register_operand" "r,l"))
16174 (clobber (reg:CC FLAGS_REG))
16175 (clobber (mem:BLK (scratch)))]
16178 switch (get_attr_type (insn))
16181 return "add{q}\t{%2, %0|%0, %2}";
16184 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
16185 return "lea{q}\t{%a2, %0|%0, %a2}";
16188 gcc_unreachable ();
16191 [(set_attr "type" "alu,lea")
16192 (set_attr "mode" "DI")])
16194 (define_insn "allocate_stack_worker_32"
16195 [(set (match_operand:SI 0 "register_operand" "=a")
16196 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
16197 UNSPECV_STACK_PROBE))
16198 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
16199 (clobber (reg:CC FLAGS_REG))]
16200 "!TARGET_64BIT && ix86_target_stack_probe ()"
16202 [(set_attr "type" "multi")
16203 (set_attr "length" "5")])
16205 (define_insn "allocate_stack_worker_64"
16206 [(set (match_operand:DI 0 "register_operand" "=a")
16207 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
16208 UNSPECV_STACK_PROBE))
16209 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
16210 (clobber (reg:DI R10_REG))
16211 (clobber (reg:DI R11_REG))
16212 (clobber (reg:CC FLAGS_REG))]
16213 "TARGET_64BIT && ix86_target_stack_probe ()"
16215 [(set_attr "type" "multi")
16216 (set_attr "length" "5")])
16218 (define_expand "allocate_stack"
16219 [(match_operand 0 "register_operand" "")
16220 (match_operand 1 "general_operand" "")]
16221 "ix86_target_stack_probe ()"
16225 #ifndef CHECK_STACK_LIMIT
16226 #define CHECK_STACK_LIMIT 0
16229 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16230 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16232 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16233 stack_pointer_rtx, 0, OPTAB_DIRECT);
16234 if (x != stack_pointer_rtx)
16235 emit_move_insn (stack_pointer_rtx, x);
16239 rtx (*gen_allocate_stack_worker) (rtx, rtx);
16242 gen_allocate_stack_worker = gen_allocate_stack_worker_64;
16244 gen_allocate_stack_worker = gen_allocate_stack_worker_32;
16246 x = copy_to_mode_reg (Pmode, operands[1]);
16247 emit_insn (gen_allocate_stack_worker (x, x));
16250 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16254 ;; Use IOR for stack probes, this is shorter.
16255 (define_expand "probe_stack"
16256 [(match_operand 0 "memory_operand" "")]
16259 rtx (*gen_ior3) (rtx, rtx, rtx);
16261 gen_ior3 = (GET_MODE (operands[0]) == DImode
16262 ? gen_iordi3 : gen_iorsi3);
16264 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16268 (define_insn "adjust_stack_and_probe<mode>"
16269 [(set (match_operand:P 0 "register_operand" "=r")
16270 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16271 UNSPECV_PROBE_STACK_RANGE))
16272 (set (reg:P SP_REG)
16273 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16274 (clobber (reg:CC FLAGS_REG))
16275 (clobber (mem:BLK (scratch)))]
16277 "* return output_adjust_stack_and_probe (operands[0]);"
16278 [(set_attr "type" "multi")])
16280 (define_insn "probe_stack_range<mode>"
16281 [(set (match_operand:P 0 "register_operand" "=r")
16282 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16283 (match_operand:P 2 "const_int_operand" "n")]
16284 UNSPECV_PROBE_STACK_RANGE))
16285 (clobber (reg:CC FLAGS_REG))]
16287 "* return output_probe_stack_range (operands[0], operands[2]);"
16288 [(set_attr "type" "multi")])
16290 (define_expand "builtin_setjmp_receiver"
16291 [(label_ref (match_operand 0 "" ""))]
16292 "!TARGET_64BIT && flag_pic"
16298 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16299 rtx label_rtx = gen_label_rtx ();
16300 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16301 xops[0] = xops[1] = picreg;
16302 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16303 ix86_expand_binary_operator (MINUS, SImode, xops);
16307 emit_insn (gen_set_got (pic_offset_table_rtx));
16311 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16314 [(set (match_operand 0 "register_operand" "")
16315 (match_operator 3 "promotable_binary_operator"
16316 [(match_operand 1 "register_operand" "")
16317 (match_operand 2 "aligned_operand" "")]))
16318 (clobber (reg:CC FLAGS_REG))]
16319 "! TARGET_PARTIAL_REG_STALL && reload_completed
16320 && ((GET_MODE (operands[0]) == HImode
16321 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16322 /* ??? next two lines just !satisfies_constraint_K (...) */
16323 || !CONST_INT_P (operands[2])
16324 || satisfies_constraint_K (operands[2])))
16325 || (GET_MODE (operands[0]) == QImode
16326 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16327 [(parallel [(set (match_dup 0)
16328 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16329 (clobber (reg:CC FLAGS_REG))])]
16330 "operands[0] = gen_lowpart (SImode, operands[0]);
16331 operands[1] = gen_lowpart (SImode, operands[1]);
16332 if (GET_CODE (operands[3]) != ASHIFT)
16333 operands[2] = gen_lowpart (SImode, operands[2]);
16334 PUT_MODE (operands[3], SImode);")
16336 ; Promote the QImode tests, as i386 has encoding of the AND
16337 ; instruction with 32-bit sign-extended immediate and thus the
16338 ; instruction size is unchanged, except in the %eax case for
16339 ; which it is increased by one byte, hence the ! optimize_size.
16341 [(set (match_operand 0 "flags_reg_operand" "")
16342 (match_operator 2 "compare_operator"
16343 [(and (match_operand 3 "aligned_operand" "")
16344 (match_operand 4 "const_int_operand" ""))
16346 (set (match_operand 1 "register_operand" "")
16347 (and (match_dup 3) (match_dup 4)))]
16348 "! TARGET_PARTIAL_REG_STALL && reload_completed
16349 && optimize_insn_for_speed_p ()
16350 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16351 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16352 /* Ensure that the operand will remain sign-extended immediate. */
16353 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16354 [(parallel [(set (match_dup 0)
16355 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16358 (and:SI (match_dup 3) (match_dup 4)))])]
16361 = gen_int_mode (INTVAL (operands[4])
16362 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16363 operands[1] = gen_lowpart (SImode, operands[1]);
16364 operands[3] = gen_lowpart (SImode, operands[3]);
16367 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16368 ; the TEST instruction with 32-bit sign-extended immediate and thus
16369 ; the instruction size would at least double, which is not what we
16370 ; want even with ! optimize_size.
16372 [(set (match_operand 0 "flags_reg_operand" "")
16373 (match_operator 1 "compare_operator"
16374 [(and (match_operand:HI 2 "aligned_operand" "")
16375 (match_operand:HI 3 "const_int_operand" ""))
16377 "! TARGET_PARTIAL_REG_STALL && reload_completed
16378 && ! TARGET_FAST_PREFIX
16379 && optimize_insn_for_speed_p ()
16380 /* Ensure that the operand will remain sign-extended immediate. */
16381 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16382 [(set (match_dup 0)
16383 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16387 = gen_int_mode (INTVAL (operands[3])
16388 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16389 operands[2] = gen_lowpart (SImode, operands[2]);
16393 [(set (match_operand 0 "register_operand" "")
16394 (neg (match_operand 1 "register_operand" "")))
16395 (clobber (reg:CC FLAGS_REG))]
16396 "! TARGET_PARTIAL_REG_STALL && reload_completed
16397 && (GET_MODE (operands[0]) == HImode
16398 || (GET_MODE (operands[0]) == QImode
16399 && (TARGET_PROMOTE_QImode
16400 || optimize_insn_for_size_p ())))"
16401 [(parallel [(set (match_dup 0)
16402 (neg:SI (match_dup 1)))
16403 (clobber (reg:CC FLAGS_REG))])]
16404 "operands[0] = gen_lowpart (SImode, operands[0]);
16405 operands[1] = gen_lowpart (SImode, operands[1]);")
16408 [(set (match_operand 0 "register_operand" "")
16409 (not (match_operand 1 "register_operand" "")))]
16410 "! TARGET_PARTIAL_REG_STALL && reload_completed
16411 && (GET_MODE (operands[0]) == HImode
16412 || (GET_MODE (operands[0]) == QImode
16413 && (TARGET_PROMOTE_QImode
16414 || optimize_insn_for_size_p ())))"
16415 [(set (match_dup 0)
16416 (not:SI (match_dup 1)))]
16417 "operands[0] = gen_lowpart (SImode, operands[0]);
16418 operands[1] = gen_lowpart (SImode, operands[1]);")
16421 [(set (match_operand 0 "register_operand" "")
16422 (if_then_else (match_operator 1 "ordered_comparison_operator"
16423 [(reg FLAGS_REG) (const_int 0)])
16424 (match_operand 2 "register_operand" "")
16425 (match_operand 3 "register_operand" "")))]
16426 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16427 && (GET_MODE (operands[0]) == HImode
16428 || (GET_MODE (operands[0]) == QImode
16429 && (TARGET_PROMOTE_QImode
16430 || optimize_insn_for_size_p ())))"
16431 [(set (match_dup 0)
16432 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16433 "operands[0] = gen_lowpart (SImode, operands[0]);
16434 operands[2] = gen_lowpart (SImode, operands[2]);
16435 operands[3] = gen_lowpart (SImode, operands[3]);")
16437 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16438 ;; transform a complex memory operation into two memory to register operations.
16440 ;; Don't push memory operands
16442 [(set (match_operand:SWI 0 "push_operand" "")
16443 (match_operand:SWI 1 "memory_operand" ""))
16444 (match_scratch:SWI 2 "<r>")]
16445 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16446 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16447 [(set (match_dup 2) (match_dup 1))
16448 (set (match_dup 0) (match_dup 2))])
16450 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16453 [(set (match_operand:SF 0 "push_operand" "")
16454 (match_operand:SF 1 "memory_operand" ""))
16455 (match_scratch:SF 2 "r")]
16456 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16457 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16458 [(set (match_dup 2) (match_dup 1))
16459 (set (match_dup 0) (match_dup 2))])
16461 ;; Don't move an immediate directly to memory when the instruction
16464 [(match_scratch:SWI124 1 "<r>")
16465 (set (match_operand:SWI124 0 "memory_operand" "")
16467 "optimize_insn_for_speed_p ()
16468 && !TARGET_USE_MOV0
16469 && TARGET_SPLIT_LONG_MOVES
16470 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16471 && peep2_regno_dead_p (0, FLAGS_REG)"
16472 [(parallel [(set (match_dup 2) (const_int 0))
16473 (clobber (reg:CC FLAGS_REG))])
16474 (set (match_dup 0) (match_dup 1))]
16475 "operands[2] = gen_lowpart (SImode, operands[1]);")
16478 [(match_scratch:SWI124 2 "<r>")
16479 (set (match_operand:SWI124 0 "memory_operand" "")
16480 (match_operand:SWI124 1 "immediate_operand" ""))]
16481 "optimize_insn_for_speed_p ()
16482 && TARGET_SPLIT_LONG_MOVES
16483 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16484 [(set (match_dup 2) (match_dup 1))
16485 (set (match_dup 0) (match_dup 2))])
16487 ;; Don't compare memory with zero, load and use a test instead.
16489 [(set (match_operand 0 "flags_reg_operand" "")
16490 (match_operator 1 "compare_operator"
16491 [(match_operand:SI 2 "memory_operand" "")
16493 (match_scratch:SI 3 "r")]
16494 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16495 [(set (match_dup 3) (match_dup 2))
16496 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16498 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16499 ;; Don't split NOTs with a displacement operand, because resulting XOR
16500 ;; will not be pairable anyway.
16502 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16503 ;; represented using a modRM byte. The XOR replacement is long decoded,
16504 ;; so this split helps here as well.
16506 ;; Note: Can't do this as a regular split because we can't get proper
16507 ;; lifetime information then.
16510 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16511 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16512 "optimize_insn_for_speed_p ()
16513 && ((TARGET_NOT_UNPAIRABLE
16514 && (!MEM_P (operands[0])
16515 || !memory_displacement_operand (operands[0], <MODE>mode)))
16516 || (TARGET_NOT_VECTORMODE
16517 && long_memory_operand (operands[0], <MODE>mode)))
16518 && peep2_regno_dead_p (0, FLAGS_REG)"
16519 [(parallel [(set (match_dup 0)
16520 (xor:SWI124 (match_dup 1) (const_int -1)))
16521 (clobber (reg:CC FLAGS_REG))])])
16523 ;; Non pairable "test imm, reg" instructions can be translated to
16524 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16525 ;; byte opcode instead of two, have a short form for byte operands),
16526 ;; so do it for other CPUs as well. Given that the value was dead,
16527 ;; this should not create any new dependencies. Pass on the sub-word
16528 ;; versions if we're concerned about partial register stalls.
16531 [(set (match_operand 0 "flags_reg_operand" "")
16532 (match_operator 1 "compare_operator"
16533 [(and:SI (match_operand:SI 2 "register_operand" "")
16534 (match_operand:SI 3 "immediate_operand" ""))
16536 "ix86_match_ccmode (insn, CCNOmode)
16537 && (true_regnum (operands[2]) != AX_REG
16538 || satisfies_constraint_K (operands[3]))
16539 && peep2_reg_dead_p (1, operands[2])"
16541 [(set (match_dup 0)
16542 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16545 (and:SI (match_dup 2) (match_dup 3)))])])
16547 ;; We don't need to handle HImode case, because it will be promoted to SImode
16548 ;; on ! TARGET_PARTIAL_REG_STALL
16551 [(set (match_operand 0 "flags_reg_operand" "")
16552 (match_operator 1 "compare_operator"
16553 [(and:QI (match_operand:QI 2 "register_operand" "")
16554 (match_operand:QI 3 "immediate_operand" ""))
16556 "! TARGET_PARTIAL_REG_STALL
16557 && ix86_match_ccmode (insn, CCNOmode)
16558 && true_regnum (operands[2]) != AX_REG
16559 && peep2_reg_dead_p (1, operands[2])"
16561 [(set (match_dup 0)
16562 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16565 (and:QI (match_dup 2) (match_dup 3)))])])
16568 [(set (match_operand 0 "flags_reg_operand" "")
16569 (match_operator 1 "compare_operator"
16572 (match_operand 2 "ext_register_operand" "")
16575 (match_operand 3 "const_int_operand" ""))
16577 "! TARGET_PARTIAL_REG_STALL
16578 && ix86_match_ccmode (insn, CCNOmode)
16579 && true_regnum (operands[2]) != AX_REG
16580 && peep2_reg_dead_p (1, operands[2])"
16581 [(parallel [(set (match_dup 0)
16590 (set (zero_extract:SI (match_dup 2)
16598 (match_dup 3)))])])
16600 ;; Don't do logical operations with memory inputs.
16602 [(match_scratch:SI 2 "r")
16603 (parallel [(set (match_operand:SI 0 "register_operand" "")
16604 (match_operator:SI 3 "arith_or_logical_operator"
16606 (match_operand:SI 1 "memory_operand" "")]))
16607 (clobber (reg:CC FLAGS_REG))])]
16608 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16609 [(set (match_dup 2) (match_dup 1))
16610 (parallel [(set (match_dup 0)
16611 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16612 (clobber (reg:CC FLAGS_REG))])])
16615 [(match_scratch:SI 2 "r")
16616 (parallel [(set (match_operand:SI 0 "register_operand" "")
16617 (match_operator:SI 3 "arith_or_logical_operator"
16618 [(match_operand:SI 1 "memory_operand" "")
16620 (clobber (reg:CC FLAGS_REG))])]
16621 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16622 [(set (match_dup 2) (match_dup 1))
16623 (parallel [(set (match_dup 0)
16624 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16625 (clobber (reg:CC FLAGS_REG))])])
16627 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
16628 ;; refers to the destination of the load!
16631 [(set (match_operand:SI 0 "register_operand" "")
16632 (match_operand:SI 1 "register_operand" ""))
16633 (parallel [(set (match_dup 0)
16634 (match_operator:SI 3 "commutative_operator"
16636 (match_operand:SI 2 "memory_operand" "")]))
16637 (clobber (reg:CC FLAGS_REG))])]
16638 "REGNO (operands[0]) != REGNO (operands[1])
16639 && GENERAL_REGNO_P (REGNO (operands[0]))
16640 && GENERAL_REGNO_P (REGNO (operands[1]))"
16641 [(set (match_dup 0) (match_dup 4))
16642 (parallel [(set (match_dup 0)
16643 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16644 (clobber (reg:CC FLAGS_REG))])]
16645 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
16648 [(set (match_operand 0 "register_operand" "")
16649 (match_operand 1 "register_operand" ""))
16651 (match_operator 3 "commutative_operator"
16653 (match_operand 2 "memory_operand" "")]))]
16654 "REGNO (operands[0]) != REGNO (operands[1])
16655 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
16656 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
16657 [(set (match_dup 0) (match_dup 2))
16659 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
16661 ; Don't do logical operations with memory outputs
16663 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16664 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
16665 ; the same decoder scheduling characteristics as the original.
16668 [(match_scratch:SI 2 "r")
16669 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16670 (match_operator:SI 3 "arith_or_logical_operator"
16672 (match_operand:SI 1 "nonmemory_operand" "")]))
16673 (clobber (reg:CC FLAGS_REG))])]
16674 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16675 /* Do not split stack checking probes. */
16676 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16677 [(set (match_dup 2) (match_dup 0))
16678 (parallel [(set (match_dup 2)
16679 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16680 (clobber (reg:CC FLAGS_REG))])
16681 (set (match_dup 0) (match_dup 2))])
16684 [(match_scratch:SI 2 "r")
16685 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16686 (match_operator:SI 3 "arith_or_logical_operator"
16687 [(match_operand:SI 1 "nonmemory_operand" "")
16689 (clobber (reg:CC FLAGS_REG))])]
16690 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16691 /* Do not split stack checking probes. */
16692 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16693 [(set (match_dup 2) (match_dup 0))
16694 (parallel [(set (match_dup 2)
16695 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16696 (clobber (reg:CC FLAGS_REG))])
16697 (set (match_dup 0) (match_dup 2))])
16699 ;; Attempt to always use XOR for zeroing registers.
16701 [(set (match_operand 0 "register_operand" "")
16702 (match_operand 1 "const0_operand" ""))]
16703 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
16704 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16705 && GENERAL_REG_P (operands[0])
16706 && peep2_regno_dead_p (0, FLAGS_REG)"
16707 [(parallel [(set (match_dup 0) (const_int 0))
16708 (clobber (reg:CC FLAGS_REG))])]
16709 "operands[0] = gen_lowpart (word_mode, operands[0]);")
16712 [(set (strict_low_part (match_operand 0 "register_operand" ""))
16714 "(GET_MODE (operands[0]) == QImode
16715 || GET_MODE (operands[0]) == HImode)
16716 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16717 && peep2_regno_dead_p (0, FLAGS_REG)"
16718 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
16719 (clobber (reg:CC FLAGS_REG))])])
16721 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
16723 [(set (match_operand:SWI248 0 "register_operand" "")
16725 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
16726 && peep2_regno_dead_p (0, FLAGS_REG)"
16727 [(parallel [(set (match_dup 0) (const_int -1))
16728 (clobber (reg:CC FLAGS_REG))])]
16730 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
16731 operands[0] = gen_lowpart (SImode, operands[0]);
16734 ;; Attempt to convert simple lea to add/shift.
16735 ;; These can be created by move expanders.
16738 [(set (match_operand:SWI48 0 "register_operand" "")
16739 (plus:SWI48 (match_dup 0)
16740 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
16741 "peep2_regno_dead_p (0, FLAGS_REG)"
16742 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
16743 (clobber (reg:CC FLAGS_REG))])])
16746 [(set (match_operand:SI 0 "register_operand" "")
16747 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
16748 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
16750 && peep2_regno_dead_p (0, FLAGS_REG)
16751 && REGNO (operands[0]) == REGNO (operands[1])"
16752 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
16753 (clobber (reg:CC FLAGS_REG))])]
16754 "operands[2] = gen_lowpart (SImode, operands[2]);")
16757 [(set (match_operand:SWI48 0 "register_operand" "")
16758 (mult:SWI48 (match_dup 0)
16759 (match_operand:SWI48 1 "const_int_operand" "")))]
16760 "exact_log2 (INTVAL (operands[1])) >= 0
16761 && peep2_regno_dead_p (0, FLAGS_REG)"
16762 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
16763 (clobber (reg:CC FLAGS_REG))])]
16764 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
16767 [(set (match_operand:SI 0 "register_operand" "")
16768 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
16769 (match_operand:DI 2 "const_int_operand" "")) 0))]
16771 && exact_log2 (INTVAL (operands[2])) >= 0
16772 && REGNO (operands[0]) == REGNO (operands[1])
16773 && peep2_regno_dead_p (0, FLAGS_REG)"
16774 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
16775 (clobber (reg:CC FLAGS_REG))])]
16776 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
16778 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
16779 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
16780 ;; On many CPUs it is also faster, since special hardware to avoid esp
16781 ;; dependencies is present.
16783 ;; While some of these conversions may be done using splitters, we use
16784 ;; peepholes in order to allow combine_stack_adjustments pass to see
16785 ;; nonobfuscated RTL.
16787 ;; Convert prologue esp subtractions to push.
16788 ;; We need register to push. In order to keep verify_flow_info happy we have
16790 ;; - use scratch and clobber it in order to avoid dependencies
16791 ;; - use already live register
16792 ;; We can't use the second way right now, since there is no reliable way how to
16793 ;; verify that given register is live. First choice will also most likely in
16794 ;; fewer dependencies. On the place of esp adjustments it is very likely that
16795 ;; call clobbered registers are dead. We may want to use base pointer as an
16796 ;; alternative when no register is available later.
16799 [(match_scratch:P 1 "r")
16800 (parallel [(set (reg:P SP_REG)
16801 (plus:P (reg:P SP_REG)
16802 (match_operand:P 0 "const_int_operand" "")))
16803 (clobber (reg:CC FLAGS_REG))
16804 (clobber (mem:BLK (scratch)))])]
16805 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16806 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
16807 [(clobber (match_dup 1))
16808 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16809 (clobber (mem:BLK (scratch)))])])
16812 [(match_scratch:P 1 "r")
16813 (parallel [(set (reg:P SP_REG)
16814 (plus:P (reg:P SP_REG)
16815 (match_operand:P 0 "const_int_operand" "")))
16816 (clobber (reg:CC FLAGS_REG))
16817 (clobber (mem:BLK (scratch)))])]
16818 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16819 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
16820 [(clobber (match_dup 1))
16821 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16822 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16823 (clobber (mem:BLK (scratch)))])])
16825 ;; Convert esp subtractions to push.
16827 [(match_scratch:P 1 "r")
16828 (parallel [(set (reg:P SP_REG)
16829 (plus:P (reg:P SP_REG)
16830 (match_operand:P 0 "const_int_operand" "")))
16831 (clobber (reg:CC FLAGS_REG))])]
16832 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16833 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
16834 [(clobber (match_dup 1))
16835 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
16838 [(match_scratch:P 1 "r")
16839 (parallel [(set (reg:P SP_REG)
16840 (plus:P (reg:P SP_REG)
16841 (match_operand:P 0 "const_int_operand" "")))
16842 (clobber (reg:CC FLAGS_REG))])]
16843 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16844 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
16845 [(clobber (match_dup 1))
16846 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16847 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
16849 ;; Convert epilogue deallocator to pop.
16851 [(match_scratch:P 1 "r")
16852 (parallel [(set (reg:P SP_REG)
16853 (plus:P (reg:P SP_REG)
16854 (match_operand:P 0 "const_int_operand" "")))
16855 (clobber (reg:CC FLAGS_REG))
16856 (clobber (mem:BLK (scratch)))])]
16857 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
16858 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
16859 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
16860 (clobber (mem:BLK (scratch)))])])
16862 ;; Two pops case is tricky, since pop causes dependency
16863 ;; on destination register. We use two registers if available.
16865 [(match_scratch:P 1 "r")
16866 (match_scratch:P 2 "r")
16867 (parallel [(set (reg:P SP_REG)
16868 (plus:P (reg:P SP_REG)
16869 (match_operand:P 0 "const_int_operand" "")))
16870 (clobber (reg:CC FLAGS_REG))
16871 (clobber (mem:BLK (scratch)))])]
16872 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
16873 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
16874 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
16875 (clobber (mem:BLK (scratch)))])
16876 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
16879 [(match_scratch:P 1 "r")
16880 (parallel [(set (reg:P SP_REG)
16881 (plus:P (reg:P SP_REG)
16882 (match_operand:P 0 "const_int_operand" "")))
16883 (clobber (reg:CC FLAGS_REG))
16884 (clobber (mem:BLK (scratch)))])]
16885 "optimize_insn_for_size_p ()
16886 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
16887 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
16888 (clobber (mem:BLK (scratch)))])
16889 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
16891 ;; Convert esp additions to pop.
16893 [(match_scratch:P 1 "r")
16894 (parallel [(set (reg:P SP_REG)
16895 (plus:P (reg:P SP_REG)
16896 (match_operand:P 0 "const_int_operand" "")))
16897 (clobber (reg:CC FLAGS_REG))])]
16898 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
16899 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
16901 ;; Two pops case is tricky, since pop causes dependency
16902 ;; on destination register. We use two registers if available.
16904 [(match_scratch:P 1 "r")
16905 (match_scratch:P 2 "r")
16906 (parallel [(set (reg:P SP_REG)
16907 (plus:P (reg:P SP_REG)
16908 (match_operand:P 0 "const_int_operand" "")))
16909 (clobber (reg:CC FLAGS_REG))])]
16910 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
16911 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
16912 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
16915 [(match_scratch:P 1 "r")
16916 (parallel [(set (reg:P SP_REG)
16917 (plus:P (reg:P SP_REG)
16918 (match_operand:P 0 "const_int_operand" "")))
16919 (clobber (reg:CC FLAGS_REG))])]
16920 "optimize_insn_for_size_p ()
16921 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
16922 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
16923 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
16925 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
16926 ;; required and register dies. Similarly for 128 to -128.
16928 [(set (match_operand 0 "flags_reg_operand" "")
16929 (match_operator 1 "compare_operator"
16930 [(match_operand 2 "register_operand" "")
16931 (match_operand 3 "const_int_operand" "")]))]
16932 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
16933 && incdec_operand (operands[3], GET_MODE (operands[3])))
16934 || (!TARGET_FUSE_CMP_AND_BRANCH
16935 && INTVAL (operands[3]) == 128))
16936 && ix86_match_ccmode (insn, CCGCmode)
16937 && peep2_reg_dead_p (1, operands[2])"
16938 [(parallel [(set (match_dup 0)
16939 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
16940 (clobber (match_dup 2))])])
16942 ;; Convert imul by three, five and nine into lea
16945 [(set (match_operand:SWI48 0 "register_operand" "")
16946 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
16947 (match_operand:SWI48 2 "const_int_operand" "")))
16948 (clobber (reg:CC FLAGS_REG))])]
16949 "INTVAL (operands[2]) == 3
16950 || INTVAL (operands[2]) == 5
16951 || INTVAL (operands[2]) == 9"
16952 [(set (match_dup 0)
16953 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
16955 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
16959 [(set (match_operand:SWI48 0 "register_operand" "")
16960 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
16961 (match_operand:SWI48 2 "const_int_operand" "")))
16962 (clobber (reg:CC FLAGS_REG))])]
16963 "optimize_insn_for_speed_p ()
16964 && (INTVAL (operands[2]) == 3
16965 || INTVAL (operands[2]) == 5
16966 || INTVAL (operands[2]) == 9)"
16967 [(set (match_dup 0) (match_dup 1))
16969 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
16971 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
16973 ;; imul $32bit_imm, mem, reg is vector decoded, while
16974 ;; imul $32bit_imm, reg, reg is direct decoded.
16976 [(match_scratch:SWI48 3 "r")
16977 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
16978 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
16979 (match_operand:SWI48 2 "immediate_operand" "")))
16980 (clobber (reg:CC FLAGS_REG))])]
16981 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
16982 && !satisfies_constraint_K (operands[2])"
16983 [(set (match_dup 3) (match_dup 1))
16984 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
16985 (clobber (reg:CC FLAGS_REG))])])
16988 [(match_scratch:SI 3 "r")
16989 (parallel [(set (match_operand:DI 0 "register_operand" "")
16991 (mult:SI (match_operand:SI 1 "memory_operand" "")
16992 (match_operand:SI 2 "immediate_operand" ""))))
16993 (clobber (reg:CC FLAGS_REG))])]
16995 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
16996 && !satisfies_constraint_K (operands[2])"
16997 [(set (match_dup 3) (match_dup 1))
16998 (parallel [(set (match_dup 0)
16999 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17000 (clobber (reg:CC FLAGS_REG))])])
17002 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17003 ;; Convert it into imul reg, reg
17004 ;; It would be better to force assembler to encode instruction using long
17005 ;; immediate, but there is apparently no way to do so.
17007 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17009 (match_operand:SWI248 1 "nonimmediate_operand" "")
17010 (match_operand:SWI248 2 "const_int_operand" "")))
17011 (clobber (reg:CC FLAGS_REG))])
17012 (match_scratch:SWI248 3 "r")]
17013 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17014 && satisfies_constraint_K (operands[2])"
17015 [(set (match_dup 3) (match_dup 2))
17016 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17017 (clobber (reg:CC FLAGS_REG))])]
17019 if (!rtx_equal_p (operands[0], operands[1]))
17020 emit_move_insn (operands[0], operands[1]);
17023 ;; After splitting up read-modify operations, array accesses with memory
17024 ;; operands might end up in form:
17026 ;; movl 4(%esp), %edx
17028 ;; instead of pre-splitting:
17030 ;; addl 4(%esp), %eax
17032 ;; movl 4(%esp), %edx
17033 ;; leal (%edx,%eax,4), %eax
17036 [(match_scratch:P 5 "r")
17037 (parallel [(set (match_operand 0 "register_operand" "")
17038 (ashift (match_operand 1 "register_operand" "")
17039 (match_operand 2 "const_int_operand" "")))
17040 (clobber (reg:CC FLAGS_REG))])
17041 (parallel [(set (match_operand 3 "register_operand" "")
17042 (plus (match_dup 0)
17043 (match_operand 4 "x86_64_general_operand" "")))
17044 (clobber (reg:CC FLAGS_REG))])]
17045 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
17046 /* Validate MODE for lea. */
17047 && ((!TARGET_PARTIAL_REG_STALL
17048 && (GET_MODE (operands[0]) == QImode
17049 || GET_MODE (operands[0]) == HImode))
17050 || GET_MODE (operands[0]) == SImode
17051 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17052 && (rtx_equal_p (operands[0], operands[3])
17053 || peep2_reg_dead_p (2, operands[0]))
17054 /* We reorder load and the shift. */
17055 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17056 [(set (match_dup 5) (match_dup 4))
17057 (set (match_dup 0) (match_dup 1))]
17059 enum machine_mode mode = GET_MODE (operands[1]) == DImode ? DImode : SImode;
17060 int scale = 1 << INTVAL (operands[2]);
17061 rtx index = gen_lowpart (Pmode, operands[1]);
17062 rtx base = gen_lowpart (Pmode, operands[5]);
17063 rtx dest = gen_lowpart (mode, operands[3]);
17065 operands[1] = gen_rtx_PLUS (Pmode, base,
17066 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17067 operands[5] = base;
17070 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17071 operands[5] = gen_rtx_SUBREG (mode, operands[5], 0);
17073 operands[0] = dest;
17076 ;; Call-value patterns last so that the wildcard operand does not
17077 ;; disrupt insn-recog's switch tables.
17079 (define_insn "*call_value_pop_0"
17080 [(set (match_operand 0 "" "")
17081 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17082 (match_operand:SI 2 "" "")))
17083 (set (reg:SI SP_REG)
17084 (plus:SI (reg:SI SP_REG)
17085 (match_operand:SI 3 "immediate_operand" "")))]
17088 if (SIBLING_CALL_P (insn))
17091 return "call\t%P1";
17093 [(set_attr "type" "callv")])
17095 (define_insn "*call_value_pop_1"
17096 [(set (match_operand 0 "" "")
17097 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17098 (match_operand:SI 2 "" "")))
17099 (set (reg:SI SP_REG)
17100 (plus:SI (reg:SI SP_REG)
17101 (match_operand:SI 3 "immediate_operand" "i")))]
17102 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17104 if (constant_call_address_operand (operands[1], Pmode))
17105 return "call\t%P1";
17106 return "call\t%A1";
17108 [(set_attr "type" "callv")])
17110 (define_insn "*sibcall_value_pop_1"
17111 [(set (match_operand 0 "" "")
17112 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17113 (match_operand:SI 2 "" "")))
17114 (set (reg:SI SP_REG)
17115 (plus:SI (reg:SI SP_REG)
17116 (match_operand:SI 3 "immediate_operand" "i,i")))]
17117 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17121 [(set_attr "type" "callv")])
17123 (define_insn "*call_value_0"
17124 [(set (match_operand 0 "" "")
17125 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17126 (match_operand:SI 2 "" "")))]
17129 if (SIBLING_CALL_P (insn))
17132 return "call\t%P1";
17134 [(set_attr "type" "callv")])
17136 (define_insn "*call_value_0_rex64"
17137 [(set (match_operand 0 "" "")
17138 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17139 (match_operand:DI 2 "const_int_operand" "")))]
17142 if (SIBLING_CALL_P (insn))
17145 return "call\t%P1";
17147 [(set_attr "type" "callv")])
17149 (define_insn "*call_value_0_rex64_ms_sysv"
17150 [(set (match_operand 0 "" "")
17151 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17152 (match_operand:DI 2 "const_int_operand" "")))
17153 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17154 (clobber (reg:TI XMM6_REG))
17155 (clobber (reg:TI XMM7_REG))
17156 (clobber (reg:TI XMM8_REG))
17157 (clobber (reg:TI XMM9_REG))
17158 (clobber (reg:TI XMM10_REG))
17159 (clobber (reg:TI XMM11_REG))
17160 (clobber (reg:TI XMM12_REG))
17161 (clobber (reg:TI XMM13_REG))
17162 (clobber (reg:TI XMM14_REG))
17163 (clobber (reg:TI XMM15_REG))
17164 (clobber (reg:DI SI_REG))
17165 (clobber (reg:DI DI_REG))]
17166 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17168 if (SIBLING_CALL_P (insn))
17171 return "call\t%P1";
17173 [(set_attr "type" "callv")])
17175 (define_insn "*call_value_1"
17176 [(set (match_operand 0 "" "")
17177 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17178 (match_operand:SI 2 "" "")))]
17179 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17181 if (constant_call_address_operand (operands[1], Pmode))
17182 return "call\t%P1";
17183 return "call\t%A1";
17185 [(set_attr "type" "callv")])
17187 (define_insn "*sibcall_value_1"
17188 [(set (match_operand 0 "" "")
17189 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17190 (match_operand:SI 2 "" "")))]
17191 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17195 [(set_attr "type" "callv")])
17197 (define_insn "*call_value_1_rex64"
17198 [(set (match_operand 0 "" "")
17199 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17200 (match_operand:DI 2 "" "")))]
17201 "TARGET_64BIT && !SIBLING_CALL_P (insn)
17202 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17204 if (constant_call_address_operand (operands[1], Pmode))
17205 return "call\t%P1";
17206 return "call\t%A1";
17208 [(set_attr "type" "callv")])
17210 (define_insn "*call_value_1_rex64_ms_sysv"
17211 [(set (match_operand 0 "" "")
17212 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17213 (match_operand:DI 2 "" "")))
17214 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17215 (clobber (reg:TI XMM6_REG))
17216 (clobber (reg:TI XMM7_REG))
17217 (clobber (reg:TI XMM8_REG))
17218 (clobber (reg:TI XMM9_REG))
17219 (clobber (reg:TI XMM10_REG))
17220 (clobber (reg:TI XMM11_REG))
17221 (clobber (reg:TI XMM12_REG))
17222 (clobber (reg:TI XMM13_REG))
17223 (clobber (reg:TI XMM14_REG))
17224 (clobber (reg:TI XMM15_REG))
17225 (clobber (reg:DI SI_REG))
17226 (clobber (reg:DI DI_REG))]
17227 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17229 if (constant_call_address_operand (operands[1], Pmode))
17230 return "call\t%P1";
17231 return "call\t%A1";
17233 [(set_attr "type" "callv")])
17235 (define_insn "*call_value_1_rex64_large"
17236 [(set (match_operand 0 "" "")
17237 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17238 (match_operand:DI 2 "" "")))]
17239 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17241 [(set_attr "type" "callv")])
17243 (define_insn "*sibcall_value_1_rex64"
17244 [(set (match_operand 0 "" "")
17245 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17246 (match_operand:DI 2 "" "")))]
17247 "TARGET_64BIT && SIBLING_CALL_P (insn)"
17251 [(set_attr "type" "callv")])
17253 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17254 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17255 ;; caught for use by garbage collectors and the like. Using an insn that
17256 ;; maps to SIGILL makes it more likely the program will rightfully die.
17257 ;; Keeping with tradition, "6" is in honor of #UD.
17258 (define_insn "trap"
17259 [(trap_if (const_int 1) (const_int 6))]
17261 { return ASM_SHORT "0x0b0f"; }
17262 [(set_attr "length" "2")])
17264 (define_expand "prefetch"
17265 [(prefetch (match_operand 0 "address_operand" "")
17266 (match_operand:SI 1 "const_int_operand" "")
17267 (match_operand:SI 2 "const_int_operand" ""))]
17268 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17270 int rw = INTVAL (operands[1]);
17271 int locality = INTVAL (operands[2]);
17273 gcc_assert (rw == 0 || rw == 1);
17274 gcc_assert (locality >= 0 && locality <= 3);
17275 gcc_assert (GET_MODE (operands[0]) == Pmode
17276 || GET_MODE (operands[0]) == VOIDmode);
17278 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17279 supported by SSE counterpart or the SSE prefetch is not available
17280 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17282 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17283 operands[2] = GEN_INT (3);
17285 operands[1] = const0_rtx;
17288 (define_insn "*prefetch_sse_<mode>"
17289 [(prefetch (match_operand:P 0 "address_operand" "p")
17291 (match_operand:SI 1 "const_int_operand" ""))]
17292 "TARGET_PREFETCH_SSE"
17294 static const char * const patterns[4] = {
17295 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17298 int locality = INTVAL (operands[1]);
17299 gcc_assert (locality >= 0 && locality <= 3);
17301 return patterns[locality];
17303 [(set_attr "type" "sse")
17304 (set_attr "atom_sse_attr" "prefetch")
17305 (set (attr "length_address")
17306 (symbol_ref "memory_address_length (operands[0])"))
17307 (set_attr "memory" "none")])
17309 (define_insn "*prefetch_3dnow_<mode>"
17310 [(prefetch (match_operand:P 0 "address_operand" "p")
17311 (match_operand:SI 1 "const_int_operand" "n")
17315 if (INTVAL (operands[1]) == 0)
17316 return "prefetch\t%a0";
17318 return "prefetchw\t%a0";
17320 [(set_attr "type" "mmx")
17321 (set (attr "length_address")
17322 (symbol_ref "memory_address_length (operands[0])"))
17323 (set_attr "memory" "none")])
17325 (define_expand "stack_protect_set"
17326 [(match_operand 0 "memory_operand" "")
17327 (match_operand 1 "memory_operand" "")]
17330 rtx (*insn)(rtx, rtx);
17332 #ifdef TARGET_THREAD_SSP_OFFSET
17333 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17334 insn = (TARGET_64BIT
17335 ? gen_stack_tls_protect_set_di
17336 : gen_stack_tls_protect_set_si);
17338 insn = (TARGET_64BIT
17339 ? gen_stack_protect_set_di
17340 : gen_stack_protect_set_si);
17343 emit_insn (insn (operands[0], operands[1]));
17347 (define_insn "stack_protect_set_<mode>"
17348 [(set (match_operand:P 0 "memory_operand" "=m")
17349 (unspec:P [(match_operand:P 1 "memory_operand" "m")] UNSPEC_SP_SET))
17350 (set (match_scratch:P 2 "=&r") (const_int 0))
17351 (clobber (reg:CC FLAGS_REG))]
17353 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17354 [(set_attr "type" "multi")])
17356 (define_insn "stack_tls_protect_set_<mode>"
17357 [(set (match_operand:P 0 "memory_operand" "=m")
17358 (unspec:P [(match_operand:P 1 "const_int_operand" "i")]
17359 UNSPEC_SP_TLS_SET))
17360 (set (match_scratch:P 2 "=&r") (const_int 0))
17361 (clobber (reg:CC FLAGS_REG))]
17363 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17364 [(set_attr "type" "multi")])
17366 (define_expand "stack_protect_test"
17367 [(match_operand 0 "memory_operand" "")
17368 (match_operand 1 "memory_operand" "")
17369 (match_operand 2 "" "")]
17372 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17374 rtx (*insn)(rtx, rtx, rtx);
17376 #ifdef TARGET_THREAD_SSP_OFFSET
17377 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17378 insn = (TARGET_64BIT
17379 ? gen_stack_tls_protect_test_di
17380 : gen_stack_tls_protect_test_si);
17382 insn = (TARGET_64BIT
17383 ? gen_stack_protect_test_di
17384 : gen_stack_protect_test_si);
17387 emit_insn (insn (flags, operands[0], operands[1]));
17389 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17390 flags, const0_rtx, operands[2]));
17394 (define_insn "stack_protect_test_<mode>"
17395 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17396 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17397 (match_operand:P 2 "memory_operand" "m")]
17399 (clobber (match_scratch:P 3 "=&r"))]
17401 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17402 [(set_attr "type" "multi")])
17404 (define_insn "stack_tls_protect_test_<mode>"
17405 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17406 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17407 (match_operand:P 2 "const_int_operand" "i")]
17408 UNSPEC_SP_TLS_TEST))
17409 (clobber (match_scratch:P 3 "=r"))]
17411 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17412 [(set_attr "type" "multi")])
17414 (define_insn "sse4_2_crc32<mode>"
17415 [(set (match_operand:SI 0 "register_operand" "=r")
17417 [(match_operand:SI 1 "register_operand" "0")
17418 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17420 "TARGET_SSE4_2 || TARGET_CRC32"
17421 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17422 [(set_attr "type" "sselog1")
17423 (set_attr "prefix_rep" "1")
17424 (set_attr "prefix_extra" "1")
17425 (set (attr "prefix_data16")
17426 (if_then_else (match_operand:HI 2 "" "")
17428 (const_string "*")))
17429 (set (attr "prefix_rex")
17430 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17432 (const_string "*")))
17433 (set_attr "mode" "SI")])
17435 (define_insn "sse4_2_crc32di"
17436 [(set (match_operand:DI 0 "register_operand" "=r")
17438 [(match_operand:DI 1 "register_operand" "0")
17439 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17441 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17442 "crc32{q}\t{%2, %0|%0, %2}"
17443 [(set_attr "type" "sselog1")
17444 (set_attr "prefix_rep" "1")
17445 (set_attr "prefix_extra" "1")
17446 (set_attr "mode" "DI")])
17448 (define_expand "rdpmc"
17449 [(match_operand:DI 0 "register_operand" "")
17450 (match_operand:SI 1 "register_operand" "")]
17453 rtx reg = gen_reg_rtx (DImode);
17456 /* Force operand 1 into ECX. */
17457 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17458 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17459 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17464 rtvec vec = rtvec_alloc (2);
17465 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17466 rtx upper = gen_reg_rtx (DImode);
17467 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17468 gen_rtvec (1, const0_rtx),
17470 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17471 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17473 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17474 NULL, 1, OPTAB_DIRECT);
17475 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17479 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17480 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17484 (define_insn "*rdpmc"
17485 [(set (match_operand:DI 0 "register_operand" "=A")
17486 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17490 [(set_attr "type" "other")
17491 (set_attr "length" "2")])
17493 (define_insn "*rdpmc_rex64"
17494 [(set (match_operand:DI 0 "register_operand" "=a")
17495 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17497 (set (match_operand:DI 1 "register_operand" "=d")
17498 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17501 [(set_attr "type" "other")
17502 (set_attr "length" "2")])
17504 (define_expand "rdtsc"
17505 [(set (match_operand:DI 0 "register_operand" "")
17506 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17511 rtvec vec = rtvec_alloc (2);
17512 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17513 rtx upper = gen_reg_rtx (DImode);
17514 rtx lower = gen_reg_rtx (DImode);
17515 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17516 gen_rtvec (1, const0_rtx),
17518 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17519 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17521 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17522 NULL, 1, OPTAB_DIRECT);
17523 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17525 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17530 (define_insn "*rdtsc"
17531 [(set (match_operand:DI 0 "register_operand" "=A")
17532 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17535 [(set_attr "type" "other")
17536 (set_attr "length" "2")])
17538 (define_insn "*rdtsc_rex64"
17539 [(set (match_operand:DI 0 "register_operand" "=a")
17540 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17541 (set (match_operand:DI 1 "register_operand" "=d")
17542 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17545 [(set_attr "type" "other")
17546 (set_attr "length" "2")])
17548 (define_expand "rdtscp"
17549 [(match_operand:DI 0 "register_operand" "")
17550 (match_operand:SI 1 "memory_operand" "")]
17553 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17554 gen_rtvec (1, const0_rtx),
17556 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17557 gen_rtvec (1, const0_rtx),
17559 rtx reg = gen_reg_rtx (DImode);
17560 rtx tmp = gen_reg_rtx (SImode);
17564 rtvec vec = rtvec_alloc (3);
17565 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17566 rtx upper = gen_reg_rtx (DImode);
17567 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17568 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17569 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17571 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17572 NULL, 1, OPTAB_DIRECT);
17573 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17578 rtvec vec = rtvec_alloc (2);
17579 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17580 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17581 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17584 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17585 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17589 (define_insn "*rdtscp"
17590 [(set (match_operand:DI 0 "register_operand" "=A")
17591 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17592 (set (match_operand:SI 1 "register_operand" "=c")
17593 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17596 [(set_attr "type" "other")
17597 (set_attr "length" "3")])
17599 (define_insn "*rdtscp_rex64"
17600 [(set (match_operand:DI 0 "register_operand" "=a")
17601 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17602 (set (match_operand:DI 1 "register_operand" "=d")
17603 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17604 (set (match_operand:SI 2 "register_operand" "=c")
17605 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17608 [(set_attr "type" "other")
17609 (set_attr "length" "3")])
17611 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17613 ;; LWP instructions
17615 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17617 (define_expand "lwp_llwpcb"
17618 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17619 UNSPECV_LLWP_INTRINSIC)]
17623 (define_insn "*lwp_llwpcb<mode>1"
17624 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17625 UNSPECV_LLWP_INTRINSIC)]
17628 [(set_attr "type" "lwp")
17629 (set_attr "mode" "<MODE>")
17630 (set_attr "length" "5")])
17632 (define_expand "lwp_slwpcb"
17633 [(set (match_operand 0 "register_operand" "=r")
17634 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17638 emit_insn (gen_lwp_slwpcbdi (operands[0]));
17640 emit_insn (gen_lwp_slwpcbsi (operands[0]));
17644 (define_insn "lwp_slwpcb<mode>"
17645 [(set (match_operand:P 0 "register_operand" "=r")
17646 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17649 [(set_attr "type" "lwp")
17650 (set_attr "mode" "<MODE>")
17651 (set_attr "length" "5")])
17653 (define_expand "lwp_lwpval<mode>3"
17654 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
17655 (match_operand:SI 2 "nonimmediate_operand" "rm")
17656 (match_operand:SI 3 "const_int_operand" "i")]
17657 UNSPECV_LWPVAL_INTRINSIC)]
17659 "/* Avoid unused variable warning. */
17662 (define_insn "*lwp_lwpval<mode>3_1"
17663 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
17664 (match_operand:SI 1 "nonimmediate_operand" "rm")
17665 (match_operand:SI 2 "const_int_operand" "i")]
17666 UNSPECV_LWPVAL_INTRINSIC)]
17668 "lwpval\t{%2, %1, %0|%0, %1, %2}"
17669 [(set_attr "type" "lwp")
17670 (set_attr "mode" "<MODE>")
17671 (set (attr "length")
17672 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17674 (define_expand "lwp_lwpins<mode>3"
17675 [(set (reg:CCC FLAGS_REG)
17676 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
17677 (match_operand:SI 2 "nonimmediate_operand" "rm")
17678 (match_operand:SI 3 "const_int_operand" "i")]
17679 UNSPECV_LWPINS_INTRINSIC))
17680 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
17681 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
17685 (define_insn "*lwp_lwpins<mode>3_1"
17686 [(set (reg:CCC FLAGS_REG)
17687 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
17688 (match_operand:SI 1 "nonimmediate_operand" "rm")
17689 (match_operand:SI 2 "const_int_operand" "i")]
17690 UNSPECV_LWPINS_INTRINSIC))]
17692 "lwpins\t{%2, %1, %0|%0, %1, %2}"
17693 [(set_attr "type" "lwp")
17694 (set_attr "mode" "<MODE>")
17695 (set (attr "length")
17696 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17698 (define_insn "rdfsbase<mode>"
17699 [(set (match_operand:SWI48 0 "register_operand" "=r")
17700 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
17701 "TARGET_64BIT && TARGET_FSGSBASE"
17703 [(set_attr "type" "other")
17704 (set_attr "prefix_extra" "2")])
17706 (define_insn "rdgsbase<mode>"
17707 [(set (match_operand:SWI48 0 "register_operand" "=r")
17708 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
17709 "TARGET_64BIT && TARGET_FSGSBASE"
17711 [(set_attr "type" "other")
17712 (set_attr "prefix_extra" "2")])
17714 (define_insn "wrfsbase<mode>"
17715 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17717 "TARGET_64BIT && TARGET_FSGSBASE"
17719 [(set_attr "type" "other")
17720 (set_attr "prefix_extra" "2")])
17722 (define_insn "wrgsbase<mode>"
17723 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17725 "TARGET_64BIT && TARGET_FSGSBASE"
17727 [(set_attr "type" "other")
17728 (set_attr "prefix_extra" "2")])
17730 (define_expand "rdrand<mode>"
17731 [(set (match_operand:SWI248 0 "register_operand" "=r")
17732 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))]
17735 rtx retry_label, insn, ccc;
17737 retry_label = gen_label_rtx ();
17739 emit_label (retry_label);
17741 /* Generate rdrand. */
17742 emit_insn (gen_rdrand<mode>_1 (operands[0]));
17744 /* Retry if the carry flag isn't valid. */
17745 ccc = gen_rtx_REG (CCCmode, FLAGS_REG);
17746 ccc = gen_rtx_EQ (VOIDmode, ccc, const0_rtx);
17747 ccc = gen_rtx_IF_THEN_ELSE (VOIDmode, ccc, pc_rtx,
17748 gen_rtx_LABEL_REF (VOIDmode, retry_label));
17749 insn = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, ccc));
17750 JUMP_LABEL (insn) = retry_label;
17755 (define_insn "rdrand<mode>_1"
17756 [(set (match_operand:SWI248 0 "register_operand" "=r")
17757 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))]
17760 [(set_attr "type" "other")
17761 (set_attr "prefix_extra" "1")])
17765 (include "sync.md")