1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>. */
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;; The special asm out single letter directives following a '%' are:
30 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; F,f -- likewise, but for floating-point.
34 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
36 ;; R -- print the prefix for register names.
37 ;; z -- print the opcode suffix for the size of the current operand.
38 ;; Z -- likewise, with special suffixes for x87 instructions.
39 ;; * -- print a star (in certain assembler syntax)
40 ;; A -- print an absolute memory reference.
41 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
42 ;; s -- print a shift double count, followed by the assemblers argument
44 ;; b -- print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; w -- likewise, print the HImode name of the register.
47 ;; k -- likewise, print the SImode name of the register.
48 ;; q -- likewise, print the DImode name of the register.
49 ;; x -- likewise, print the V4SFmode name of the register.
50 ;; t -- likewise, print the V8SFmode name of the register.
51 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
52 ;; y -- print "st(0)" instead of "st" as a register.
53 ;; d -- print duplicated register operand for AVX instruction.
54 ;; D -- print condition for SSE cmp instruction.
55 ;; P -- if PIC, print an @PLT suffix.
56 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; Y -- print condition for XOP pcom* instruction.
60 ;; + -- print a branch hint as 'cs' or 'ds' prefix
61 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
65 (define_c_enum "unspec" [
66 ;; Relocation specifiers
77 UNSPEC_MACHOPIC_OFFSET
86 UNSPEC_MEMORY_BLOCKAGE
94 ;; Other random patterns
103 UNSPEC_LD_MPIC ; load_macho_picbase
106 ;; For SSE/MMX support:
124 UNSPEC_MS_TO_SYSV_CALL
126 ;; Generic math support
128 UNSPEC_IEEE_MIN ; not commutative
129 UNSPEC_IEEE_MAX ; not commutative
131 ;; x87 Floating point
147 UNSPEC_FRNDINT_MASK_PM
151 ;; x87 Double output FP
183 ;; For SSE4.1 support
193 ;; For SSE4.2 support
199 UNSPEC_FMA4_INTRINSIC
202 UNSPEC_XOP_UNSIGNED_CMP
213 UNSPEC_AESKEYGENASSIST
215 ;; For PCLMUL support
231 (define_c_enum "unspecv" [
234 UNSPECV_PROBE_STACK_RANGE
253 UNSPECV_LLWP_INTRINSIC
254 UNSPECV_SLWP_INTRINSIC
255 UNSPECV_LWPVAL_INTRINSIC
256 UNSPECV_LWPINS_INTRINSIC
264 ;; Constants to represent pcomtrue/pcomfalse variants
274 ;; Constants used in the XOP pperm instruction
276 [(PPERM_SRC 0x00) /* copy source */
277 (PPERM_INVERT 0x20) /* invert source */
278 (PPERM_REVERSE 0x40) /* bit reverse source */
279 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
280 (PPERM_ZERO 0x80) /* all 0's */
281 (PPERM_ONES 0xa0) /* all 1's */
282 (PPERM_SIGN 0xc0) /* propagate sign bit */
283 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
284 (PPERM_SRC1 0x00) /* use first source byte */
285 (PPERM_SRC2 0x10) /* use second source byte */
288 ;; Registers by name.
341 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
344 ;; In C guard expressions, put expressions which may be compile-time
345 ;; constants first. This allows for better optimization. For
346 ;; example, write "TARGET_64BIT && reload_completed", not
347 ;; "reload_completed && TARGET_64BIT".
351 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,atom,
352 generic64,amdfam10,bdver1"
353 (const (symbol_ref "ix86_schedule")))
355 ;; A basic instruction type. Refinements due to arguments to be
356 ;; provided in other attributes.
359 alu,alu1,negnot,imov,imovx,lea,
360 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
361 icmp,test,ibr,setcc,icmov,
362 push,pop,call,callv,leave,
364 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
365 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
366 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
367 ssemuladd,sse4arg,lwp,
368 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
369 (const_string "other"))
371 ;; Main data type used by the insn
373 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
374 (const_string "unknown"))
376 ;; The CPU unit operations uses.
377 (define_attr "unit" "integer,i387,sse,mmx,unknown"
378 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
379 (const_string "i387")
380 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
381 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
382 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
384 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
386 (eq_attr "type" "other")
387 (const_string "unknown")]
388 (const_string "integer")))
390 ;; The (bounding maximum) length of an instruction immediate.
391 (define_attr "length_immediate" ""
392 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
395 (eq_attr "unit" "i387,sse,mmx")
397 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
399 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
400 (eq_attr "type" "imov,test")
401 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
402 (eq_attr "type" "call")
403 (if_then_else (match_operand 0 "constant_call_address_operand" "")
406 (eq_attr "type" "callv")
407 (if_then_else (match_operand 1 "constant_call_address_operand" "")
410 ;; We don't know the size before shorten_branches. Expect
411 ;; the instruction to fit for better scheduling.
412 (eq_attr "type" "ibr")
415 (symbol_ref "/* Update immediate_length and other attributes! */
416 gcc_unreachable (),1")))
418 ;; The (bounding maximum) length of an instruction address.
419 (define_attr "length_address" ""
420 (cond [(eq_attr "type" "str,other,multi,fxch")
422 (and (eq_attr "type" "call")
423 (match_operand 0 "constant_call_address_operand" ""))
425 (and (eq_attr "type" "callv")
426 (match_operand 1 "constant_call_address_operand" ""))
429 (symbol_ref "ix86_attr_length_address_default (insn)")))
431 ;; Set when length prefix is used.
432 (define_attr "prefix_data16" ""
433 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
435 (eq_attr "mode" "HI")
437 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
442 ;; Set when string REP prefix is used.
443 (define_attr "prefix_rep" ""
444 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
446 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
451 ;; Set when 0f opcode prefix is used.
452 (define_attr "prefix_0f" ""
454 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
455 (eq_attr "unit" "sse,mmx"))
459 ;; Set when REX opcode prefix is used.
460 (define_attr "prefix_rex" ""
461 (cond [(ne (symbol_ref "!TARGET_64BIT") (const_int 0))
463 (and (eq_attr "mode" "DI")
464 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
465 (eq_attr "unit" "!mmx")))
467 (and (eq_attr "mode" "QI")
468 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
471 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
474 (and (eq_attr "type" "imovx")
475 (match_operand:QI 1 "ext_QIreg_operand" ""))
480 ;; There are also additional prefixes in 3DNOW, SSSE3.
481 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
482 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
483 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
484 (define_attr "prefix_extra" ""
485 (cond [(eq_attr "type" "ssemuladd,sse4arg")
487 (eq_attr "type" "sseiadd1,ssecvt1")
492 ;; Prefix used: original, VEX or maybe VEX.
493 (define_attr "prefix" "orig,vex,maybe_vex"
494 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
496 (const_string "orig")))
498 ;; VEX W bit is used.
499 (define_attr "prefix_vex_w" "" (const_int 0))
501 ;; The length of VEX prefix
502 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
503 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
504 ;; still prefix_0f 1, with prefix_extra 1.
505 (define_attr "length_vex" ""
506 (if_then_else (and (eq_attr "prefix_0f" "1")
507 (eq_attr "prefix_extra" "0"))
508 (if_then_else (eq_attr "prefix_vex_w" "1")
509 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
510 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
511 (if_then_else (eq_attr "prefix_vex_w" "1")
512 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
513 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
515 ;; Set when modrm byte is used.
516 (define_attr "modrm" ""
517 (cond [(eq_attr "type" "str,leave")
519 (eq_attr "unit" "i387")
521 (and (eq_attr "type" "incdec")
522 (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
523 (ior (match_operand:SI 1 "register_operand" "")
524 (match_operand:HI 1 "register_operand" ""))))
526 (and (eq_attr "type" "push")
527 (not (match_operand 1 "memory_operand" "")))
529 (and (eq_attr "type" "pop")
530 (not (match_operand 0 "memory_operand" "")))
532 (and (eq_attr "type" "imov")
533 (and (not (eq_attr "mode" "DI"))
534 (ior (and (match_operand 0 "register_operand" "")
535 (match_operand 1 "immediate_operand" ""))
536 (ior (and (match_operand 0 "ax_reg_operand" "")
537 (match_operand 1 "memory_displacement_only_operand" ""))
538 (and (match_operand 0 "memory_displacement_only_operand" "")
539 (match_operand 1 "ax_reg_operand" ""))))))
541 (and (eq_attr "type" "call")
542 (match_operand 0 "constant_call_address_operand" ""))
544 (and (eq_attr "type" "callv")
545 (match_operand 1 "constant_call_address_operand" ""))
547 (and (eq_attr "type" "alu,alu1,icmp,test")
548 (match_operand 0 "ax_reg_operand" ""))
549 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
553 ;; The (bounding maximum) length of an instruction in bytes.
554 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
555 ;; Later we may want to split them and compute proper length as for
557 (define_attr "length" ""
558 (cond [(eq_attr "type" "other,multi,fistp,frndint")
560 (eq_attr "type" "fcmp")
562 (eq_attr "unit" "i387")
564 (plus (attr "prefix_data16")
565 (attr "length_address")))
566 (ior (eq_attr "prefix" "vex")
567 (and (eq_attr "prefix" "maybe_vex")
568 (ne (symbol_ref "TARGET_AVX") (const_int 0))))
569 (plus (attr "length_vex")
570 (plus (attr "length_immediate")
572 (attr "length_address"))))]
573 (plus (plus (attr "modrm")
574 (plus (attr "prefix_0f")
575 (plus (attr "prefix_rex")
576 (plus (attr "prefix_extra")
578 (plus (attr "prefix_rep")
579 (plus (attr "prefix_data16")
580 (plus (attr "length_immediate")
581 (attr "length_address")))))))
583 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
584 ;; `store' if there is a simple memory reference therein, or `unknown'
585 ;; if the instruction is complex.
587 (define_attr "memory" "none,load,store,both,unknown"
588 (cond [(eq_attr "type" "other,multi,str,lwp")
589 (const_string "unknown")
590 (eq_attr "type" "lea,fcmov,fpspc")
591 (const_string "none")
592 (eq_attr "type" "fistp,leave")
593 (const_string "both")
594 (eq_attr "type" "frndint")
595 (const_string "load")
596 (eq_attr "type" "push")
597 (if_then_else (match_operand 1 "memory_operand" "")
598 (const_string "both")
599 (const_string "store"))
600 (eq_attr "type" "pop")
601 (if_then_else (match_operand 0 "memory_operand" "")
602 (const_string "both")
603 (const_string "load"))
604 (eq_attr "type" "setcc")
605 (if_then_else (match_operand 0 "memory_operand" "")
606 (const_string "store")
607 (const_string "none"))
608 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
609 (if_then_else (ior (match_operand 0 "memory_operand" "")
610 (match_operand 1 "memory_operand" ""))
611 (const_string "load")
612 (const_string "none"))
613 (eq_attr "type" "ibr")
614 (if_then_else (match_operand 0 "memory_operand" "")
615 (const_string "load")
616 (const_string "none"))
617 (eq_attr "type" "call")
618 (if_then_else (match_operand 0 "constant_call_address_operand" "")
619 (const_string "none")
620 (const_string "load"))
621 (eq_attr "type" "callv")
622 (if_then_else (match_operand 1 "constant_call_address_operand" "")
623 (const_string "none")
624 (const_string "load"))
625 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
626 (match_operand 1 "memory_operand" ""))
627 (const_string "both")
628 (and (match_operand 0 "memory_operand" "")
629 (match_operand 1 "memory_operand" ""))
630 (const_string "both")
631 (match_operand 0 "memory_operand" "")
632 (const_string "store")
633 (match_operand 1 "memory_operand" "")
634 (const_string "load")
636 "!alu1,negnot,ishift1,
637 imov,imovx,icmp,test,bitmanip,
639 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
640 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
641 (match_operand 2 "memory_operand" ""))
642 (const_string "load")
643 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
644 (match_operand 3 "memory_operand" ""))
645 (const_string "load")
647 (const_string "none")))
649 ;; Indicates if an instruction has both an immediate and a displacement.
651 (define_attr "imm_disp" "false,true,unknown"
652 (cond [(eq_attr "type" "other,multi")
653 (const_string "unknown")
654 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
655 (and (match_operand 0 "memory_displacement_operand" "")
656 (match_operand 1 "immediate_operand" "")))
657 (const_string "true")
658 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
659 (and (match_operand 0 "memory_displacement_operand" "")
660 (match_operand 2 "immediate_operand" "")))
661 (const_string "true")
663 (const_string "false")))
665 ;; Indicates if an FP operation has an integer source.
667 (define_attr "fp_int_src" "false,true"
668 (const_string "false"))
670 ;; Defines rounding mode of an FP operation.
672 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
673 (const_string "any"))
675 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
676 (define_attr "use_carry" "0,1" (const_string "0"))
678 ;; Define attribute to indicate unaligned ssemov insns
679 (define_attr "movu" "0,1" (const_string "0"))
681 ;; Describe a user's asm statement.
682 (define_asm_attributes
683 [(set_attr "length" "128")
684 (set_attr "type" "multi")])
686 (define_code_iterator plusminus [plus minus])
688 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
690 ;; Base name for define_insn
691 (define_code_attr plusminus_insn
692 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
693 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
695 ;; Base name for insn mnemonic.
696 (define_code_attr plusminus_mnemonic
697 [(plus "add") (ss_plus "adds") (us_plus "addus")
698 (minus "sub") (ss_minus "subs") (us_minus "subus")])
699 (define_code_attr plusminus_carry_mnemonic
700 [(plus "adc") (minus "sbb")])
702 ;; Mark commutative operators as such in constraints.
703 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
704 (minus "") (ss_minus "") (us_minus "")])
706 ;; Mapping of signed max and min
707 (define_code_iterator smaxmin [smax smin])
709 ;; Mapping of unsigned max and min
710 (define_code_iterator umaxmin [umax umin])
712 ;; Mapping of signed/unsigned max and min
713 (define_code_iterator maxmin [smax smin umax umin])
715 ;; Base name for integer and FP insn mnemonic
716 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
717 (umax "maxu") (umin "minu")])
718 (define_code_attr maxmin_float [(smax "max") (smin "min")])
720 ;; Mapping of logic operators
721 (define_code_iterator any_logic [and ior xor])
722 (define_code_iterator any_or [ior xor])
724 ;; Base name for insn mnemonic.
725 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
727 ;; Mapping of shift-right operators
728 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
730 ;; Base name for define_insn
731 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
733 ;; Base name for insn mnemonic.
734 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
736 ;; Mapping of rotate operators
737 (define_code_iterator any_rotate [rotate rotatert])
739 ;; Base name for define_insn
740 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
742 ;; Base name for insn mnemonic.
743 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
745 ;; Mapping of abs neg operators
746 (define_code_iterator absneg [abs neg])
748 ;; Base name for x87 insn mnemonic.
749 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
751 ;; Used in signed and unsigned widening multiplications.
752 (define_code_iterator any_extend [sign_extend zero_extend])
754 ;; Various insn prefixes for signed and unsigned operations.
755 (define_code_attr u [(sign_extend "") (zero_extend "u")
756 (div "") (udiv "u")])
757 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
759 ;; Used in signed and unsigned divisions.
760 (define_code_iterator any_div [div udiv])
762 ;; Instruction prefix for signed and unsigned operations.
763 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
764 (div "i") (udiv "")])
766 ;; 64bit single word integer modes.
767 (define_mode_iterator SWI1248x [QI HI SI DI])
769 ;; 64bit single word integer modes without QImode and HImode.
770 (define_mode_iterator SWI48x [SI DI])
772 ;; Single word integer modes.
773 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
775 ;; Single word integer modes without SImode and DImode.
776 (define_mode_iterator SWI12 [QI HI])
778 ;; Single word integer modes without DImode.
779 (define_mode_iterator SWI124 [QI HI SI])
781 ;; Single word integer modes without QImode and DImode.
782 (define_mode_iterator SWI24 [HI SI])
784 ;; Single word integer modes without QImode.
785 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
787 ;; Single word integer modes without QImode and HImode.
788 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
790 ;; All math-dependant single and double word integer modes.
791 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
792 (HI "TARGET_HIMODE_MATH")
793 SI DI (TI "TARGET_64BIT")])
795 ;; Math-dependant single word integer modes.
796 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
797 (HI "TARGET_HIMODE_MATH")
798 SI (DI "TARGET_64BIT")])
800 ;; Math-dependant single word integer modes without DImode.
801 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
802 (HI "TARGET_HIMODE_MATH")
805 ;; Math-dependant single word integer modes without QImode.
806 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
807 SI (DI "TARGET_64BIT")])
809 ;; Double word integer modes.
810 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
811 (TI "TARGET_64BIT")])
813 ;; Double word integer modes as mode attribute.
814 (define_mode_attr DWI [(SI "DI") (DI "TI")])
815 (define_mode_attr dwi [(SI "di") (DI "ti")])
817 ;; Half mode for double word integer modes.
818 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
819 (DI "TARGET_64BIT")])
821 ;; Instruction suffix for integer modes.
822 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
824 ;; Register class for integer modes.
825 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
827 ;; Immediate operand constraint for integer modes.
828 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
830 ;; General operand constraint for word modes.
831 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
833 ;; Immediate operand constraint for double integer modes.
834 (define_mode_attr di [(SI "iF") (DI "e")])
836 ;; Immediate operand constraint for shifts.
837 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
839 ;; General operand predicate for integer modes.
840 (define_mode_attr general_operand
841 [(QI "general_operand")
842 (HI "general_operand")
843 (SI "general_operand")
844 (DI "x86_64_general_operand")
845 (TI "x86_64_general_operand")])
847 ;; General sign/zero extend operand predicate for integer modes.
848 (define_mode_attr general_szext_operand
849 [(QI "general_operand")
850 (HI "general_operand")
851 (SI "general_operand")
852 (DI "x86_64_szext_general_operand")])
854 ;; Immediate operand predicate for integer modes.
855 (define_mode_attr immediate_operand
856 [(QI "immediate_operand")
857 (HI "immediate_operand")
858 (SI "immediate_operand")
859 (DI "x86_64_immediate_operand")])
861 ;; Nonmemory operand predicate for integer modes.
862 (define_mode_attr nonmemory_operand
863 [(QI "nonmemory_operand")
864 (HI "nonmemory_operand")
865 (SI "nonmemory_operand")
866 (DI "x86_64_nonmemory_operand")])
868 ;; Operand predicate for shifts.
869 (define_mode_attr shift_operand
870 [(QI "nonimmediate_operand")
871 (HI "nonimmediate_operand")
872 (SI "nonimmediate_operand")
873 (DI "shiftdi_operand")
874 (TI "register_operand")])
876 ;; Operand predicate for shift argument.
877 (define_mode_attr shift_immediate_operand
878 [(QI "const_1_to_31_operand")
879 (HI "const_1_to_31_operand")
880 (SI "const_1_to_31_operand")
881 (DI "const_1_to_63_operand")])
883 ;; Input operand predicate for arithmetic left shifts.
884 (define_mode_attr ashl_input_operand
885 [(QI "nonimmediate_operand")
886 (HI "nonimmediate_operand")
887 (SI "nonimmediate_operand")
888 (DI "ashldi_input_operand")
889 (TI "reg_or_pm1_operand")])
891 ;; SSE and x87 SFmode and DFmode floating point modes
892 (define_mode_iterator MODEF [SF DF])
894 ;; All x87 floating point modes
895 (define_mode_iterator X87MODEF [SF DF XF])
897 ;; All integer modes handled by x87 fisttp operator.
898 (define_mode_iterator X87MODEI [HI SI DI])
900 ;; All integer modes handled by integer x87 operators.
901 (define_mode_iterator X87MODEI12 [HI SI])
903 ;; All integer modes handled by SSE cvtts?2si* operators.
904 (define_mode_iterator SSEMODEI24 [SI DI])
906 ;; SSE asm suffix for floating point modes
907 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
909 ;; SSE vector mode corresponding to a scalar mode
910 (define_mode_attr ssevecmode
911 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
913 ;; Instruction suffix for REX 64bit operators.
914 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
916 ;; This mode iterator allows :P to be used for patterns that operate on
917 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
918 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
920 ;; Scheduling descriptions
922 (include "pentium.md")
925 (include "athlon.md")
930 ;; Operand and operator predicates and constraints
932 (include "predicates.md")
933 (include "constraints.md")
936 ;; Compare and branch/compare and store instructions.
938 (define_expand "cbranch<mode>4"
939 [(set (reg:CC FLAGS_REG)
940 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
941 (match_operand:SDWIM 2 "<general_operand>" "")))
942 (set (pc) (if_then_else
943 (match_operator 0 "ordered_comparison_operator"
944 [(reg:CC FLAGS_REG) (const_int 0)])
945 (label_ref (match_operand 3 "" ""))
949 if (MEM_P (operands[1]) && MEM_P (operands[2]))
950 operands[1] = force_reg (<MODE>mode, operands[1]);
951 ix86_expand_branch (GET_CODE (operands[0]),
952 operands[1], operands[2], operands[3]);
956 (define_expand "cstore<mode>4"
957 [(set (reg:CC FLAGS_REG)
958 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
959 (match_operand:SWIM 3 "<general_operand>" "")))
960 (set (match_operand:QI 0 "register_operand" "")
961 (match_operator 1 "ordered_comparison_operator"
962 [(reg:CC FLAGS_REG) (const_int 0)]))]
965 if (MEM_P (operands[2]) && MEM_P (operands[3]))
966 operands[2] = force_reg (<MODE>mode, operands[2]);
967 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
968 operands[2], operands[3]);
972 (define_expand "cmp<mode>_1"
973 [(set (reg:CC FLAGS_REG)
974 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
975 (match_operand:SWI48 1 "<general_operand>" "")))]
979 (define_insn "*cmp<mode>_ccno_1"
980 [(set (reg FLAGS_REG)
981 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
982 (match_operand:SWI 1 "const0_operand" "")))]
983 "ix86_match_ccmode (insn, CCNOmode)"
985 test{<imodesuffix>}\t%0, %0
986 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
987 [(set_attr "type" "test,icmp")
988 (set_attr "length_immediate" "0,1")
989 (set_attr "mode" "<MODE>")])
991 (define_insn "*cmp<mode>_1"
992 [(set (reg FLAGS_REG)
993 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
994 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
995 "ix86_match_ccmode (insn, CCmode)"
996 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
997 [(set_attr "type" "icmp")
998 (set_attr "mode" "<MODE>")])
1000 (define_insn "*cmp<mode>_minus_1"
1001 [(set (reg FLAGS_REG)
1003 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1004 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1006 "ix86_match_ccmode (insn, CCGOCmode)"
1007 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1008 [(set_attr "type" "icmp")
1009 (set_attr "mode" "<MODE>")])
1011 (define_insn "*cmpqi_ext_1"
1012 [(set (reg FLAGS_REG)
1014 (match_operand:QI 0 "general_operand" "Qm")
1017 (match_operand 1 "ext_register_operand" "Q")
1019 (const_int 8)) 0)))]
1020 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1021 "cmp{b}\t{%h1, %0|%0, %h1}"
1022 [(set_attr "type" "icmp")
1023 (set_attr "mode" "QI")])
1025 (define_insn "*cmpqi_ext_1_rex64"
1026 [(set (reg FLAGS_REG)
1028 (match_operand:QI 0 "register_operand" "Q")
1031 (match_operand 1 "ext_register_operand" "Q")
1033 (const_int 8)) 0)))]
1034 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1035 "cmp{b}\t{%h1, %0|%0, %h1}"
1036 [(set_attr "type" "icmp")
1037 (set_attr "mode" "QI")])
1039 (define_insn "*cmpqi_ext_2"
1040 [(set (reg FLAGS_REG)
1044 (match_operand 0 "ext_register_operand" "Q")
1047 (match_operand:QI 1 "const0_operand" "")))]
1048 "ix86_match_ccmode (insn, CCNOmode)"
1050 [(set_attr "type" "test")
1051 (set_attr "length_immediate" "0")
1052 (set_attr "mode" "QI")])
1054 (define_expand "cmpqi_ext_3"
1055 [(set (reg:CC FLAGS_REG)
1059 (match_operand 0 "ext_register_operand" "")
1062 (match_operand:QI 1 "immediate_operand" "")))]
1066 (define_insn "*cmpqi_ext_3_insn"
1067 [(set (reg FLAGS_REG)
1071 (match_operand 0 "ext_register_operand" "Q")
1074 (match_operand:QI 1 "general_operand" "Qmn")))]
1075 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1076 "cmp{b}\t{%1, %h0|%h0, %1}"
1077 [(set_attr "type" "icmp")
1078 (set_attr "modrm" "1")
1079 (set_attr "mode" "QI")])
1081 (define_insn "*cmpqi_ext_3_insn_rex64"
1082 [(set (reg FLAGS_REG)
1086 (match_operand 0 "ext_register_operand" "Q")
1089 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1090 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1091 "cmp{b}\t{%1, %h0|%h0, %1}"
1092 [(set_attr "type" "icmp")
1093 (set_attr "modrm" "1")
1094 (set_attr "mode" "QI")])
1096 (define_insn "*cmpqi_ext_4"
1097 [(set (reg FLAGS_REG)
1101 (match_operand 0 "ext_register_operand" "Q")
1106 (match_operand 1 "ext_register_operand" "Q")
1108 (const_int 8)) 0)))]
1109 "ix86_match_ccmode (insn, CCmode)"
1110 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1111 [(set_attr "type" "icmp")
1112 (set_attr "mode" "QI")])
1114 ;; These implement float point compares.
1115 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1116 ;; which would allow mix and match FP modes on the compares. Which is what
1117 ;; the old patterns did, but with many more of them.
1119 (define_expand "cbranchxf4"
1120 [(set (reg:CC FLAGS_REG)
1121 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1122 (match_operand:XF 2 "nonmemory_operand" "")))
1123 (set (pc) (if_then_else
1124 (match_operator 0 "ix86_fp_comparison_operator"
1127 (label_ref (match_operand 3 "" ""))
1131 ix86_expand_branch (GET_CODE (operands[0]),
1132 operands[1], operands[2], operands[3]);
1136 (define_expand "cstorexf4"
1137 [(set (reg:CC FLAGS_REG)
1138 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1139 (match_operand:XF 3 "nonmemory_operand" "")))
1140 (set (match_operand:QI 0 "register_operand" "")
1141 (match_operator 1 "ix86_fp_comparison_operator"
1146 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1147 operands[2], operands[3]);
1151 (define_expand "cbranch<mode>4"
1152 [(set (reg:CC FLAGS_REG)
1153 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1154 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1155 (set (pc) (if_then_else
1156 (match_operator 0 "ix86_fp_comparison_operator"
1159 (label_ref (match_operand 3 "" ""))
1161 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1163 ix86_expand_branch (GET_CODE (operands[0]),
1164 operands[1], operands[2], operands[3]);
1168 (define_expand "cstore<mode>4"
1169 [(set (reg:CC FLAGS_REG)
1170 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1171 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1172 (set (match_operand:QI 0 "register_operand" "")
1173 (match_operator 1 "ix86_fp_comparison_operator"
1176 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1178 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1179 operands[2], operands[3]);
1183 (define_expand "cbranchcc4"
1184 [(set (pc) (if_then_else
1185 (match_operator 0 "comparison_operator"
1186 [(match_operand 1 "flags_reg_operand" "")
1187 (match_operand 2 "const0_operand" "")])
1188 (label_ref (match_operand 3 "" ""))
1192 ix86_expand_branch (GET_CODE (operands[0]),
1193 operands[1], operands[2], operands[3]);
1197 (define_expand "cstorecc4"
1198 [(set (match_operand:QI 0 "register_operand" "")
1199 (match_operator 1 "comparison_operator"
1200 [(match_operand 2 "flags_reg_operand" "")
1201 (match_operand 3 "const0_operand" "")]))]
1204 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1205 operands[2], operands[3]);
1210 ;; FP compares, step 1:
1211 ;; Set the FP condition codes.
1213 ;; CCFPmode compare with exceptions
1214 ;; CCFPUmode compare with no exceptions
1216 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1217 ;; used to manage the reg stack popping would not be preserved.
1219 (define_insn "*cmpfp_0"
1220 [(set (match_operand:HI 0 "register_operand" "=a")
1223 (match_operand 1 "register_operand" "f")
1224 (match_operand 2 "const0_operand" ""))]
1226 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1227 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1228 "* return output_fp_compare (insn, operands, 0, 0);"
1229 [(set_attr "type" "multi")
1230 (set_attr "unit" "i387")
1232 (cond [(match_operand:SF 1 "" "")
1234 (match_operand:DF 1 "" "")
1237 (const_string "XF")))])
1239 (define_insn_and_split "*cmpfp_0_cc"
1240 [(set (reg:CCFP FLAGS_REG)
1242 (match_operand 1 "register_operand" "f")
1243 (match_operand 2 "const0_operand" "")))
1244 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1245 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1246 && TARGET_SAHF && !TARGET_CMOVE
1247 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1249 "&& reload_completed"
1252 [(compare:CCFP (match_dup 1)(match_dup 2))]
1254 (set (reg:CC FLAGS_REG)
1255 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1257 [(set_attr "type" "multi")
1258 (set_attr "unit" "i387")
1260 (cond [(match_operand:SF 1 "" "")
1262 (match_operand:DF 1 "" "")
1265 (const_string "XF")))])
1267 (define_insn "*cmpfp_xf"
1268 [(set (match_operand:HI 0 "register_operand" "=a")
1271 (match_operand:XF 1 "register_operand" "f")
1272 (match_operand:XF 2 "register_operand" "f"))]
1275 "* return output_fp_compare (insn, operands, 0, 0);"
1276 [(set_attr "type" "multi")
1277 (set_attr "unit" "i387")
1278 (set_attr "mode" "XF")])
1280 (define_insn_and_split "*cmpfp_xf_cc"
1281 [(set (reg:CCFP FLAGS_REG)
1283 (match_operand:XF 1 "register_operand" "f")
1284 (match_operand:XF 2 "register_operand" "f")))
1285 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1287 && TARGET_SAHF && !TARGET_CMOVE"
1289 "&& reload_completed"
1292 [(compare:CCFP (match_dup 1)(match_dup 2))]
1294 (set (reg:CC FLAGS_REG)
1295 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1297 [(set_attr "type" "multi")
1298 (set_attr "unit" "i387")
1299 (set_attr "mode" "XF")])
1301 (define_insn "*cmpfp_<mode>"
1302 [(set (match_operand:HI 0 "register_operand" "=a")
1305 (match_operand:MODEF 1 "register_operand" "f")
1306 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1309 "* return output_fp_compare (insn, operands, 0, 0);"
1310 [(set_attr "type" "multi")
1311 (set_attr "unit" "i387")
1312 (set_attr "mode" "<MODE>")])
1314 (define_insn_and_split "*cmpfp_<mode>_cc"
1315 [(set (reg:CCFP FLAGS_REG)
1317 (match_operand:MODEF 1 "register_operand" "f")
1318 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1319 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1321 && TARGET_SAHF && !TARGET_CMOVE"
1323 "&& reload_completed"
1326 [(compare:CCFP (match_dup 1)(match_dup 2))]
1328 (set (reg:CC FLAGS_REG)
1329 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1331 [(set_attr "type" "multi")
1332 (set_attr "unit" "i387")
1333 (set_attr "mode" "<MODE>")])
1335 (define_insn "*cmpfp_u"
1336 [(set (match_operand:HI 0 "register_operand" "=a")
1339 (match_operand 1 "register_operand" "f")
1340 (match_operand 2 "register_operand" "f"))]
1342 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1343 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1344 "* return output_fp_compare (insn, operands, 0, 1);"
1345 [(set_attr "type" "multi")
1346 (set_attr "unit" "i387")
1348 (cond [(match_operand:SF 1 "" "")
1350 (match_operand:DF 1 "" "")
1353 (const_string "XF")))])
1355 (define_insn_and_split "*cmpfp_u_cc"
1356 [(set (reg:CCFPU FLAGS_REG)
1358 (match_operand 1 "register_operand" "f")
1359 (match_operand 2 "register_operand" "f")))
1360 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1361 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1362 && TARGET_SAHF && !TARGET_CMOVE
1363 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1365 "&& reload_completed"
1368 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1370 (set (reg:CC FLAGS_REG)
1371 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1373 [(set_attr "type" "multi")
1374 (set_attr "unit" "i387")
1376 (cond [(match_operand:SF 1 "" "")
1378 (match_operand:DF 1 "" "")
1381 (const_string "XF")))])
1383 (define_insn "*cmpfp_<mode>"
1384 [(set (match_operand:HI 0 "register_operand" "=a")
1387 (match_operand 1 "register_operand" "f")
1388 (match_operator 3 "float_operator"
1389 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1391 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1392 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1393 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1394 "* return output_fp_compare (insn, operands, 0, 0);"
1395 [(set_attr "type" "multi")
1396 (set_attr "unit" "i387")
1397 (set_attr "fp_int_src" "true")
1398 (set_attr "mode" "<MODE>")])
1400 (define_insn_and_split "*cmpfp_<mode>_cc"
1401 [(set (reg:CCFP FLAGS_REG)
1403 (match_operand 1 "register_operand" "f")
1404 (match_operator 3 "float_operator"
1405 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1406 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1407 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1408 && TARGET_SAHF && !TARGET_CMOVE
1409 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1410 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1412 "&& reload_completed"
1417 (match_op_dup 3 [(match_dup 2)]))]
1419 (set (reg:CC FLAGS_REG)
1420 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1422 [(set_attr "type" "multi")
1423 (set_attr "unit" "i387")
1424 (set_attr "fp_int_src" "true")
1425 (set_attr "mode" "<MODE>")])
1427 ;; FP compares, step 2
1428 ;; Move the fpsw to ax.
1430 (define_insn "x86_fnstsw_1"
1431 [(set (match_operand:HI 0 "register_operand" "=a")
1432 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1435 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1436 (set_attr "mode" "SI")
1437 (set_attr "unit" "i387")])
1439 ;; FP compares, step 3
1440 ;; Get ax into flags, general case.
1442 (define_insn "x86_sahf_1"
1443 [(set (reg:CC FLAGS_REG)
1444 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1448 #ifndef HAVE_AS_IX86_SAHF
1450 return ASM_BYTE "0x9e";
1455 [(set_attr "length" "1")
1456 (set_attr "athlon_decode" "vector")
1457 (set_attr "amdfam10_decode" "direct")
1458 (set_attr "mode" "SI")])
1460 ;; Pentium Pro can do steps 1 through 3 in one go.
1461 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1462 (define_insn "*cmpfp_i_mixed"
1463 [(set (reg:CCFP FLAGS_REG)
1464 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1465 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1466 "TARGET_MIX_SSE_I387
1467 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1468 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1469 "* return output_fp_compare (insn, operands, 1, 0);"
1470 [(set_attr "type" "fcmp,ssecomi")
1471 (set_attr "prefix" "orig,maybe_vex")
1473 (if_then_else (match_operand:SF 1 "" "")
1475 (const_string "DF")))
1476 (set (attr "prefix_rep")
1477 (if_then_else (eq_attr "type" "ssecomi")
1479 (const_string "*")))
1480 (set (attr "prefix_data16")
1481 (cond [(eq_attr "type" "fcmp")
1483 (eq_attr "mode" "DF")
1486 (const_string "0")))
1487 (set_attr "athlon_decode" "vector")
1488 (set_attr "amdfam10_decode" "direct")])
1490 (define_insn "*cmpfp_i_sse"
1491 [(set (reg:CCFP FLAGS_REG)
1492 (compare:CCFP (match_operand 0 "register_operand" "x")
1493 (match_operand 1 "nonimmediate_operand" "xm")))]
1495 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1496 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1497 "* return output_fp_compare (insn, operands, 1, 0);"
1498 [(set_attr "type" "ssecomi")
1499 (set_attr "prefix" "maybe_vex")
1501 (if_then_else (match_operand:SF 1 "" "")
1503 (const_string "DF")))
1504 (set_attr "prefix_rep" "0")
1505 (set (attr "prefix_data16")
1506 (if_then_else (eq_attr "mode" "DF")
1508 (const_string "0")))
1509 (set_attr "athlon_decode" "vector")
1510 (set_attr "amdfam10_decode" "direct")])
1512 (define_insn "*cmpfp_i_i387"
1513 [(set (reg:CCFP FLAGS_REG)
1514 (compare:CCFP (match_operand 0 "register_operand" "f")
1515 (match_operand 1 "register_operand" "f")))]
1516 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1518 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1519 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1520 "* return output_fp_compare (insn, operands, 1, 0);"
1521 [(set_attr "type" "fcmp")
1523 (cond [(match_operand:SF 1 "" "")
1525 (match_operand:DF 1 "" "")
1528 (const_string "XF")))
1529 (set_attr "athlon_decode" "vector")
1530 (set_attr "amdfam10_decode" "direct")])
1532 (define_insn "*cmpfp_iu_mixed"
1533 [(set (reg:CCFPU FLAGS_REG)
1534 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1535 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1536 "TARGET_MIX_SSE_I387
1537 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1538 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1539 "* return output_fp_compare (insn, operands, 1, 1);"
1540 [(set_attr "type" "fcmp,ssecomi")
1541 (set_attr "prefix" "orig,maybe_vex")
1543 (if_then_else (match_operand:SF 1 "" "")
1545 (const_string "DF")))
1546 (set (attr "prefix_rep")
1547 (if_then_else (eq_attr "type" "ssecomi")
1549 (const_string "*")))
1550 (set (attr "prefix_data16")
1551 (cond [(eq_attr "type" "fcmp")
1553 (eq_attr "mode" "DF")
1556 (const_string "0")))
1557 (set_attr "athlon_decode" "vector")
1558 (set_attr "amdfam10_decode" "direct")])
1560 (define_insn "*cmpfp_iu_sse"
1561 [(set (reg:CCFPU FLAGS_REG)
1562 (compare:CCFPU (match_operand 0 "register_operand" "x")
1563 (match_operand 1 "nonimmediate_operand" "xm")))]
1565 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1566 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1567 "* return output_fp_compare (insn, operands, 1, 1);"
1568 [(set_attr "type" "ssecomi")
1569 (set_attr "prefix" "maybe_vex")
1571 (if_then_else (match_operand:SF 1 "" "")
1573 (const_string "DF")))
1574 (set_attr "prefix_rep" "0")
1575 (set (attr "prefix_data16")
1576 (if_then_else (eq_attr "mode" "DF")
1578 (const_string "0")))
1579 (set_attr "athlon_decode" "vector")
1580 (set_attr "amdfam10_decode" "direct")])
1582 (define_insn "*cmpfp_iu_387"
1583 [(set (reg:CCFPU FLAGS_REG)
1584 (compare:CCFPU (match_operand 0 "register_operand" "f")
1585 (match_operand 1 "register_operand" "f")))]
1586 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1588 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1589 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1590 "* return output_fp_compare (insn, operands, 1, 1);"
1591 [(set_attr "type" "fcmp")
1593 (cond [(match_operand:SF 1 "" "")
1595 (match_operand:DF 1 "" "")
1598 (const_string "XF")))
1599 (set_attr "athlon_decode" "vector")
1600 (set_attr "amdfam10_decode" "direct")])
1602 ;; Push/pop instructions.
1604 (define_insn "*pushdi2_rex64"
1605 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1606 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1611 [(set_attr "type" "push,multi")
1612 (set_attr "mode" "DI")])
1614 ;; Convert impossible pushes of immediate to existing instructions.
1615 ;; First try to get scratch register and go through it. In case this
1616 ;; fails, push sign extended lower part first and then overwrite
1617 ;; upper part by 32bit move.
1619 [(match_scratch:DI 2 "r")
1620 (set (match_operand:DI 0 "push_operand" "")
1621 (match_operand:DI 1 "immediate_operand" ""))]
1622 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1623 && !x86_64_immediate_operand (operands[1], DImode)"
1624 [(set (match_dup 2) (match_dup 1))
1625 (set (match_dup 0) (match_dup 2))])
1627 ;; We need to define this as both peepholer and splitter for case
1628 ;; peephole2 pass is not run.
1629 ;; "&& 1" is needed to keep it from matching the previous pattern.
1631 [(set (match_operand:DI 0 "push_operand" "")
1632 (match_operand:DI 1 "immediate_operand" ""))]
1633 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1634 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1635 [(set (match_dup 0) (match_dup 1))
1636 (set (match_dup 2) (match_dup 3))]
1638 split_di (&operands[1], 1, &operands[2], &operands[3]);
1640 operands[1] = gen_lowpart (DImode, operands[2]);
1641 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1646 [(set (match_operand:DI 0 "push_operand" "")
1647 (match_operand:DI 1 "immediate_operand" ""))]
1648 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1649 ? epilogue_completed : reload_completed)
1650 && !symbolic_operand (operands[1], DImode)
1651 && !x86_64_immediate_operand (operands[1], DImode)"
1652 [(set (match_dup 0) (match_dup 1))
1653 (set (match_dup 2) (match_dup 3))]
1655 split_di (&operands[1], 1, &operands[2], &operands[3]);
1657 operands[1] = gen_lowpart (DImode, operands[2]);
1658 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1662 (define_insn "*pushdi2"
1663 [(set (match_operand:DI 0 "push_operand" "=<")
1664 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
1669 [(set (match_operand:DI 0 "push_operand" "")
1670 (match_operand:DI 1 "general_operand" ""))]
1671 "!TARGET_64BIT && reload_completed
1672 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1674 "ix86_split_long_move (operands); DONE;")
1676 (define_insn "*pushsi2"
1677 [(set (match_operand:SI 0 "push_operand" "=<")
1678 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1681 [(set_attr "type" "push")
1682 (set_attr "mode" "SI")])
1684 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1685 ;; "push a byte/word". But actually we use pushl, which has the effect
1686 ;; of rounding the amount pushed up to a word.
1688 ;; For 64BIT abi we always round up to 8 bytes.
1689 (define_insn "*push<mode>2_rex64"
1690 [(set (match_operand:SWI124 0 "push_operand" "=X")
1691 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1694 [(set_attr "type" "push")
1695 (set_attr "mode" "DI")])
1697 (define_insn "*push<mode>2"
1698 [(set (match_operand:SWI12 0 "push_operand" "=X")
1699 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1702 [(set_attr "type" "push")
1703 (set_attr "mode" "SI")])
1705 (define_insn "*push<mode>2_prologue"
1706 [(set (match_operand:P 0 "push_operand" "=<")
1707 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1708 (clobber (mem:BLK (scratch)))]
1710 "push{<imodesuffix>}\t%1"
1711 [(set_attr "type" "push")
1712 (set_attr "mode" "<MODE>")])
1714 (define_insn "*pop<mode>1"
1715 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1716 (match_operand:P 1 "pop_operand" ">"))]
1718 "pop{<imodesuffix>}\t%0"
1719 [(set_attr "type" "pop")
1720 (set_attr "mode" "<MODE>")])
1722 (define_insn "*pop<mode>1_epilogue"
1723 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1724 (match_operand:P 1 "pop_operand" ">"))
1725 (clobber (mem:BLK (scratch)))]
1727 "pop{<imodesuffix>}\t%0"
1728 [(set_attr "type" "pop")
1729 (set_attr "mode" "<MODE>")])
1731 ;; Move instructions.
1733 (define_expand "movoi"
1734 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1735 (match_operand:OI 1 "general_operand" ""))]
1737 "ix86_expand_move (OImode, operands); DONE;")
1739 (define_expand "movti"
1740 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1741 (match_operand:TI 1 "nonimmediate_operand" ""))]
1742 "TARGET_64BIT || TARGET_SSE"
1745 ix86_expand_move (TImode, operands);
1746 else if (push_operand (operands[0], TImode))
1747 ix86_expand_push (TImode, operands[1]);
1749 ix86_expand_vector_move (TImode, operands);
1753 ;; This expands to what emit_move_complex would generate if we didn't
1754 ;; have a movti pattern. Having this avoids problems with reload on
1755 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1756 ;; to have around all the time.
1757 (define_expand "movcdi"
1758 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1759 (match_operand:CDI 1 "general_operand" ""))]
1762 if (push_operand (operands[0], CDImode))
1763 emit_move_complex_push (CDImode, operands[0], operands[1]);
1765 emit_move_complex_parts (operands[0], operands[1]);
1769 (define_expand "mov<mode>"
1770 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1771 (match_operand:SWI1248x 1 "general_operand" ""))]
1773 "ix86_expand_move (<MODE>mode, operands); DONE;")
1775 (define_insn "*mov<mode>_xor"
1776 [(set (match_operand:SWI48 0 "register_operand" "=r")
1777 (match_operand:SWI48 1 "const0_operand" ""))
1778 (clobber (reg:CC FLAGS_REG))]
1781 [(set_attr "type" "alu1")
1782 (set_attr "mode" "SI")
1783 (set_attr "length_immediate" "0")])
1785 (define_insn "*mov<mode>_or"
1786 [(set (match_operand:SWI48 0 "register_operand" "=r")
1787 (match_operand:SWI48 1 "const_int_operand" ""))
1788 (clobber (reg:CC FLAGS_REG))]
1790 && operands[1] == constm1_rtx"
1791 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1792 [(set_attr "type" "alu1")
1793 (set_attr "mode" "<MODE>")
1794 (set_attr "length_immediate" "1")])
1796 (define_insn "*movoi_internal_avx"
1797 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1798 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1799 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1801 switch (which_alternative)
1804 return "vxorps\t%0, %0, %0";
1807 if (misaligned_operand (operands[0], OImode)
1808 || misaligned_operand (operands[1], OImode))
1809 return "vmovdqu\t{%1, %0|%0, %1}";
1811 return "vmovdqa\t{%1, %0|%0, %1}";
1816 [(set_attr "type" "sselog1,ssemov,ssemov")
1817 (set_attr "prefix" "vex")
1818 (set_attr "mode" "OI")])
1820 (define_insn "*movti_internal_rex64"
1821 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1822 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1823 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1825 switch (which_alternative)
1831 if (get_attr_mode (insn) == MODE_V4SF)
1832 return "%vxorps\t%0, %d0";
1834 return "%vpxor\t%0, %d0";
1837 /* TDmode values are passed as TImode on the stack. Moving them
1838 to stack may result in unaligned memory access. */
1839 if (misaligned_operand (operands[0], TImode)
1840 || misaligned_operand (operands[1], TImode))
1842 if (get_attr_mode (insn) == MODE_V4SF)
1843 return "%vmovups\t{%1, %0|%0, %1}";
1845 return "%vmovdqu\t{%1, %0|%0, %1}";
1849 if (get_attr_mode (insn) == MODE_V4SF)
1850 return "%vmovaps\t{%1, %0|%0, %1}";
1852 return "%vmovdqa\t{%1, %0|%0, %1}";
1858 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1859 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1861 (cond [(eq_attr "alternative" "2,3")
1863 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1865 (const_string "V4SF")
1866 (const_string "TI"))
1867 (eq_attr "alternative" "4")
1869 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1871 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1873 (const_string "V4SF")
1874 (const_string "TI"))]
1875 (const_string "DI")))])
1878 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1879 (match_operand:TI 1 "general_operand" ""))]
1881 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1883 "ix86_split_long_move (operands); DONE;")
1885 (define_insn "*movti_internal_sse"
1886 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1887 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1888 "TARGET_SSE && !TARGET_64BIT
1889 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1891 switch (which_alternative)
1894 if (get_attr_mode (insn) == MODE_V4SF)
1895 return "%vxorps\t%0, %d0";
1897 return "%vpxor\t%0, %d0";
1900 /* TDmode values are passed as TImode on the stack. Moving them
1901 to stack may result in unaligned memory access. */
1902 if (misaligned_operand (operands[0], TImode)
1903 || misaligned_operand (operands[1], TImode))
1905 if (get_attr_mode (insn) == MODE_V4SF)
1906 return "%vmovups\t{%1, %0|%0, %1}";
1908 return "%vmovdqu\t{%1, %0|%0, %1}";
1912 if (get_attr_mode (insn) == MODE_V4SF)
1913 return "%vmovaps\t{%1, %0|%0, %1}";
1915 return "%vmovdqa\t{%1, %0|%0, %1}";
1921 [(set_attr "type" "sselog1,ssemov,ssemov")
1922 (set_attr "prefix" "maybe_vex")
1924 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1925 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1927 (const_string "V4SF")
1928 (and (eq_attr "alternative" "2")
1929 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1931 (const_string "V4SF")]
1932 (const_string "TI")))])
1934 (define_insn "*movdi_internal_rex64"
1935 [(set (match_operand:DI 0 "nonimmediate_operand"
1936 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
1937 (match_operand:DI 1 "general_operand"
1938 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
1939 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1941 switch (get_attr_type (insn))
1944 if (SSE_REG_P (operands[0]))
1945 return "movq2dq\t{%1, %0|%0, %1}";
1947 return "movdq2q\t{%1, %0|%0, %1}";
1952 if (get_attr_mode (insn) == MODE_TI)
1953 return "vmovdqa\t{%1, %0|%0, %1}";
1955 return "vmovq\t{%1, %0|%0, %1}";
1958 if (get_attr_mode (insn) == MODE_TI)
1959 return "movdqa\t{%1, %0|%0, %1}";
1963 /* Moves from and into integer register is done using movd
1964 opcode with REX prefix. */
1965 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1966 return "movd\t{%1, %0|%0, %1}";
1967 return "movq\t{%1, %0|%0, %1}";
1970 return "%vpxor\t%0, %d0";
1973 return "pxor\t%0, %0";
1979 return "lea{q}\t{%a1, %0|%0, %a1}";
1982 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1983 if (get_attr_mode (insn) == MODE_SI)
1984 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1985 else if (which_alternative == 2)
1986 return "movabs{q}\t{%1, %0|%0, %1}";
1988 return "mov{q}\t{%1, %0|%0, %1}";
1992 (cond [(eq_attr "alternative" "5")
1993 (const_string "mmx")
1994 (eq_attr "alternative" "6,7,8,9,10")
1995 (const_string "mmxmov")
1996 (eq_attr "alternative" "11")
1997 (const_string "sselog1")
1998 (eq_attr "alternative" "12,13,14,15,16")
1999 (const_string "ssemov")
2000 (eq_attr "alternative" "17,18")
2001 (const_string "ssecvt")
2002 (eq_attr "alternative" "4")
2003 (const_string "multi")
2004 (match_operand:DI 1 "pic_32bit_operand" "")
2005 (const_string "lea")
2007 (const_string "imov")))
2010 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2012 (const_string "*")))
2013 (set (attr "length_immediate")
2015 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2017 (const_string "*")))
2018 (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2019 (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2020 (set (attr "prefix")
2021 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2022 (const_string "maybe_vex")
2023 (const_string "orig")))
2024 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2026 ;; Convert impossible stores of immediate to existing instructions.
2027 ;; First try to get scratch register and go through it. In case this
2028 ;; fails, move by 32bit parts.
2030 [(match_scratch:DI 2 "r")
2031 (set (match_operand:DI 0 "memory_operand" "")
2032 (match_operand:DI 1 "immediate_operand" ""))]
2033 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2034 && !x86_64_immediate_operand (operands[1], DImode)"
2035 [(set (match_dup 2) (match_dup 1))
2036 (set (match_dup 0) (match_dup 2))])
2038 ;; We need to define this as both peepholer and splitter for case
2039 ;; peephole2 pass is not run.
2040 ;; "&& 1" is needed to keep it from matching the previous pattern.
2042 [(set (match_operand:DI 0 "memory_operand" "")
2043 (match_operand:DI 1 "immediate_operand" ""))]
2044 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2045 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2046 [(set (match_dup 2) (match_dup 3))
2047 (set (match_dup 4) (match_dup 5))]
2048 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2051 [(set (match_operand:DI 0 "memory_operand" "")
2052 (match_operand:DI 1 "immediate_operand" ""))]
2053 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2054 ? epilogue_completed : reload_completed)
2055 && !symbolic_operand (operands[1], DImode)
2056 && !x86_64_immediate_operand (operands[1], DImode)"
2057 [(set (match_dup 2) (match_dup 3))
2058 (set (match_dup 4) (match_dup 5))]
2059 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2061 (define_insn "*movdi_internal"
2062 [(set (match_operand:DI 0 "nonimmediate_operand"
2063 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2064 (match_operand:DI 1 "general_operand"
2065 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2066 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2071 movq\t{%1, %0|%0, %1}
2072 movq\t{%1, %0|%0, %1}
2074 %vmovq\t{%1, %0|%0, %1}
2075 %vmovdqa\t{%1, %0|%0, %1}
2076 %vmovq\t{%1, %0|%0, %1}
2078 movlps\t{%1, %0|%0, %1}
2079 movaps\t{%1, %0|%0, %1}
2080 movlps\t{%1, %0|%0, %1}"
2081 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2082 (set (attr "prefix")
2083 (if_then_else (eq_attr "alternative" "5,6,7,8")
2084 (const_string "vex")
2085 (const_string "orig")))
2086 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2089 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2090 (match_operand:DI 1 "general_operand" ""))]
2091 "!TARGET_64BIT && reload_completed
2092 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2093 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2095 "ix86_split_long_move (operands); DONE;")
2097 (define_insn "*movsi_internal"
2098 [(set (match_operand:SI 0 "nonimmediate_operand"
2099 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2100 (match_operand:SI 1 "general_operand"
2101 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2102 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2104 switch (get_attr_type (insn))
2107 if (get_attr_mode (insn) == MODE_TI)
2108 return "%vpxor\t%0, %d0";
2109 return "%vxorps\t%0, %d0";
2112 switch (get_attr_mode (insn))
2115 return "%vmovdqa\t{%1, %0|%0, %1}";
2117 return "%vmovaps\t{%1, %0|%0, %1}";
2119 return "%vmovd\t{%1, %0|%0, %1}";
2121 return "%vmovss\t{%1, %0|%0, %1}";
2127 return "pxor\t%0, %0";
2130 if (get_attr_mode (insn) == MODE_DI)
2131 return "movq\t{%1, %0|%0, %1}";
2132 return "movd\t{%1, %0|%0, %1}";
2135 return "lea{l}\t{%a1, %0|%0, %a1}";
2138 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2139 return "mov{l}\t{%1, %0|%0, %1}";
2143 (cond [(eq_attr "alternative" "2")
2144 (const_string "mmx")
2145 (eq_attr "alternative" "3,4,5")
2146 (const_string "mmxmov")
2147 (eq_attr "alternative" "6")
2148 (const_string "sselog1")
2149 (eq_attr "alternative" "7,8,9,10,11")
2150 (const_string "ssemov")
2151 (match_operand:DI 1 "pic_32bit_operand" "")
2152 (const_string "lea")
2154 (const_string "imov")))
2155 (set (attr "prefix")
2156 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2157 (const_string "orig")
2158 (const_string "maybe_vex")))
2159 (set (attr "prefix_data16")
2160 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2162 (const_string "*")))
2164 (cond [(eq_attr "alternative" "2,3")
2166 (eq_attr "alternative" "6,7")
2168 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2169 (const_string "V4SF")
2170 (const_string "TI"))
2171 (and (eq_attr "alternative" "8,9,10,11")
2172 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
2175 (const_string "SI")))])
2177 (define_insn "*movhi_internal"
2178 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2179 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2180 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2182 switch (get_attr_type (insn))
2185 /* movzwl is faster than movw on p2 due to partial word stalls,
2186 though not as fast as an aligned movl. */
2187 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2189 if (get_attr_mode (insn) == MODE_SI)
2190 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2192 return "mov{w}\t{%1, %0|%0, %1}";
2196 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2198 (const_string "imov")
2199 (and (eq_attr "alternative" "0")
2200 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2202 (eq (symbol_ref "TARGET_HIMODE_MATH")
2204 (const_string "imov")
2205 (and (eq_attr "alternative" "1,2")
2206 (match_operand:HI 1 "aligned_operand" ""))
2207 (const_string "imov")
2208 (and (ne (symbol_ref "TARGET_MOVX")
2210 (eq_attr "alternative" "0,2"))
2211 (const_string "imovx")
2213 (const_string "imov")))
2215 (cond [(eq_attr "type" "imovx")
2217 (and (eq_attr "alternative" "1,2")
2218 (match_operand:HI 1 "aligned_operand" ""))
2220 (and (eq_attr "alternative" "0")
2221 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2223 (eq (symbol_ref "TARGET_HIMODE_MATH")
2227 (const_string "HI")))])
2229 ;; Situation is quite tricky about when to choose full sized (SImode) move
2230 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2231 ;; partial register dependency machines (such as AMD Athlon), where QImode
2232 ;; moves issue extra dependency and for partial register stalls machines
2233 ;; that don't use QImode patterns (and QImode move cause stall on the next
2236 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2237 ;; register stall machines with, where we use QImode instructions, since
2238 ;; partial register stall can be caused there. Then we use movzx.
2239 (define_insn "*movqi_internal"
2240 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2241 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2242 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2244 switch (get_attr_type (insn))
2247 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2248 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2250 if (get_attr_mode (insn) == MODE_SI)
2251 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2253 return "mov{b}\t{%1, %0|%0, %1}";
2257 (cond [(and (eq_attr "alternative" "5")
2258 (not (match_operand:QI 1 "aligned_operand" "")))
2259 (const_string "imovx")
2260 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2262 (const_string "imov")
2263 (and (eq_attr "alternative" "3")
2264 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2266 (eq (symbol_ref "TARGET_QIMODE_MATH")
2268 (const_string "imov")
2269 (eq_attr "alternative" "3,5")
2270 (const_string "imovx")
2271 (and (ne (symbol_ref "TARGET_MOVX")
2273 (eq_attr "alternative" "2"))
2274 (const_string "imovx")
2276 (const_string "imov")))
2278 (cond [(eq_attr "alternative" "3,4,5")
2280 (eq_attr "alternative" "6")
2282 (eq_attr "type" "imovx")
2284 (and (eq_attr "type" "imov")
2285 (and (eq_attr "alternative" "0,1")
2286 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2288 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2290 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2293 ;; Avoid partial register stalls when not using QImode arithmetic
2294 (and (eq_attr "type" "imov")
2295 (and (eq_attr "alternative" "0,1")
2296 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2298 (eq (symbol_ref "TARGET_QIMODE_MATH")
2302 (const_string "QI")))])
2304 ;; Stores and loads of ax to arbitrary constant address.
2305 ;; We fake an second form of instruction to force reload to load address
2306 ;; into register when rax is not available
2307 (define_insn "*movabs<mode>_1"
2308 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2309 (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2310 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2312 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2313 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2314 [(set_attr "type" "imov")
2315 (set_attr "modrm" "0,*")
2316 (set_attr "length_address" "8,0")
2317 (set_attr "length_immediate" "0,*")
2318 (set_attr "memory" "store")
2319 (set_attr "mode" "<MODE>")])
2321 (define_insn "*movabs<mode>_2"
2322 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2323 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2324 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2326 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2327 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2328 [(set_attr "type" "imov")
2329 (set_attr "modrm" "0,*")
2330 (set_attr "length_address" "8,0")
2331 (set_attr "length_immediate" "0")
2332 (set_attr "memory" "load")
2333 (set_attr "mode" "<MODE>")])
2335 (define_insn "*swap<mode>"
2336 [(set (match_operand:SWI48 0 "register_operand" "+r")
2337 (match_operand:SWI48 1 "register_operand" "+r"))
2341 "xchg{<imodesuffix>}\t%1, %0"
2342 [(set_attr "type" "imov")
2343 (set_attr "mode" "<MODE>")
2344 (set_attr "pent_pair" "np")
2345 (set_attr "athlon_decode" "vector")
2346 (set_attr "amdfam10_decode" "double")])
2348 (define_insn "*swap<mode>_1"
2349 [(set (match_operand:SWI12 0 "register_operand" "+r")
2350 (match_operand:SWI12 1 "register_operand" "+r"))
2353 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2355 [(set_attr "type" "imov")
2356 (set_attr "mode" "SI")
2357 (set_attr "pent_pair" "np")
2358 (set_attr "athlon_decode" "vector")
2359 (set_attr "amdfam10_decode" "double")])
2361 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2362 ;; is disabled for AMDFAM10
2363 (define_insn "*swap<mode>_2"
2364 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2365 (match_operand:SWI12 1 "register_operand" "+<r>"))
2368 "TARGET_PARTIAL_REG_STALL"
2369 "xchg{<imodesuffix>}\t%1, %0"
2370 [(set_attr "type" "imov")
2371 (set_attr "mode" "<MODE>")
2372 (set_attr "pent_pair" "np")
2373 (set_attr "athlon_decode" "vector")])
2375 (define_expand "movstrict<mode>"
2376 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2377 (match_operand:SWI12 1 "general_operand" ""))]
2380 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2382 /* Don't generate memory->memory moves, go through a register */
2383 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2384 operands[1] = force_reg (<MODE>mode, operands[1]);
2387 (define_insn "*movstrict<mode>_1"
2388 [(set (strict_low_part
2389 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2390 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2391 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2392 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2393 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2394 [(set_attr "type" "imov")
2395 (set_attr "mode" "<MODE>")])
2397 (define_insn "*movstrict<mode>_xor"
2398 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2399 (match_operand:SWI12 1 "const0_operand" ""))
2400 (clobber (reg:CC FLAGS_REG))]
2402 "xor{<imodesuffix>}\t%0, %0"
2403 [(set_attr "type" "alu1")
2404 (set_attr "mode" "<MODE>")
2405 (set_attr "length_immediate" "0")])
2407 (define_insn "*mov<mode>_extv_1"
2408 [(set (match_operand:SWI24 0 "register_operand" "=R")
2409 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2413 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2414 [(set_attr "type" "imovx")
2415 (set_attr "mode" "SI")])
2417 (define_insn "*movqi_extv_1_rex64"
2418 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2419 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2424 switch (get_attr_type (insn))
2427 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2429 return "mov{b}\t{%h1, %0|%0, %h1}";
2433 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2434 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2435 (ne (symbol_ref "TARGET_MOVX")
2437 (const_string "imovx")
2438 (const_string "imov")))
2440 (if_then_else (eq_attr "type" "imovx")
2442 (const_string "QI")))])
2444 (define_insn "*movqi_extv_1"
2445 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2446 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2451 switch (get_attr_type (insn))
2454 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2456 return "mov{b}\t{%h1, %0|%0, %h1}";
2460 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2461 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2462 (ne (symbol_ref "TARGET_MOVX")
2464 (const_string "imovx")
2465 (const_string "imov")))
2467 (if_then_else (eq_attr "type" "imovx")
2469 (const_string "QI")))])
2471 (define_insn "*mov<mode>_extzv_1"
2472 [(set (match_operand:SWI48 0 "register_operand" "=R")
2473 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2477 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2478 [(set_attr "type" "imovx")
2479 (set_attr "mode" "SI")])
2481 (define_insn "*movqi_extzv_2_rex64"
2482 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2484 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2489 switch (get_attr_type (insn))
2492 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2494 return "mov{b}\t{%h1, %0|%0, %h1}";
2498 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2499 (ne (symbol_ref "TARGET_MOVX")
2501 (const_string "imovx")
2502 (const_string "imov")))
2504 (if_then_else (eq_attr "type" "imovx")
2506 (const_string "QI")))])
2508 (define_insn "*movqi_extzv_2"
2509 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2511 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2516 switch (get_attr_type (insn))
2519 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2521 return "mov{b}\t{%h1, %0|%0, %h1}";
2525 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2526 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2527 (ne (symbol_ref "TARGET_MOVX")
2529 (const_string "imovx")
2530 (const_string "imov")))
2532 (if_then_else (eq_attr "type" "imovx")
2534 (const_string "QI")))])
2536 (define_expand "mov<mode>_insv_1"
2537 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2540 (match_operand:SWI48 1 "nonmemory_operand" ""))]
2544 (define_insn "*mov<mode>_insv_1_rex64"
2545 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2548 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2550 "mov{b}\t{%b1, %h0|%h0, %b1}"
2551 [(set_attr "type" "imov")
2552 (set_attr "mode" "QI")])
2554 (define_insn "*movsi_insv_1"
2555 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2558 (match_operand:SI 1 "general_operand" "Qmn"))]
2560 "mov{b}\t{%b1, %h0|%h0, %b1}"
2561 [(set_attr "type" "imov")
2562 (set_attr "mode" "QI")])
2564 (define_insn "*movqi_insv_2"
2565 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2568 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2571 "mov{b}\t{%h1, %h0|%h0, %h1}"
2572 [(set_attr "type" "imov")
2573 (set_attr "mode" "QI")])
2575 ;; Floating point push instructions.
2577 (define_insn "*pushtf"
2578 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2579 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2582 /* This insn should be already split before reg-stack. */
2585 [(set_attr "type" "multi")
2586 (set_attr "unit" "sse,*,*")
2587 (set_attr "mode" "TF,SI,SI")])
2590 [(set (match_operand:TF 0 "push_operand" "")
2591 (match_operand:TF 1 "general_operand" ""))]
2592 "TARGET_SSE2 && reload_completed
2593 && !SSE_REG_P (operands[1])"
2595 "ix86_split_long_move (operands); DONE;")
2598 [(set (match_operand:TF 0 "push_operand" "")
2599 (match_operand:TF 1 "any_fp_register_operand" ""))]
2601 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2602 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2604 (define_insn "*pushxf"
2605 [(set (match_operand:XF 0 "push_operand" "=<,<")
2606 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2607 "optimize_function_for_speed_p (cfun)"
2609 /* This insn should be already split before reg-stack. */
2612 [(set_attr "type" "multi")
2613 (set_attr "unit" "i387,*")
2614 (set_attr "mode" "XF,SI")])
2616 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2617 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2618 ;; Pushing using integer instructions is longer except for constants
2619 ;; and direct memory references (assuming that any given constant is pushed
2620 ;; only once, but this ought to be handled elsewhere).
2622 (define_insn "*pushxf_nointeger"
2623 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2624 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2625 "optimize_function_for_size_p (cfun)"
2627 /* This insn should be already split before reg-stack. */
2630 [(set_attr "type" "multi")
2631 (set_attr "unit" "i387,*,*")
2632 (set_attr "mode" "XF,SI,SI")])
2635 [(set (match_operand:XF 0 "push_operand" "")
2636 (match_operand:XF 1 "any_fp_register_operand" ""))]
2638 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2639 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2640 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2643 [(set (match_operand:XF 0 "push_operand" "")
2644 (match_operand:XF 1 "general_operand" ""))]
2646 && !ANY_FP_REG_P (operands[1])"
2648 "ix86_split_long_move (operands); DONE;")
2650 (define_insn "*pushdf"
2651 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2652 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2653 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2655 /* This insn should be already split before reg-stack. */
2658 [(set_attr "type" "multi")
2659 (set_attr "unit" "i387,*,*")
2660 (set_attr "mode" "DF,SI,DF")])
2662 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2663 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2664 ;; On the average, pushdf using integers can be still shorter. Allow this
2665 ;; pattern for optimize_size too.
2667 (define_insn "*pushdf_nointeger"
2668 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2669 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2670 "!(TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES)"
2672 /* This insn should be already split before reg-stack. */
2675 [(set_attr "type" "multi")
2676 (set_attr "unit" "i387,*,*,*")
2677 (set_attr "mode" "DF,SI,SI,DF")])
2679 ;; %%% Kill this when call knows how to work this out.
2681 [(set (match_operand:DF 0 "push_operand" "")
2682 (match_operand:DF 1 "any_fp_register_operand" ""))]
2684 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2685 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2688 [(set (match_operand:DF 0 "push_operand" "")
2689 (match_operand:DF 1 "general_operand" ""))]
2691 && !ANY_FP_REG_P (operands[1])"
2693 "ix86_split_long_move (operands); DONE;")
2695 (define_insn "*pushsf_rex64"
2696 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2697 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2700 /* Anything else should be already split before reg-stack. */
2701 gcc_assert (which_alternative == 1);
2702 return "push{q}\t%q1";
2704 [(set_attr "type" "multi,push,multi")
2705 (set_attr "unit" "i387,*,*")
2706 (set_attr "mode" "SF,DI,SF")])
2708 (define_insn "*pushsf"
2709 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2710 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2713 /* Anything else should be already split before reg-stack. */
2714 gcc_assert (which_alternative == 1);
2715 return "push{l}\t%1";
2717 [(set_attr "type" "multi,push,multi")
2718 (set_attr "unit" "i387,*,*")
2719 (set_attr "mode" "SF,SI,SF")])
2722 [(set (match_operand:SF 0 "push_operand" "")
2723 (match_operand:SF 1 "memory_operand" ""))]
2725 && MEM_P (operands[1])
2726 && (operands[2] = find_constant_src (insn))"
2730 ;; %%% Kill this when call knows how to work this out.
2732 [(set (match_operand:SF 0 "push_operand" "")
2733 (match_operand:SF 1 "any_fp_register_operand" ""))]
2735 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2736 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2737 "operands[2] = GEN_INT (-GET_MODE_SIZE (<MODE>mode));")
2739 ;; Floating point move instructions.
2741 (define_expand "movtf"
2742 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2743 (match_operand:TF 1 "nonimmediate_operand" ""))]
2746 ix86_expand_move (TFmode, operands);
2750 (define_expand "mov<mode>"
2751 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2752 (match_operand:X87MODEF 1 "general_operand" ""))]
2754 "ix86_expand_move (<MODE>mode, operands); DONE;")
2756 (define_insn "*movtf_internal"
2757 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
2758 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
2760 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2762 switch (which_alternative)
2766 if (get_attr_mode (insn) == MODE_V4SF)
2767 return "%vmovaps\t{%1, %0|%0, %1}";
2769 return "%vmovdqa\t{%1, %0|%0, %1}";
2771 if (get_attr_mode (insn) == MODE_V4SF)
2772 return "%vxorps\t%0, %d0";
2774 return "%vpxor\t%0, %d0";
2782 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2783 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2785 (cond [(eq_attr "alternative" "0,2")
2787 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2789 (const_string "V4SF")
2790 (const_string "TI"))
2791 (eq_attr "alternative" "1")
2793 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2795 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2797 (const_string "V4SF")
2798 (const_string "TI"))]
2799 (const_string "DI")))])
2802 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2803 (match_operand:TF 1 "general_operand" ""))]
2805 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
2807 "ix86_split_long_move (operands); DONE;")
2809 (define_insn "*movxf_internal"
2810 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2811 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2812 "optimize_function_for_speed_p (cfun)
2813 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2814 && (reload_in_progress || reload_completed
2815 || GET_CODE (operands[1]) != CONST_DOUBLE
2816 || memory_operand (operands[0], XFmode))"
2818 switch (which_alternative)
2822 return output_387_reg_move (insn, operands);
2825 return standard_80387_constant_opcode (operands[1]);
2834 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2835 (set_attr "mode" "XF,XF,XF,SI,SI")])
2837 ;; Do not use integer registers when optimizing for size
2838 (define_insn "*movxf_internal_nointeger"
2839 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2840 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2841 "optimize_function_for_size_p (cfun)
2842 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2843 && (reload_in_progress || reload_completed
2844 || standard_80387_constant_p (operands[1])
2845 || GET_CODE (operands[1]) != CONST_DOUBLE
2846 || memory_operand (operands[0], XFmode))"
2848 switch (which_alternative)
2852 return output_387_reg_move (insn, operands);
2855 return standard_80387_constant_opcode (operands[1]);
2863 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2864 (set_attr "mode" "XF,XF,XF,SI,SI")])
2867 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2868 (match_operand:XF 1 "general_operand" ""))]
2870 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2871 && ! (ANY_FP_REG_P (operands[0]) ||
2872 (GET_CODE (operands[0]) == SUBREG
2873 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
2874 && ! (ANY_FP_REG_P (operands[1]) ||
2875 (GET_CODE (operands[1]) == SUBREG
2876 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
2878 "ix86_split_long_move (operands); DONE;")
2880 (define_insn "*movdf_internal_rex64"
2881 [(set (match_operand:DF 0 "nonimmediate_operand"
2882 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2883 (match_operand:DF 1 "general_operand"
2884 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2885 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2886 && (reload_in_progress || reload_completed
2887 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2888 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2889 && optimize_function_for_size_p (cfun)
2890 && standard_80387_constant_p (operands[1]))
2891 || GET_CODE (operands[1]) != CONST_DOUBLE
2892 || memory_operand (operands[0], DFmode))"
2894 switch (which_alternative)
2898 return output_387_reg_move (insn, operands);
2901 return standard_80387_constant_opcode (operands[1]);
2908 switch (get_attr_mode (insn))
2911 return "%vxorps\t%0, %d0";
2913 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2914 return "%vxorps\t%0, %d0";
2916 return "%vxorpd\t%0, %d0";
2918 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2919 return "%vxorps\t%0, %d0";
2921 return "%vpxor\t%0, %d0";
2928 switch (get_attr_mode (insn))
2931 return "%vmovaps\t{%1, %0|%0, %1}";
2933 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2934 return "%vmovaps\t{%1, %0|%0, %1}";
2936 return "%vmovapd\t{%1, %0|%0, %1}";
2938 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2939 return "%vmovaps\t{%1, %0|%0, %1}";
2941 return "%vmovdqa\t{%1, %0|%0, %1}";
2943 return "%vmovq\t{%1, %0|%0, %1}";
2947 if (REG_P (operands[0]) && REG_P (operands[1]))
2948 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2950 return "vmovsd\t{%1, %0|%0, %1}";
2953 return "movsd\t{%1, %0|%0, %1}";
2955 return "%vmovlpd\t{%1, %d0|%d0, %1}";
2957 return "%vmovlps\t{%1, %d0|%d0, %1}";
2964 return "%vmovd\t{%1, %0|%0, %1}";
2970 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2971 (set (attr "prefix")
2972 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
2973 (const_string "orig")
2974 (const_string "maybe_vex")))
2975 (set (attr "prefix_data16")
2976 (if_then_else (eq_attr "mode" "V1DF")
2978 (const_string "*")))
2980 (cond [(eq_attr "alternative" "0,1,2")
2982 (eq_attr "alternative" "3,4,9,10")
2985 /* For SSE1, we have many fewer alternatives. */
2986 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2987 (cond [(eq_attr "alternative" "5,6")
2988 (const_string "V4SF")
2990 (const_string "V2SF"))
2992 /* xorps is one byte shorter. */
2993 (eq_attr "alternative" "5")
2994 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2996 (const_string "V4SF")
2997 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3001 (const_string "V2DF"))
3003 /* For architectures resolving dependencies on
3004 whole SSE registers use APD move to break dependency
3005 chains, otherwise use short move to avoid extra work.
3007 movaps encodes one byte shorter. */
3008 (eq_attr "alternative" "6")
3010 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3012 (const_string "V4SF")
3013 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3015 (const_string "V2DF")
3017 (const_string "DF"))
3018 /* For architectures resolving dependencies on register
3019 parts we may avoid extra work to zero out upper part
3021 (eq_attr "alternative" "7")
3023 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3025 (const_string "V1DF")
3026 (const_string "DF"))
3028 (const_string "DF")))])
3030 (define_insn "*movdf_internal"
3031 [(set (match_operand:DF 0 "nonimmediate_operand"
3032 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3033 (match_operand:DF 1 "general_operand"
3034 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3035 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3036 && optimize_function_for_speed_p (cfun)
3037 && TARGET_INTEGER_DFMODE_MOVES
3038 && (reload_in_progress || reload_completed
3039 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3040 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3041 && optimize_function_for_size_p (cfun)
3042 && standard_80387_constant_p (operands[1]))
3043 || GET_CODE (operands[1]) != CONST_DOUBLE
3044 || memory_operand (operands[0], DFmode))"
3046 switch (which_alternative)
3050 return output_387_reg_move (insn, operands);
3053 return standard_80387_constant_opcode (operands[1]);
3060 switch (get_attr_mode (insn))
3063 return "xorps\t%0, %0";
3065 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3066 return "xorps\t%0, %0";
3068 return "xorpd\t%0, %0";
3070 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3071 return "xorps\t%0, %0";
3073 return "pxor\t%0, %0";
3080 switch (get_attr_mode (insn))
3083 return "movaps\t{%1, %0|%0, %1}";
3085 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3086 return "movaps\t{%1, %0|%0, %1}";
3088 return "movapd\t{%1, %0|%0, %1}";
3090 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3091 return "movaps\t{%1, %0|%0, %1}";
3093 return "movdqa\t{%1, %0|%0, %1}";
3095 return "movq\t{%1, %0|%0, %1}";
3097 return "movsd\t{%1, %0|%0, %1}";
3099 return "movlpd\t{%1, %0|%0, %1}";
3101 return "movlps\t{%1, %0|%0, %1}";
3110 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3111 (set (attr "prefix_data16")
3112 (if_then_else (eq_attr "mode" "V1DF")
3114 (const_string "*")))
3116 (cond [(eq_attr "alternative" "0,1,2")
3118 (eq_attr "alternative" "3,4")
3121 /* For SSE1, we have many fewer alternatives. */
3122 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3123 (cond [(eq_attr "alternative" "5,6")
3124 (const_string "V4SF")
3126 (const_string "V2SF"))
3128 /* xorps is one byte shorter. */
3129 (eq_attr "alternative" "5")
3130 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3132 (const_string "V4SF")
3133 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3137 (const_string "V2DF"))
3139 /* For architectures resolving dependencies on
3140 whole SSE registers use APD move to break dependency
3141 chains, otherwise use short move to avoid extra work.
3143 movaps encodes one byte shorter. */
3144 (eq_attr "alternative" "6")
3146 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3148 (const_string "V4SF")
3149 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3151 (const_string "V2DF")
3153 (const_string "DF"))
3154 /* For architectures resolving dependencies on register
3155 parts we may avoid extra work to zero out upper part
3157 (eq_attr "alternative" "7")
3159 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3161 (const_string "V1DF")
3162 (const_string "DF"))
3164 (const_string "DF")))])
3166 ;; Moving is usually shorter when only FP registers are used. This separate
3167 ;; movdf pattern avoids the use of integer registers for FP operations
3168 ;; when optimizing for size.
3170 (define_insn "*movdf_internal_nointeger"
3171 [(set (match_operand:DF 0 "nonimmediate_operand"
3172 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
3173 (match_operand:DF 1 "general_operand"
3174 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
3175 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3176 && ((optimize_function_for_size_p (cfun)
3177 || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3178 && (reload_in_progress || reload_completed
3179 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3180 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3181 && optimize_function_for_size_p (cfun)
3182 && !memory_operand (operands[0], DFmode)
3183 && standard_80387_constant_p (operands[1]))
3184 || GET_CODE (operands[1]) != CONST_DOUBLE
3185 || ((optimize_function_for_size_p (cfun)
3186 || !TARGET_MEMORY_MISMATCH_STALL
3187 || reload_in_progress || reload_completed)
3188 && memory_operand (operands[0], DFmode)))"
3190 switch (which_alternative)
3194 return output_387_reg_move (insn, operands);
3197 return standard_80387_constant_opcode (operands[1]);
3204 switch (get_attr_mode (insn))
3207 return "%vxorps\t%0, %d0";
3209 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3210 return "%vxorps\t%0, %d0";
3212 return "%vxorpd\t%0, %d0";
3214 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3215 return "%vxorps\t%0, %d0";
3217 return "%vpxor\t%0, %d0";
3224 switch (get_attr_mode (insn))
3227 return "%vmovaps\t{%1, %0|%0, %1}";
3229 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3230 return "%vmovaps\t{%1, %0|%0, %1}";
3232 return "%vmovapd\t{%1, %0|%0, %1}";
3234 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3235 return "%vmovaps\t{%1, %0|%0, %1}";
3237 return "%vmovdqa\t{%1, %0|%0, %1}";
3239 return "%vmovq\t{%1, %0|%0, %1}";
3243 if (REG_P (operands[0]) && REG_P (operands[1]))
3244 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3246 return "vmovsd\t{%1, %0|%0, %1}";
3249 return "movsd\t{%1, %0|%0, %1}";
3253 if (REG_P (operands[0]))
3254 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3256 return "vmovlpd\t{%1, %0|%0, %1}";
3259 return "movlpd\t{%1, %0|%0, %1}";
3263 if (REG_P (operands[0]))
3264 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3266 return "vmovlps\t{%1, %0|%0, %1}";
3269 return "movlps\t{%1, %0|%0, %1}";
3278 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3279 (set (attr "prefix")
3280 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3281 (const_string "orig")
3282 (const_string "maybe_vex")))
3283 (set (attr "prefix_data16")
3284 (if_then_else (eq_attr "mode" "V1DF")
3286 (const_string "*")))
3288 (cond [(eq_attr "alternative" "0,1,2")
3290 (eq_attr "alternative" "3,4")
3293 /* For SSE1, we have many fewer alternatives. */
3294 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3295 (cond [(eq_attr "alternative" "5,6")
3296 (const_string "V4SF")
3298 (const_string "V2SF"))
3300 /* xorps is one byte shorter. */
3301 (eq_attr "alternative" "5")
3302 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3304 (const_string "V4SF")
3305 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3309 (const_string "V2DF"))
3311 /* For architectures resolving dependencies on
3312 whole SSE registers use APD move to break dependency
3313 chains, otherwise use short move to avoid extra work.
3315 movaps encodes one byte shorter. */
3316 (eq_attr "alternative" "6")
3318 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3320 (const_string "V4SF")
3321 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3323 (const_string "V2DF")
3325 (const_string "DF"))
3326 /* For architectures resolving dependencies on register
3327 parts we may avoid extra work to zero out upper part
3329 (eq_attr "alternative" "7")
3331 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3333 (const_string "V1DF")
3334 (const_string "DF"))
3336 (const_string "DF")))])
3339 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3340 (match_operand:DF 1 "general_operand" ""))]
3342 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3343 && ! (ANY_FP_REG_P (operands[0]) ||
3344 (GET_CODE (operands[0]) == SUBREG
3345 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3346 && ! (ANY_FP_REG_P (operands[1]) ||
3347 (GET_CODE (operands[1]) == SUBREG
3348 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3350 "ix86_split_long_move (operands); DONE;")
3352 (define_insn "*movsf_internal"
3353 [(set (match_operand:SF 0 "nonimmediate_operand"
3354 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3355 (match_operand:SF 1 "general_operand"
3356 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3357 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3358 && (reload_in_progress || reload_completed
3359 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3360 || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
3361 && standard_80387_constant_p (operands[1]))
3362 || GET_CODE (operands[1]) != CONST_DOUBLE
3363 || memory_operand (operands[0], SFmode))"
3365 switch (which_alternative)
3369 return output_387_reg_move (insn, operands);
3372 return standard_80387_constant_opcode (operands[1]);
3376 return "mov{l}\t{%1, %0|%0, %1}";
3378 if (get_attr_mode (insn) == MODE_TI)
3379 return "%vpxor\t%0, %d0";
3381 return "%vxorps\t%0, %d0";
3383 if (get_attr_mode (insn) == MODE_V4SF)
3384 return "%vmovaps\t{%1, %0|%0, %1}";
3386 return "%vmovss\t{%1, %d0|%d0, %1}";
3389 return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
3390 : "vmovss\t{%1, %0|%0, %1}";
3392 return "movss\t{%1, %0|%0, %1}";
3394 return "%vmovss\t{%1, %0|%0, %1}";
3396 case 9: case 10: case 14: case 15:
3397 return "movd\t{%1, %0|%0, %1}";
3399 return "%vmovd\t{%1, %0|%0, %1}";
3402 return "movq\t{%1, %0|%0, %1}";
3408 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3409 (set (attr "prefix")
3410 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3411 (const_string "maybe_vex")
3412 (const_string "orig")))
3414 (cond [(eq_attr "alternative" "3,4,9,10")
3416 (eq_attr "alternative" "5")
3418 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3420 (ne (symbol_ref "TARGET_SSE2")
3422 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3425 (const_string "V4SF"))
3426 /* For architectures resolving dependencies on
3427 whole SSE registers use APS move to break dependency
3428 chains, otherwise use short move to avoid extra work.
3430 Do the same for architectures resolving dependencies on
3431 the parts. While in DF mode it is better to always handle
3432 just register parts, the SF mode is different due to lack
3433 of instructions to load just part of the register. It is
3434 better to maintain the whole registers in single format
3435 to avoid problems on using packed logical operations. */
3436 (eq_attr "alternative" "6")
3438 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3440 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3442 (const_string "V4SF")
3443 (const_string "SF"))
3444 (eq_attr "alternative" "11")
3445 (const_string "DI")]
3446 (const_string "SF")))])
3449 [(set (match_operand 0 "register_operand" "")
3450 (match_operand 1 "memory_operand" ""))]
3452 && MEM_P (operands[1])
3453 && (GET_MODE (operands[0]) == TFmode
3454 || GET_MODE (operands[0]) == XFmode
3455 || GET_MODE (operands[0]) == DFmode
3456 || GET_MODE (operands[0]) == SFmode)
3457 && (operands[2] = find_constant_src (insn))"
3458 [(set (match_dup 0) (match_dup 2))]
3460 rtx c = operands[2];
3461 rtx r = operands[0];
3463 if (GET_CODE (r) == SUBREG)
3468 if (!standard_sse_constant_p (c))
3471 else if (FP_REG_P (r))
3473 if (!standard_80387_constant_p (c))
3476 else if (MMX_REG_P (r))
3481 [(set (match_operand 0 "register_operand" "")
3482 (float_extend (match_operand 1 "memory_operand" "")))]
3484 && MEM_P (operands[1])
3485 && (GET_MODE (operands[0]) == TFmode
3486 || GET_MODE (operands[0]) == XFmode
3487 || GET_MODE (operands[0]) == DFmode
3488 || GET_MODE (operands[0]) == SFmode)
3489 && (operands[2] = find_constant_src (insn))"
3490 [(set (match_dup 0) (match_dup 2))]
3492 rtx c = operands[2];
3493 rtx r = operands[0];
3495 if (GET_CODE (r) == SUBREG)
3500 if (!standard_sse_constant_p (c))
3503 else if (FP_REG_P (r))
3505 if (!standard_80387_constant_p (c))
3508 else if (MMX_REG_P (r))
3512 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3514 [(set (match_operand:X87MODEF 0 "register_operand" "")
3515 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3516 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3517 && (standard_80387_constant_p (operands[1]) == 8
3518 || standard_80387_constant_p (operands[1]) == 9)"
3519 [(set (match_dup 0)(match_dup 1))
3521 (neg:X87MODEF (match_dup 0)))]
3525 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3526 if (real_isnegzero (&r))
3527 operands[1] = CONST0_RTX (<MODE>mode);
3529 operands[1] = CONST1_RTX (<MODE>mode);
3532 (define_insn "swapxf"
3533 [(set (match_operand:XF 0 "register_operand" "+f")
3534 (match_operand:XF 1 "register_operand" "+f"))
3539 if (STACK_TOP_P (operands[0]))
3544 [(set_attr "type" "fxch")
3545 (set_attr "mode" "XF")])
3547 (define_insn "*swap<mode>"
3548 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3549 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3552 "TARGET_80387 || reload_completed"
3554 if (STACK_TOP_P (operands[0]))
3559 [(set_attr "type" "fxch")
3560 (set_attr "mode" "<MODE>")])
3562 ;; Zero extension instructions
3564 (define_expand "zero_extendsidi2"
3565 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3566 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3571 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3576 (define_insn "*zero_extendsidi2_rex64"
3577 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3579 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3582 mov\t{%k1, %k0|%k0, %k1}
3584 movd\t{%1, %0|%0, %1}
3585 movd\t{%1, %0|%0, %1}
3586 %vmovd\t{%1, %0|%0, %1}
3587 %vmovd\t{%1, %0|%0, %1}"
3588 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3589 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3590 (set_attr "prefix_0f" "0,*,*,*,*,*")
3591 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3594 [(set (match_operand:DI 0 "memory_operand" "")
3595 (zero_extend:DI (match_dup 0)))]
3597 [(set (match_dup 4) (const_int 0))]
3598 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3600 ;; %%% Kill me once multi-word ops are sane.
3601 (define_insn "zero_extendsidi2_1"
3602 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3604 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3605 (clobber (reg:CC FLAGS_REG))]
3611 movd\t{%1, %0|%0, %1}
3612 movd\t{%1, %0|%0, %1}
3613 %vmovd\t{%1, %0|%0, %1}
3614 %vmovd\t{%1, %0|%0, %1}"
3615 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3616 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3617 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3620 [(set (match_operand:DI 0 "register_operand" "")
3621 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3622 (clobber (reg:CC FLAGS_REG))]
3623 "!TARGET_64BIT && reload_completed
3624 && true_regnum (operands[0]) == true_regnum (operands[1])"
3625 [(set (match_dup 4) (const_int 0))]
3626 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3629 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3630 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3631 (clobber (reg:CC FLAGS_REG))]
3632 "!TARGET_64BIT && reload_completed
3633 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3634 [(set (match_dup 3) (match_dup 1))
3635 (set (match_dup 4) (const_int 0))]
3636 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3638 (define_insn "zero_extend<mode>di2"
3639 [(set (match_operand:DI 0 "register_operand" "=r")
3641 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3643 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3644 [(set_attr "type" "imovx")
3645 (set_attr "mode" "SI")])
3647 (define_expand "zero_extendhisi2"
3648 [(set (match_operand:SI 0 "register_operand" "")
3649 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3652 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3654 operands[1] = force_reg (HImode, operands[1]);
3655 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3660 (define_insn_and_split "zero_extendhisi2_and"
3661 [(set (match_operand:SI 0 "register_operand" "=r")
3662 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3663 (clobber (reg:CC FLAGS_REG))]
3664 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3666 "&& reload_completed"
3667 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3668 (clobber (reg:CC FLAGS_REG))])]
3670 [(set_attr "type" "alu1")
3671 (set_attr "mode" "SI")])
3673 (define_insn "*zero_extendhisi2_movzwl"
3674 [(set (match_operand:SI 0 "register_operand" "=r")
3675 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3676 "!TARGET_ZERO_EXTEND_WITH_AND
3677 || optimize_function_for_size_p (cfun)"
3678 "movz{wl|x}\t{%1, %0|%0, %1}"
3679 [(set_attr "type" "imovx")
3680 (set_attr "mode" "SI")])
3682 (define_expand "zero_extendqi<mode>2"
3684 [(set (match_operand:SWI24 0 "register_operand" "")
3685 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3686 (clobber (reg:CC FLAGS_REG))])]
3690 (define_insn "*zero_extendqi<mode>2_and"
3691 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3692 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3693 (clobber (reg:CC FLAGS_REG))]
3694 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3696 [(set_attr "type" "alu1")
3697 (set_attr "mode" "<MODE>")])
3699 ;; When source and destination does not overlap, clear destination
3700 ;; first and then do the movb
3702 [(set (match_operand:SWI24 0 "register_operand" "")
3703 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3704 (clobber (reg:CC FLAGS_REG))]
3706 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3707 && ANY_QI_REG_P (operands[0])
3708 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3709 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3710 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3712 operands[2] = gen_lowpart (QImode, operands[0]);
3713 ix86_expand_clear (operands[0]);
3716 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3717 [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3718 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3719 (clobber (reg:CC FLAGS_REG))]
3720 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3722 [(set_attr "type" "imovx,alu1")
3723 (set_attr "mode" "<MODE>")])
3725 ;; For the movzbl case strip only the clobber
3727 [(set (match_operand:SWI24 0 "register_operand" "")
3728 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3729 (clobber (reg:CC FLAGS_REG))]
3731 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3732 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3734 (zero_extend:SWI24 (match_dup 1)))])
3736 ; zero extend to SImode to avoid partial register stalls
3737 (define_insn "*zero_extendqi<mode>2_movzbl"
3738 [(set (match_operand:SWI24 0 "register_operand" "=r")
3739 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3741 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3742 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3743 [(set_attr "type" "imovx")
3744 (set_attr "mode" "SI")])
3746 ;; Rest is handled by single and.
3748 [(set (match_operand:SWI24 0 "register_operand" "")
3749 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3750 (clobber (reg:CC FLAGS_REG))]
3752 && true_regnum (operands[0]) == true_regnum (operands[1])"
3753 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3754 (clobber (reg:CC FLAGS_REG))])])
3756 ;; Sign extension instructions
3758 (define_expand "extendsidi2"
3759 [(set (match_operand:DI 0 "register_operand" "")
3760 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3765 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3770 (define_insn "*extendsidi2_rex64"
3771 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3772 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3776 movs{lq|x}\t{%1, %0|%0, %1}"
3777 [(set_attr "type" "imovx")
3778 (set_attr "mode" "DI")
3779 (set_attr "prefix_0f" "0")
3780 (set_attr "modrm" "0,1")])
3782 (define_insn "extendsidi2_1"
3783 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3784 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3785 (clobber (reg:CC FLAGS_REG))
3786 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3790 ;; Extend to memory case when source register does die.
3792 [(set (match_operand:DI 0 "memory_operand" "")
3793 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3794 (clobber (reg:CC FLAGS_REG))
3795 (clobber (match_operand:SI 2 "register_operand" ""))]
3797 && dead_or_set_p (insn, operands[1])
3798 && !reg_mentioned_p (operands[1], operands[0]))"
3799 [(set (match_dup 3) (match_dup 1))
3800 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3801 (clobber (reg:CC FLAGS_REG))])
3802 (set (match_dup 4) (match_dup 1))]
3803 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
3805 ;; Extend to memory case when source register does not die.
3807 [(set (match_operand:DI 0 "memory_operand" "")
3808 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3809 (clobber (reg:CC FLAGS_REG))
3810 (clobber (match_operand:SI 2 "register_operand" ""))]
3814 split_di (&operands[0], 1, &operands[3], &operands[4]);
3816 emit_move_insn (operands[3], operands[1]);
3818 /* Generate a cltd if possible and doing so it profitable. */
3819 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3820 && true_regnum (operands[1]) == AX_REG
3821 && true_regnum (operands[2]) == DX_REG)
3823 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3827 emit_move_insn (operands[2], operands[1]);
3828 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3830 emit_move_insn (operands[4], operands[2]);
3834 ;; Extend to register case. Optimize case where source and destination
3835 ;; registers match and cases where we can use cltd.
3837 [(set (match_operand:DI 0 "register_operand" "")
3838 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3839 (clobber (reg:CC FLAGS_REG))
3840 (clobber (match_scratch:SI 2 ""))]
3844 split_di (&operands[0], 1, &operands[3], &operands[4]);
3846 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3847 emit_move_insn (operands[3], operands[1]);
3849 /* Generate a cltd if possible and doing so it profitable. */
3850 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3851 && true_regnum (operands[3]) == AX_REG
3852 && true_regnum (operands[4]) == DX_REG)
3854 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3858 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3859 emit_move_insn (operands[4], operands[1]);
3861 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3865 (define_insn "extend<mode>di2"
3866 [(set (match_operand:DI 0 "register_operand" "=r")
3868 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3870 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3871 [(set_attr "type" "imovx")
3872 (set_attr "mode" "DI")])
3874 (define_insn "extendhisi2"
3875 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3876 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3879 switch (get_attr_prefix_0f (insn))
3882 return "{cwtl|cwde}";
3884 return "movs{wl|x}\t{%1, %0|%0, %1}";
3887 [(set_attr "type" "imovx")
3888 (set_attr "mode" "SI")
3889 (set (attr "prefix_0f")
3890 ;; movsx is short decodable while cwtl is vector decoded.
3891 (if_then_else (and (eq_attr "cpu" "!k6")
3892 (eq_attr "alternative" "0"))
3894 (const_string "1")))
3896 (if_then_else (eq_attr "prefix_0f" "0")
3898 (const_string "1")))])
3900 (define_insn "*extendhisi2_zext"
3901 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3904 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3907 switch (get_attr_prefix_0f (insn))
3910 return "{cwtl|cwde}";
3912 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3915 [(set_attr "type" "imovx")
3916 (set_attr "mode" "SI")
3917 (set (attr "prefix_0f")
3918 ;; movsx is short decodable while cwtl is vector decoded.
3919 (if_then_else (and (eq_attr "cpu" "!k6")
3920 (eq_attr "alternative" "0"))
3922 (const_string "1")))
3924 (if_then_else (eq_attr "prefix_0f" "0")
3926 (const_string "1")))])
3928 (define_insn "extendqisi2"
3929 [(set (match_operand:SI 0 "register_operand" "=r")
3930 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3932 "movs{bl|x}\t{%1, %0|%0, %1}"
3933 [(set_attr "type" "imovx")
3934 (set_attr "mode" "SI")])
3936 (define_insn "*extendqisi2_zext"
3937 [(set (match_operand:DI 0 "register_operand" "=r")
3939 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3941 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3942 [(set_attr "type" "imovx")
3943 (set_attr "mode" "SI")])
3945 (define_insn "extendqihi2"
3946 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3947 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3950 switch (get_attr_prefix_0f (insn))
3953 return "{cbtw|cbw}";
3955 return "movs{bw|x}\t{%1, %0|%0, %1}";
3958 [(set_attr "type" "imovx")
3959 (set_attr "mode" "HI")
3960 (set (attr "prefix_0f")
3961 ;; movsx is short decodable while cwtl is vector decoded.
3962 (if_then_else (and (eq_attr "cpu" "!k6")
3963 (eq_attr "alternative" "0"))
3965 (const_string "1")))
3967 (if_then_else (eq_attr "prefix_0f" "0")
3969 (const_string "1")))])
3971 ;; Conversions between float and double.
3973 ;; These are all no-ops in the model used for the 80387. So just
3976 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3977 (define_insn "*dummy_extendsfdf2"
3978 [(set (match_operand:DF 0 "push_operand" "=<")
3979 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
3984 [(set (match_operand:DF 0 "push_operand" "")
3985 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3987 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3988 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3990 (define_insn "*dummy_extendsfxf2"
3991 [(set (match_operand:XF 0 "push_operand" "=<")
3992 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
3997 [(set (match_operand:XF 0 "push_operand" "")
3998 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4000 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4001 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4002 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4005 [(set (match_operand:XF 0 "push_operand" "")
4006 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4008 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4009 (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4010 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4012 (define_expand "extendsfdf2"
4013 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4014 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4015 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4017 /* ??? Needed for compress_float_constant since all fp constants
4018 are LEGITIMATE_CONSTANT_P. */
4019 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4021 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4022 && standard_80387_constant_p (operands[1]) > 0)
4024 operands[1] = simplify_const_unary_operation
4025 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4026 emit_move_insn_1 (operands[0], operands[1]);
4029 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4033 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4035 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4037 We do the conversion post reload to avoid producing of 128bit spills
4038 that might lead to ICE on 32bit target. The sequence unlikely combine
4041 [(set (match_operand:DF 0 "register_operand" "")
4043 (match_operand:SF 1 "nonimmediate_operand" "")))]
4044 "TARGET_USE_VECTOR_FP_CONVERTS
4045 && optimize_insn_for_speed_p ()
4046 && reload_completed && SSE_REG_P (operands[0])"
4051 (parallel [(const_int 0) (const_int 1)]))))]
4053 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4054 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4055 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4056 Try to avoid move when unpacking can be done in source. */
4057 if (REG_P (operands[1]))
4059 /* If it is unsafe to overwrite upper half of source, we need
4060 to move to destination and unpack there. */
4061 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4062 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4063 && true_regnum (operands[0]) != true_regnum (operands[1]))
4065 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4066 emit_move_insn (tmp, operands[1]);
4069 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4070 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4074 emit_insn (gen_vec_setv4sf_0 (operands[3],
4075 CONST0_RTX (V4SFmode), operands[1]));
4078 (define_insn "*extendsfdf2_mixed"
4079 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4081 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4082 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4084 switch (which_alternative)
4088 return output_387_reg_move (insn, operands);
4091 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4097 [(set_attr "type" "fmov,fmov,ssecvt")
4098 (set_attr "prefix" "orig,orig,maybe_vex")
4099 (set_attr "mode" "SF,XF,DF")])
4101 (define_insn "*extendsfdf2_sse"
4102 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4103 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4104 "TARGET_SSE2 && TARGET_SSE_MATH"
4105 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4106 [(set_attr "type" "ssecvt")
4107 (set_attr "prefix" "maybe_vex")
4108 (set_attr "mode" "DF")])
4110 (define_insn "*extendsfdf2_i387"
4111 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4112 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4114 "* return output_387_reg_move (insn, operands);"
4115 [(set_attr "type" "fmov")
4116 (set_attr "mode" "SF,XF")])
4118 (define_expand "extend<mode>xf2"
4119 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4120 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4123 /* ??? Needed for compress_float_constant since all fp constants
4124 are LEGITIMATE_CONSTANT_P. */
4125 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4127 if (standard_80387_constant_p (operands[1]) > 0)
4129 operands[1] = simplify_const_unary_operation
4130 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4131 emit_move_insn_1 (operands[0], operands[1]);
4134 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4138 (define_insn "*extend<mode>xf2_i387"
4139 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4141 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4143 "* return output_387_reg_move (insn, operands);"
4144 [(set_attr "type" "fmov")
4145 (set_attr "mode" "<MODE>,XF")])
4147 ;; %%% This seems bad bad news.
4148 ;; This cannot output into an f-reg because there is no way to be sure
4149 ;; of truncating in that case. Otherwise this is just like a simple move
4150 ;; insn. So we pretend we can output to a reg in order to get better
4151 ;; register preferencing, but we really use a stack slot.
4153 ;; Conversion from DFmode to SFmode.
4155 (define_expand "truncdfsf2"
4156 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4158 (match_operand:DF 1 "nonimmediate_operand" "")))]
4159 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4161 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4163 else if (flag_unsafe_math_optimizations)
4167 enum ix86_stack_slot slot = (virtuals_instantiated
4170 rtx temp = assign_386_stack_local (SFmode, slot);
4171 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4176 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4178 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4180 We do the conversion post reload to avoid producing of 128bit spills
4181 that might lead to ICE on 32bit target. The sequence unlikely combine
4184 [(set (match_operand:SF 0 "register_operand" "")
4186 (match_operand:DF 1 "nonimmediate_operand" "")))]
4187 "TARGET_USE_VECTOR_FP_CONVERTS
4188 && optimize_insn_for_speed_p ()
4189 && reload_completed && SSE_REG_P (operands[0])"
4192 (float_truncate:V2SF
4196 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4197 operands[3] = CONST0_RTX (V2SFmode);
4198 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4199 /* Use movsd for loading from memory, unpcklpd for registers.
4200 Try to avoid move when unpacking can be done in source, or SSE3
4201 movddup is available. */
4202 if (REG_P (operands[1]))
4205 && true_regnum (operands[0]) != true_regnum (operands[1])
4206 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4207 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4209 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4210 emit_move_insn (tmp, operands[1]);
4213 else if (!TARGET_SSE3)
4214 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4215 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4218 emit_insn (gen_sse2_loadlpd (operands[4],
4219 CONST0_RTX (V2DFmode), operands[1]));
4222 (define_expand "truncdfsf2_with_temp"
4223 [(parallel [(set (match_operand:SF 0 "" "")
4224 (float_truncate:SF (match_operand:DF 1 "" "")))
4225 (clobber (match_operand:SF 2 "" ""))])]
4228 (define_insn "*truncdfsf_fast_mixed"
4229 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4231 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4232 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4234 switch (which_alternative)
4237 return output_387_reg_move (insn, operands);
4239 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4244 [(set_attr "type" "fmov,ssecvt")
4245 (set_attr "prefix" "orig,maybe_vex")
4246 (set_attr "mode" "SF")])
4248 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4249 ;; because nothing we do here is unsafe.
4250 (define_insn "*truncdfsf_fast_sse"
4251 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4253 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4254 "TARGET_SSE2 && TARGET_SSE_MATH"
4255 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4256 [(set_attr "type" "ssecvt")
4257 (set_attr "prefix" "maybe_vex")
4258 (set_attr "mode" "SF")])
4260 (define_insn "*truncdfsf_fast_i387"
4261 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4263 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4264 "TARGET_80387 && flag_unsafe_math_optimizations"
4265 "* return output_387_reg_move (insn, operands);"
4266 [(set_attr "type" "fmov")
4267 (set_attr "mode" "SF")])
4269 (define_insn "*truncdfsf_mixed"
4270 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4272 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4273 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4274 "TARGET_MIX_SSE_I387"
4276 switch (which_alternative)
4279 return output_387_reg_move (insn, operands);
4281 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4287 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4288 (set_attr "unit" "*,*,i387,i387,i387")
4289 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4290 (set_attr "mode" "SF")])
4292 (define_insn "*truncdfsf_i387"
4293 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4295 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4296 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4299 switch (which_alternative)
4302 return output_387_reg_move (insn, operands);
4308 [(set_attr "type" "fmov,multi,multi,multi")
4309 (set_attr "unit" "*,i387,i387,i387")
4310 (set_attr "mode" "SF")])
4312 (define_insn "*truncdfsf2_i387_1"
4313 [(set (match_operand:SF 0 "memory_operand" "=m")
4315 (match_operand:DF 1 "register_operand" "f")))]
4317 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4318 && !TARGET_MIX_SSE_I387"
4319 "* return output_387_reg_move (insn, operands);"
4320 [(set_attr "type" "fmov")
4321 (set_attr "mode" "SF")])
4324 [(set (match_operand:SF 0 "register_operand" "")
4326 (match_operand:DF 1 "fp_register_operand" "")))
4327 (clobber (match_operand 2 "" ""))]
4329 [(set (match_dup 2) (match_dup 1))
4330 (set (match_dup 0) (match_dup 2))]
4331 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4333 ;; Conversion from XFmode to {SF,DF}mode
4335 (define_expand "truncxf<mode>2"
4336 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4337 (float_truncate:MODEF
4338 (match_operand:XF 1 "register_operand" "")))
4339 (clobber (match_dup 2))])]
4342 if (flag_unsafe_math_optimizations)
4344 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4345 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4346 if (reg != operands[0])
4347 emit_move_insn (operands[0], reg);
4352 enum ix86_stack_slot slot = (virtuals_instantiated
4355 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4359 (define_insn "*truncxfsf2_mixed"
4360 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4362 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4363 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4366 gcc_assert (!which_alternative);
4367 return output_387_reg_move (insn, operands);
4369 [(set_attr "type" "fmov,multi,multi,multi")
4370 (set_attr "unit" "*,i387,i387,i387")
4371 (set_attr "mode" "SF")])
4373 (define_insn "*truncxfdf2_mixed"
4374 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4376 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4377 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4380 gcc_assert (!which_alternative);
4381 return output_387_reg_move (insn, operands);
4383 [(set_attr "type" "fmov,multi,multi,multi")
4384 (set_attr "unit" "*,i387,i387,i387")
4385 (set_attr "mode" "DF")])
4387 (define_insn "truncxf<mode>2_i387_noop"
4388 [(set (match_operand:MODEF 0 "register_operand" "=f")
4389 (float_truncate:MODEF
4390 (match_operand:XF 1 "register_operand" "f")))]
4391 "TARGET_80387 && flag_unsafe_math_optimizations"
4392 "* return output_387_reg_move (insn, operands);"
4393 [(set_attr "type" "fmov")
4394 (set_attr "mode" "<MODE>")])
4396 (define_insn "*truncxf<mode>2_i387"
4397 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4398 (float_truncate:MODEF
4399 (match_operand:XF 1 "register_operand" "f")))]
4401 "* return output_387_reg_move (insn, operands);"
4402 [(set_attr "type" "fmov")
4403 (set_attr "mode" "<MODE>")])
4406 [(set (match_operand:MODEF 0 "register_operand" "")
4407 (float_truncate:MODEF
4408 (match_operand:XF 1 "register_operand" "")))
4409 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4410 "TARGET_80387 && reload_completed"
4411 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4412 (set (match_dup 0) (match_dup 2))])
4415 [(set (match_operand:MODEF 0 "memory_operand" "")
4416 (float_truncate:MODEF
4417 (match_operand:XF 1 "register_operand" "")))
4418 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4420 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4422 ;; Signed conversion to DImode.
4424 (define_expand "fix_truncxfdi2"
4425 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4426 (fix:DI (match_operand:XF 1 "register_operand" "")))
4427 (clobber (reg:CC FLAGS_REG))])]
4432 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4437 (define_expand "fix_trunc<mode>di2"
4438 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4439 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4440 (clobber (reg:CC FLAGS_REG))])]
4441 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4444 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4446 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4449 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4451 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4452 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4453 if (out != operands[0])
4454 emit_move_insn (operands[0], out);
4459 ;; Signed conversion to SImode.
4461 (define_expand "fix_truncxfsi2"
4462 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4463 (fix:SI (match_operand:XF 1 "register_operand" "")))
4464 (clobber (reg:CC FLAGS_REG))])]
4469 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4474 (define_expand "fix_trunc<mode>si2"
4475 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4476 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4477 (clobber (reg:CC FLAGS_REG))])]
4478 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4481 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4483 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4486 if (SSE_FLOAT_MODE_P (<MODE>mode))
4488 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4489 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4490 if (out != operands[0])
4491 emit_move_insn (operands[0], out);
4496 ;; Signed conversion to HImode.
4498 (define_expand "fix_trunc<mode>hi2"
4499 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4500 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4501 (clobber (reg:CC FLAGS_REG))])]
4503 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4507 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4512 ;; Unsigned conversion to SImode.
4514 (define_expand "fixuns_trunc<mode>si2"
4516 [(set (match_operand:SI 0 "register_operand" "")
4518 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4520 (clobber (match_scratch:<ssevecmode> 3 ""))
4521 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4522 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4524 enum machine_mode mode = <MODE>mode;
4525 enum machine_mode vecmode = <ssevecmode>mode;
4526 REAL_VALUE_TYPE TWO31r;
4529 if (optimize_insn_for_size_p ())
4532 real_ldexp (&TWO31r, &dconst1, 31);
4533 two31 = const_double_from_real_value (TWO31r, mode);
4534 two31 = ix86_build_const_vector (mode, true, two31);
4535 operands[2] = force_reg (vecmode, two31);
4538 (define_insn_and_split "*fixuns_trunc<mode>_1"
4539 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4541 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4542 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4543 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4544 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4545 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4546 && optimize_function_for_speed_p (cfun)"
4548 "&& reload_completed"
4551 ix86_split_convert_uns_si_sse (operands);
4555 ;; Unsigned conversion to HImode.
4556 ;; Without these patterns, we'll try the unsigned SI conversion which
4557 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4559 (define_expand "fixuns_trunc<mode>hi2"
4561 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4562 (set (match_operand:HI 0 "nonimmediate_operand" "")
4563 (subreg:HI (match_dup 2) 0))]
4564 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4565 "operands[2] = gen_reg_rtx (SImode);")
4567 ;; When SSE is available, it is always faster to use it!
4568 (define_insn "fix_trunc<mode>di_sse"
4569 [(set (match_operand:DI 0 "register_operand" "=r,r")
4570 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4571 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4572 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4573 "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4574 [(set_attr "type" "sseicvt")
4575 (set_attr "prefix" "maybe_vex")
4576 (set_attr "prefix_rex" "1")
4577 (set_attr "mode" "<MODE>")
4578 (set_attr "athlon_decode" "double,vector")
4579 (set_attr "amdfam10_decode" "double,double")])
4581 (define_insn "fix_trunc<mode>si_sse"
4582 [(set (match_operand:SI 0 "register_operand" "=r,r")
4583 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4584 "SSE_FLOAT_MODE_P (<MODE>mode)
4585 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4586 "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4587 [(set_attr "type" "sseicvt")
4588 (set_attr "prefix" "maybe_vex")
4589 (set_attr "mode" "<MODE>")
4590 (set_attr "athlon_decode" "double,vector")
4591 (set_attr "amdfam10_decode" "double,double")])
4593 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4595 [(set (match_operand:MODEF 0 "register_operand" "")
4596 (match_operand:MODEF 1 "memory_operand" ""))
4597 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4598 (fix:SSEMODEI24 (match_dup 0)))]
4599 "TARGET_SHORTEN_X87_SSE
4600 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4601 && peep2_reg_dead_p (2, operands[0])"
4602 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))])
4604 ;; Avoid vector decoded forms of the instruction.
4606 [(match_scratch:DF 2 "Y2")
4607 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4608 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4609 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4610 [(set (match_dup 2) (match_dup 1))
4611 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4614 [(match_scratch:SF 2 "x")
4615 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4616 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4617 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4618 [(set (match_dup 2) (match_dup 1))
4619 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4621 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4622 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4623 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4624 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4626 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4627 && (TARGET_64BIT || <MODE>mode != DImode))
4629 && can_create_pseudo_p ()"
4634 if (memory_operand (operands[0], VOIDmode))
4635 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4638 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4639 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4645 [(set_attr "type" "fisttp")
4646 (set_attr "mode" "<MODE>")])
4648 (define_insn "fix_trunc<mode>_i387_fisttp"
4649 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4650 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4651 (clobber (match_scratch:XF 2 "=&1f"))]
4652 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4654 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4655 && (TARGET_64BIT || <MODE>mode != DImode))
4656 && TARGET_SSE_MATH)"
4657 "* return output_fix_trunc (insn, operands, 1);"
4658 [(set_attr "type" "fisttp")
4659 (set_attr "mode" "<MODE>")])
4661 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4662 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4663 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4664 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4665 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4666 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4668 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4669 && (TARGET_64BIT || <MODE>mode != DImode))
4670 && TARGET_SSE_MATH)"
4672 [(set_attr "type" "fisttp")
4673 (set_attr "mode" "<MODE>")])
4676 [(set (match_operand:X87MODEI 0 "register_operand" "")
4677 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4678 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4679 (clobber (match_scratch 3 ""))]
4681 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4682 (clobber (match_dup 3))])
4683 (set (match_dup 0) (match_dup 2))])
4686 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4687 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4688 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4689 (clobber (match_scratch 3 ""))]
4691 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4692 (clobber (match_dup 3))])])
4694 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4695 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4696 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4697 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4698 ;; function in i386.c.
4699 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4700 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4701 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4702 (clobber (reg:CC FLAGS_REG))]
4703 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4705 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4706 && (TARGET_64BIT || <MODE>mode != DImode))
4707 && can_create_pseudo_p ()"
4712 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4714 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4715 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4716 if (memory_operand (operands[0], VOIDmode))
4717 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4718 operands[2], operands[3]));
4721 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4722 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4723 operands[2], operands[3],
4728 [(set_attr "type" "fistp")
4729 (set_attr "i387_cw" "trunc")
4730 (set_attr "mode" "<MODE>")])
4732 (define_insn "fix_truncdi_i387"
4733 [(set (match_operand:DI 0 "memory_operand" "=m")
4734 (fix:DI (match_operand 1 "register_operand" "f")))
4735 (use (match_operand:HI 2 "memory_operand" "m"))
4736 (use (match_operand:HI 3 "memory_operand" "m"))
4737 (clobber (match_scratch:XF 4 "=&1f"))]
4738 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4740 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4741 "* return output_fix_trunc (insn, operands, 0);"
4742 [(set_attr "type" "fistp")
4743 (set_attr "i387_cw" "trunc")
4744 (set_attr "mode" "DI")])
4746 (define_insn "fix_truncdi_i387_with_temp"
4747 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4748 (fix:DI (match_operand 1 "register_operand" "f,f")))
4749 (use (match_operand:HI 2 "memory_operand" "m,m"))
4750 (use (match_operand:HI 3 "memory_operand" "m,m"))
4751 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4752 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4753 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4755 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4757 [(set_attr "type" "fistp")
4758 (set_attr "i387_cw" "trunc")
4759 (set_attr "mode" "DI")])
4762 [(set (match_operand:DI 0 "register_operand" "")
4763 (fix:DI (match_operand 1 "register_operand" "")))
4764 (use (match_operand:HI 2 "memory_operand" ""))
4765 (use (match_operand:HI 3 "memory_operand" ""))
4766 (clobber (match_operand:DI 4 "memory_operand" ""))
4767 (clobber (match_scratch 5 ""))]
4769 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4772 (clobber (match_dup 5))])
4773 (set (match_dup 0) (match_dup 4))])
4776 [(set (match_operand:DI 0 "memory_operand" "")
4777 (fix:DI (match_operand 1 "register_operand" "")))
4778 (use (match_operand:HI 2 "memory_operand" ""))
4779 (use (match_operand:HI 3 "memory_operand" ""))
4780 (clobber (match_operand:DI 4 "memory_operand" ""))
4781 (clobber (match_scratch 5 ""))]
4783 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4786 (clobber (match_dup 5))])])
4788 (define_insn "fix_trunc<mode>_i387"
4789 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4790 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4791 (use (match_operand:HI 2 "memory_operand" "m"))
4792 (use (match_operand:HI 3 "memory_operand" "m"))]
4793 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4795 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4796 "* return output_fix_trunc (insn, operands, 0);"
4797 [(set_attr "type" "fistp")
4798 (set_attr "i387_cw" "trunc")
4799 (set_attr "mode" "<MODE>")])
4801 (define_insn "fix_trunc<mode>_i387_with_temp"
4802 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4803 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4804 (use (match_operand:HI 2 "memory_operand" "m,m"))
4805 (use (match_operand:HI 3 "memory_operand" "m,m"))
4806 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4807 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4809 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4811 [(set_attr "type" "fistp")
4812 (set_attr "i387_cw" "trunc")
4813 (set_attr "mode" "<MODE>")])
4816 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4817 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4818 (use (match_operand:HI 2 "memory_operand" ""))
4819 (use (match_operand:HI 3 "memory_operand" ""))
4820 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4822 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4824 (use (match_dup 3))])
4825 (set (match_dup 0) (match_dup 4))])
4828 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4829 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4830 (use (match_operand:HI 2 "memory_operand" ""))
4831 (use (match_operand:HI 3 "memory_operand" ""))
4832 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4834 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4836 (use (match_dup 3))])])
4838 (define_insn "x86_fnstcw_1"
4839 [(set (match_operand:HI 0 "memory_operand" "=m")
4840 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4843 [(set (attr "length")
4844 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4845 (set_attr "mode" "HI")
4846 (set_attr "unit" "i387")])
4848 (define_insn "x86_fldcw_1"
4849 [(set (reg:HI FPCR_REG)
4850 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4853 [(set (attr "length")
4854 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4855 (set_attr "mode" "HI")
4856 (set_attr "unit" "i387")
4857 (set_attr "athlon_decode" "vector")
4858 (set_attr "amdfam10_decode" "vector")])
4860 ;; Conversion between fixed point and floating point.
4862 ;; Even though we only accept memory inputs, the backend _really_
4863 ;; wants to be able to do this between registers.
4865 (define_expand "floathi<mode>2"
4866 [(set (match_operand:X87MODEF 0 "register_operand" "")
4867 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4869 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4870 || TARGET_MIX_SSE_I387)"
4873 ;; Pre-reload splitter to add memory clobber to the pattern.
4874 (define_insn_and_split "*floathi<mode>2_1"
4875 [(set (match_operand:X87MODEF 0 "register_operand" "")
4876 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4878 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4879 || TARGET_MIX_SSE_I387)
4880 && can_create_pseudo_p ()"
4883 [(parallel [(set (match_dup 0)
4884 (float:X87MODEF (match_dup 1)))
4885 (clobber (match_dup 2))])]
4886 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4888 (define_insn "*floathi<mode>2_i387_with_temp"
4889 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4890 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4891 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4893 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4894 || TARGET_MIX_SSE_I387)"
4896 [(set_attr "type" "fmov,multi")
4897 (set_attr "mode" "<MODE>")
4898 (set_attr "unit" "*,i387")
4899 (set_attr "fp_int_src" "true")])
4901 (define_insn "*floathi<mode>2_i387"
4902 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4903 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4905 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4906 || TARGET_MIX_SSE_I387)"
4908 [(set_attr "type" "fmov")
4909 (set_attr "mode" "<MODE>")
4910 (set_attr "fp_int_src" "true")])
4913 [(set (match_operand:X87MODEF 0 "register_operand" "")
4914 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4915 (clobber (match_operand:HI 2 "memory_operand" ""))]
4917 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4918 || TARGET_MIX_SSE_I387)
4919 && reload_completed"
4920 [(set (match_dup 2) (match_dup 1))
4921 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4924 [(set (match_operand:X87MODEF 0 "register_operand" "")
4925 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4926 (clobber (match_operand:HI 2 "memory_operand" ""))]
4928 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4929 || TARGET_MIX_SSE_I387)
4930 && reload_completed"
4931 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4933 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
4934 [(set (match_operand:X87MODEF 0 "register_operand" "")
4936 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
4938 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4939 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4941 if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4942 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4943 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
4945 rtx reg = gen_reg_rtx (XFmode);
4948 emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
4950 if (<X87MODEF:MODE>mode == SFmode)
4951 insn = gen_truncxfsf2 (operands[0], reg);
4952 else if (<X87MODEF:MODE>mode == DFmode)
4953 insn = gen_truncxfdf2 (operands[0], reg);
4962 ;; Pre-reload splitter to add memory clobber to the pattern.
4963 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
4964 [(set (match_operand:X87MODEF 0 "register_operand" "")
4965 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
4967 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
4968 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4969 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4970 || TARGET_MIX_SSE_I387))
4971 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4972 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4973 && ((<SSEMODEI24:MODE>mode == SImode
4974 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4975 && optimize_function_for_speed_p (cfun)
4976 && flag_trapping_math)
4977 || !(TARGET_INTER_UNIT_CONVERSIONS
4978 || optimize_function_for_size_p (cfun)))))
4979 && can_create_pseudo_p ()"
4982 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4983 (clobber (match_dup 2))])]
4985 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
4987 /* Avoid store forwarding (partial memory) stall penalty
4988 by passing DImode value through XMM registers. */
4989 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
4990 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4991 && optimize_function_for_speed_p (cfun))
4993 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5000 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5001 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5003 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5004 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5005 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5006 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5008 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5009 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5010 (set_attr "unit" "*,i387,*,*,*")
5011 (set_attr "athlon_decode" "*,*,double,direct,double")
5012 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5013 (set_attr "fp_int_src" "true")])
5015 (define_insn "*floatsi<mode>2_vector_mixed"
5016 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5017 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5018 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5019 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5023 [(set_attr "type" "fmov,sseicvt")
5024 (set_attr "mode" "<MODE>,<ssevecmode>")
5025 (set_attr "unit" "i387,*")
5026 (set_attr "athlon_decode" "*,direct")
5027 (set_attr "amdfam10_decode" "*,double")
5028 (set_attr "fp_int_src" "true")])
5030 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5031 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5033 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5034 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5035 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5036 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5038 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5039 (set_attr "mode" "<MODEF:MODE>")
5040 (set_attr "unit" "*,i387,*,*")
5041 (set_attr "athlon_decode" "*,*,double,direct")
5042 (set_attr "amdfam10_decode" "*,*,vector,double")
5043 (set_attr "fp_int_src" "true")])
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
5053 && (SSE_REG_P (operands[0])
5054 || (GET_CODE (operands[0]) == SUBREG
5055 && SSE_REG_P (operands[0])))"
5056 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5059 [(set (match_operand:MODEF 0 "register_operand" "")
5060 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5061 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5062 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5063 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5064 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5066 && (SSE_REG_P (operands[0])
5067 || (GET_CODE (operands[0]) == SUBREG
5068 && SSE_REG_P (operands[0])))"
5069 [(set (match_dup 2) (match_dup 1))
5070 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5072 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5073 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5075 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5076 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5077 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5078 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5081 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5082 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5083 [(set_attr "type" "fmov,sseicvt,sseicvt")
5084 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5085 (set_attr "mode" "<MODEF:MODE>")
5086 (set (attr "prefix_rex")
5088 (and (eq_attr "prefix" "maybe_vex")
5089 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5091 (const_string "*")))
5092 (set_attr "unit" "i387,*,*")
5093 (set_attr "athlon_decode" "*,double,direct")
5094 (set_attr "amdfam10_decode" "*,vector,double")
5095 (set_attr "fp_int_src" "true")])
5097 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5098 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5100 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5101 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5102 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5103 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5106 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5107 [(set_attr "type" "fmov,sseicvt")
5108 (set_attr "prefix" "orig,maybe_vex")
5109 (set_attr "mode" "<MODEF:MODE>")
5110 (set (attr "prefix_rex")
5112 (and (eq_attr "prefix" "maybe_vex")
5113 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5115 (const_string "*")))
5116 (set_attr "athlon_decode" "*,direct")
5117 (set_attr "amdfam10_decode" "*,double")
5118 (set_attr "fp_int_src" "true")])
5120 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5121 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5123 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5124 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5125 "TARGET_SSE2 && TARGET_SSE_MATH
5126 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5128 [(set_attr "type" "sseicvt")
5129 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5130 (set_attr "athlon_decode" "double,direct,double")
5131 (set_attr "amdfam10_decode" "vector,double,double")
5132 (set_attr "fp_int_src" "true")])
5134 (define_insn "*floatsi<mode>2_vector_sse"
5135 [(set (match_operand:MODEF 0 "register_operand" "=x")
5136 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5137 "TARGET_SSE2 && TARGET_SSE_MATH
5138 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5140 [(set_attr "type" "sseicvt")
5141 (set_attr "mode" "<MODE>")
5142 (set_attr "athlon_decode" "direct")
5143 (set_attr "amdfam10_decode" "double")
5144 (set_attr "fp_int_src" "true")])
5147 [(set (match_operand:MODEF 0 "register_operand" "")
5148 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5149 (clobber (match_operand:SI 2 "memory_operand" ""))]
5150 "TARGET_SSE2 && TARGET_SSE_MATH
5151 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5153 && (SSE_REG_P (operands[0])
5154 || (GET_CODE (operands[0]) == SUBREG
5155 && SSE_REG_P (operands[0])))"
5158 rtx op1 = operands[1];
5160 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5162 if (GET_CODE (op1) == SUBREG)
5163 op1 = SUBREG_REG (op1);
5165 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5167 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5168 emit_insn (gen_sse2_loadld (operands[4],
5169 CONST0_RTX (V4SImode), operands[1]));
5171 /* We can ignore possible trapping value in the
5172 high part of SSE register for non-trapping math. */
5173 else if (SSE_REG_P (op1) && !flag_trapping_math)
5174 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5177 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5178 emit_move_insn (operands[2], operands[1]);
5179 emit_insn (gen_sse2_loadld (operands[4],
5180 CONST0_RTX (V4SImode), operands[2]));
5183 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5188 [(set (match_operand:MODEF 0 "register_operand" "")
5189 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5190 (clobber (match_operand:SI 2 "memory_operand" ""))]
5191 "TARGET_SSE2 && TARGET_SSE_MATH
5192 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5194 && (SSE_REG_P (operands[0])
5195 || (GET_CODE (operands[0]) == SUBREG
5196 && SSE_REG_P (operands[0])))"
5199 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5201 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5203 emit_insn (gen_sse2_loadld (operands[4],
5204 CONST0_RTX (V4SImode), operands[1]));
5206 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5211 [(set (match_operand:MODEF 0 "register_operand" "")
5212 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5213 "TARGET_SSE2 && TARGET_SSE_MATH
5214 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5216 && (SSE_REG_P (operands[0])
5217 || (GET_CODE (operands[0]) == SUBREG
5218 && SSE_REG_P (operands[0])))"
5221 rtx op1 = operands[1];
5223 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5225 if (GET_CODE (op1) == SUBREG)
5226 op1 = SUBREG_REG (op1);
5228 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5230 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5231 emit_insn (gen_sse2_loadld (operands[4],
5232 CONST0_RTX (V4SImode), operands[1]));
5234 /* We can ignore possible trapping value in the
5235 high part of SSE register for non-trapping math. */
5236 else if (SSE_REG_P (op1) && !flag_trapping_math)
5237 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5241 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5246 [(set (match_operand:MODEF 0 "register_operand" "")
5247 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5248 "TARGET_SSE2 && TARGET_SSE_MATH
5249 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5251 && (SSE_REG_P (operands[0])
5252 || (GET_CODE (operands[0]) == SUBREG
5253 && SSE_REG_P (operands[0])))"
5256 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5258 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5260 emit_insn (gen_sse2_loadld (operands[4],
5261 CONST0_RTX (V4SImode), operands[1]));
5263 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5267 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5268 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5270 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5271 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5272 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5273 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5275 [(set_attr "type" "sseicvt")
5276 (set_attr "mode" "<MODEF:MODE>")
5277 (set_attr "athlon_decode" "double,direct")
5278 (set_attr "amdfam10_decode" "vector,double")
5279 (set_attr "fp_int_src" "true")])
5281 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5282 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5284 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5285 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5286 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5287 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5288 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5289 [(set_attr "type" "sseicvt")
5290 (set_attr "prefix" "maybe_vex")
5291 (set_attr "mode" "<MODEF:MODE>")
5292 (set (attr "prefix_rex")
5294 (and (eq_attr "prefix" "maybe_vex")
5295 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5297 (const_string "*")))
5298 (set_attr "athlon_decode" "double,direct")
5299 (set_attr "amdfam10_decode" "vector,double")
5300 (set_attr "fp_int_src" "true")])
5303 [(set (match_operand:MODEF 0 "register_operand" "")
5304 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5305 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
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))
5310 && (SSE_REG_P (operands[0])
5311 || (GET_CODE (operands[0]) == SUBREG
5312 && SSE_REG_P (operands[0])))"
5313 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5315 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5316 [(set (match_operand:MODEF 0 "register_operand" "=x")
5318 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5319 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5320 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5321 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5322 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5323 [(set_attr "type" "sseicvt")
5324 (set_attr "prefix" "maybe_vex")
5325 (set_attr "mode" "<MODEF:MODE>")
5326 (set (attr "prefix_rex")
5328 (and (eq_attr "prefix" "maybe_vex")
5329 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5331 (const_string "*")))
5332 (set_attr "athlon_decode" "direct")
5333 (set_attr "amdfam10_decode" "double")
5334 (set_attr "fp_int_src" "true")])
5337 [(set (match_operand:MODEF 0 "register_operand" "")
5338 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5339 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5340 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5341 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5342 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5344 && (SSE_REG_P (operands[0])
5345 || (GET_CODE (operands[0]) == SUBREG
5346 && SSE_REG_P (operands[0])))"
5347 [(set (match_dup 2) (match_dup 1))
5348 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5351 [(set (match_operand:MODEF 0 "register_operand" "")
5352 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5353 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5354 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5355 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5357 && (SSE_REG_P (operands[0])
5358 || (GET_CODE (operands[0]) == SUBREG
5359 && SSE_REG_P (operands[0])))"
5360 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5362 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5363 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5365 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5366 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5368 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5372 [(set_attr "type" "fmov,multi")
5373 (set_attr "mode" "<X87MODEF:MODE>")
5374 (set_attr "unit" "*,i387")
5375 (set_attr "fp_int_src" "true")])
5377 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5378 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5380 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5382 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5384 [(set_attr "type" "fmov")
5385 (set_attr "mode" "<X87MODEF:MODE>")
5386 (set_attr "fp_int_src" "true")])
5389 [(set (match_operand:X87MODEF 0 "register_operand" "")
5390 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5391 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5393 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5395 && FP_REG_P (operands[0])"
5396 [(set (match_dup 2) (match_dup 1))
5397 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5400 [(set (match_operand:X87MODEF 0 "register_operand" "")
5401 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5402 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5404 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5406 && FP_REG_P (operands[0])"
5407 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5409 ;; Avoid store forwarding (partial memory) stall penalty
5410 ;; by passing DImode value through XMM registers. */
5412 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5413 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5415 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5416 (clobber (match_scratch:V4SI 3 "=X,x"))
5417 (clobber (match_scratch:V4SI 4 "=X,x"))
5418 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5419 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5420 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5421 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5423 [(set_attr "type" "multi")
5424 (set_attr "mode" "<X87MODEF:MODE>")
5425 (set_attr "unit" "i387")
5426 (set_attr "fp_int_src" "true")])
5429 [(set (match_operand:X87MODEF 0 "register_operand" "")
5430 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5431 (clobber (match_scratch:V4SI 3 ""))
5432 (clobber (match_scratch:V4SI 4 ""))
5433 (clobber (match_operand:DI 2 "memory_operand" ""))]
5434 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5435 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5436 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5438 && FP_REG_P (operands[0])"
5439 [(set (match_dup 2) (match_dup 3))
5440 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5442 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5443 Assemble the 64-bit DImode value in an xmm register. */
5444 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5445 gen_rtx_SUBREG (SImode, operands[1], 0)));
5446 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5447 gen_rtx_SUBREG (SImode, operands[1], 4)));
5448 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5451 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5455 [(set (match_operand:X87MODEF 0 "register_operand" "")
5456 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5457 (clobber (match_scratch:V4SI 3 ""))
5458 (clobber (match_scratch:V4SI 4 ""))
5459 (clobber (match_operand:DI 2 "memory_operand" ""))]
5460 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5461 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5462 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5464 && FP_REG_P (operands[0])"
5465 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5467 ;; Avoid store forwarding (partial memory) stall penalty by extending
5468 ;; SImode value to DImode through XMM register instead of pushing two
5469 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5470 ;; targets benefit from this optimization. Also note that fild
5471 ;; loads from memory only.
5473 (define_insn "*floatunssi<mode>2_1"
5474 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5475 (unsigned_float:X87MODEF
5476 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5477 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5478 (clobber (match_scratch:SI 3 "=X,x"))]
5480 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5483 [(set_attr "type" "multi")
5484 (set_attr "mode" "<MODE>")])
5487 [(set (match_operand:X87MODEF 0 "register_operand" "")
5488 (unsigned_float:X87MODEF
5489 (match_operand:SI 1 "register_operand" "")))
5490 (clobber (match_operand:DI 2 "memory_operand" ""))
5491 (clobber (match_scratch:SI 3 ""))]
5493 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5495 && reload_completed"
5496 [(set (match_dup 2) (match_dup 1))
5498 (float:X87MODEF (match_dup 2)))]
5499 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5502 [(set (match_operand:X87MODEF 0 "register_operand" "")
5503 (unsigned_float:X87MODEF
5504 (match_operand:SI 1 "memory_operand" "")))
5505 (clobber (match_operand:DI 2 "memory_operand" ""))
5506 (clobber (match_scratch:SI 3 ""))]
5508 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5510 && reload_completed"
5511 [(set (match_dup 2) (match_dup 3))
5513 (float:X87MODEF (match_dup 2)))]
5515 emit_move_insn (operands[3], operands[1]);
5516 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5519 (define_expand "floatunssi<mode>2"
5521 [(set (match_operand:X87MODEF 0 "register_operand" "")
5522 (unsigned_float:X87MODEF
5523 (match_operand:SI 1 "nonimmediate_operand" "")))
5524 (clobber (match_dup 2))
5525 (clobber (match_scratch:SI 3 ""))])]
5527 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5529 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5531 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5533 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5538 enum ix86_stack_slot slot = (virtuals_instantiated
5541 operands[2] = assign_386_stack_local (DImode, slot);
5545 (define_expand "floatunsdisf2"
5546 [(use (match_operand:SF 0 "register_operand" ""))
5547 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5548 "TARGET_64BIT && TARGET_SSE_MATH"
5549 "x86_emit_floatuns (operands); DONE;")
5551 (define_expand "floatunsdidf2"
5552 [(use (match_operand:DF 0 "register_operand" ""))
5553 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5554 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5555 && TARGET_SSE2 && TARGET_SSE_MATH"
5558 x86_emit_floatuns (operands);
5560 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5566 (define_expand "add<mode>3"
5567 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5568 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5569 (match_operand:SDWIM 2 "<general_operand>" "")))]
5571 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5573 (define_insn_and_split "*add<dwi>3_doubleword"
5574 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5576 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5577 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5578 (clobber (reg:CC FLAGS_REG))]
5579 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5582 [(parallel [(set (reg:CC FLAGS_REG)
5583 (unspec:CC [(match_dup 1) (match_dup 2)]
5586 (plus:DWIH (match_dup 1) (match_dup 2)))])
5587 (parallel [(set (match_dup 3)
5591 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5593 (clobber (reg:CC FLAGS_REG))])]
5594 "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
5596 (define_insn "*add<mode>3_cc"
5597 [(set (reg:CC FLAGS_REG)
5599 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5600 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5602 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5603 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5604 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5605 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5606 [(set_attr "type" "alu")
5607 (set_attr "mode" "<MODE>")])
5609 (define_insn "addqi3_cc"
5610 [(set (reg:CC FLAGS_REG)
5612 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5613 (match_operand:QI 2 "general_operand" "qn,qm")]
5615 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5616 (plus:QI (match_dup 1) (match_dup 2)))]
5617 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5618 "add{b}\t{%2, %0|%0, %2}"
5619 [(set_attr "type" "alu")
5620 (set_attr "mode" "QI")])
5622 (define_insn "*lea_1"
5623 [(set (match_operand:P 0 "register_operand" "=r")
5624 (match_operand:P 1 "no_seg_address_operand" "p"))]
5626 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5627 [(set_attr "type" "lea")
5628 (set_attr "mode" "<MODE>")])
5630 (define_insn "*lea_2"
5631 [(set (match_operand:SI 0 "register_operand" "=r")
5632 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5634 "lea{l}\t{%a1, %0|%0, %a1}"
5635 [(set_attr "type" "lea")
5636 (set_attr "mode" "SI")])
5638 (define_insn "*lea_2_zext"
5639 [(set (match_operand:DI 0 "register_operand" "=r")
5641 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5643 "lea{l}\t{%a1, %k0|%k0, %a1}"
5644 [(set_attr "type" "lea")
5645 (set_attr "mode" "SI")])
5647 (define_insn "*add<mode>_1"
5648 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5650 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5651 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5652 (clobber (reg:CC FLAGS_REG))]
5653 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5655 switch (get_attr_type (insn))
5661 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5662 if (operands[2] == const1_rtx)
5663 return "inc{<imodesuffix>}\t%0";
5666 gcc_assert (operands[2] == constm1_rtx);
5667 return "dec{<imodesuffix>}\t%0";
5671 /* For most processors, ADD is faster than LEA. This alternative
5672 was added to use ADD as much as possible. */
5673 if (which_alternative == 2)
5676 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5679 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5680 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5681 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5683 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5687 (cond [(eq_attr "alternative" "3")
5688 (const_string "lea")
5689 (match_operand:SWI48 2 "incdec_operand" "")
5690 (const_string "incdec")
5692 (const_string "alu")))
5693 (set (attr "length_immediate")
5695 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5697 (const_string "*")))
5698 (set_attr "mode" "<MODE>")])
5700 ;; It may seem that nonimmediate operand is proper one for operand 1.
5701 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5702 ;; we take care in ix86_binary_operator_ok to not allow two memory
5703 ;; operands so proper swapping will be done in reload. This allow
5704 ;; patterns constructed from addsi_1 to match.
5706 (define_insn "*addsi_1_zext"
5707 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5709 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5710 (match_operand:SI 2 "general_operand" "g,0,li"))))
5711 (clobber (reg:CC FLAGS_REG))]
5712 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5714 switch (get_attr_type (insn))
5720 if (operands[2] == const1_rtx)
5721 return "inc{l}\t%k0";
5724 gcc_assert (operands[2] == constm1_rtx);
5725 return "dec{l}\t%k0";
5729 /* For most processors, ADD is faster than LEA. This alternative
5730 was added to use ADD as much as possible. */
5731 if (which_alternative == 1)
5734 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5737 if (x86_maybe_negate_const_int (&operands[2], SImode))
5738 return "sub{l}\t{%2, %k0|%k0, %2}";
5740 return "add{l}\t{%2, %k0|%k0, %2}";
5744 (cond [(eq_attr "alternative" "2")
5745 (const_string "lea")
5746 (match_operand:SI 2 "incdec_operand" "")
5747 (const_string "incdec")
5749 (const_string "alu")))
5750 (set (attr "length_immediate")
5752 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5754 (const_string "*")))
5755 (set_attr "mode" "SI")])
5757 (define_insn "*addhi_1"
5758 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5759 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5760 (match_operand:HI 2 "general_operand" "rn,rm")))
5761 (clobber (reg:CC FLAGS_REG))]
5762 "TARGET_PARTIAL_REG_STALL
5763 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5765 switch (get_attr_type (insn))
5768 if (operands[2] == const1_rtx)
5769 return "inc{w}\t%0";
5772 gcc_assert (operands[2] == constm1_rtx);
5773 return "dec{w}\t%0";
5777 if (x86_maybe_negate_const_int (&operands[2], HImode))
5778 return "sub{w}\t{%2, %0|%0, %2}";
5780 return "add{w}\t{%2, %0|%0, %2}";
5784 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5785 (const_string "incdec")
5786 (const_string "alu")))
5787 (set (attr "length_immediate")
5789 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5791 (const_string "*")))
5792 (set_attr "mode" "HI")])
5794 (define_insn "*addhi_1_lea"
5795 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r")
5796 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r")
5797 (match_operand:HI 2 "general_operand" "rmn,rn,0,ln")))
5798 (clobber (reg:CC FLAGS_REG))]
5799 "!TARGET_PARTIAL_REG_STALL
5800 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5802 switch (get_attr_type (insn))
5808 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5809 if (operands[2] == const1_rtx)
5810 return "inc{w}\t%0";
5813 gcc_assert (operands[2] == constm1_rtx);
5814 return "dec{w}\t%0";
5818 /* For most processors, ADD is faster than LEA. This alternative
5819 was added to use ADD as much as possible. */
5820 if (which_alternative == 2)
5823 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5826 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5827 if (x86_maybe_negate_const_int (&operands[2], HImode))
5828 return "sub{w}\t{%2, %0|%0, %2}";
5830 return "add{w}\t{%2, %0|%0, %2}";
5834 (cond [(eq_attr "alternative" "3")
5835 (const_string "lea")
5836 (match_operand:HI 2 "incdec_operand" "")
5837 (const_string "incdec")
5839 (const_string "alu")))
5840 (set (attr "length_immediate")
5842 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5844 (const_string "*")))
5845 (set_attr "mode" "HI,HI,HI,SI")])
5847 ;; %%% Potential partial reg stall on alternative 2. What to do?
5848 (define_insn "*addqi_1"
5849 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5850 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5851 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5852 (clobber (reg:CC FLAGS_REG))]
5853 "TARGET_PARTIAL_REG_STALL
5854 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5856 int widen = (which_alternative == 2);
5857 switch (get_attr_type (insn))
5860 if (operands[2] == const1_rtx)
5861 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5864 gcc_assert (operands[2] == constm1_rtx);
5865 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5869 if (x86_maybe_negate_const_int (&operands[2], QImode))
5872 return "sub{l}\t{%2, %k0|%k0, %2}";
5874 return "sub{b}\t{%2, %0|%0, %2}";
5877 return "add{l}\t{%k2, %k0|%k0, %k2}";
5879 return "add{b}\t{%2, %0|%0, %2}";
5883 (if_then_else (match_operand:QI 2 "incdec_operand" "")
5884 (const_string "incdec")
5885 (const_string "alu")))
5886 (set (attr "length_immediate")
5888 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5890 (const_string "*")))
5891 (set_attr "mode" "QI,QI,SI")])
5893 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5894 (define_insn "*addqi_1_lea"
5895 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r")
5896 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r")
5897 (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln")))
5898 (clobber (reg:CC FLAGS_REG))]
5899 "!TARGET_PARTIAL_REG_STALL
5900 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5902 int widen = (which_alternative == 3 || which_alternative == 4);
5904 switch (get_attr_type (insn))
5910 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5911 if (operands[2] == const1_rtx)
5912 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5915 gcc_assert (operands[2] == constm1_rtx);
5916 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5920 /* For most processors, ADD is faster than LEA. These alternatives
5921 were added to use ADD as much as possible. */
5922 if (which_alternative == 2 || which_alternative == 4)
5925 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5928 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5929 if (x86_maybe_negate_const_int (&operands[2], QImode))
5932 return "sub{l}\t{%2, %k0|%k0, %2}";
5934 return "sub{b}\t{%2, %0|%0, %2}";
5937 return "add{l}\t{%k2, %k0|%k0, %k2}";
5939 return "add{b}\t{%2, %0|%0, %2}";
5943 (cond [(eq_attr "alternative" "5")
5944 (const_string "lea")
5945 (match_operand:QI 2 "incdec_operand" "")
5946 (const_string "incdec")
5948 (const_string "alu")))
5949 (set (attr "length_immediate")
5951 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5953 (const_string "*")))
5954 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5956 (define_insn "*addqi_1_slp"
5957 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5958 (plus:QI (match_dup 0)
5959 (match_operand:QI 1 "general_operand" "qn,qnm")))
5960 (clobber (reg:CC FLAGS_REG))]
5961 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5962 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5964 switch (get_attr_type (insn))
5967 if (operands[1] == const1_rtx)
5968 return "inc{b}\t%0";
5971 gcc_assert (operands[1] == constm1_rtx);
5972 return "dec{b}\t%0";
5976 if (x86_maybe_negate_const_int (&operands[1], QImode))
5977 return "sub{b}\t{%1, %0|%0, %1}";
5979 return "add{b}\t{%1, %0|%0, %1}";
5983 (if_then_else (match_operand:QI 1 "incdec_operand" "")
5984 (const_string "incdec")
5985 (const_string "alu1")))
5986 (set (attr "memory")
5987 (if_then_else (match_operand 1 "memory_operand" "")
5988 (const_string "load")
5989 (const_string "none")))
5990 (set_attr "mode" "QI")])
5992 ;; Convert lea to the lea pattern to avoid flags dependency.
5994 [(set (match_operand 0 "register_operand" "")
5995 (plus (match_operand 1 "register_operand" "")
5996 (match_operand 2 "nonmemory_operand" "")))
5997 (clobber (reg:CC FLAGS_REG))]
5998 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
6002 enum machine_mode mode = GET_MODE (operands[0]);
6004 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6005 may confuse gen_lowpart. */
6008 operands[1] = gen_lowpart (Pmode, operands[1]);
6009 operands[2] = gen_lowpart (Pmode, operands[2]);
6012 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6014 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6015 operands[0] = gen_lowpart (SImode, operands[0]);
6017 if (TARGET_64BIT && mode != Pmode)
6018 pat = gen_rtx_SUBREG (SImode, pat, 0);
6020 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6024 ;; Convert lea to the lea pattern to avoid flags dependency.
6025 ;; ??? This pattern handles immediate operands that do not satisfy immediate
6026 ;; operand predicate (LEGITIMATE_CONSTANT_P) in the previous pattern.
6028 [(set (match_operand:DI 0 "register_operand" "")
6029 (plus:DI (match_operand:DI 1 "register_operand" "")
6030 (match_operand:DI 2 "x86_64_immediate_operand" "")))
6031 (clobber (reg:CC FLAGS_REG))]
6032 "TARGET_64BIT && reload_completed
6033 && true_regnum (operands[0]) != true_regnum (operands[1])"
6035 (plus:DI (match_dup 1) (match_dup 2)))])
6037 ;; Convert lea to the lea pattern to avoid flags dependency.
6039 [(set (match_operand:DI 0 "register_operand" "")
6041 (plus:SI (match_operand:SI 1 "register_operand" "")
6042 (match_operand:SI 2 "nonmemory_operand" ""))))
6043 (clobber (reg:CC FLAGS_REG))]
6044 "TARGET_64BIT && reload_completed
6045 && ix86_lea_for_add_ok (insn, operands)"
6047 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6049 operands[1] = gen_lowpart (DImode, operands[1]);
6050 operands[2] = gen_lowpart (DImode, operands[2]);
6053 (define_insn "*add<mode>_2"
6054 [(set (reg FLAGS_REG)
6057 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6058 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
6060 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6061 (plus:SWI (match_dup 1) (match_dup 2)))]
6062 "ix86_match_ccmode (insn, CCGOCmode)
6063 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6065 switch (get_attr_type (insn))
6068 if (operands[2] == const1_rtx)
6069 return "inc{<imodesuffix>}\t%0";
6072 gcc_assert (operands[2] == constm1_rtx);
6073 return "dec{<imodesuffix>}\t%0";
6077 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6078 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6080 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6084 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6085 (const_string "incdec")
6086 (const_string "alu")))
6087 (set (attr "length_immediate")
6089 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6091 (const_string "*")))
6092 (set_attr "mode" "<MODE>")])
6094 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6095 (define_insn "*addsi_2_zext"
6096 [(set (reg FLAGS_REG)
6098 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6099 (match_operand:SI 2 "general_operand" "g"))
6101 (set (match_operand:DI 0 "register_operand" "=r")
6102 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6103 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6104 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6106 switch (get_attr_type (insn))
6109 if (operands[2] == const1_rtx)
6110 return "inc{l}\t%k0";
6113 gcc_assert (operands[2] == constm1_rtx);
6114 return "dec{l}\t%k0";
6118 if (x86_maybe_negate_const_int (&operands[2], SImode))
6119 return "sub{l}\t{%2, %k0|%k0, %2}";
6121 return "add{l}\t{%2, %k0|%k0, %2}";
6125 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6126 (const_string "incdec")
6127 (const_string "alu")))
6128 (set (attr "length_immediate")
6130 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6132 (const_string "*")))
6133 (set_attr "mode" "SI")])
6135 (define_insn "*add<mode>_3"
6136 [(set (reg FLAGS_REG)
6138 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
6139 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
6140 (clobber (match_scratch:SWI 0 "=<r>"))]
6141 "ix86_match_ccmode (insn, CCZmode)
6142 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6144 switch (get_attr_type (insn))
6147 if (operands[2] == const1_rtx)
6148 return "inc{<imodesuffix>}\t%0";
6151 gcc_assert (operands[2] == constm1_rtx);
6152 return "dec{<imodesuffix>}\t%0";
6156 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6157 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6159 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6163 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6164 (const_string "incdec")
6165 (const_string "alu")))
6166 (set (attr "length_immediate")
6168 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6170 (const_string "*")))
6171 (set_attr "mode" "<MODE>")])
6173 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6174 (define_insn "*addsi_3_zext"
6175 [(set (reg FLAGS_REG)
6177 (neg:SI (match_operand:SI 2 "general_operand" "g"))
6178 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6179 (set (match_operand:DI 0 "register_operand" "=r")
6180 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6181 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6182 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6184 switch (get_attr_type (insn))
6187 if (operands[2] == const1_rtx)
6188 return "inc{l}\t%k0";
6191 gcc_assert (operands[2] == constm1_rtx);
6192 return "dec{l}\t%k0";
6196 if (x86_maybe_negate_const_int (&operands[2], SImode))
6197 return "sub{l}\t{%2, %k0|%k0, %2}";
6199 return "add{l}\t{%2, %k0|%k0, %2}";
6203 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6204 (const_string "incdec")
6205 (const_string "alu")))
6206 (set (attr "length_immediate")
6208 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6210 (const_string "*")))
6211 (set_attr "mode" "SI")])
6213 ; For comparisons against 1, -1 and 128, we may generate better code
6214 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6215 ; is matched then. We can't accept general immediate, because for
6216 ; case of overflows, the result is messed up.
6217 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6218 ; only for comparisons not depending on it.
6220 (define_insn "*adddi_4"
6221 [(set (reg FLAGS_REG)
6223 (match_operand:DI 1 "nonimmediate_operand" "0")
6224 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6225 (clobber (match_scratch:DI 0 "=rm"))]
6227 && ix86_match_ccmode (insn, CCGCmode)"
6229 switch (get_attr_type (insn))
6232 if (operands[2] == constm1_rtx)
6233 return "inc{q}\t%0";
6236 gcc_assert (operands[2] == const1_rtx);
6237 return "dec{q}\t%0";
6241 if (x86_maybe_negate_const_int (&operands[2], DImode))
6242 return "add{q}\t{%2, %0|%0, %2}";
6244 return "sub{q}\t{%2, %0|%0, %2}";
6248 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6249 (const_string "incdec")
6250 (const_string "alu")))
6251 (set (attr "length_immediate")
6253 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6255 (const_string "*")))
6256 (set_attr "mode" "DI")])
6258 ; For comparisons against 1, -1 and 128, we may generate better code
6259 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6260 ; is matched then. We can't accept general immediate, because for
6261 ; case of overflows, the result is messed up.
6262 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6263 ; only for comparisons not depending on it.
6265 (define_insn "*add<mode>_4"
6266 [(set (reg FLAGS_REG)
6268 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6269 (match_operand:SWI124 2 "const_int_operand" "n")))
6270 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6271 "ix86_match_ccmode (insn, CCGCmode)"
6273 switch (get_attr_type (insn))
6276 if (operands[2] == constm1_rtx)
6277 return "inc{<imodesuffix>}\t%0";
6280 gcc_assert (operands[2] == const1_rtx);
6281 return "dec{<imodesuffix>}\t%0";
6285 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6286 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6288 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6292 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6293 (const_string "incdec")
6294 (const_string "alu")))
6295 (set (attr "length_immediate")
6297 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6299 (const_string "*")))
6300 (set_attr "mode" "<MODE>")])
6302 (define_insn "*add<mode>_5"
6303 [(set (reg FLAGS_REG)
6306 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6307 (match_operand:SWI 2 "<general_operand>" "<g>"))
6309 (clobber (match_scratch:SWI 0 "=<r>"))]
6310 "ix86_match_ccmode (insn, CCGOCmode)
6311 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6313 switch (get_attr_type (insn))
6316 if (operands[2] == const1_rtx)
6317 return "inc{<imodesuffix>}\t%0";
6320 gcc_assert (operands[2] == constm1_rtx);
6321 return "dec{<imodesuffix>}\t%0";
6325 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6326 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6328 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6332 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6333 (const_string "incdec")
6334 (const_string "alu")))
6335 (set (attr "length_immediate")
6337 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6339 (const_string "*")))
6340 (set_attr "mode" "<MODE>")])
6342 (define_insn "*addqi_ext_1_rex64"
6343 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6348 (match_operand 1 "ext_register_operand" "0")
6351 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6352 (clobber (reg:CC FLAGS_REG))]
6355 switch (get_attr_type (insn))
6358 if (operands[2] == const1_rtx)
6359 return "inc{b}\t%h0";
6362 gcc_assert (operands[2] == constm1_rtx);
6363 return "dec{b}\t%h0";
6367 return "add{b}\t{%2, %h0|%h0, %2}";
6371 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6372 (const_string "incdec")
6373 (const_string "alu")))
6374 (set_attr "modrm" "1")
6375 (set_attr "mode" "QI")])
6377 (define_insn "addqi_ext_1"
6378 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6383 (match_operand 1 "ext_register_operand" "0")
6386 (match_operand:QI 2 "general_operand" "Qmn")))
6387 (clobber (reg:CC FLAGS_REG))]
6390 switch (get_attr_type (insn))
6393 if (operands[2] == const1_rtx)
6394 return "inc{b}\t%h0";
6397 gcc_assert (operands[2] == constm1_rtx);
6398 return "dec{b}\t%h0";
6402 return "add{b}\t{%2, %h0|%h0, %2}";
6406 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6407 (const_string "incdec")
6408 (const_string "alu")))
6409 (set_attr "modrm" "1")
6410 (set_attr "mode" "QI")])
6412 (define_insn "*addqi_ext_2"
6413 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6418 (match_operand 1 "ext_register_operand" "%0")
6422 (match_operand 2 "ext_register_operand" "Q")
6425 (clobber (reg:CC FLAGS_REG))]
6427 "add{b}\t{%h2, %h0|%h0, %h2}"
6428 [(set_attr "type" "alu")
6429 (set_attr "mode" "QI")])
6431 ;; The lea patterns for non-Pmodes needs to be matched by
6432 ;; several insns converted to real lea by splitters.
6434 (define_insn_and_split "*lea_general_1"
6435 [(set (match_operand 0 "register_operand" "=r")
6436 (plus (plus (match_operand 1 "index_register_operand" "l")
6437 (match_operand 2 "register_operand" "r"))
6438 (match_operand 3 "immediate_operand" "i")))]
6439 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6440 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6441 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6442 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6443 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6444 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6445 || GET_MODE (operands[3]) == VOIDmode)"
6447 "&& reload_completed"
6451 operands[0] = gen_lowpart (SImode, operands[0]);
6452 operands[1] = gen_lowpart (Pmode, operands[1]);
6453 operands[2] = gen_lowpart (Pmode, operands[2]);
6454 operands[3] = gen_lowpart (Pmode, operands[3]);
6455 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6457 if (Pmode != SImode)
6458 pat = gen_rtx_SUBREG (SImode, pat, 0);
6459 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6462 [(set_attr "type" "lea")
6463 (set_attr "mode" "SI")])
6465 (define_insn_and_split "*lea_general_1_zext"
6466 [(set (match_operand:DI 0 "register_operand" "=r")
6469 (match_operand:SI 1 "index_register_operand" "l")
6470 (match_operand:SI 2 "register_operand" "r"))
6471 (match_operand:SI 3 "immediate_operand" "i"))))]
6474 "&& reload_completed"
6476 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6478 (match_dup 3)) 0)))]
6480 operands[1] = gen_lowpart (Pmode, operands[1]);
6481 operands[2] = gen_lowpart (Pmode, operands[2]);
6482 operands[3] = gen_lowpart (Pmode, operands[3]);
6484 [(set_attr "type" "lea")
6485 (set_attr "mode" "SI")])
6487 (define_insn_and_split "*lea_general_2"
6488 [(set (match_operand 0 "register_operand" "=r")
6489 (plus (mult (match_operand 1 "index_register_operand" "l")
6490 (match_operand 2 "const248_operand" "i"))
6491 (match_operand 3 "nonmemory_operand" "ri")))]
6492 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6493 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6494 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6495 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6496 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6497 || GET_MODE (operands[3]) == VOIDmode)"
6499 "&& reload_completed"
6503 operands[0] = gen_lowpart (SImode, operands[0]);
6504 operands[1] = gen_lowpart (Pmode, operands[1]);
6505 operands[3] = gen_lowpart (Pmode, operands[3]);
6506 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6508 if (Pmode != SImode)
6509 pat = gen_rtx_SUBREG (SImode, pat, 0);
6510 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6513 [(set_attr "type" "lea")
6514 (set_attr "mode" "SI")])
6516 (define_insn_and_split "*lea_general_2_zext"
6517 [(set (match_operand:DI 0 "register_operand" "=r")
6520 (match_operand:SI 1 "index_register_operand" "l")
6521 (match_operand:SI 2 "const248_operand" "n"))
6522 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6525 "&& reload_completed"
6527 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6529 (match_dup 3)) 0)))]
6531 operands[1] = gen_lowpart (Pmode, operands[1]);
6532 operands[3] = gen_lowpart (Pmode, operands[3]);
6534 [(set_attr "type" "lea")
6535 (set_attr "mode" "SI")])
6537 (define_insn_and_split "*lea_general_3"
6538 [(set (match_operand 0 "register_operand" "=r")
6539 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6540 (match_operand 2 "const248_operand" "i"))
6541 (match_operand 3 "register_operand" "r"))
6542 (match_operand 4 "immediate_operand" "i")))]
6543 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6544 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6545 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6546 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6547 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6549 "&& reload_completed"
6553 operands[0] = gen_lowpart (SImode, operands[0]);
6554 operands[1] = gen_lowpart (Pmode, operands[1]);
6555 operands[3] = gen_lowpart (Pmode, operands[3]);
6556 operands[4] = gen_lowpart (Pmode, operands[4]);
6557 pat = gen_rtx_PLUS (Pmode,
6558 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6562 if (Pmode != SImode)
6563 pat = gen_rtx_SUBREG (SImode, pat, 0);
6564 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6567 [(set_attr "type" "lea")
6568 (set_attr "mode" "SI")])
6570 (define_insn_and_split "*lea_general_3_zext"
6571 [(set (match_operand:DI 0 "register_operand" "=r")
6575 (match_operand:SI 1 "index_register_operand" "l")
6576 (match_operand:SI 2 "const248_operand" "n"))
6577 (match_operand:SI 3 "register_operand" "r"))
6578 (match_operand:SI 4 "immediate_operand" "i"))))]
6581 "&& reload_completed"
6583 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6586 (match_dup 4)) 0)))]
6588 operands[1] = gen_lowpart (Pmode, operands[1]);
6589 operands[3] = gen_lowpart (Pmode, operands[3]);
6590 operands[4] = gen_lowpart (Pmode, operands[4]);
6592 [(set_attr "type" "lea")
6593 (set_attr "mode" "SI")])
6595 ;; Subtract instructions
6597 (define_expand "sub<mode>3"
6598 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6599 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6600 (match_operand:SDWIM 2 "<general_operand>" "")))]
6602 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6604 (define_insn_and_split "*sub<dwi>3_doubleword"
6605 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6607 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6608 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6609 (clobber (reg:CC FLAGS_REG))]
6610 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6613 [(parallel [(set (reg:CC FLAGS_REG)
6614 (compare:CC (match_dup 1) (match_dup 2)))
6616 (minus:DWIH (match_dup 1) (match_dup 2)))])
6617 (parallel [(set (match_dup 3)
6621 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6623 (clobber (reg:CC FLAGS_REG))])]
6624 "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
6626 (define_insn "*sub<mode>_1"
6627 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6629 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6630 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6631 (clobber (reg:CC FLAGS_REG))]
6632 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6633 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6634 [(set_attr "type" "alu")
6635 (set_attr "mode" "<MODE>")])
6637 (define_insn "*subsi_1_zext"
6638 [(set (match_operand:DI 0 "register_operand" "=r")
6640 (minus:SI (match_operand:SI 1 "register_operand" "0")
6641 (match_operand:SI 2 "general_operand" "g"))))
6642 (clobber (reg:CC FLAGS_REG))]
6643 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6644 "sub{l}\t{%2, %k0|%k0, %2}"
6645 [(set_attr "type" "alu")
6646 (set_attr "mode" "SI")])
6648 (define_insn "*subqi_1_slp"
6649 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6650 (minus:QI (match_dup 0)
6651 (match_operand:QI 1 "general_operand" "qn,qm")))
6652 (clobber (reg:CC FLAGS_REG))]
6653 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6654 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6655 "sub{b}\t{%1, %0|%0, %1}"
6656 [(set_attr "type" "alu1")
6657 (set_attr "mode" "QI")])
6659 (define_insn "*sub<mode>_2"
6660 [(set (reg FLAGS_REG)
6663 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6664 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6666 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6667 (minus:SWI (match_dup 1) (match_dup 2)))]
6668 "ix86_match_ccmode (insn, CCGOCmode)
6669 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6670 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6671 [(set_attr "type" "alu")
6672 (set_attr "mode" "<MODE>")])
6674 (define_insn "*subsi_2_zext"
6675 [(set (reg FLAGS_REG)
6677 (minus:SI (match_operand:SI 1 "register_operand" "0")
6678 (match_operand:SI 2 "general_operand" "g"))
6680 (set (match_operand:DI 0 "register_operand" "=r")
6682 (minus:SI (match_dup 1)
6684 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6685 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6686 "sub{l}\t{%2, %k0|%k0, %2}"
6687 [(set_attr "type" "alu")
6688 (set_attr "mode" "SI")])
6690 (define_insn "*sub<mode>_3"
6691 [(set (reg FLAGS_REG)
6692 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6693 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6694 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6695 (minus:SWI (match_dup 1) (match_dup 2)))]
6696 "ix86_match_ccmode (insn, CCmode)
6697 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6698 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6699 [(set_attr "type" "alu")
6700 (set_attr "mode" "<MODE>")])
6702 (define_insn "*subsi_3_zext"
6703 [(set (reg FLAGS_REG)
6704 (compare (match_operand:SI 1 "register_operand" "0")
6705 (match_operand:SI 2 "general_operand" "g")))
6706 (set (match_operand:DI 0 "register_operand" "=r")
6708 (minus:SI (match_dup 1)
6710 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6711 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6712 "sub{l}\t{%2, %1|%1, %2}"
6713 [(set_attr "type" "alu")
6714 (set_attr "mode" "SI")])
6716 ;; Add with carry and subtract with borrow
6718 (define_expand "<plusminus_insn><mode>3_carry"
6720 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6722 (match_operand:SWI 1 "nonimmediate_operand" "")
6723 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6724 [(match_operand 3 "flags_reg_operand" "")
6726 (match_operand:SWI 2 "<general_operand>" ""))))
6727 (clobber (reg:CC FLAGS_REG))])]
6728 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6731 (define_insn "*<plusminus_insn><mode>3_carry"
6732 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6734 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6736 (match_operator 3 "ix86_carry_flag_operator"
6737 [(reg FLAGS_REG) (const_int 0)])
6738 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6739 (clobber (reg:CC FLAGS_REG))]
6740 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6741 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6742 [(set_attr "type" "alu")
6743 (set_attr "use_carry" "1")
6744 (set_attr "pent_pair" "pu")
6745 (set_attr "mode" "<MODE>")])
6747 (define_insn "*addsi3_carry_zext"
6748 [(set (match_operand:DI 0 "register_operand" "=r")
6750 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6751 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6752 [(reg FLAGS_REG) (const_int 0)])
6753 (match_operand:SI 2 "general_operand" "g")))))
6754 (clobber (reg:CC FLAGS_REG))]
6755 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6756 "adc{l}\t{%2, %k0|%k0, %2}"
6757 [(set_attr "type" "alu")
6758 (set_attr "use_carry" "1")
6759 (set_attr "pent_pair" "pu")
6760 (set_attr "mode" "SI")])
6762 (define_insn "*subsi3_carry_zext"
6763 [(set (match_operand:DI 0 "register_operand" "=r")
6765 (minus:SI (match_operand:SI 1 "register_operand" "0")
6766 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6767 [(reg FLAGS_REG) (const_int 0)])
6768 (match_operand:SI 2 "general_operand" "g")))))
6769 (clobber (reg:CC FLAGS_REG))]
6770 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6771 "sbb{l}\t{%2, %k0|%k0, %2}"
6772 [(set_attr "type" "alu")
6773 (set_attr "pent_pair" "pu")
6774 (set_attr "mode" "SI")])
6776 ;; Overflow setting add and subtract instructions
6778 (define_insn "*add<mode>3_cconly_overflow"
6779 [(set (reg:CCC FLAGS_REG)
6782 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6783 (match_operand:SWI 2 "<general_operand>" "<g>"))
6785 (clobber (match_scratch:SWI 0 "=<r>"))]
6786 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6787 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6788 [(set_attr "type" "alu")
6789 (set_attr "mode" "<MODE>")])
6791 (define_insn "*sub<mode>3_cconly_overflow"
6792 [(set (reg:CCC FLAGS_REG)
6795 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6796 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6799 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6800 [(set_attr "type" "icmp")
6801 (set_attr "mode" "<MODE>")])
6803 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6804 [(set (reg:CCC FLAGS_REG)
6807 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6808 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6810 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6811 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6812 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6813 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6814 [(set_attr "type" "alu")
6815 (set_attr "mode" "<MODE>")])
6817 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6818 [(set (reg:CCC FLAGS_REG)
6821 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6822 (match_operand:SI 2 "general_operand" "g"))
6824 (set (match_operand:DI 0 "register_operand" "=r")
6825 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6826 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6827 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6828 [(set_attr "type" "alu")
6829 (set_attr "mode" "SI")])
6831 ;; The patterns that match these are at the end of this file.
6833 (define_expand "<plusminus_insn>xf3"
6834 [(set (match_operand:XF 0 "register_operand" "")
6836 (match_operand:XF 1 "register_operand" "")
6837 (match_operand:XF 2 "register_operand" "")))]
6841 (define_expand "<plusminus_insn><mode>3"
6842 [(set (match_operand:MODEF 0 "register_operand" "")
6844 (match_operand:MODEF 1 "register_operand" "")
6845 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6846 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6847 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
6850 ;; Multiply instructions
6852 (define_expand "mul<mode>3"
6853 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6855 (match_operand:SWIM248 1 "register_operand" "")
6856 (match_operand:SWIM248 2 "<general_operand>" "")))
6857 (clobber (reg:CC FLAGS_REG))])]
6861 (define_expand "mulqi3"
6862 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6864 (match_operand:QI 1 "register_operand" "")
6865 (match_operand:QI 2 "nonimmediate_operand" "")))
6866 (clobber (reg:CC FLAGS_REG))])]
6867 "TARGET_QIMODE_MATH"
6871 ;; IMUL reg32/64, reg32/64, imm8 Direct
6872 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6873 ;; IMUL reg32/64, reg32/64, imm32 Direct
6874 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6875 ;; IMUL reg32/64, reg32/64 Direct
6876 ;; IMUL reg32/64, mem32/64 Direct
6878 (define_insn "*mul<mode>3_1"
6879 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6881 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6882 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6883 (clobber (reg:CC FLAGS_REG))]
6884 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6886 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6887 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6888 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6889 [(set_attr "type" "imul")
6890 (set_attr "prefix_0f" "0,0,1")
6891 (set (attr "athlon_decode")
6892 (cond [(eq_attr "cpu" "athlon")
6893 (const_string "vector")
6894 (eq_attr "alternative" "1")
6895 (const_string "vector")
6896 (and (eq_attr "alternative" "2")
6897 (match_operand 1 "memory_operand" ""))
6898 (const_string "vector")]
6899 (const_string "direct")))
6900 (set (attr "amdfam10_decode")
6901 (cond [(and (eq_attr "alternative" "0,1")
6902 (match_operand 1 "memory_operand" ""))
6903 (const_string "vector")]
6904 (const_string "direct")))
6905 (set_attr "mode" "<MODE>")])
6907 (define_insn "*mulsi3_1_zext"
6908 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6910 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6911 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6912 (clobber (reg:CC FLAGS_REG))]
6914 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6916 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6917 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6918 imul{l}\t{%2, %k0|%k0, %2}"
6919 [(set_attr "type" "imul")
6920 (set_attr "prefix_0f" "0,0,1")
6921 (set (attr "athlon_decode")
6922 (cond [(eq_attr "cpu" "athlon")
6923 (const_string "vector")
6924 (eq_attr "alternative" "1")
6925 (const_string "vector")
6926 (and (eq_attr "alternative" "2")
6927 (match_operand 1 "memory_operand" ""))
6928 (const_string "vector")]
6929 (const_string "direct")))
6930 (set (attr "amdfam10_decode")
6931 (cond [(and (eq_attr "alternative" "0,1")
6932 (match_operand 1 "memory_operand" ""))
6933 (const_string "vector")]
6934 (const_string "direct")))
6935 (set_attr "mode" "SI")])
6938 ;; IMUL reg16, reg16, imm8 VectorPath
6939 ;; IMUL reg16, mem16, imm8 VectorPath
6940 ;; IMUL reg16, reg16, imm16 VectorPath
6941 ;; IMUL reg16, mem16, imm16 VectorPath
6942 ;; IMUL reg16, reg16 Direct
6943 ;; IMUL reg16, mem16 Direct
6945 (define_insn "*mulhi3_1"
6946 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6947 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6948 (match_operand:HI 2 "general_operand" "K,n,mr")))
6949 (clobber (reg:CC FLAGS_REG))]
6951 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6953 imul{w}\t{%2, %1, %0|%0, %1, %2}
6954 imul{w}\t{%2, %1, %0|%0, %1, %2}
6955 imul{w}\t{%2, %0|%0, %2}"
6956 [(set_attr "type" "imul")
6957 (set_attr "prefix_0f" "0,0,1")
6958 (set (attr "athlon_decode")
6959 (cond [(eq_attr "cpu" "athlon")
6960 (const_string "vector")
6961 (eq_attr "alternative" "1,2")
6962 (const_string "vector")]
6963 (const_string "direct")))
6964 (set (attr "amdfam10_decode")
6965 (cond [(eq_attr "alternative" "0,1")
6966 (const_string "vector")]
6967 (const_string "direct")))
6968 (set_attr "mode" "HI")])
6974 (define_insn "*mulqi3_1"
6975 [(set (match_operand:QI 0 "register_operand" "=a")
6976 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6977 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6978 (clobber (reg:CC FLAGS_REG))]
6980 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6982 [(set_attr "type" "imul")
6983 (set_attr "length_immediate" "0")
6984 (set (attr "athlon_decode")
6985 (if_then_else (eq_attr "cpu" "athlon")
6986 (const_string "vector")
6987 (const_string "direct")))
6988 (set_attr "amdfam10_decode" "direct")
6989 (set_attr "mode" "QI")])
6991 (define_expand "<u>mul<mode><dwi>3"
6992 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6995 (match_operand:DWIH 1 "nonimmediate_operand" ""))
6997 (match_operand:DWIH 2 "register_operand" ""))))
6998 (clobber (reg:CC FLAGS_REG))])]
7002 (define_expand "<u>mulqihi3"
7003 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7006 (match_operand:QI 1 "nonimmediate_operand" ""))
7008 (match_operand:QI 2 "register_operand" ""))))
7009 (clobber (reg:CC FLAGS_REG))])]
7010 "TARGET_QIMODE_MATH"
7013 (define_insn "*<u>mul<mode><dwi>3_1"
7014 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7017 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7019 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7020 (clobber (reg:CC FLAGS_REG))]
7021 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7022 "<sgnprefix>mul{<imodesuffix>}\t%2"
7023 [(set_attr "type" "imul")
7024 (set_attr "length_immediate" "0")
7025 (set (attr "athlon_decode")
7026 (if_then_else (eq_attr "cpu" "athlon")
7027 (const_string "vector")
7028 (const_string "double")))
7029 (set_attr "amdfam10_decode" "double")
7030 (set_attr "mode" "<MODE>")])
7032 (define_insn "*<u>mulqihi3_1"
7033 [(set (match_operand:HI 0 "register_operand" "=a")
7036 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7038 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7039 (clobber (reg:CC FLAGS_REG))]
7041 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7042 "<sgnprefix>mul{b}\t%2"
7043 [(set_attr "type" "imul")
7044 (set_attr "length_immediate" "0")
7045 (set (attr "athlon_decode")
7046 (if_then_else (eq_attr "cpu" "athlon")
7047 (const_string "vector")
7048 (const_string "direct")))
7049 (set_attr "amdfam10_decode" "direct")
7050 (set_attr "mode" "QI")])
7052 (define_expand "<s>mul<mode>3_highpart"
7053 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7058 (match_operand:SWI48 1 "nonimmediate_operand" ""))
7060 (match_operand:SWI48 2 "register_operand" "")))
7062 (clobber (match_scratch:SWI48 3 ""))
7063 (clobber (reg:CC FLAGS_REG))])]
7065 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7067 (define_insn "*<s>muldi3_highpart_1"
7068 [(set (match_operand:DI 0 "register_operand" "=d")
7073 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7075 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7077 (clobber (match_scratch:DI 3 "=1"))
7078 (clobber (reg:CC FLAGS_REG))]
7080 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7081 "<sgnprefix>mul{q}\t%2"
7082 [(set_attr "type" "imul")
7083 (set_attr "length_immediate" "0")
7084 (set (attr "athlon_decode")
7085 (if_then_else (eq_attr "cpu" "athlon")
7086 (const_string "vector")
7087 (const_string "double")))
7088 (set_attr "amdfam10_decode" "double")
7089 (set_attr "mode" "DI")])
7091 (define_insn "*<s>mulsi3_highpart_1"
7092 [(set (match_operand:SI 0 "register_operand" "=d")
7097 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7099 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7101 (clobber (match_scratch:SI 3 "=1"))
7102 (clobber (reg:CC FLAGS_REG))]
7103 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7104 "<sgnprefix>mul{l}\t%2"
7105 [(set_attr "type" "imul")
7106 (set_attr "length_immediate" "0")
7107 (set (attr "athlon_decode")
7108 (if_then_else (eq_attr "cpu" "athlon")
7109 (const_string "vector")
7110 (const_string "double")))
7111 (set_attr "amdfam10_decode" "double")
7112 (set_attr "mode" "SI")])
7114 (define_insn "*<s>mulsi3_highpart_zext"
7115 [(set (match_operand:DI 0 "register_operand" "=d")
7116 (zero_extend:DI (truncate:SI
7118 (mult:DI (any_extend:DI
7119 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7121 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7123 (clobber (match_scratch:SI 3 "=1"))
7124 (clobber (reg:CC FLAGS_REG))]
7126 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7127 "<sgnprefix>mul{l}\t%2"
7128 [(set_attr "type" "imul")
7129 (set_attr "length_immediate" "0")
7130 (set (attr "athlon_decode")
7131 (if_then_else (eq_attr "cpu" "athlon")
7132 (const_string "vector")
7133 (const_string "double")))
7134 (set_attr "amdfam10_decode" "double")
7135 (set_attr "mode" "SI")])
7137 ;; The patterns that match these are at the end of this file.
7139 (define_expand "mulxf3"
7140 [(set (match_operand:XF 0 "register_operand" "")
7141 (mult:XF (match_operand:XF 1 "register_operand" "")
7142 (match_operand:XF 2 "register_operand" "")))]
7146 (define_expand "mul<mode>3"
7147 [(set (match_operand:MODEF 0 "register_operand" "")
7148 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7149 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7150 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7151 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7154 ;; Divide instructions
7156 ;; The patterns that match these are at the end of this file.
7158 (define_expand "divxf3"
7159 [(set (match_operand:XF 0 "register_operand" "")
7160 (div:XF (match_operand:XF 1 "register_operand" "")
7161 (match_operand:XF 2 "register_operand" "")))]
7165 (define_expand "divdf3"
7166 [(set (match_operand:DF 0 "register_operand" "")
7167 (div:DF (match_operand:DF 1 "register_operand" "")
7168 (match_operand:DF 2 "nonimmediate_operand" "")))]
7169 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7170 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7173 (define_expand "divsf3"
7174 [(set (match_operand:SF 0 "register_operand" "")
7175 (div:SF (match_operand:SF 1 "register_operand" "")
7176 (match_operand:SF 2 "nonimmediate_operand" "")))]
7177 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7180 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7181 && flag_finite_math_only && !flag_trapping_math
7182 && flag_unsafe_math_optimizations)
7184 ix86_emit_swdivsf (operands[0], operands[1],
7185 operands[2], SFmode);
7190 ;; Divmod instructions.
7192 (define_expand "divmodqi4"
7193 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7195 (match_operand:QI 1 "register_operand" "")
7196 (match_operand:QI 2 "nonimmediate_operand" "")))
7197 (set (match_operand:QI 3 "register_operand" "")
7198 (mod:QI (match_dup 1) (match_dup 2)))
7199 (clobber (reg:CC FLAGS_REG))])]
7200 "TARGET_QIMODE_MATH"
7205 tmp0 = gen_reg_rtx (HImode);
7206 tmp1 = gen_reg_rtx (HImode);
7208 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7210 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7211 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7213 /* Extract remainder from AH. */
7214 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7215 insn = emit_move_insn (operands[3], tmp1);
7217 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7218 set_unique_reg_note (insn, REG_EQUAL, mod);
7220 /* Extract quotient from AL. */
7221 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7223 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7224 set_unique_reg_note (insn, REG_EQUAL, div);
7229 (define_expand "udivmodqi4"
7230 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7232 (match_operand:QI 1 "register_operand" "")
7233 (match_operand:QI 2 "nonimmediate_operand" "")))
7234 (set (match_operand:QI 3 "register_operand" "")
7235 (umod:QI (match_dup 1) (match_dup 2)))
7236 (clobber (reg:CC FLAGS_REG))])]
7237 "TARGET_QIMODE_MATH"
7242 tmp0 = gen_reg_rtx (HImode);
7243 tmp1 = gen_reg_rtx (HImode);
7245 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7247 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7248 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7250 /* Extract remainder from AH. */
7251 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7252 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7253 insn = emit_move_insn (operands[3], tmp1);
7255 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7256 set_unique_reg_note (insn, REG_EQUAL, mod);
7258 /* Extract quotient from AL. */
7259 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7261 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7262 set_unique_reg_note (insn, REG_EQUAL, div);
7267 ;; Divide AX by r/m8, with result stored in
7270 ;; Change div/mod to HImode and extend the second argument to HImode
7271 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7272 ;; combine may fail.
7273 (define_insn "divmodhiqi3"
7274 [(set (match_operand:HI 0 "register_operand" "=a")
7279 (mod:HI (match_operand:HI 1 "register_operand" "0")
7281 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7285 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7286 (clobber (reg:CC FLAGS_REG))]
7287 "TARGET_QIMODE_MATH"
7289 [(set_attr "type" "idiv")
7290 (set_attr "mode" "QI")])
7292 (define_insn "udivmodhiqi3"
7293 [(set (match_operand:HI 0 "register_operand" "=a")
7298 (mod:HI (match_operand:HI 1 "register_operand" "0")
7300 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7304 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7305 (clobber (reg:CC FLAGS_REG))]
7306 "TARGET_QIMODE_MATH"
7308 [(set_attr "type" "idiv")
7309 (set_attr "mode" "QI")])
7311 (define_expand "divmod<mode>4"
7312 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7314 (match_operand:SWIM248 1 "register_operand" "")
7315 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7316 (set (match_operand:SWIM248 3 "register_operand" "")
7317 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7318 (clobber (reg:CC FLAGS_REG))])]
7322 (define_insn_and_split "*divmod<mode>4"
7323 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7324 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7325 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7326 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7327 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7328 (clobber (reg:CC FLAGS_REG))]
7332 [(parallel [(set (match_dup 1)
7333 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7334 (clobber (reg:CC FLAGS_REG))])
7335 (parallel [(set (match_dup 0)
7336 (div:SWIM248 (match_dup 2) (match_dup 3)))
7338 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7340 (clobber (reg:CC FLAGS_REG))])]
7342 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7344 if (<MODE>mode != HImode
7345 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7346 operands[4] = operands[2];
7349 /* Avoid use of cltd in favor of a mov+shift. */
7350 emit_move_insn (operands[1], operands[2]);
7351 operands[4] = operands[1];
7354 [(set_attr "type" "multi")
7355 (set_attr "mode" "<MODE>")])
7357 (define_insn "*divmod<mode>4_noext"
7358 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7359 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7360 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7361 (set (match_operand:SWIM248 1 "register_operand" "=d")
7362 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7363 (use (match_operand:SWIM248 4 "register_operand" "1"))
7364 (clobber (reg:CC FLAGS_REG))]
7366 "idiv{<imodesuffix>}\t%3"
7367 [(set_attr "type" "idiv")
7368 (set_attr "mode" "<MODE>")])
7370 (define_expand "udivmod<mode>4"
7371 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7373 (match_operand:SWIM248 1 "register_operand" "")
7374 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7375 (set (match_operand:SWIM248 3 "register_operand" "")
7376 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7377 (clobber (reg:CC FLAGS_REG))])]
7381 (define_insn_and_split "*udivmod<mode>4"
7382 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7383 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7384 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7385 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7386 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7387 (clobber (reg:CC FLAGS_REG))]
7391 [(set (match_dup 1) (const_int 0))
7392 (parallel [(set (match_dup 0)
7393 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7395 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7397 (clobber (reg:CC FLAGS_REG))])]
7399 [(set_attr "type" "multi")
7400 (set_attr "mode" "<MODE>")])
7402 (define_insn "*udivmod<mode>4_noext"
7403 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7404 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7405 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7406 (set (match_operand:SWIM248 1 "register_operand" "=d")
7407 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7408 (use (match_operand:SWIM248 4 "register_operand" "1"))
7409 (clobber (reg:CC FLAGS_REG))]
7411 "div{<imodesuffix>}\t%3"
7412 [(set_attr "type" "idiv")
7413 (set_attr "mode" "<MODE>")])
7415 ;; We cannot use div/idiv for double division, because it causes
7416 ;; "division by zero" on the overflow and that's not what we expect
7417 ;; from truncate. Because true (non truncating) double division is
7418 ;; never generated, we can't create this insn anyway.
7421 ; [(set (match_operand:SI 0 "register_operand" "=a")
7423 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7425 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7426 ; (set (match_operand:SI 3 "register_operand" "=d")
7428 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7429 ; (clobber (reg:CC FLAGS_REG))]
7431 ; "div{l}\t{%2, %0|%0, %2}"
7432 ; [(set_attr "type" "idiv")])
7434 ;;- Logical AND instructions
7436 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7437 ;; Note that this excludes ah.
7439 (define_expand "testsi_ccno_1"
7440 [(set (reg:CCNO FLAGS_REG)
7442 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7443 (match_operand:SI 1 "nonmemory_operand" ""))
7448 (define_expand "testqi_ccz_1"
7449 [(set (reg:CCZ FLAGS_REG)
7450 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7451 (match_operand:QI 1 "nonmemory_operand" ""))
7456 (define_insn "*testdi_1"
7457 [(set (reg FLAGS_REG)
7460 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7461 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7463 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7464 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7466 test{l}\t{%k1, %k0|%k0, %k1}
7467 test{l}\t{%k1, %k0|%k0, %k1}
7468 test{q}\t{%1, %0|%0, %1}
7469 test{q}\t{%1, %0|%0, %1}
7470 test{q}\t{%1, %0|%0, %1}"
7471 [(set_attr "type" "test")
7472 (set_attr "modrm" "0,1,0,1,1")
7473 (set_attr "mode" "SI,SI,DI,DI,DI")])
7475 (define_insn "*testqi_1_maybe_si"
7476 [(set (reg FLAGS_REG)
7479 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7480 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7482 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7483 && ix86_match_ccmode (insn,
7484 CONST_INT_P (operands[1])
7485 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7487 if (which_alternative == 3)
7489 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7490 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7491 return "test{l}\t{%1, %k0|%k0, %1}";
7493 return "test{b}\t{%1, %0|%0, %1}";
7495 [(set_attr "type" "test")
7496 (set_attr "modrm" "0,1,1,1")
7497 (set_attr "mode" "QI,QI,QI,SI")
7498 (set_attr "pent_pair" "uv,np,uv,np")])
7500 (define_insn "*test<mode>_1"
7501 [(set (reg FLAGS_REG)
7504 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7505 (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7507 "ix86_match_ccmode (insn, CCNOmode)
7508 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7509 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7510 [(set_attr "type" "test")
7511 (set_attr "modrm" "0,1,1")
7512 (set_attr "mode" "<MODE>")
7513 (set_attr "pent_pair" "uv,np,uv")])
7515 (define_expand "testqi_ext_ccno_0"
7516 [(set (reg:CCNO FLAGS_REG)
7520 (match_operand 0 "ext_register_operand" "")
7523 (match_operand 1 "const_int_operand" ""))
7528 (define_insn "*testqi_ext_0"
7529 [(set (reg FLAGS_REG)
7533 (match_operand 0 "ext_register_operand" "Q")
7536 (match_operand 1 "const_int_operand" "n"))
7538 "ix86_match_ccmode (insn, CCNOmode)"
7539 "test{b}\t{%1, %h0|%h0, %1}"
7540 [(set_attr "type" "test")
7541 (set_attr "mode" "QI")
7542 (set_attr "length_immediate" "1")
7543 (set_attr "modrm" "1")
7544 (set_attr "pent_pair" "np")])
7546 (define_insn "*testqi_ext_1_rex64"
7547 [(set (reg FLAGS_REG)
7551 (match_operand 0 "ext_register_operand" "Q")
7555 (match_operand:QI 1 "register_operand" "Q")))
7557 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7558 "test{b}\t{%1, %h0|%h0, %1}"
7559 [(set_attr "type" "test")
7560 (set_attr "mode" "QI")])
7562 (define_insn "*testqi_ext_1"
7563 [(set (reg FLAGS_REG)
7567 (match_operand 0 "ext_register_operand" "Q")
7571 (match_operand:QI 1 "general_operand" "Qm")))
7573 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7574 "test{b}\t{%1, %h0|%h0, %1}"
7575 [(set_attr "type" "test")
7576 (set_attr "mode" "QI")])
7578 (define_insn "*testqi_ext_2"
7579 [(set (reg FLAGS_REG)
7583 (match_operand 0 "ext_register_operand" "Q")
7587 (match_operand 1 "ext_register_operand" "Q")
7591 "ix86_match_ccmode (insn, CCNOmode)"
7592 "test{b}\t{%h1, %h0|%h0, %h1}"
7593 [(set_attr "type" "test")
7594 (set_attr "mode" "QI")])
7596 (define_insn "*testqi_ext_3_rex64"
7597 [(set (reg FLAGS_REG)
7598 (compare (zero_extract:DI
7599 (match_operand 0 "nonimmediate_operand" "rm")
7600 (match_operand:DI 1 "const_int_operand" "")
7601 (match_operand:DI 2 "const_int_operand" ""))
7604 && ix86_match_ccmode (insn, CCNOmode)
7605 && INTVAL (operands[1]) > 0
7606 && INTVAL (operands[2]) >= 0
7607 /* Ensure that resulting mask is zero or sign extended operand. */
7608 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7609 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7610 && INTVAL (operands[1]) > 32))
7611 && (GET_MODE (operands[0]) == SImode
7612 || GET_MODE (operands[0]) == DImode
7613 || GET_MODE (operands[0]) == HImode
7614 || GET_MODE (operands[0]) == QImode)"
7617 ;; Combine likes to form bit extractions for some tests. Humor it.
7618 (define_insn "*testqi_ext_3"
7619 [(set (reg FLAGS_REG)
7620 (compare (zero_extract:SI
7621 (match_operand 0 "nonimmediate_operand" "rm")
7622 (match_operand:SI 1 "const_int_operand" "")
7623 (match_operand:SI 2 "const_int_operand" ""))
7625 "ix86_match_ccmode (insn, CCNOmode)
7626 && INTVAL (operands[1]) > 0
7627 && INTVAL (operands[2]) >= 0
7628 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7629 && (GET_MODE (operands[0]) == SImode
7630 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7631 || GET_MODE (operands[0]) == HImode
7632 || GET_MODE (operands[0]) == QImode)"
7636 [(set (match_operand 0 "flags_reg_operand" "")
7637 (match_operator 1 "compare_operator"
7639 (match_operand 2 "nonimmediate_operand" "")
7640 (match_operand 3 "const_int_operand" "")
7641 (match_operand 4 "const_int_operand" ""))
7643 "ix86_match_ccmode (insn, CCNOmode)"
7644 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7646 rtx val = operands[2];
7647 HOST_WIDE_INT len = INTVAL (operands[3]);
7648 HOST_WIDE_INT pos = INTVAL (operands[4]);
7650 enum machine_mode mode, submode;
7652 mode = GET_MODE (val);
7655 /* ??? Combine likes to put non-volatile mem extractions in QImode
7656 no matter the size of the test. So find a mode that works. */
7657 if (! MEM_VOLATILE_P (val))
7659 mode = smallest_mode_for_size (pos + len, MODE_INT);
7660 val = adjust_address (val, mode, 0);
7663 else if (GET_CODE (val) == SUBREG
7664 && (submode = GET_MODE (SUBREG_REG (val)),
7665 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7666 && pos + len <= GET_MODE_BITSIZE (submode)
7667 && GET_MODE_CLASS (submode) == MODE_INT)
7669 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7671 val = SUBREG_REG (val);
7673 else if (mode == HImode && pos + len <= 8)
7675 /* Small HImode tests can be converted to QImode. */
7677 val = gen_lowpart (QImode, val);
7680 if (len == HOST_BITS_PER_WIDE_INT)
7683 mask = ((HOST_WIDE_INT)1 << len) - 1;
7686 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7689 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7690 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7691 ;; this is relatively important trick.
7692 ;; Do the conversion only post-reload to avoid limiting of the register class
7695 [(set (match_operand 0 "flags_reg_operand" "")
7696 (match_operator 1 "compare_operator"
7697 [(and (match_operand 2 "register_operand" "")
7698 (match_operand 3 "const_int_operand" ""))
7701 && QI_REG_P (operands[2])
7702 && GET_MODE (operands[2]) != QImode
7703 && ((ix86_match_ccmode (insn, CCZmode)
7704 && !(INTVAL (operands[3]) & ~(255 << 8)))
7705 || (ix86_match_ccmode (insn, CCNOmode)
7706 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7709 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7712 "operands[2] = gen_lowpart (SImode, operands[2]);
7713 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7716 [(set (match_operand 0 "flags_reg_operand" "")
7717 (match_operator 1 "compare_operator"
7718 [(and (match_operand 2 "nonimmediate_operand" "")
7719 (match_operand 3 "const_int_operand" ""))
7722 && GET_MODE (operands[2]) != QImode
7723 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7724 && ((ix86_match_ccmode (insn, CCZmode)
7725 && !(INTVAL (operands[3]) & ~255))
7726 || (ix86_match_ccmode (insn, CCNOmode)
7727 && !(INTVAL (operands[3]) & ~127)))"
7729 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7731 "operands[2] = gen_lowpart (QImode, operands[2]);
7732 operands[3] = gen_lowpart (QImode, operands[3]);")
7734 ;; %%% This used to optimize known byte-wide and operations to memory,
7735 ;; and sometimes to QImode registers. If this is considered useful,
7736 ;; it should be done with splitters.
7738 (define_expand "and<mode>3"
7739 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7740 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7741 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7743 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7745 (define_insn "*anddi_1"
7746 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7748 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7749 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7750 (clobber (reg:CC FLAGS_REG))]
7751 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7753 switch (get_attr_type (insn))
7757 enum machine_mode mode;
7759 gcc_assert (CONST_INT_P (operands[2]));
7760 if (INTVAL (operands[2]) == 0xff)
7764 gcc_assert (INTVAL (operands[2]) == 0xffff);
7768 operands[1] = gen_lowpart (mode, operands[1]);
7770 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7772 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7776 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7777 if (get_attr_mode (insn) == MODE_SI)
7778 return "and{l}\t{%k2, %k0|%k0, %k2}";
7780 return "and{q}\t{%2, %0|%0, %2}";
7783 [(set_attr "type" "alu,alu,alu,imovx")
7784 (set_attr "length_immediate" "*,*,*,0")
7785 (set (attr "prefix_rex")
7787 (and (eq_attr "type" "imovx")
7788 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7789 (match_operand 1 "ext_QIreg_nomode_operand" "")))
7791 (const_string "*")))
7792 (set_attr "mode" "SI,DI,DI,SI")])
7794 (define_insn "*andsi_1"
7795 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7796 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7797 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7798 (clobber (reg:CC FLAGS_REG))]
7799 "ix86_binary_operator_ok (AND, SImode, operands)"
7801 switch (get_attr_type (insn))
7805 enum machine_mode mode;
7807 gcc_assert (CONST_INT_P (operands[2]));
7808 if (INTVAL (operands[2]) == 0xff)
7812 gcc_assert (INTVAL (operands[2]) == 0xffff);
7816 operands[1] = gen_lowpart (mode, operands[1]);
7818 return "movz{bl|x}\t{%1, %0|%0, %1}";
7820 return "movz{wl|x}\t{%1, %0|%0, %1}";
7824 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7825 return "and{l}\t{%2, %0|%0, %2}";
7828 [(set_attr "type" "alu,alu,imovx")
7829 (set (attr "prefix_rex")
7831 (and (eq_attr "type" "imovx")
7832 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7833 (match_operand 1 "ext_QIreg_nomode_operand" "")))
7835 (const_string "*")))
7836 (set_attr "length_immediate" "*,*,0")
7837 (set_attr "mode" "SI")])
7839 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7840 (define_insn "*andsi_1_zext"
7841 [(set (match_operand:DI 0 "register_operand" "=r")
7843 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7844 (match_operand:SI 2 "general_operand" "g"))))
7845 (clobber (reg:CC FLAGS_REG))]
7846 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7847 "and{l}\t{%2, %k0|%k0, %2}"
7848 [(set_attr "type" "alu")
7849 (set_attr "mode" "SI")])
7851 (define_insn "*andhi_1"
7852 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7853 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7854 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7855 (clobber (reg:CC FLAGS_REG))]
7856 "ix86_binary_operator_ok (AND, HImode, operands)"
7858 switch (get_attr_type (insn))
7861 gcc_assert (CONST_INT_P (operands[2]));
7862 gcc_assert (INTVAL (operands[2]) == 0xff);
7863 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7866 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7868 return "and{w}\t{%2, %0|%0, %2}";
7871 [(set_attr "type" "alu,alu,imovx")
7872 (set_attr "length_immediate" "*,*,0")
7873 (set (attr "prefix_rex")
7875 (and (eq_attr "type" "imovx")
7876 (match_operand 1 "ext_QIreg_nomode_operand" ""))
7878 (const_string "*")))
7879 (set_attr "mode" "HI,HI,SI")])
7881 ;; %%% Potential partial reg stall on alternative 2. What to do?
7882 (define_insn "*andqi_1"
7883 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7884 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7885 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7886 (clobber (reg:CC FLAGS_REG))]
7887 "ix86_binary_operator_ok (AND, QImode, operands)"
7889 and{b}\t{%2, %0|%0, %2}
7890 and{b}\t{%2, %0|%0, %2}
7891 and{l}\t{%k2, %k0|%k0, %k2}"
7892 [(set_attr "type" "alu")
7893 (set_attr "mode" "QI,QI,SI")])
7895 (define_insn "*andqi_1_slp"
7896 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7897 (and:QI (match_dup 0)
7898 (match_operand:QI 1 "general_operand" "qn,qmn")))
7899 (clobber (reg:CC FLAGS_REG))]
7900 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7901 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7902 "and{b}\t{%1, %0|%0, %1}"
7903 [(set_attr "type" "alu1")
7904 (set_attr "mode" "QI")])
7907 [(set (match_operand 0 "register_operand" "")
7909 (const_int -65536)))
7910 (clobber (reg:CC FLAGS_REG))]
7911 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7912 || optimize_function_for_size_p (cfun)"
7913 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7914 "operands[1] = gen_lowpart (HImode, operands[0]);")
7917 [(set (match_operand 0 "ext_register_operand" "")
7920 (clobber (reg:CC FLAGS_REG))]
7921 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7922 && reload_completed"
7923 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7924 "operands[1] = gen_lowpart (QImode, operands[0]);")
7927 [(set (match_operand 0 "ext_register_operand" "")
7929 (const_int -65281)))
7930 (clobber (reg:CC FLAGS_REG))]
7931 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7932 && reload_completed"
7933 [(parallel [(set (zero_extract:SI (match_dup 0)
7937 (zero_extract:SI (match_dup 0)
7940 (zero_extract:SI (match_dup 0)
7943 (clobber (reg:CC FLAGS_REG))])]
7944 "operands[0] = gen_lowpart (SImode, operands[0]);")
7946 (define_insn "*anddi_2"
7947 [(set (reg FLAGS_REG)
7950 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7951 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7953 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7954 (and:DI (match_dup 1) (match_dup 2)))]
7955 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7956 && ix86_binary_operator_ok (AND, DImode, operands)"
7958 and{l}\t{%k2, %k0|%k0, %k2}
7959 and{q}\t{%2, %0|%0, %2}
7960 and{q}\t{%2, %0|%0, %2}"
7961 [(set_attr "type" "alu")
7962 (set_attr "mode" "SI,DI,DI")])
7964 (define_insn "*andqi_2_maybe_si"
7965 [(set (reg FLAGS_REG)
7967 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7968 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7970 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7971 (and:QI (match_dup 1) (match_dup 2)))]
7972 "ix86_binary_operator_ok (AND, QImode, operands)
7973 && ix86_match_ccmode (insn,
7974 CONST_INT_P (operands[2])
7975 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7977 if (which_alternative == 2)
7979 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7980 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7981 return "and{l}\t{%2, %k0|%k0, %2}";
7983 return "and{b}\t{%2, %0|%0, %2}";
7985 [(set_attr "type" "alu")
7986 (set_attr "mode" "QI,QI,SI")])
7988 (define_insn "*and<mode>_2"
7989 [(set (reg FLAGS_REG)
7990 (compare (and:SWI124
7991 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7992 (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
7994 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7995 (and:SWI124 (match_dup 1) (match_dup 2)))]
7996 "ix86_match_ccmode (insn, CCNOmode)
7997 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7998 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7999 [(set_attr "type" "alu")
8000 (set_attr "mode" "<MODE>")])
8002 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8003 (define_insn "*andsi_2_zext"
8004 [(set (reg FLAGS_REG)
8006 (match_operand:SI 1 "nonimmediate_operand" "%0")
8007 (match_operand:SI 2 "general_operand" "g"))
8009 (set (match_operand:DI 0 "register_operand" "=r")
8010 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8011 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8012 && ix86_binary_operator_ok (AND, SImode, operands)"
8013 "and{l}\t{%2, %k0|%k0, %2}"
8014 [(set_attr "type" "alu")
8015 (set_attr "mode" "SI")])
8017 (define_insn "*andqi_2_slp"
8018 [(set (reg FLAGS_REG)
8020 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8021 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8023 (set (strict_low_part (match_dup 0))
8024 (and:QI (match_dup 0) (match_dup 1)))]
8025 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8026 && ix86_match_ccmode (insn, CCNOmode)
8027 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8028 "and{b}\t{%1, %0|%0, %1}"
8029 [(set_attr "type" "alu1")
8030 (set_attr "mode" "QI")])
8032 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8033 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8034 ;; for a QImode operand, which of course failed.
8035 (define_insn "andqi_ext_0"
8036 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8041 (match_operand 1 "ext_register_operand" "0")
8044 (match_operand 2 "const_int_operand" "n")))
8045 (clobber (reg:CC FLAGS_REG))]
8047 "and{b}\t{%2, %h0|%h0, %2}"
8048 [(set_attr "type" "alu")
8049 (set_attr "length_immediate" "1")
8050 (set_attr "modrm" "1")
8051 (set_attr "mode" "QI")])
8053 ;; Generated by peephole translating test to and. This shows up
8054 ;; often in fp comparisons.
8055 (define_insn "*andqi_ext_0_cc"
8056 [(set (reg FLAGS_REG)
8060 (match_operand 1 "ext_register_operand" "0")
8063 (match_operand 2 "const_int_operand" "n"))
8065 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8074 "ix86_match_ccmode (insn, CCNOmode)"
8075 "and{b}\t{%2, %h0|%h0, %2}"
8076 [(set_attr "type" "alu")
8077 (set_attr "length_immediate" "1")
8078 (set_attr "modrm" "1")
8079 (set_attr "mode" "QI")])
8081 (define_insn "*andqi_ext_1_rex64"
8082 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8087 (match_operand 1 "ext_register_operand" "0")
8091 (match_operand 2 "ext_register_operand" "Q"))))
8092 (clobber (reg:CC FLAGS_REG))]
8094 "and{b}\t{%2, %h0|%h0, %2}"
8095 [(set_attr "type" "alu")
8096 (set_attr "length_immediate" "0")
8097 (set_attr "mode" "QI")])
8099 (define_insn "*andqi_ext_1"
8100 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8105 (match_operand 1 "ext_register_operand" "0")
8109 (match_operand:QI 2 "general_operand" "Qm"))))
8110 (clobber (reg:CC FLAGS_REG))]
8112 "and{b}\t{%2, %h0|%h0, %2}"
8113 [(set_attr "type" "alu")
8114 (set_attr "length_immediate" "0")
8115 (set_attr "mode" "QI")])
8117 (define_insn "*andqi_ext_2"
8118 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8123 (match_operand 1 "ext_register_operand" "%0")
8127 (match_operand 2 "ext_register_operand" "Q")
8130 (clobber (reg:CC FLAGS_REG))]
8132 "and{b}\t{%h2, %h0|%h0, %h2}"
8133 [(set_attr "type" "alu")
8134 (set_attr "length_immediate" "0")
8135 (set_attr "mode" "QI")])
8137 ;; Convert wide AND instructions with immediate operand to shorter QImode
8138 ;; equivalents when possible.
8139 ;; Don't do the splitting with memory operands, since it introduces risk
8140 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8141 ;; for size, but that can (should?) be handled by generic code instead.
8143 [(set (match_operand 0 "register_operand" "")
8144 (and (match_operand 1 "register_operand" "")
8145 (match_operand 2 "const_int_operand" "")))
8146 (clobber (reg:CC FLAGS_REG))]
8148 && QI_REG_P (operands[0])
8149 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8150 && !(~INTVAL (operands[2]) & ~(255 << 8))
8151 && GET_MODE (operands[0]) != QImode"
8152 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8153 (and:SI (zero_extract:SI (match_dup 1)
8154 (const_int 8) (const_int 8))
8156 (clobber (reg:CC FLAGS_REG))])]
8157 "operands[0] = gen_lowpart (SImode, operands[0]);
8158 operands[1] = gen_lowpart (SImode, operands[1]);
8159 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8161 ;; Since AND can be encoded with sign extended immediate, this is only
8162 ;; profitable when 7th bit is not set.
8164 [(set (match_operand 0 "register_operand" "")
8165 (and (match_operand 1 "general_operand" "")
8166 (match_operand 2 "const_int_operand" "")))
8167 (clobber (reg:CC FLAGS_REG))]
8169 && ANY_QI_REG_P (operands[0])
8170 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8171 && !(~INTVAL (operands[2]) & ~255)
8172 && !(INTVAL (operands[2]) & 128)
8173 && GET_MODE (operands[0]) != QImode"
8174 [(parallel [(set (strict_low_part (match_dup 0))
8175 (and:QI (match_dup 1)
8177 (clobber (reg:CC FLAGS_REG))])]
8178 "operands[0] = gen_lowpart (QImode, operands[0]);
8179 operands[1] = gen_lowpart (QImode, operands[1]);
8180 operands[2] = gen_lowpart (QImode, operands[2]);")
8182 ;; Logical inclusive and exclusive OR instructions
8184 ;; %%% This used to optimize known byte-wide and operations to memory.
8185 ;; If this is considered useful, it should be done with splitters.
8187 (define_expand "<code><mode>3"
8188 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8189 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8190 (match_operand:SWIM 2 "<general_operand>" "")))]
8192 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8194 (define_insn "*<code><mode>_1"
8195 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8197 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8198 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8199 (clobber (reg:CC FLAGS_REG))]
8200 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8201 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8202 [(set_attr "type" "alu")
8203 (set_attr "mode" "<MODE>")])
8205 ;; %%% Potential partial reg stall on alternative 2. What to do?
8206 (define_insn "*<code>qi_1"
8207 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8208 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8209 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8210 (clobber (reg:CC FLAGS_REG))]
8211 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8213 <logic>{b}\t{%2, %0|%0, %2}
8214 <logic>{b}\t{%2, %0|%0, %2}
8215 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8216 [(set_attr "type" "alu")
8217 (set_attr "mode" "QI,QI,SI")])
8219 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8220 (define_insn "*<code>si_1_zext"
8221 [(set (match_operand:DI 0 "register_operand" "=r")
8223 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8224 (match_operand:SI 2 "general_operand" "g"))))
8225 (clobber (reg:CC FLAGS_REG))]
8226 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8227 "<logic>{l}\t{%2, %k0|%k0, %2}"
8228 [(set_attr "type" "alu")
8229 (set_attr "mode" "SI")])
8231 (define_insn "*<code>si_1_zext_imm"
8232 [(set (match_operand:DI 0 "register_operand" "=r")
8234 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8235 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8236 (clobber (reg:CC FLAGS_REG))]
8237 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8238 "<logic>{l}\t{%2, %k0|%k0, %2}"
8239 [(set_attr "type" "alu")
8240 (set_attr "mode" "SI")])
8242 (define_insn "*<code>qi_1_slp"
8243 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8244 (any_or:QI (match_dup 0)
8245 (match_operand:QI 1 "general_operand" "qmn,qn")))
8246 (clobber (reg:CC FLAGS_REG))]
8247 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8248 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8249 "<logic>{b}\t{%1, %0|%0, %1}"
8250 [(set_attr "type" "alu1")
8251 (set_attr "mode" "QI")])
8253 (define_insn "*<code><mode>_2"
8254 [(set (reg FLAGS_REG)
8255 (compare (any_or:SWI
8256 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8257 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8259 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8260 (any_or:SWI (match_dup 1) (match_dup 2)))]
8261 "ix86_match_ccmode (insn, CCNOmode)
8262 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8263 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8264 [(set_attr "type" "alu")
8265 (set_attr "mode" "<MODE>")])
8267 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8268 ;; ??? Special case for immediate operand is missing - it is tricky.
8269 (define_insn "*<code>si_2_zext"
8270 [(set (reg FLAGS_REG)
8271 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8272 (match_operand:SI 2 "general_operand" "g"))
8274 (set (match_operand:DI 0 "register_operand" "=r")
8275 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8276 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8277 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8278 "<logic>{l}\t{%2, %k0|%k0, %2}"
8279 [(set_attr "type" "alu")
8280 (set_attr "mode" "SI")])
8282 (define_insn "*<code>si_2_zext_imm"
8283 [(set (reg FLAGS_REG)
8285 (match_operand:SI 1 "nonimmediate_operand" "%0")
8286 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8288 (set (match_operand:DI 0 "register_operand" "=r")
8289 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8290 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8291 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8292 "<logic>{l}\t{%2, %k0|%k0, %2}"
8293 [(set_attr "type" "alu")
8294 (set_attr "mode" "SI")])
8296 (define_insn "*<code>qi_2_slp"
8297 [(set (reg FLAGS_REG)
8298 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8299 (match_operand:QI 1 "general_operand" "qmn,qn"))
8301 (set (strict_low_part (match_dup 0))
8302 (any_or:QI (match_dup 0) (match_dup 1)))]
8303 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8304 && ix86_match_ccmode (insn, CCNOmode)
8305 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8306 "<logic>{b}\t{%1, %0|%0, %1}"
8307 [(set_attr "type" "alu1")
8308 (set_attr "mode" "QI")])
8310 (define_insn "*<code><mode>_3"
8311 [(set (reg FLAGS_REG)
8312 (compare (any_or:SWI
8313 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8314 (match_operand:SWI 2 "<general_operand>" "<g>"))
8316 (clobber (match_scratch:SWI 0 "=<r>"))]
8317 "ix86_match_ccmode (insn, CCNOmode)
8318 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8319 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8320 [(set_attr "type" "alu")
8321 (set_attr "mode" "<MODE>")])
8323 (define_insn "*<code>qi_ext_0"
8324 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8329 (match_operand 1 "ext_register_operand" "0")
8332 (match_operand 2 "const_int_operand" "n")))
8333 (clobber (reg:CC FLAGS_REG))]
8334 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8335 "<logic>{b}\t{%2, %h0|%h0, %2}"
8336 [(set_attr "type" "alu")
8337 (set_attr "length_immediate" "1")
8338 (set_attr "modrm" "1")
8339 (set_attr "mode" "QI")])
8341 (define_insn "*<code>qi_ext_1_rex64"
8342 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8347 (match_operand 1 "ext_register_operand" "0")
8351 (match_operand 2 "ext_register_operand" "Q"))))
8352 (clobber (reg:CC FLAGS_REG))]
8354 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8355 "<logic>{b}\t{%2, %h0|%h0, %2}"
8356 [(set_attr "type" "alu")
8357 (set_attr "length_immediate" "0")
8358 (set_attr "mode" "QI")])
8360 (define_insn "*<code>qi_ext_1"
8361 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8366 (match_operand 1 "ext_register_operand" "0")
8370 (match_operand:QI 2 "general_operand" "Qm"))))
8371 (clobber (reg:CC FLAGS_REG))]
8373 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8374 "<logic>{b}\t{%2, %h0|%h0, %2}"
8375 [(set_attr "type" "alu")
8376 (set_attr "length_immediate" "0")
8377 (set_attr "mode" "QI")])
8379 (define_insn "*<code>qi_ext_2"
8380 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8384 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8387 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8390 (clobber (reg:CC FLAGS_REG))]
8391 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8392 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8393 [(set_attr "type" "alu")
8394 (set_attr "length_immediate" "0")
8395 (set_attr "mode" "QI")])
8398 [(set (match_operand 0 "register_operand" "")
8399 (any_or (match_operand 1 "register_operand" "")
8400 (match_operand 2 "const_int_operand" "")))
8401 (clobber (reg:CC FLAGS_REG))]
8403 && QI_REG_P (operands[0])
8404 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8405 && !(INTVAL (operands[2]) & ~(255 << 8))
8406 && GET_MODE (operands[0]) != QImode"
8407 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8408 (any_or:SI (zero_extract:SI (match_dup 1)
8409 (const_int 8) (const_int 8))
8411 (clobber (reg:CC FLAGS_REG))])]
8412 "operands[0] = gen_lowpart (SImode, operands[0]);
8413 operands[1] = gen_lowpart (SImode, operands[1]);
8414 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8416 ;; Since OR can be encoded with sign extended immediate, this is only
8417 ;; profitable when 7th bit is set.
8419 [(set (match_operand 0 "register_operand" "")
8420 (any_or (match_operand 1 "general_operand" "")
8421 (match_operand 2 "const_int_operand" "")))
8422 (clobber (reg:CC FLAGS_REG))]
8424 && ANY_QI_REG_P (operands[0])
8425 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8426 && !(INTVAL (operands[2]) & ~255)
8427 && (INTVAL (operands[2]) & 128)
8428 && GET_MODE (operands[0]) != QImode"
8429 [(parallel [(set (strict_low_part (match_dup 0))
8430 (any_or:QI (match_dup 1)
8432 (clobber (reg:CC FLAGS_REG))])]
8433 "operands[0] = gen_lowpart (QImode, operands[0]);
8434 operands[1] = gen_lowpart (QImode, operands[1]);
8435 operands[2] = gen_lowpart (QImode, operands[2]);")
8437 (define_expand "xorqi_cc_ext_1"
8439 (set (reg:CCNO FLAGS_REG)
8443 (match_operand 1 "ext_register_operand" "")
8446 (match_operand:QI 2 "general_operand" ""))
8448 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8460 (define_insn "*xorqi_cc_ext_1_rex64"
8461 [(set (reg FLAGS_REG)
8465 (match_operand 1 "ext_register_operand" "0")
8468 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8470 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8479 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8480 "xor{b}\t{%2, %h0|%h0, %2}"
8481 [(set_attr "type" "alu")
8482 (set_attr "modrm" "1")
8483 (set_attr "mode" "QI")])
8485 (define_insn "*xorqi_cc_ext_1"
8486 [(set (reg FLAGS_REG)
8490 (match_operand 1 "ext_register_operand" "0")
8493 (match_operand:QI 2 "general_operand" "qmn"))
8495 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8504 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8505 "xor{b}\t{%2, %h0|%h0, %2}"
8506 [(set_attr "type" "alu")
8507 (set_attr "modrm" "1")
8508 (set_attr "mode" "QI")])
8510 ;; Negation instructions
8512 (define_expand "neg<mode>2"
8513 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8514 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8516 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8518 (define_insn_and_split "*neg<dwi>2_doubleword"
8519 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8520 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8521 (clobber (reg:CC FLAGS_REG))]
8522 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8526 [(set (reg:CCZ FLAGS_REG)
8527 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8528 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8531 (plus:DWIH (match_dup 3)
8532 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8534 (clobber (reg:CC FLAGS_REG))])
8537 (neg:DWIH (match_dup 2)))
8538 (clobber (reg:CC FLAGS_REG))])]
8539 "split_<dwi> (&operands[0], 2, &operands[0], &operands[2]);")
8541 (define_insn "*neg<mode>2_1"
8542 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8543 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8544 (clobber (reg:CC FLAGS_REG))]
8545 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8546 "neg{<imodesuffix>}\t%0"
8547 [(set_attr "type" "negnot")
8548 (set_attr "mode" "<MODE>")])
8550 ;; Combine is quite creative about this pattern.
8551 (define_insn "*negsi2_1_zext"
8552 [(set (match_operand:DI 0 "register_operand" "=r")
8554 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8557 (clobber (reg:CC FLAGS_REG))]
8558 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8560 [(set_attr "type" "negnot")
8561 (set_attr "mode" "SI")])
8563 ;; The problem with neg is that it does not perform (compare x 0),
8564 ;; it really performs (compare 0 x), which leaves us with the zero
8565 ;; flag being the only useful item.
8567 (define_insn "*neg<mode>2_cmpz"
8568 [(set (reg:CCZ FLAGS_REG)
8570 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8572 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8573 (neg:SWI (match_dup 1)))]
8574 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8575 "neg{<imodesuffix>}\t%0"
8576 [(set_attr "type" "negnot")
8577 (set_attr "mode" "<MODE>")])
8579 (define_insn "*negsi2_cmpz_zext"
8580 [(set (reg:CCZ FLAGS_REG)
8584 (match_operand:DI 1 "register_operand" "0")
8588 (set (match_operand:DI 0 "register_operand" "=r")
8589 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8592 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8594 [(set_attr "type" "negnot")
8595 (set_attr "mode" "SI")])
8597 ;; Changing of sign for FP values is doable using integer unit too.
8599 (define_expand "<code><mode>2"
8600 [(set (match_operand:X87MODEF 0 "register_operand" "")
8601 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8602 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8603 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8605 (define_insn "*absneg<mode>2_mixed"
8606 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8607 (match_operator:MODEF 3 "absneg_operator"
8608 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8609 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8610 (clobber (reg:CC FLAGS_REG))]
8611 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8614 (define_insn "*absneg<mode>2_sse"
8615 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8616 (match_operator:MODEF 3 "absneg_operator"
8617 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8618 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8619 (clobber (reg:CC FLAGS_REG))]
8620 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8623 (define_insn "*absneg<mode>2_i387"
8624 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8625 (match_operator:X87MODEF 3 "absneg_operator"
8626 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8627 (use (match_operand 2 "" ""))
8628 (clobber (reg:CC FLAGS_REG))]
8629 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8632 (define_expand "<code>tf2"
8633 [(set (match_operand:TF 0 "register_operand" "")
8634 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8636 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8638 (define_insn "*absnegtf2_sse"
8639 [(set (match_operand:TF 0 "register_operand" "=x,x")
8640 (match_operator:TF 3 "absneg_operator"
8641 [(match_operand:TF 1 "register_operand" "0,x")]))
8642 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8643 (clobber (reg:CC FLAGS_REG))]
8647 ;; Splitters for fp abs and neg.
8650 [(set (match_operand 0 "fp_register_operand" "")
8651 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8652 (use (match_operand 2 "" ""))
8653 (clobber (reg:CC FLAGS_REG))]
8655 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8658 [(set (match_operand 0 "register_operand" "")
8659 (match_operator 3 "absneg_operator"
8660 [(match_operand 1 "register_operand" "")]))
8661 (use (match_operand 2 "nonimmediate_operand" ""))
8662 (clobber (reg:CC FLAGS_REG))]
8663 "reload_completed && SSE_REG_P (operands[0])"
8664 [(set (match_dup 0) (match_dup 3))]
8666 enum machine_mode mode = GET_MODE (operands[0]);
8667 enum machine_mode vmode = GET_MODE (operands[2]);
8670 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8671 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8672 if (operands_match_p (operands[0], operands[2]))
8675 operands[1] = operands[2];
8678 if (GET_CODE (operands[3]) == ABS)
8679 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8681 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8686 [(set (match_operand:SF 0 "register_operand" "")
8687 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8688 (use (match_operand:V4SF 2 "" ""))
8689 (clobber (reg:CC FLAGS_REG))]
8691 [(parallel [(set (match_dup 0) (match_dup 1))
8692 (clobber (reg:CC FLAGS_REG))])]
8695 operands[0] = gen_lowpart (SImode, operands[0]);
8696 if (GET_CODE (operands[1]) == ABS)
8698 tmp = gen_int_mode (0x7fffffff, SImode);
8699 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8703 tmp = gen_int_mode (0x80000000, SImode);
8704 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8710 [(set (match_operand:DF 0 "register_operand" "")
8711 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8712 (use (match_operand 2 "" ""))
8713 (clobber (reg:CC FLAGS_REG))]
8715 [(parallel [(set (match_dup 0) (match_dup 1))
8716 (clobber (reg:CC FLAGS_REG))])]
8721 tmp = gen_lowpart (DImode, operands[0]);
8722 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8725 if (GET_CODE (operands[1]) == ABS)
8728 tmp = gen_rtx_NOT (DImode, tmp);
8732 operands[0] = gen_highpart (SImode, operands[0]);
8733 if (GET_CODE (operands[1]) == ABS)
8735 tmp = gen_int_mode (0x7fffffff, SImode);
8736 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8740 tmp = gen_int_mode (0x80000000, SImode);
8741 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8748 [(set (match_operand:XF 0 "register_operand" "")
8749 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8750 (use (match_operand 2 "" ""))
8751 (clobber (reg:CC FLAGS_REG))]
8753 [(parallel [(set (match_dup 0) (match_dup 1))
8754 (clobber (reg:CC FLAGS_REG))])]
8757 operands[0] = gen_rtx_REG (SImode,
8758 true_regnum (operands[0])
8759 + (TARGET_64BIT ? 1 : 2));
8760 if (GET_CODE (operands[1]) == ABS)
8762 tmp = GEN_INT (0x7fff);
8763 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8767 tmp = GEN_INT (0x8000);
8768 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8773 ;; Conditionalize these after reload. If they match before reload, we
8774 ;; lose the clobber and ability to use integer instructions.
8776 (define_insn "*<code><mode>2_1"
8777 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8778 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8780 && (reload_completed
8781 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8782 "f<absneg_mnemonic>"
8783 [(set_attr "type" "fsgn")
8784 (set_attr "mode" "<MODE>")])
8786 (define_insn "*<code>extendsfdf2"
8787 [(set (match_operand:DF 0 "register_operand" "=f")
8788 (absneg:DF (float_extend:DF
8789 (match_operand:SF 1 "register_operand" "0"))))]
8790 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8791 "f<absneg_mnemonic>"
8792 [(set_attr "type" "fsgn")
8793 (set_attr "mode" "DF")])
8795 (define_insn "*<code>extendsfxf2"
8796 [(set (match_operand:XF 0 "register_operand" "=f")
8797 (absneg:XF (float_extend:XF
8798 (match_operand:SF 1 "register_operand" "0"))))]
8800 "f<absneg_mnemonic>"
8801 [(set_attr "type" "fsgn")
8802 (set_attr "mode" "XF")])
8804 (define_insn "*<code>extenddfxf2"
8805 [(set (match_operand:XF 0 "register_operand" "=f")
8806 (absneg:XF (float_extend:XF
8807 (match_operand:DF 1 "register_operand" "0"))))]
8809 "f<absneg_mnemonic>"
8810 [(set_attr "type" "fsgn")
8811 (set_attr "mode" "XF")])
8813 ;; Copysign instructions
8815 (define_mode_iterator CSGNMODE [SF DF TF])
8816 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8818 (define_expand "copysign<mode>3"
8819 [(match_operand:CSGNMODE 0 "register_operand" "")
8820 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8821 (match_operand:CSGNMODE 2 "register_operand" "")]
8822 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8823 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8824 "ix86_expand_copysign (operands); DONE;")
8826 (define_insn_and_split "copysign<mode>3_const"
8827 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8829 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8830 (match_operand:CSGNMODE 2 "register_operand" "0")
8831 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8833 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8834 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8836 "&& reload_completed"
8838 "ix86_split_copysign_const (operands); DONE;")
8840 (define_insn "copysign<mode>3_var"
8841 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8843 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8844 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8845 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8846 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8848 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8849 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8850 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8854 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8856 [(match_operand:CSGNMODE 2 "register_operand" "")
8857 (match_operand:CSGNMODE 3 "register_operand" "")
8858 (match_operand:<CSGNVMODE> 4 "" "")
8859 (match_operand:<CSGNVMODE> 5 "" "")]
8861 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8862 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8863 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8864 && reload_completed"
8866 "ix86_split_copysign_var (operands); DONE;")
8868 ;; One complement instructions
8870 (define_expand "one_cmpl<mode>2"
8871 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8872 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8874 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8876 (define_insn "*one_cmpl<mode>2_1"
8877 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8878 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8879 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8880 "not{<imodesuffix>}\t%0"
8881 [(set_attr "type" "negnot")
8882 (set_attr "mode" "<MODE>")])
8884 ;; %%% Potential partial reg stall on alternative 1. What to do?
8885 (define_insn "*one_cmplqi2_1"
8886 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8887 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8888 "ix86_unary_operator_ok (NOT, QImode, operands)"
8892 [(set_attr "type" "negnot")
8893 (set_attr "mode" "QI,SI")])
8895 ;; ??? Currently never generated - xor is used instead.
8896 (define_insn "*one_cmplsi2_1_zext"
8897 [(set (match_operand:DI 0 "register_operand" "=r")
8899 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8900 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8902 [(set_attr "type" "negnot")
8903 (set_attr "mode" "SI")])
8905 (define_insn "*one_cmpl<mode>2_2"
8906 [(set (reg FLAGS_REG)
8907 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8909 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8910 (not:SWI (match_dup 1)))]
8911 "ix86_match_ccmode (insn, CCNOmode)
8912 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8914 [(set_attr "type" "alu1")
8915 (set_attr "mode" "<MODE>")])
8918 [(set (match_operand 0 "flags_reg_operand" "")
8919 (match_operator 2 "compare_operator"
8920 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8922 (set (match_operand:SWI 1 "nonimmediate_operand" "")
8923 (not:SWI (match_dup 3)))]
8924 "ix86_match_ccmode (insn, CCNOmode)"
8925 [(parallel [(set (match_dup 0)
8926 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8929 (xor:SWI (match_dup 3) (const_int -1)))])])
8931 ;; ??? Currently never generated - xor is used instead.
8932 (define_insn "*one_cmplsi2_2_zext"
8933 [(set (reg FLAGS_REG)
8934 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8936 (set (match_operand:DI 0 "register_operand" "=r")
8937 (zero_extend:DI (not:SI (match_dup 1))))]
8938 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8939 && ix86_unary_operator_ok (NOT, SImode, operands)"
8941 [(set_attr "type" "alu1")
8942 (set_attr "mode" "SI")])
8945 [(set (match_operand 0 "flags_reg_operand" "")
8946 (match_operator 2 "compare_operator"
8947 [(not:SI (match_operand:SI 3 "register_operand" ""))
8949 (set (match_operand:DI 1 "register_operand" "")
8950 (zero_extend:DI (not:SI (match_dup 3))))]
8951 "ix86_match_ccmode (insn, CCNOmode)"
8952 [(parallel [(set (match_dup 0)
8953 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8956 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8958 ;; Shift instructions
8960 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8961 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8962 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8963 ;; from the assembler input.
8965 ;; This instruction shifts the target reg/mem as usual, but instead of
8966 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8967 ;; is a left shift double, bits are taken from the high order bits of
8968 ;; reg, else if the insn is a shift right double, bits are taken from the
8969 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8970 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8972 ;; Since sh[lr]d does not change the `reg' operand, that is done
8973 ;; separately, making all shifts emit pairs of shift double and normal
8974 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8975 ;; support a 63 bit shift, each shift where the count is in a reg expands
8976 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8978 ;; If the shift count is a constant, we need never emit more than one
8979 ;; shift pair, instead using moves and sign extension for counts greater
8982 (define_expand "ashl<mode>3"
8983 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8984 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8985 (match_operand:QI 2 "nonmemory_operand" "")))]
8987 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8989 (define_insn "*ashl<mode>3_doubleword"
8990 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8991 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8992 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8993 (clobber (reg:CC FLAGS_REG))]
8996 [(set_attr "type" "multi")])
8999 [(set (match_operand:DWI 0 "register_operand" "")
9000 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
9001 (match_operand:QI 2 "nonmemory_operand" "")))
9002 (clobber (reg:CC FLAGS_REG))]
9003 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9005 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9007 ;; By default we don't ask for a scratch register, because when DWImode
9008 ;; values are manipulated, registers are already at a premium. But if
9009 ;; we have one handy, we won't turn it away.
9012 [(match_scratch:DWIH 3 "r")
9013 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9015 (match_operand:<DWI> 1 "nonmemory_operand" "")
9016 (match_operand:QI 2 "nonmemory_operand" "")))
9017 (clobber (reg:CC FLAGS_REG))])
9021 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9023 (define_insn "x86_64_shld"
9024 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9025 (ior:DI (ashift:DI (match_dup 0)
9026 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9027 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9028 (minus:QI (const_int 64) (match_dup 2)))))
9029 (clobber (reg:CC FLAGS_REG))]
9031 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9032 [(set_attr "type" "ishift")
9033 (set_attr "prefix_0f" "1")
9034 (set_attr "mode" "DI")
9035 (set_attr "athlon_decode" "vector")
9036 (set_attr "amdfam10_decode" "vector")])
9038 (define_insn "x86_shld"
9039 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9040 (ior:SI (ashift:SI (match_dup 0)
9041 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9042 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9043 (minus:QI (const_int 32) (match_dup 2)))))
9044 (clobber (reg:CC FLAGS_REG))]
9046 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9047 [(set_attr "type" "ishift")
9048 (set_attr "prefix_0f" "1")
9049 (set_attr "mode" "SI")
9050 (set_attr "pent_pair" "np")
9051 (set_attr "athlon_decode" "vector")
9052 (set_attr "amdfam10_decode" "vector")])
9054 (define_expand "x86_shift<mode>_adj_1"
9055 [(set (reg:CCZ FLAGS_REG)
9056 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9059 (set (match_operand:SWI48 0 "register_operand" "")
9060 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9061 (match_operand:SWI48 1 "register_operand" "")
9064 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9065 (match_operand:SWI48 3 "register_operand" "r")
9068 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9070 (define_expand "x86_shift<mode>_adj_2"
9071 [(use (match_operand:SWI48 0 "register_operand" ""))
9072 (use (match_operand:SWI48 1 "register_operand" ""))
9073 (use (match_operand:QI 2 "register_operand" ""))]
9076 rtx label = gen_label_rtx ();
9079 emit_insn (gen_testqi_ccz_1 (operands[2],
9080 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9082 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9083 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9084 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9085 gen_rtx_LABEL_REF (VOIDmode, label),
9087 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9088 JUMP_LABEL (tmp) = label;
9090 emit_move_insn (operands[0], operands[1]);
9091 ix86_expand_clear (operands[1]);
9094 LABEL_NUSES (label) = 1;
9099 (define_insn "*ashl<mode>3_1"
9100 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9101 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9102 (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9103 (clobber (reg:CC FLAGS_REG))]
9104 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9106 switch (get_attr_type (insn))
9112 gcc_assert (operands[2] == const1_rtx);
9113 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9114 return "add{<imodesuffix>}\t%0, %0";
9117 if (operands[2] == const1_rtx
9118 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9119 return "sal{<imodesuffix>}\t%0";
9121 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9125 (cond [(eq_attr "alternative" "1")
9126 (const_string "lea")
9127 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9129 (match_operand 0 "register_operand" ""))
9130 (match_operand 2 "const1_operand" ""))
9131 (const_string "alu")
9133 (const_string "ishift")))
9134 (set (attr "length_immediate")
9136 (ior (eq_attr "type" "alu")
9137 (and (eq_attr "type" "ishift")
9138 (and (match_operand 2 "const1_operand" "")
9139 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9142 (const_string "*")))
9143 (set_attr "mode" "<MODE>")])
9145 (define_insn "*ashlsi3_1_zext"
9146 [(set (match_operand:DI 0 "register_operand" "=r,r")
9148 (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9149 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9150 (clobber (reg:CC FLAGS_REG))]
9151 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9153 switch (get_attr_type (insn))
9159 gcc_assert (operands[2] == const1_rtx);
9160 return "add{l}\t%k0, %k0";
9163 if (operands[2] == const1_rtx
9164 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9165 return "sal{l}\t%k0";
9167 return "sal{l}\t{%2, %k0|%k0, %2}";
9171 (cond [(eq_attr "alternative" "1")
9172 (const_string "lea")
9173 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9175 (match_operand 2 "const1_operand" ""))
9176 (const_string "alu")
9178 (const_string "ishift")))
9179 (set (attr "length_immediate")
9181 (ior (eq_attr "type" "alu")
9182 (and (eq_attr "type" "ishift")
9183 (and (match_operand 2 "const1_operand" "")
9184 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9187 (const_string "*")))
9188 (set_attr "mode" "SI")])
9190 (define_insn "*ashlhi3_1"
9191 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9192 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9193 (match_operand:QI 2 "nonmemory_operand" "cI")))
9194 (clobber (reg:CC FLAGS_REG))]
9195 "TARGET_PARTIAL_REG_STALL
9196 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9198 switch (get_attr_type (insn))
9201 gcc_assert (operands[2] == const1_rtx);
9202 return "add{w}\t%0, %0";
9205 if (operands[2] == const1_rtx
9206 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9207 return "sal{w}\t%0";
9209 return "sal{w}\t{%2, %0|%0, %2}";
9213 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9215 (match_operand 0 "register_operand" ""))
9216 (match_operand 2 "const1_operand" ""))
9217 (const_string "alu")
9219 (const_string "ishift")))
9220 (set (attr "length_immediate")
9222 (ior (eq_attr "type" "alu")
9223 (and (eq_attr "type" "ishift")
9224 (and (match_operand 2 "const1_operand" "")
9225 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9228 (const_string "*")))
9229 (set_attr "mode" "HI")])
9231 (define_insn "*ashlhi3_1_lea"
9232 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9233 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9234 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9235 (clobber (reg:CC FLAGS_REG))]
9236 "!TARGET_PARTIAL_REG_STALL
9237 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9239 switch (get_attr_type (insn))
9245 gcc_assert (operands[2] == const1_rtx);
9246 return "add{w}\t%0, %0";
9249 if (operands[2] == const1_rtx
9250 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9251 return "sal{w}\t%0";
9253 return "sal{w}\t{%2, %0|%0, %2}";
9257 (cond [(eq_attr "alternative" "1")
9258 (const_string "lea")
9259 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9261 (match_operand 0 "register_operand" ""))
9262 (match_operand 2 "const1_operand" ""))
9263 (const_string "alu")
9265 (const_string "ishift")))
9266 (set (attr "length_immediate")
9268 (ior (eq_attr "type" "alu")
9269 (and (eq_attr "type" "ishift")
9270 (and (match_operand 2 "const1_operand" "")
9271 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9274 (const_string "*")))
9275 (set_attr "mode" "HI,SI")])
9277 (define_insn "*ashlqi3_1"
9278 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9279 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9280 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9281 (clobber (reg:CC FLAGS_REG))]
9282 "TARGET_PARTIAL_REG_STALL
9283 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9285 switch (get_attr_type (insn))
9288 gcc_assert (operands[2] == const1_rtx);
9289 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9290 return "add{l}\t%k0, %k0";
9292 return "add{b}\t%0, %0";
9295 if (operands[2] == const1_rtx
9296 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9298 if (get_attr_mode (insn) == MODE_SI)
9299 return "sal{l}\t%k0";
9301 return "sal{b}\t%0";
9305 if (get_attr_mode (insn) == MODE_SI)
9306 return "sal{l}\t{%2, %k0|%k0, %2}";
9308 return "sal{b}\t{%2, %0|%0, %2}";
9313 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9315 (match_operand 0 "register_operand" ""))
9316 (match_operand 2 "const1_operand" ""))
9317 (const_string "alu")
9319 (const_string "ishift")))
9320 (set (attr "length_immediate")
9322 (ior (eq_attr "type" "alu")
9323 (and (eq_attr "type" "ishift")
9324 (and (match_operand 2 "const1_operand" "")
9325 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9328 (const_string "*")))
9329 (set_attr "mode" "QI,SI")])
9331 ;; %%% Potential partial reg stall on alternative 2. What to do?
9332 (define_insn "*ashlqi3_1_lea"
9333 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9334 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9335 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9336 (clobber (reg:CC FLAGS_REG))]
9337 "!TARGET_PARTIAL_REG_STALL
9338 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9340 switch (get_attr_type (insn))
9346 gcc_assert (operands[2] == const1_rtx);
9347 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9348 return "add{l}\t%k0, %k0";
9350 return "add{b}\t%0, %0";
9353 if (operands[2] == const1_rtx
9354 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9356 if (get_attr_mode (insn) == MODE_SI)
9357 return "sal{l}\t%k0";
9359 return "sal{b}\t%0";
9363 if (get_attr_mode (insn) == MODE_SI)
9364 return "sal{l}\t{%2, %k0|%k0, %2}";
9366 return "sal{b}\t{%2, %0|%0, %2}";
9371 (cond [(eq_attr "alternative" "2")
9372 (const_string "lea")
9373 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9375 (match_operand 0 "register_operand" ""))
9376 (match_operand 2 "const1_operand" ""))
9377 (const_string "alu")
9379 (const_string "ishift")))
9380 (set (attr "length_immediate")
9382 (ior (eq_attr "type" "alu")
9383 (and (eq_attr "type" "ishift")
9384 (and (match_operand 2 "const1_operand" "")
9385 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9388 (const_string "*")))
9389 (set_attr "mode" "QI,SI,SI")])
9391 (define_insn "*ashlqi3_1_slp"
9392 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9393 (ashift:QI (match_dup 0)
9394 (match_operand:QI 1 "nonmemory_operand" "cI")))
9395 (clobber (reg:CC FLAGS_REG))]
9396 "(optimize_function_for_size_p (cfun)
9397 || !TARGET_PARTIAL_FLAG_REG_STALL
9398 || (operands[1] == const1_rtx
9400 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9402 switch (get_attr_type (insn))
9405 gcc_assert (operands[1] == const1_rtx);
9406 return "add{b}\t%0, %0";
9409 if (operands[1] == const1_rtx
9410 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9411 return "sal{b}\t%0";
9413 return "sal{b}\t{%1, %0|%0, %1}";
9417 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9419 (match_operand 0 "register_operand" ""))
9420 (match_operand 1 "const1_operand" ""))
9421 (const_string "alu")
9423 (const_string "ishift1")))
9424 (set (attr "length_immediate")
9426 (ior (eq_attr "type" "alu")
9427 (and (eq_attr "type" "ishift1")
9428 (and (match_operand 1 "const1_operand" "")
9429 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9432 (const_string "*")))
9433 (set_attr "mode" "QI")])
9435 ;; Convert lea to the lea pattern to avoid flags dependency.
9437 [(set (match_operand 0 "register_operand" "")
9438 (ashift (match_operand 1 "index_register_operand" "")
9439 (match_operand:QI 2 "const_int_operand" "")))
9440 (clobber (reg:CC FLAGS_REG))]
9442 && true_regnum (operands[0]) != true_regnum (operands[1])"
9446 enum machine_mode mode = GET_MODE (operands[0]);
9449 operands[1] = gen_lowpart (Pmode, operands[1]);
9450 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9452 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9454 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9455 operands[0] = gen_lowpart (SImode, operands[0]);
9457 if (TARGET_64BIT && mode != Pmode)
9458 pat = gen_rtx_SUBREG (SImode, pat, 0);
9460 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9464 ;; Convert lea to the lea pattern to avoid flags dependency.
9466 [(set (match_operand:DI 0 "register_operand" "")
9468 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9469 (match_operand:QI 2 "const_int_operand" ""))))
9470 (clobber (reg:CC FLAGS_REG))]
9471 "TARGET_64BIT && reload_completed
9472 && true_regnum (operands[0]) != true_regnum (operands[1])"
9474 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9476 operands[1] = gen_lowpart (DImode, operands[1]);
9477 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9480 ;; This pattern can't accept a variable shift count, since shifts by
9481 ;; zero don't affect the flags. We assume that shifts by constant
9482 ;; zero are optimized away.
9483 (define_insn "*ashl<mode>3_cmp"
9484 [(set (reg FLAGS_REG)
9486 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9487 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9489 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9490 (ashift:SWI (match_dup 1) (match_dup 2)))]
9491 "(optimize_function_for_size_p (cfun)
9492 || !TARGET_PARTIAL_FLAG_REG_STALL
9493 || (operands[2] == const1_rtx
9495 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9496 && ix86_match_ccmode (insn, CCGOCmode)
9497 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9499 switch (get_attr_type (insn))
9502 gcc_assert (operands[2] == const1_rtx);
9503 return "add{<imodesuffix>}\t%0, %0";
9506 if (operands[2] == const1_rtx
9507 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9508 return "sal{<imodesuffix>}\t%0";
9510 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9514 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9516 (match_operand 0 "register_operand" ""))
9517 (match_operand 2 "const1_operand" ""))
9518 (const_string "alu")
9520 (const_string "ishift")))
9521 (set (attr "length_immediate")
9523 (ior (eq_attr "type" "alu")
9524 (and (eq_attr "type" "ishift")
9525 (and (match_operand 2 "const1_operand" "")
9526 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9529 (const_string "*")))
9530 (set_attr "mode" "<MODE>")])
9532 (define_insn "*ashlsi3_cmp_zext"
9533 [(set (reg FLAGS_REG)
9535 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9536 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9538 (set (match_operand:DI 0 "register_operand" "=r")
9539 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9541 && (optimize_function_for_size_p (cfun)
9542 || !TARGET_PARTIAL_FLAG_REG_STALL
9543 || (operands[2] == const1_rtx
9545 || TARGET_DOUBLE_WITH_ADD)))
9546 && ix86_match_ccmode (insn, CCGOCmode)
9547 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9549 switch (get_attr_type (insn))
9552 gcc_assert (operands[2] == const1_rtx);
9553 return "add{l}\t%k0, %k0";
9556 if (operands[2] == const1_rtx
9557 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9558 return "sal{l}\t%k0";
9560 return "sal{l}\t{%2, %k0|%k0, %2}";
9564 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9566 (match_operand 2 "const1_operand" ""))
9567 (const_string "alu")
9569 (const_string "ishift")))
9570 (set (attr "length_immediate")
9572 (ior (eq_attr "type" "alu")
9573 (and (eq_attr "type" "ishift")
9574 (and (match_operand 2 "const1_operand" "")
9575 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9578 (const_string "*")))
9579 (set_attr "mode" "SI")])
9581 (define_insn "*ashl<mode>3_cconly"
9582 [(set (reg FLAGS_REG)
9584 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9585 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9587 (clobber (match_scratch:SWI 0 "=<r>"))]
9588 "(optimize_function_for_size_p (cfun)
9589 || !TARGET_PARTIAL_FLAG_REG_STALL
9590 || (operands[2] == const1_rtx
9592 || TARGET_DOUBLE_WITH_ADD)))
9593 && ix86_match_ccmode (insn, CCGOCmode)
9594 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9596 switch (get_attr_type (insn))
9599 gcc_assert (operands[2] == const1_rtx);
9600 return "add{<imodesuffix>}\t%0, %0";
9603 if (operands[2] == const1_rtx
9604 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9605 return "sal{<imodesuffix>}\t%0";
9607 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9611 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9613 (match_operand 0 "register_operand" ""))
9614 (match_operand 2 "const1_operand" ""))
9615 (const_string "alu")
9617 (const_string "ishift")))
9618 (set (attr "length_immediate")
9620 (ior (eq_attr "type" "alu")
9621 (and (eq_attr "type" "ishift")
9622 (and (match_operand 2 "const1_operand" "")
9623 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9626 (const_string "*")))
9627 (set_attr "mode" "<MODE>")])
9629 ;; See comment above `ashl<mode>3' about how this works.
9631 (define_expand "<shiftrt_insn><mode>3"
9632 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9633 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9634 (match_operand:QI 2 "nonmemory_operand" "")))]
9636 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9638 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9639 [(set (match_operand:DWI 0 "register_operand" "=r")
9640 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9641 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9642 (clobber (reg:CC FLAGS_REG))]
9645 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9647 "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9648 [(set_attr "type" "multi")])
9650 ;; By default we don't ask for a scratch register, because when DWImode
9651 ;; values are manipulated, registers are already at a premium. But if
9652 ;; we have one handy, we won't turn it away.
9655 [(match_scratch:DWIH 3 "r")
9656 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9658 (match_operand:<DWI> 1 "register_operand" "")
9659 (match_operand:QI 2 "nonmemory_operand" "")))
9660 (clobber (reg:CC FLAGS_REG))])
9664 "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9666 (define_insn "x86_64_shrd"
9667 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9668 (ior:DI (ashiftrt:DI (match_dup 0)
9669 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9670 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9671 (minus:QI (const_int 64) (match_dup 2)))))
9672 (clobber (reg:CC FLAGS_REG))]
9674 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9675 [(set_attr "type" "ishift")
9676 (set_attr "prefix_0f" "1")
9677 (set_attr "mode" "DI")
9678 (set_attr "athlon_decode" "vector")
9679 (set_attr "amdfam10_decode" "vector")])
9681 (define_insn "x86_shrd"
9682 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9683 (ior:SI (ashiftrt:SI (match_dup 0)
9684 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9685 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9686 (minus:QI (const_int 32) (match_dup 2)))))
9687 (clobber (reg:CC FLAGS_REG))]
9689 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9690 [(set_attr "type" "ishift")
9691 (set_attr "prefix_0f" "1")
9692 (set_attr "mode" "SI")
9693 (set_attr "pent_pair" "np")
9694 (set_attr "athlon_decode" "vector")
9695 (set_attr "amdfam10_decode" "vector")])
9697 (define_insn "ashrdi3_cvt"
9698 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9699 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9700 (match_operand:QI 2 "const_int_operand" "")))
9701 (clobber (reg:CC FLAGS_REG))]
9702 "TARGET_64BIT && INTVAL (operands[2]) == 63
9703 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9704 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9707 sar{q}\t{%2, %0|%0, %2}"
9708 [(set_attr "type" "imovx,ishift")
9709 (set_attr "prefix_0f" "0,*")
9710 (set_attr "length_immediate" "0,*")
9711 (set_attr "modrm" "0,1")
9712 (set_attr "mode" "DI")])
9714 (define_insn "ashrsi3_cvt"
9715 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9716 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9717 (match_operand:QI 2 "const_int_operand" "")))
9718 (clobber (reg:CC FLAGS_REG))]
9719 "INTVAL (operands[2]) == 31
9720 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9721 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9724 sar{l}\t{%2, %0|%0, %2}"
9725 [(set_attr "type" "imovx,ishift")
9726 (set_attr "prefix_0f" "0,*")
9727 (set_attr "length_immediate" "0,*")
9728 (set_attr "modrm" "0,1")
9729 (set_attr "mode" "SI")])
9731 (define_insn "*ashrsi3_cvt_zext"
9732 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9734 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9735 (match_operand:QI 2 "const_int_operand" ""))))
9736 (clobber (reg:CC FLAGS_REG))]
9737 "TARGET_64BIT && INTVAL (operands[2]) == 31
9738 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9739 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9742 sar{l}\t{%2, %k0|%k0, %2}"
9743 [(set_attr "type" "imovx,ishift")
9744 (set_attr "prefix_0f" "0,*")
9745 (set_attr "length_immediate" "0,*")
9746 (set_attr "modrm" "0,1")
9747 (set_attr "mode" "SI")])
9749 (define_expand "x86_shift<mode>_adj_3"
9750 [(use (match_operand:SWI48 0 "register_operand" ""))
9751 (use (match_operand:SWI48 1 "register_operand" ""))
9752 (use (match_operand:QI 2 "register_operand" ""))]
9755 rtx label = gen_label_rtx ();
9758 emit_insn (gen_testqi_ccz_1 (operands[2],
9759 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9761 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9762 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9763 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9764 gen_rtx_LABEL_REF (VOIDmode, label),
9766 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9767 JUMP_LABEL (tmp) = label;
9769 emit_move_insn (operands[0], operands[1]);
9770 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9771 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9773 LABEL_NUSES (label) = 1;
9778 (define_insn "*<shiftrt_insn><mode>3_1"
9779 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9780 (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9781 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9782 (clobber (reg:CC FLAGS_REG))]
9783 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9785 if (operands[2] == const1_rtx
9786 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9787 return "<shiftrt>{<imodesuffix>}\t%0";
9789 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9791 [(set_attr "type" "ishift")
9792 (set (attr "length_immediate")
9794 (and (match_operand 2 "const1_operand" "")
9795 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9798 (const_string "*")))
9799 (set_attr "mode" "<MODE>")])
9801 (define_insn "*<shiftrt_insn>si3_1_zext"
9802 [(set (match_operand:DI 0 "register_operand" "=r")
9804 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9805 (match_operand:QI 2 "nonmemory_operand" "cI"))))
9806 (clobber (reg:CC FLAGS_REG))]
9807 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9809 if (operands[2] == const1_rtx
9810 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9811 return "<shiftrt>{l}\t%k0";
9813 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9815 [(set_attr "type" "ishift")
9816 (set (attr "length_immediate")
9818 (and (match_operand 2 "const1_operand" "")
9819 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9822 (const_string "*")))
9823 (set_attr "mode" "SI")])
9825 (define_insn "*<shiftrt_insn>qi3_1_slp"
9826 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9827 (any_shiftrt:QI (match_dup 0)
9828 (match_operand:QI 1 "nonmemory_operand" "cI")))
9829 (clobber (reg:CC FLAGS_REG))]
9830 "(optimize_function_for_size_p (cfun)
9831 || !TARGET_PARTIAL_REG_STALL
9832 || (operands[1] == const1_rtx
9835 if (operands[1] == const1_rtx
9836 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9837 return "<shiftrt>{b}\t%0";
9839 return "<shiftrt>{b}\t{%1, %0|%0, %1}";
9841 [(set_attr "type" "ishift1")
9842 (set (attr "length_immediate")
9844 (and (match_operand 1 "const1_operand" "")
9845 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9848 (const_string "*")))
9849 (set_attr "mode" "QI")])
9851 ;; This pattern can't accept a variable shift count, since shifts by
9852 ;; zero don't affect the flags. We assume that shifts by constant
9853 ;; zero are optimized away.
9854 (define_insn "*<shiftrt_insn><mode>3_cmp"
9855 [(set (reg FLAGS_REG)
9858 (match_operand:SWI 1 "nonimmediate_operand" "0")
9859 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9861 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9862 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9863 "(optimize_function_for_size_p (cfun)
9864 || !TARGET_PARTIAL_FLAG_REG_STALL
9865 || (operands[2] == const1_rtx
9867 && ix86_match_ccmode (insn, CCGOCmode)
9868 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9870 if (operands[2] == const1_rtx
9871 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9872 return "<shiftrt>{<imodesuffix>}\t%0";
9874 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9876 [(set_attr "type" "ishift")
9877 (set (attr "length_immediate")
9879 (and (match_operand 2 "const1_operand" "")
9880 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9883 (const_string "*")))
9884 (set_attr "mode" "<MODE>")])
9886 (define_insn "*<shiftrt_insn>si3_cmp_zext"
9887 [(set (reg FLAGS_REG)
9889 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9890 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9892 (set (match_operand:DI 0 "register_operand" "=r")
9893 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9895 && (optimize_function_for_size_p (cfun)
9896 || !TARGET_PARTIAL_FLAG_REG_STALL
9897 || (operands[2] == const1_rtx
9899 && ix86_match_ccmode (insn, CCGOCmode)
9900 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9902 if (operands[2] == const1_rtx
9903 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9904 return "<shiftrt>{l}\t%k0";
9906 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9908 [(set_attr "type" "ishift")
9909 (set (attr "length_immediate")
9911 (and (match_operand 2 "const1_operand" "")
9912 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9915 (const_string "*")))
9916 (set_attr "mode" "SI")])
9918 (define_insn "*<shiftrt_insn><mode>3_cconly"
9919 [(set (reg FLAGS_REG)
9922 (match_operand:SWI 1 "nonimmediate_operand" "0")
9923 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9925 (clobber (match_scratch:SWI 0 "=<r>"))]
9926 "(optimize_function_for_size_p (cfun)
9927 || !TARGET_PARTIAL_FLAG_REG_STALL
9928 || (operands[2] == const1_rtx
9930 && ix86_match_ccmode (insn, CCGOCmode)
9931 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9933 if (operands[2] == const1_rtx
9934 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9935 return "<shiftrt>{<imodesuffix>}\t%0";
9937 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9939 [(set_attr "type" "ishift")
9940 (set (attr "length_immediate")
9942 (and (match_operand 2 "const1_operand" "")
9943 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9946 (const_string "*")))
9947 (set_attr "mode" "<MODE>")])
9949 ;; Rotate instructions
9951 (define_expand "<rotate_insn>ti3"
9952 [(set (match_operand:TI 0 "register_operand" "")
9953 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
9954 (match_operand:QI 2 "nonmemory_operand" "")))]
9957 if (const_1_to_63_operand (operands[2], VOIDmode))
9958 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
9959 (operands[0], operands[1], operands[2]));
9966 (define_expand "<rotate_insn>di3"
9967 [(set (match_operand:DI 0 "shiftdi_operand" "")
9968 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
9969 (match_operand:QI 2 "nonmemory_operand" "")))]
9973 ix86_expand_binary_operator (<CODE>, DImode, operands);
9974 else if (const_1_to_31_operand (operands[2], VOIDmode))
9975 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
9976 (operands[0], operands[1], operands[2]));
9983 (define_expand "<rotate_insn><mode>3"
9984 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
9985 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
9986 (match_operand:QI 2 "nonmemory_operand" "")))]
9988 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9990 ;; Implement rotation using two double-precision
9991 ;; shift instructions and a scratch register.
9993 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
9994 [(set (match_operand:<DWI> 0 "register_operand" "=r")
9995 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
9996 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
9997 (clobber (reg:CC FLAGS_REG))
9998 (clobber (match_scratch:DWIH 3 "=&r"))]
10002 [(set (match_dup 3) (match_dup 4))
10004 [(set (match_dup 4)
10005 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10006 (lshiftrt:DWIH (match_dup 5)
10007 (minus:QI (match_dup 6) (match_dup 2)))))
10008 (clobber (reg:CC FLAGS_REG))])
10010 [(set (match_dup 5)
10011 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10012 (lshiftrt:DWIH (match_dup 3)
10013 (minus:QI (match_dup 6) (match_dup 2)))))
10014 (clobber (reg:CC FLAGS_REG))])]
10016 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10018 split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
10021 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10022 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10023 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10024 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10025 (clobber (reg:CC FLAGS_REG))
10026 (clobber (match_scratch:DWIH 3 "=&r"))]
10030 [(set (match_dup 3) (match_dup 4))
10032 [(set (match_dup 4)
10033 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10034 (ashift:DWIH (match_dup 5)
10035 (minus:QI (match_dup 6) (match_dup 2)))))
10036 (clobber (reg:CC FLAGS_REG))])
10038 [(set (match_dup 5)
10039 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10040 (ashift:DWIH (match_dup 3)
10041 (minus:QI (match_dup 6) (match_dup 2)))))
10042 (clobber (reg:CC FLAGS_REG))])]
10044 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10046 split_<dwi> (&operands[0], 1, &operands[4], &operands[5]);
10049 (define_insn "*<rotate_insn><mode>3_1"
10050 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10051 (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10052 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10053 (clobber (reg:CC FLAGS_REG))]
10054 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10056 if (operands[2] == const1_rtx
10057 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10058 return "<rotate>{<imodesuffix>}\t%0";
10060 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10062 [(set_attr "type" "rotate")
10063 (set (attr "length_immediate")
10065 (and (match_operand 2 "const1_operand" "")
10066 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10069 (const_string "*")))
10070 (set_attr "mode" "<MODE>")])
10072 (define_insn "*<rotate_insn>si3_1_zext"
10073 [(set (match_operand:DI 0 "register_operand" "=r")
10075 (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10076 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10077 (clobber (reg:CC FLAGS_REG))]
10078 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10080 if (operands[2] == const1_rtx
10081 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10082 return "<rotate>{l}\t%k0";
10084 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10086 [(set_attr "type" "rotate")
10087 (set (attr "length_immediate")
10089 (and (match_operand 2 "const1_operand" "")
10090 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10093 (const_string "*")))
10094 (set_attr "mode" "SI")])
10096 (define_insn "*<rotate_insn>qi3_1_slp"
10097 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10098 (any_rotate:QI (match_dup 0)
10099 (match_operand:QI 1 "nonmemory_operand" "cI")))
10100 (clobber (reg:CC FLAGS_REG))]
10101 "(optimize_function_for_size_p (cfun)
10102 || !TARGET_PARTIAL_REG_STALL
10103 || (operands[1] == const1_rtx
10104 && TARGET_SHIFT1))"
10106 if (operands[1] == const1_rtx
10107 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10108 return "<rotate>{b}\t%0";
10110 return "<rotate>{b}\t{%1, %0|%0, %1}";
10112 [(set_attr "type" "rotate1")
10113 (set (attr "length_immediate")
10115 (and (match_operand 1 "const1_operand" "")
10116 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10119 (const_string "*")))
10120 (set_attr "mode" "QI")])
10123 [(set (match_operand:HI 0 "register_operand" "")
10124 (any_rotate:HI (match_dup 0) (const_int 8)))
10125 (clobber (reg:CC FLAGS_REG))]
10127 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10128 [(parallel [(set (strict_low_part (match_dup 0))
10129 (bswap:HI (match_dup 0)))
10130 (clobber (reg:CC FLAGS_REG))])])
10132 ;; Bit set / bit test instructions
10134 (define_expand "extv"
10135 [(set (match_operand:SI 0 "register_operand" "")
10136 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10137 (match_operand:SI 2 "const8_operand" "")
10138 (match_operand:SI 3 "const8_operand" "")))]
10141 /* Handle extractions from %ah et al. */
10142 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10145 /* From mips.md: extract_bit_field doesn't verify that our source
10146 matches the predicate, so check it again here. */
10147 if (! ext_register_operand (operands[1], VOIDmode))
10151 (define_expand "extzv"
10152 [(set (match_operand:SI 0 "register_operand" "")
10153 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10154 (match_operand:SI 2 "const8_operand" "")
10155 (match_operand:SI 3 "const8_operand" "")))]
10158 /* Handle extractions from %ah et al. */
10159 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10162 /* From mips.md: extract_bit_field doesn't verify that our source
10163 matches the predicate, so check it again here. */
10164 if (! ext_register_operand (operands[1], VOIDmode))
10168 (define_expand "insv"
10169 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
10170 (match_operand 1 "const8_operand" "")
10171 (match_operand 2 "const8_operand" ""))
10172 (match_operand 3 "register_operand" ""))]
10175 rtx (*gen_mov_insv_1) (rtx, rtx);
10177 /* Handle insertions to %ah et al. */
10178 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10181 /* From mips.md: insert_bit_field doesn't verify that our source
10182 matches the predicate, so check it again here. */
10183 if (! ext_register_operand (operands[0], VOIDmode))
10186 gen_mov_insv_1 = (TARGET_64BIT
10187 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10189 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10193 ;; %%% bts, btr, btc, bt.
10194 ;; In general these instructions are *slow* when applied to memory,
10195 ;; since they enforce atomic operation. When applied to registers,
10196 ;; it depends on the cpu implementation. They're never faster than
10197 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10198 ;; no point. But in 64-bit, we can't hold the relevant immediates
10199 ;; within the instruction itself, so operating on bits in the high
10200 ;; 32-bits of a register becomes easier.
10202 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10203 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10204 ;; negdf respectively, so they can never be disabled entirely.
10206 (define_insn "*btsq"
10207 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10209 (match_operand:DI 1 "const_0_to_63_operand" ""))
10211 (clobber (reg:CC FLAGS_REG))]
10212 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10213 "bts{q}\t{%1, %0|%0, %1}"
10214 [(set_attr "type" "alu1")
10215 (set_attr "prefix_0f" "1")
10216 (set_attr "mode" "DI")])
10218 (define_insn "*btrq"
10219 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10221 (match_operand:DI 1 "const_0_to_63_operand" ""))
10223 (clobber (reg:CC FLAGS_REG))]
10224 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10225 "btr{q}\t{%1, %0|%0, %1}"
10226 [(set_attr "type" "alu1")
10227 (set_attr "prefix_0f" "1")
10228 (set_attr "mode" "DI")])
10230 (define_insn "*btcq"
10231 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10233 (match_operand:DI 1 "const_0_to_63_operand" ""))
10234 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10235 (clobber (reg:CC FLAGS_REG))]
10236 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10237 "btc{q}\t{%1, %0|%0, %1}"
10238 [(set_attr "type" "alu1")
10239 (set_attr "prefix_0f" "1")
10240 (set_attr "mode" "DI")])
10242 ;; Allow Nocona to avoid these instructions if a register is available.
10245 [(match_scratch:DI 2 "r")
10246 (parallel [(set (zero_extract:DI
10247 (match_operand:DI 0 "register_operand" "")
10249 (match_operand:DI 1 "const_0_to_63_operand" ""))
10251 (clobber (reg:CC FLAGS_REG))])]
10252 "TARGET_64BIT && !TARGET_USE_BT"
10255 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10258 if (HOST_BITS_PER_WIDE_INT >= 64)
10259 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10260 else if (i < HOST_BITS_PER_WIDE_INT)
10261 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10263 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10265 op1 = immed_double_const (lo, hi, DImode);
10268 emit_move_insn (operands[2], op1);
10272 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10277 [(match_scratch:DI 2 "r")
10278 (parallel [(set (zero_extract:DI
10279 (match_operand:DI 0 "register_operand" "")
10281 (match_operand:DI 1 "const_0_to_63_operand" ""))
10283 (clobber (reg:CC FLAGS_REG))])]
10284 "TARGET_64BIT && !TARGET_USE_BT"
10287 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10290 if (HOST_BITS_PER_WIDE_INT >= 64)
10291 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10292 else if (i < HOST_BITS_PER_WIDE_INT)
10293 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10295 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10297 op1 = immed_double_const (~lo, ~hi, DImode);
10300 emit_move_insn (operands[2], op1);
10304 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10309 [(match_scratch:DI 2 "r")
10310 (parallel [(set (zero_extract:DI
10311 (match_operand:DI 0 "register_operand" "")
10313 (match_operand:DI 1 "const_0_to_63_operand" ""))
10314 (not:DI (zero_extract:DI
10315 (match_dup 0) (const_int 1) (match_dup 1))))
10316 (clobber (reg:CC FLAGS_REG))])]
10317 "TARGET_64BIT && !TARGET_USE_BT"
10320 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10323 if (HOST_BITS_PER_WIDE_INT >= 64)
10324 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10325 else if (i < HOST_BITS_PER_WIDE_INT)
10326 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10328 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10330 op1 = immed_double_const (lo, hi, DImode);
10333 emit_move_insn (operands[2], op1);
10337 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10341 (define_insn "*bt<mode>"
10342 [(set (reg:CCC FLAGS_REG)
10344 (zero_extract:SWI48
10345 (match_operand:SWI48 0 "register_operand" "r")
10347 (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10349 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10350 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10351 [(set_attr "type" "alu1")
10352 (set_attr "prefix_0f" "1")
10353 (set_attr "mode" "<MODE>")])
10355 ;; Store-flag instructions.
10357 ;; For all sCOND expanders, also expand the compare or test insn that
10358 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10360 (define_insn_and_split "*setcc_di_1"
10361 [(set (match_operand:DI 0 "register_operand" "=q")
10362 (match_operator:DI 1 "ix86_comparison_operator"
10363 [(reg FLAGS_REG) (const_int 0)]))]
10364 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10366 "&& reload_completed"
10367 [(set (match_dup 2) (match_dup 1))
10368 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10370 PUT_MODE (operands[1], QImode);
10371 operands[2] = gen_lowpart (QImode, operands[0]);
10374 (define_insn_and_split "*setcc_si_1_and"
10375 [(set (match_operand:SI 0 "register_operand" "=q")
10376 (match_operator:SI 1 "ix86_comparison_operator"
10377 [(reg FLAGS_REG) (const_int 0)]))
10378 (clobber (reg:CC FLAGS_REG))]
10379 "!TARGET_PARTIAL_REG_STALL
10380 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10382 "&& reload_completed"
10383 [(set (match_dup 2) (match_dup 1))
10384 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10385 (clobber (reg:CC FLAGS_REG))])]
10387 PUT_MODE (operands[1], QImode);
10388 operands[2] = gen_lowpart (QImode, operands[0]);
10391 (define_insn_and_split "*setcc_si_1_movzbl"
10392 [(set (match_operand:SI 0 "register_operand" "=q")
10393 (match_operator:SI 1 "ix86_comparison_operator"
10394 [(reg FLAGS_REG) (const_int 0)]))]
10395 "!TARGET_PARTIAL_REG_STALL
10396 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10398 "&& reload_completed"
10399 [(set (match_dup 2) (match_dup 1))
10400 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10402 PUT_MODE (operands[1], QImode);
10403 operands[2] = gen_lowpart (QImode, operands[0]);
10406 (define_insn "*setcc_qi"
10407 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10408 (match_operator:QI 1 "ix86_comparison_operator"
10409 [(reg FLAGS_REG) (const_int 0)]))]
10412 [(set_attr "type" "setcc")
10413 (set_attr "mode" "QI")])
10415 (define_insn "*setcc_qi_slp"
10416 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10417 (match_operator:QI 1 "ix86_comparison_operator"
10418 [(reg FLAGS_REG) (const_int 0)]))]
10421 [(set_attr "type" "setcc")
10422 (set_attr "mode" "QI")])
10424 ;; In general it is not safe to assume too much about CCmode registers,
10425 ;; so simplify-rtx stops when it sees a second one. Under certain
10426 ;; conditions this is safe on x86, so help combine not create
10433 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10434 (ne:QI (match_operator 1 "ix86_comparison_operator"
10435 [(reg FLAGS_REG) (const_int 0)])
10438 [(set (match_dup 0) (match_dup 1))]
10439 "PUT_MODE (operands[1], QImode);")
10442 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10443 (ne:QI (match_operator 1 "ix86_comparison_operator"
10444 [(reg FLAGS_REG) (const_int 0)])
10447 [(set (match_dup 0) (match_dup 1))]
10448 "PUT_MODE (operands[1], QImode);")
10451 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10452 (eq:QI (match_operator 1 "ix86_comparison_operator"
10453 [(reg FLAGS_REG) (const_int 0)])
10456 [(set (match_dup 0) (match_dup 1))]
10458 rtx new_op1 = copy_rtx (operands[1]);
10459 operands[1] = new_op1;
10460 PUT_MODE (new_op1, QImode);
10461 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10462 GET_MODE (XEXP (new_op1, 0))));
10464 /* Make sure that (a) the CCmode we have for the flags is strong
10465 enough for the reversed compare or (b) we have a valid FP compare. */
10466 if (! ix86_comparison_operator (new_op1, VOIDmode))
10471 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10472 (eq:QI (match_operator 1 "ix86_comparison_operator"
10473 [(reg FLAGS_REG) (const_int 0)])
10476 [(set (match_dup 0) (match_dup 1))]
10478 rtx new_op1 = copy_rtx (operands[1]);
10479 operands[1] = new_op1;
10480 PUT_MODE (new_op1, QImode);
10481 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10482 GET_MODE (XEXP (new_op1, 0))));
10484 /* Make sure that (a) the CCmode we have for the flags is strong
10485 enough for the reversed compare or (b) we have a valid FP compare. */
10486 if (! ix86_comparison_operator (new_op1, VOIDmode))
10490 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10491 ;; subsequent logical operations are used to imitate conditional moves.
10492 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10495 (define_insn "*avx_setcc<mode>"
10496 [(set (match_operand:MODEF 0 "register_operand" "=x")
10497 (match_operator:MODEF 1 "avx_comparison_float_operator"
10498 [(match_operand:MODEF 2 "register_operand" "x")
10499 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10501 "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
10502 [(set_attr "type" "ssecmp")
10503 (set_attr "prefix" "vex")
10504 (set_attr "length_immediate" "1")
10505 (set_attr "mode" "<MODE>")])
10507 (define_insn "*sse_setcc<mode>"
10508 [(set (match_operand:MODEF 0 "register_operand" "=x")
10509 (match_operator:MODEF 1 "sse_comparison_operator"
10510 [(match_operand:MODEF 2 "register_operand" "0")
10511 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10512 "SSE_FLOAT_MODE_P (<MODE>mode)"
10513 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
10514 [(set_attr "type" "ssecmp")
10515 (set_attr "length_immediate" "1")
10516 (set_attr "mode" "<MODE>")])
10518 ;; Basic conditional jump instructions.
10519 ;; We ignore the overflow flag for signed branch instructions.
10521 (define_insn "*jcc_1"
10523 (if_then_else (match_operator 1 "ix86_comparison_operator"
10524 [(reg FLAGS_REG) (const_int 0)])
10525 (label_ref (match_operand 0 "" ""))
10529 [(set_attr "type" "ibr")
10530 (set_attr "modrm" "0")
10531 (set (attr "length")
10532 (if_then_else (and (ge (minus (match_dup 0) (pc))
10534 (lt (minus (match_dup 0) (pc))
10539 (define_insn "*jcc_2"
10541 (if_then_else (match_operator 1 "ix86_comparison_operator"
10542 [(reg FLAGS_REG) (const_int 0)])
10544 (label_ref (match_operand 0 "" ""))))]
10547 [(set_attr "type" "ibr")
10548 (set_attr "modrm" "0")
10549 (set (attr "length")
10550 (if_then_else (and (ge (minus (match_dup 0) (pc))
10552 (lt (minus (match_dup 0) (pc))
10557 ;; In general it is not safe to assume too much about CCmode registers,
10558 ;; so simplify-rtx stops when it sees a second one. Under certain
10559 ;; conditions this is safe on x86, so help combine not create
10567 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10568 [(reg FLAGS_REG) (const_int 0)])
10570 (label_ref (match_operand 1 "" ""))
10574 (if_then_else (match_dup 0)
10575 (label_ref (match_dup 1))
10577 "PUT_MODE (operands[0], VOIDmode);")
10581 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10582 [(reg FLAGS_REG) (const_int 0)])
10584 (label_ref (match_operand 1 "" ""))
10588 (if_then_else (match_dup 0)
10589 (label_ref (match_dup 1))
10592 rtx new_op0 = copy_rtx (operands[0]);
10593 operands[0] = new_op0;
10594 PUT_MODE (new_op0, VOIDmode);
10595 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10596 GET_MODE (XEXP (new_op0, 0))));
10598 /* Make sure that (a) the CCmode we have for the flags is strong
10599 enough for the reversed compare or (b) we have a valid FP compare. */
10600 if (! ix86_comparison_operator (new_op0, VOIDmode))
10604 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10605 ;; pass generates from shift insn with QImode operand. Actually, the mode
10606 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10607 ;; appropriate modulo of the bit offset value.
10609 (define_insn_and_split "*jcc_bt<mode>"
10611 (if_then_else (match_operator 0 "bt_comparison_operator"
10612 [(zero_extract:SWI48
10613 (match_operand:SWI48 1 "register_operand" "r")
10616 (match_operand:QI 2 "register_operand" "r")))
10618 (label_ref (match_operand 3 "" ""))
10620 (clobber (reg:CC FLAGS_REG))]
10621 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10624 [(set (reg:CCC FLAGS_REG)
10626 (zero_extract:SWI48
10632 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10633 (label_ref (match_dup 3))
10636 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10638 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10641 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10642 ;; also for DImode, this is what combine produces.
10643 (define_insn_and_split "*jcc_bt<mode>_mask"
10645 (if_then_else (match_operator 0 "bt_comparison_operator"
10646 [(zero_extract:SWI48
10647 (match_operand:SWI48 1 "register_operand" "r")
10650 (match_operand:SI 2 "register_operand" "r")
10651 (match_operand:SI 3 "const_int_operand" "n")))])
10652 (label_ref (match_operand 4 "" ""))
10654 (clobber (reg:CC FLAGS_REG))]
10655 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10656 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10657 == GET_MODE_BITSIZE (<MODE>mode)-1"
10660 [(set (reg:CCC FLAGS_REG)
10662 (zero_extract:SWI48
10668 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10669 (label_ref (match_dup 4))
10672 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10674 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10677 (define_insn_and_split "*jcc_btsi_1"
10679 (if_then_else (match_operator 0 "bt_comparison_operator"
10682 (match_operand:SI 1 "register_operand" "r")
10683 (match_operand:QI 2 "register_operand" "r"))
10686 (label_ref (match_operand 3 "" ""))
10688 (clobber (reg:CC FLAGS_REG))]
10689 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10692 [(set (reg:CCC FLAGS_REG)
10700 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10701 (label_ref (match_dup 3))
10704 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10706 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10709 ;; avoid useless masking of bit offset operand
10710 (define_insn_and_split "*jcc_btsi_mask_1"
10713 (match_operator 0 "bt_comparison_operator"
10716 (match_operand:SI 1 "register_operand" "r")
10719 (match_operand:SI 2 "register_operand" "r")
10720 (match_operand:SI 3 "const_int_operand" "n")) 0))
10723 (label_ref (match_operand 4 "" ""))
10725 (clobber (reg:CC FLAGS_REG))]
10726 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10727 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10730 [(set (reg:CCC FLAGS_REG)
10738 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10739 (label_ref (match_dup 4))
10741 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10743 ;; Define combination compare-and-branch fp compare instructions to help
10746 (define_insn "*fp_jcc_1_387"
10748 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10749 [(match_operand 1 "register_operand" "f")
10750 (match_operand 2 "nonimmediate_operand" "fm")])
10751 (label_ref (match_operand 3 "" ""))
10753 (clobber (reg:CCFP FPSR_REG))
10754 (clobber (reg:CCFP FLAGS_REG))
10755 (clobber (match_scratch:HI 4 "=a"))]
10757 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10758 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10759 && SELECT_CC_MODE (GET_CODE (operands[0]),
10760 operands[1], operands[2]) == CCFPmode
10764 (define_insn "*fp_jcc_1r_387"
10766 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10767 [(match_operand 1 "register_operand" "f")
10768 (match_operand 2 "nonimmediate_operand" "fm")])
10770 (label_ref (match_operand 3 "" ""))))
10771 (clobber (reg:CCFP FPSR_REG))
10772 (clobber (reg:CCFP FLAGS_REG))
10773 (clobber (match_scratch:HI 4 "=a"))]
10775 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10776 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10777 && SELECT_CC_MODE (GET_CODE (operands[0]),
10778 operands[1], operands[2]) == CCFPmode
10782 (define_insn "*fp_jcc_2_387"
10784 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10785 [(match_operand 1 "register_operand" "f")
10786 (match_operand 2 "register_operand" "f")])
10787 (label_ref (match_operand 3 "" ""))
10789 (clobber (reg:CCFP FPSR_REG))
10790 (clobber (reg:CCFP FLAGS_REG))
10791 (clobber (match_scratch:HI 4 "=a"))]
10792 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10793 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10797 (define_insn "*fp_jcc_2r_387"
10799 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10800 [(match_operand 1 "register_operand" "f")
10801 (match_operand 2 "register_operand" "f")])
10803 (label_ref (match_operand 3 "" ""))))
10804 (clobber (reg:CCFP FPSR_REG))
10805 (clobber (reg:CCFP FLAGS_REG))
10806 (clobber (match_scratch:HI 4 "=a"))]
10807 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10808 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10812 (define_insn "*fp_jcc_3_387"
10814 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10815 [(match_operand 1 "register_operand" "f")
10816 (match_operand 2 "const0_operand" "")])
10817 (label_ref (match_operand 3 "" ""))
10819 (clobber (reg:CCFP FPSR_REG))
10820 (clobber (reg:CCFP FLAGS_REG))
10821 (clobber (match_scratch:HI 4 "=a"))]
10822 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10823 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10824 && SELECT_CC_MODE (GET_CODE (operands[0]),
10825 operands[1], operands[2]) == CCFPmode
10831 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10832 [(match_operand 1 "register_operand" "")
10833 (match_operand 2 "nonimmediate_operand" "")])
10834 (match_operand 3 "" "")
10835 (match_operand 4 "" "")))
10836 (clobber (reg:CCFP FPSR_REG))
10837 (clobber (reg:CCFP FLAGS_REG))]
10841 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10842 operands[3], operands[4], NULL_RTX, NULL_RTX);
10848 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10849 [(match_operand 1 "register_operand" "")
10850 (match_operand 2 "general_operand" "")])
10851 (match_operand 3 "" "")
10852 (match_operand 4 "" "")))
10853 (clobber (reg:CCFP FPSR_REG))
10854 (clobber (reg:CCFP FLAGS_REG))
10855 (clobber (match_scratch:HI 5 "=a"))]
10859 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10860 operands[3], operands[4], operands[5], NULL_RTX);
10864 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
10865 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
10866 ;; with a precedence over other operators and is always put in the first
10867 ;; place. Swap condition and operands to match ficom instruction.
10869 (define_insn "*fp_jcc_4_<mode>_387"
10872 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10873 [(match_operator 1 "float_operator"
10874 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
10875 (match_operand 3 "register_operand" "f,f")])
10876 (label_ref (match_operand 4 "" ""))
10878 (clobber (reg:CCFP FPSR_REG))
10879 (clobber (reg:CCFP FLAGS_REG))
10880 (clobber (match_scratch:HI 5 "=a,a"))]
10881 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
10882 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
10883 && GET_MODE (operands[1]) == GET_MODE (operands[3])
10884 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
10891 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10892 [(match_operator 1 "float_operator"
10893 [(match_operand:X87MODEI12 2 "memory_operand" "")])
10894 (match_operand 3 "register_operand" "")])
10895 (match_operand 4 "" "")
10896 (match_operand 5 "" "")))
10897 (clobber (reg:CCFP FPSR_REG))
10898 (clobber (reg:CCFP FLAGS_REG))
10899 (clobber (match_scratch:HI 6 "=a"))]
10903 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
10905 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10906 operands[3], operands[7],
10907 operands[4], operands[5], operands[6], NULL_RTX);
10911 ;; %%% Kill this when reload knows how to do it.
10915 (match_operator 0 "ix86_swapped_fp_comparison_operator"
10916 [(match_operator 1 "float_operator"
10917 [(match_operand:X87MODEI12 2 "register_operand" "")])
10918 (match_operand 3 "register_operand" "")])
10919 (match_operand 4 "" "")
10920 (match_operand 5 "" "")))
10921 (clobber (reg:CCFP FPSR_REG))
10922 (clobber (reg:CCFP FLAGS_REG))
10923 (clobber (match_scratch:HI 6 "=a"))]
10927 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
10928 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
10930 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
10931 operands[3], operands[7],
10932 operands[4], operands[5], operands[6], operands[2]);
10936 ;; Unconditional and other jump instructions
10938 (define_insn "jump"
10940 (label_ref (match_operand 0 "" "")))]
10943 [(set_attr "type" "ibr")
10944 (set (attr "length")
10945 (if_then_else (and (ge (minus (match_dup 0) (pc))
10947 (lt (minus (match_dup 0) (pc))
10951 (set_attr "modrm" "0")])
10953 (define_expand "indirect_jump"
10954 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
10958 (define_insn "*indirect_jump"
10959 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
10962 [(set_attr "type" "ibr")
10963 (set_attr "length_immediate" "0")])
10965 (define_expand "tablejump"
10966 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
10967 (use (label_ref (match_operand 1 "" "")))])]
10970 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
10971 relative. Convert the relative address to an absolute address. */
10975 enum rtx_code code;
10977 /* We can't use @GOTOFF for text labels on VxWorks;
10978 see gotoff_operand. */
10979 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
10983 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
10985 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
10989 op1 = pic_offset_table_rtx;
10994 op0 = pic_offset_table_rtx;
10998 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11003 (define_insn "*tablejump_1"
11004 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11005 (use (label_ref (match_operand 1 "" "")))]
11008 [(set_attr "type" "ibr")
11009 (set_attr "length_immediate" "0")])
11011 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11014 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11015 (set (match_operand:QI 1 "register_operand" "")
11016 (match_operator:QI 2 "ix86_comparison_operator"
11017 [(reg FLAGS_REG) (const_int 0)]))
11018 (set (match_operand 3 "q_regs_operand" "")
11019 (zero_extend (match_dup 1)))]
11020 "(peep2_reg_dead_p (3, operands[1])
11021 || operands_match_p (operands[1], operands[3]))
11022 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11023 [(set (match_dup 4) (match_dup 0))
11024 (set (strict_low_part (match_dup 5))
11027 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11028 operands[5] = gen_lowpart (QImode, operands[3]);
11029 ix86_expand_clear (operands[3]);
11032 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11035 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11036 (set (match_operand:QI 1 "register_operand" "")
11037 (match_operator:QI 2 "ix86_comparison_operator"
11038 [(reg FLAGS_REG) (const_int 0)]))
11039 (parallel [(set (match_operand 3 "q_regs_operand" "")
11040 (zero_extend (match_dup 1)))
11041 (clobber (reg:CC FLAGS_REG))])]
11042 "(peep2_reg_dead_p (3, operands[1])
11043 || operands_match_p (operands[1], operands[3]))
11044 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11045 [(set (match_dup 4) (match_dup 0))
11046 (set (strict_low_part (match_dup 5))
11049 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11050 operands[5] = gen_lowpart (QImode, operands[3]);
11051 ix86_expand_clear (operands[3]);
11054 ;; Call instructions.
11056 ;; The predicates normally associated with named expanders are not properly
11057 ;; checked for calls. This is a bug in the generic code, but it isn't that
11058 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11060 ;; P6 processors will jump to the address after the decrement when %esp
11061 ;; is used as a call operand, so they will execute return address as a code.
11062 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11064 ;; Call subroutine returning no value.
11066 (define_expand "call_pop"
11067 [(parallel [(call (match_operand:QI 0 "" "")
11068 (match_operand:SI 1 "" ""))
11069 (set (reg:SI SP_REG)
11070 (plus:SI (reg:SI SP_REG)
11071 (match_operand:SI 3 "" "")))])]
11074 ix86_expand_call (NULL, operands[0], operands[1],
11075 operands[2], operands[3], 0);
11079 (define_insn "*call_pop_0"
11080 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11081 (match_operand:SI 1 "" ""))
11082 (set (reg:SI SP_REG)
11083 (plus:SI (reg:SI SP_REG)
11084 (match_operand:SI 2 "immediate_operand" "")))]
11087 if (SIBLING_CALL_P (insn))
11090 return "call\t%P0";
11092 [(set_attr "type" "call")])
11094 (define_insn "*call_pop_1"
11095 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11096 (match_operand:SI 1 "" ""))
11097 (set (reg:SI SP_REG)
11098 (plus:SI (reg:SI SP_REG)
11099 (match_operand:SI 2 "immediate_operand" "i")))]
11100 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11102 if (constant_call_address_operand (operands[0], Pmode))
11103 return "call\t%P0";
11104 return "call\t%A0";
11106 [(set_attr "type" "call")])
11108 (define_insn "*sibcall_pop_1"
11109 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11110 (match_operand:SI 1 "" ""))
11111 (set (reg:SI SP_REG)
11112 (plus:SI (reg:SI SP_REG)
11113 (match_operand:SI 2 "immediate_operand" "i,i")))]
11114 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11118 [(set_attr "type" "call")])
11120 (define_expand "call"
11121 [(call (match_operand:QI 0 "" "")
11122 (match_operand 1 "" ""))
11123 (use (match_operand 2 "" ""))]
11126 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
11130 (define_expand "sibcall"
11131 [(call (match_operand:QI 0 "" "")
11132 (match_operand 1 "" ""))
11133 (use (match_operand 2 "" ""))]
11136 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
11140 (define_insn "*call_0"
11141 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11142 (match_operand 1 "" ""))]
11145 if (SIBLING_CALL_P (insn))
11148 return "call\t%P0";
11150 [(set_attr "type" "call")])
11152 (define_insn "*call_1"
11153 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11154 (match_operand 1 "" ""))]
11155 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11157 if (constant_call_address_operand (operands[0], Pmode))
11158 return "call\t%P0";
11159 return "call\t%A0";
11161 [(set_attr "type" "call")])
11163 (define_insn "*sibcall_1"
11164 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11165 (match_operand 1 "" ""))]
11166 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11170 [(set_attr "type" "call")])
11172 (define_insn "*call_1_rex64"
11173 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11174 (match_operand 1 "" ""))]
11175 "TARGET_64BIT && !SIBLING_CALL_P (insn)
11176 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11178 if (constant_call_address_operand (operands[0], Pmode))
11179 return "call\t%P0";
11180 return "call\t%A0";
11182 [(set_attr "type" "call")])
11184 (define_insn "*call_1_rex64_ms_sysv"
11185 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11186 (match_operand 1 "" ""))
11187 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11188 (clobber (reg:TI XMM6_REG))
11189 (clobber (reg:TI XMM7_REG))
11190 (clobber (reg:TI XMM8_REG))
11191 (clobber (reg:TI XMM9_REG))
11192 (clobber (reg:TI XMM10_REG))
11193 (clobber (reg:TI XMM11_REG))
11194 (clobber (reg:TI XMM12_REG))
11195 (clobber (reg:TI XMM13_REG))
11196 (clobber (reg:TI XMM14_REG))
11197 (clobber (reg:TI XMM15_REG))
11198 (clobber (reg:DI SI_REG))
11199 (clobber (reg:DI DI_REG))]
11200 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11202 if (constant_call_address_operand (operands[0], Pmode))
11203 return "call\t%P0";
11204 return "call\t%A0";
11206 [(set_attr "type" "call")])
11208 (define_insn "*call_1_rex64_large"
11209 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11210 (match_operand 1 "" ""))]
11211 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11213 [(set_attr "type" "call")])
11215 (define_insn "*sibcall_1_rex64"
11216 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11217 (match_operand 1 "" ""))]
11218 "TARGET_64BIT && SIBLING_CALL_P (insn)"
11222 [(set_attr "type" "call")])
11224 ;; Call subroutine, returning value in operand 0
11225 (define_expand "call_value_pop"
11226 [(parallel [(set (match_operand 0 "" "")
11227 (call (match_operand:QI 1 "" "")
11228 (match_operand:SI 2 "" "")))
11229 (set (reg:SI SP_REG)
11230 (plus:SI (reg:SI SP_REG)
11231 (match_operand:SI 4 "" "")))])]
11234 ix86_expand_call (operands[0], operands[1], operands[2],
11235 operands[3], operands[4], 0);
11239 (define_expand "call_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, 0);
11252 (define_expand "sibcall_value"
11253 [(set (match_operand 0 "" "")
11254 (call (match_operand:QI 1 "" "")
11255 (match_operand:SI 2 "" "")))
11256 (use (match_operand:SI 3 "" ""))]
11257 ;; Operand 3 is not used on the i386.
11260 ix86_expand_call (operands[0], operands[1], operands[2],
11261 operands[3], NULL, 1);
11265 ;; Call subroutine returning any type.
11267 (define_expand "untyped_call"
11268 [(parallel [(call (match_operand 0 "" "")
11270 (match_operand 1 "" "")
11271 (match_operand 2 "" "")])]
11276 /* In order to give reg-stack an easier job in validating two
11277 coprocessor registers as containing a possible return value,
11278 simply pretend the untyped call returns a complex long double
11281 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11282 and should have the default ABI. */
11284 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11285 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11286 operands[0], const0_rtx,
11287 GEN_INT ((TARGET_64BIT
11288 ? (ix86_abi == SYSV_ABI
11289 ? X86_64_SSE_REGPARM_MAX
11290 : X86_64_MS_SSE_REGPARM_MAX)
11291 : X86_32_SSE_REGPARM_MAX)
11295 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11297 rtx set = XVECEXP (operands[2], 0, i);
11298 emit_move_insn (SET_DEST (set), SET_SRC (set));
11301 /* The optimizer does not know that the call sets the function value
11302 registers we stored in the result block. We avoid problems by
11303 claiming that all hard registers are used and clobbered at this
11305 emit_insn (gen_blockage ());
11310 ;; Prologue and epilogue instructions
11312 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11313 ;; all of memory. This blocks insns from being moved across this point.
11315 (define_insn "blockage"
11316 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11319 [(set_attr "length" "0")])
11321 ;; Do not schedule instructions accessing memory across this point.
11323 (define_expand "memory_blockage"
11324 [(set (match_dup 0)
11325 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11328 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11329 MEM_VOLATILE_P (operands[0]) = 1;
11332 (define_insn "*memory_blockage"
11333 [(set (match_operand:BLK 0 "" "")
11334 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11337 [(set_attr "length" "0")])
11339 ;; As USE insns aren't meaningful after reload, this is used instead
11340 ;; to prevent deleting instructions setting registers for PIC code
11341 (define_insn "prologue_use"
11342 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11345 [(set_attr "length" "0")])
11347 ;; Insn emitted into the body of a function to return from a function.
11348 ;; This is only done if the function's epilogue is known to be simple.
11349 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11351 (define_expand "return"
11353 "ix86_can_use_return_insn_p ()"
11355 if (crtl->args.pops_args)
11357 rtx popc = GEN_INT (crtl->args.pops_args);
11358 emit_jump_insn (gen_return_pop_internal (popc));
11363 (define_insn "return_internal"
11367 [(set_attr "length" "1")
11368 (set_attr "atom_unit" "jeu")
11369 (set_attr "length_immediate" "0")
11370 (set_attr "modrm" "0")])
11372 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11373 ;; instruction Athlon and K8 have.
11375 (define_insn "return_internal_long"
11377 (unspec [(const_int 0)] UNSPEC_REP)]
11380 [(set_attr "length" "2")
11381 (set_attr "atom_unit" "jeu")
11382 (set_attr "length_immediate" "0")
11383 (set_attr "prefix_rep" "1")
11384 (set_attr "modrm" "0")])
11386 (define_insn "return_pop_internal"
11388 (use (match_operand:SI 0 "const_int_operand" ""))]
11391 [(set_attr "length" "3")
11392 (set_attr "atom_unit" "jeu")
11393 (set_attr "length_immediate" "2")
11394 (set_attr "modrm" "0")])
11396 (define_insn "return_indirect_internal"
11398 (use (match_operand:SI 0 "register_operand" "r"))]
11401 [(set_attr "type" "ibr")
11402 (set_attr "length_immediate" "0")])
11408 [(set_attr "length" "1")
11409 (set_attr "length_immediate" "0")
11410 (set_attr "modrm" "0")])
11412 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11413 ;; branch prediction penalty for the third jump in a 16-byte
11417 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11420 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11421 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11423 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11424 The align insn is used to avoid 3 jump instructions in the row to improve
11425 branch prediction and the benefits hardly outweigh the cost of extra 8
11426 nops on the average inserted by full alignment pseudo operation. */
11430 [(set_attr "length" "16")])
11432 (define_expand "prologue"
11435 "ix86_expand_prologue (); DONE;")
11437 (define_insn "set_got"
11438 [(set (match_operand:SI 0 "register_operand" "=r")
11439 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11440 (clobber (reg:CC FLAGS_REG))]
11442 { return output_set_got (operands[0], NULL_RTX); }
11443 [(set_attr "type" "multi")
11444 (set_attr "length" "12")])
11446 (define_insn "set_got_labelled"
11447 [(set (match_operand:SI 0 "register_operand" "=r")
11448 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11450 (clobber (reg:CC FLAGS_REG))]
11452 { return output_set_got (operands[0], operands[1]); }
11453 [(set_attr "type" "multi")
11454 (set_attr "length" "12")])
11456 (define_insn "set_got_rex64"
11457 [(set (match_operand:DI 0 "register_operand" "=r")
11458 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11460 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11461 [(set_attr "type" "lea")
11462 (set_attr "length_address" "4")
11463 (set_attr "mode" "DI")])
11465 (define_insn "set_rip_rex64"
11466 [(set (match_operand:DI 0 "register_operand" "=r")
11467 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11469 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11470 [(set_attr "type" "lea")
11471 (set_attr "length_address" "4")
11472 (set_attr "mode" "DI")])
11474 (define_insn "set_got_offset_rex64"
11475 [(set (match_operand:DI 0 "register_operand" "=r")
11477 [(label_ref (match_operand 1 "" ""))]
11478 UNSPEC_SET_GOT_OFFSET))]
11480 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11481 [(set_attr "type" "imov")
11482 (set_attr "length_immediate" "0")
11483 (set_attr "length_address" "8")
11484 (set_attr "mode" "DI")])
11486 (define_expand "epilogue"
11489 "ix86_expand_epilogue (1); DONE;")
11491 (define_expand "sibcall_epilogue"
11494 "ix86_expand_epilogue (0); DONE;")
11496 (define_expand "eh_return"
11497 [(use (match_operand 0 "register_operand" ""))]
11500 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11502 /* Tricky bit: we write the address of the handler to which we will
11503 be returning into someone else's stack frame, one word below the
11504 stack address we wish to restore. */
11505 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11506 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11507 tmp = gen_rtx_MEM (Pmode, tmp);
11508 emit_move_insn (tmp, ra);
11510 emit_jump_insn (gen_eh_return_internal ());
11515 (define_insn_and_split "eh_return_internal"
11519 "epilogue_completed"
11521 "ix86_expand_epilogue (2); DONE;")
11523 (define_insn "leave"
11524 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11525 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11526 (clobber (mem:BLK (scratch)))]
11529 [(set_attr "type" "leave")])
11531 (define_insn "leave_rex64"
11532 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11533 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11534 (clobber (mem:BLK (scratch)))]
11537 [(set_attr "type" "leave")])
11539 ;; Bit manipulation instructions.
11541 (define_expand "ffs<mode>2"
11542 [(set (match_dup 2) (const_int -1))
11543 (parallel [(set (reg:CCZ FLAGS_REG)
11545 (match_operand:SWI48 1 "nonimmediate_operand" "")
11547 (set (match_operand:SWI48 0 "register_operand" "")
11548 (ctz:SWI48 (match_dup 1)))])
11549 (set (match_dup 0) (if_then_else:SWI48
11550 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11553 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11554 (clobber (reg:CC FLAGS_REG))])]
11557 if (<MODE>mode == SImode && !TARGET_CMOVE)
11559 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11562 operands[2] = gen_reg_rtx (<MODE>mode);
11565 (define_insn_and_split "ffssi2_no_cmove"
11566 [(set (match_operand:SI 0 "register_operand" "=r")
11567 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11568 (clobber (match_scratch:SI 2 "=&q"))
11569 (clobber (reg:CC FLAGS_REG))]
11572 "&& reload_completed"
11573 [(parallel [(set (reg:CCZ FLAGS_REG)
11574 (compare:CCZ (match_dup 1) (const_int 0)))
11575 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11576 (set (strict_low_part (match_dup 3))
11577 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11578 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11579 (clobber (reg:CC FLAGS_REG))])
11580 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11581 (clobber (reg:CC FLAGS_REG))])
11582 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11583 (clobber (reg:CC FLAGS_REG))])]
11585 operands[3] = gen_lowpart (QImode, operands[2]);
11586 ix86_expand_clear (operands[2]);
11589 (define_insn "*ffs<mode>_1"
11590 [(set (reg:CCZ FLAGS_REG)
11591 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11593 (set (match_operand:SWI48 0 "register_operand" "=r")
11594 (ctz:SWI48 (match_dup 1)))]
11596 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11597 [(set_attr "type" "alu1")
11598 (set_attr "prefix_0f" "1")
11599 (set_attr "mode" "<MODE>")])
11601 (define_insn "ctz<mode>2"
11602 [(set (match_operand:SWI48 0 "register_operand" "=r")
11603 (ctz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
11604 (clobber (reg:CC FLAGS_REG))]
11606 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11607 [(set_attr "type" "alu1")
11608 (set_attr "prefix_0f" "1")
11609 (set_attr "mode" "<MODE>")])
11611 (define_expand "clz<mode>2"
11613 [(set (match_operand:SWI248 0 "register_operand" "")
11616 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
11617 (clobber (reg:CC FLAGS_REG))])
11619 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
11620 (clobber (reg:CC FLAGS_REG))])]
11625 emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
11628 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11631 (define_insn "clz<mode>2_abm"
11632 [(set (match_operand:SWI248 0 "register_operand" "=r")
11633 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11634 (clobber (reg:CC FLAGS_REG))]
11636 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11637 [(set_attr "prefix_rep" "1")
11638 (set_attr "type" "bitmanip")
11639 (set_attr "mode" "<MODE>")])
11641 (define_insn "bsr_rex64"
11642 [(set (match_operand:DI 0 "register_operand" "=r")
11643 (minus:DI (const_int 63)
11644 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
11645 (clobber (reg:CC FLAGS_REG))]
11647 "bsr{q}\t{%1, %0|%0, %1}"
11648 [(set_attr "type" "alu1")
11649 (set_attr "prefix_0f" "1")
11650 (set_attr "mode" "DI")])
11653 [(set (match_operand:SI 0 "register_operand" "=r")
11654 (minus:SI (const_int 31)
11655 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
11656 (clobber (reg:CC FLAGS_REG))]
11658 "bsr{l}\t{%1, %0|%0, %1}"
11659 [(set_attr "type" "alu1")
11660 (set_attr "prefix_0f" "1")
11661 (set_attr "mode" "SI")])
11663 (define_insn "*bsrhi"
11664 [(set (match_operand:HI 0 "register_operand" "=r")
11665 (minus:HI (const_int 15)
11666 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
11667 (clobber (reg:CC FLAGS_REG))]
11669 "bsr{w}\t{%1, %0|%0, %1}"
11670 [(set_attr "type" "alu1")
11671 (set_attr "prefix_0f" "1")
11672 (set_attr "mode" "HI")])
11674 (define_insn "popcount<mode>2"
11675 [(set (match_operand:SWI248 0 "register_operand" "=r")
11677 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11678 (clobber (reg:CC FLAGS_REG))]
11682 return "popcnt\t{%1, %0|%0, %1}";
11684 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11687 [(set_attr "prefix_rep" "1")
11688 (set_attr "type" "bitmanip")
11689 (set_attr "mode" "<MODE>")])
11691 (define_insn "*popcount<mode>2_cmp"
11692 [(set (reg FLAGS_REG)
11695 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
11697 (set (match_operand:SWI248 0 "register_operand" "=r")
11698 (popcount:SWI248 (match_dup 1)))]
11699 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
11702 return "popcnt\t{%1, %0|%0, %1}";
11704 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11707 [(set_attr "prefix_rep" "1")
11708 (set_attr "type" "bitmanip")
11709 (set_attr "mode" "<MODE>")])
11711 (define_insn "*popcountsi2_cmp_zext"
11712 [(set (reg FLAGS_REG)
11714 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
11716 (set (match_operand:DI 0 "register_operand" "=r")
11717 (zero_extend:DI(popcount:SI (match_dup 1))))]
11718 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
11721 return "popcnt\t{%1, %0|%0, %1}";
11723 return "popcnt{l}\t{%1, %0|%0, %1}";
11726 [(set_attr "prefix_rep" "1")
11727 (set_attr "type" "bitmanip")
11728 (set_attr "mode" "SI")])
11730 (define_expand "bswap<mode>2"
11731 [(set (match_operand:SWI48 0 "register_operand" "")
11732 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
11735 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
11737 rtx x = operands[0];
11739 emit_move_insn (x, operands[1]);
11740 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
11741 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
11742 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
11747 (define_insn "*bswap<mode>2_movbe"
11748 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
11749 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
11751 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11754 movbe\t{%1, %0|%0, %1}
11755 movbe\t{%1, %0|%0, %1}"
11756 [(set_attr "type" "bitmanip,imov,imov")
11757 (set_attr "modrm" "0,1,1")
11758 (set_attr "prefix_0f" "*,1,1")
11759 (set_attr "prefix_extra" "*,1,1")
11760 (set_attr "mode" "<MODE>")])
11762 (define_insn "*bswap<mode>2_1"
11763 [(set (match_operand:SWI48 0 "register_operand" "=r")
11764 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
11767 [(set_attr "type" "bitmanip")
11768 (set_attr "modrm" "0")
11769 (set_attr "mode" "<MODE>")])
11771 (define_insn "*bswaphi_lowpart_1"
11772 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
11773 (bswap:HI (match_dup 0)))
11774 (clobber (reg:CC FLAGS_REG))]
11775 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
11777 xchg{b}\t{%h0, %b0|%b0, %h0}
11778 rol{w}\t{$8, %0|%0, 8}"
11779 [(set_attr "length" "2,4")
11780 (set_attr "mode" "QI,HI")])
11782 (define_insn "bswaphi_lowpart"
11783 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
11784 (bswap:HI (match_dup 0)))
11785 (clobber (reg:CC FLAGS_REG))]
11787 "rol{w}\t{$8, %0|%0, 8}"
11788 [(set_attr "length" "4")
11789 (set_attr "mode" "HI")])
11791 (define_expand "paritydi2"
11792 [(set (match_operand:DI 0 "register_operand" "")
11793 (parity:DI (match_operand:DI 1 "register_operand" "")))]
11796 rtx scratch = gen_reg_rtx (QImode);
11799 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
11800 NULL_RTX, operands[1]));
11802 cond = gen_rtx_fmt_ee (ORDERED, QImode,
11803 gen_rtx_REG (CCmode, FLAGS_REG),
11805 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
11808 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
11811 rtx tmp = gen_reg_rtx (SImode);
11813 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
11814 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
11819 (define_expand "paritysi2"
11820 [(set (match_operand:SI 0 "register_operand" "")
11821 (parity:SI (match_operand:SI 1 "register_operand" "")))]
11824 rtx scratch = gen_reg_rtx (QImode);
11827 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
11829 cond = gen_rtx_fmt_ee (ORDERED, QImode,
11830 gen_rtx_REG (CCmode, FLAGS_REG),
11832 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
11834 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
11838 (define_insn_and_split "paritydi2_cmp"
11839 [(set (reg:CC FLAGS_REG)
11840 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
11842 (clobber (match_scratch:DI 0 "=r"))
11843 (clobber (match_scratch:SI 1 "=&r"))
11844 (clobber (match_scratch:HI 2 "=Q"))]
11847 "&& reload_completed"
11849 [(set (match_dup 1)
11850 (xor:SI (match_dup 1) (match_dup 4)))
11851 (clobber (reg:CC FLAGS_REG))])
11853 [(set (reg:CC FLAGS_REG)
11854 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
11855 (clobber (match_dup 1))
11856 (clobber (match_dup 2))])]
11858 operands[4] = gen_lowpart (SImode, operands[3]);
11862 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
11863 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
11866 operands[1] = gen_highpart (SImode, operands[3]);
11869 (define_insn_and_split "paritysi2_cmp"
11870 [(set (reg:CC FLAGS_REG)
11871 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
11873 (clobber (match_scratch:SI 0 "=r"))
11874 (clobber (match_scratch:HI 1 "=&Q"))]
11877 "&& reload_completed"
11879 [(set (match_dup 1)
11880 (xor:HI (match_dup 1) (match_dup 3)))
11881 (clobber (reg:CC FLAGS_REG))])
11883 [(set (reg:CC FLAGS_REG)
11884 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
11885 (clobber (match_dup 1))])]
11887 operands[3] = gen_lowpart (HImode, operands[2]);
11889 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
11890 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
11893 (define_insn "*parityhi2_cmp"
11894 [(set (reg:CC FLAGS_REG)
11895 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
11897 (clobber (match_scratch:HI 0 "=Q"))]
11899 "xor{b}\t{%h0, %b0|%b0, %h0}"
11900 [(set_attr "length" "2")
11901 (set_attr "mode" "HI")])
11903 ;; Thread-local storage patterns for ELF.
11905 ;; Note that these code sequences must appear exactly as shown
11906 ;; in order to allow linker relaxation.
11908 (define_insn "*tls_global_dynamic_32_gnu"
11909 [(set (match_operand:SI 0 "register_operand" "=a")
11910 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
11911 (match_operand:SI 2 "tls_symbolic_operand" "")
11912 (match_operand:SI 3 "call_insn_operand" "")]
11914 (clobber (match_scratch:SI 4 "=d"))
11915 (clobber (match_scratch:SI 5 "=c"))
11916 (clobber (reg:CC FLAGS_REG))]
11917 "!TARGET_64BIT && TARGET_GNU_TLS"
11918 "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
11919 [(set_attr "type" "multi")
11920 (set_attr "length" "12")])
11922 (define_expand "tls_global_dynamic_32"
11923 [(parallel [(set (match_operand:SI 0 "register_operand" "")
11926 (match_operand:SI 1 "tls_symbolic_operand" "")
11929 (clobber (match_scratch:SI 4 ""))
11930 (clobber (match_scratch:SI 5 ""))
11931 (clobber (reg:CC FLAGS_REG))])]
11935 operands[2] = pic_offset_table_rtx;
11938 operands[2] = gen_reg_rtx (Pmode);
11939 emit_insn (gen_set_got (operands[2]));
11941 if (TARGET_GNU2_TLS)
11943 emit_insn (gen_tls_dynamic_gnu2_32
11944 (operands[0], operands[1], operands[2]));
11947 operands[3] = ix86_tls_get_addr ();
11950 (define_insn "*tls_global_dynamic_64"
11951 [(set (match_operand:DI 0 "register_operand" "=a")
11952 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
11953 (match_operand:DI 3 "" "")))
11954 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
11957 { 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"; }
11958 [(set_attr "type" "multi")
11959 (set_attr "length" "16")])
11961 (define_expand "tls_global_dynamic_64"
11962 [(parallel [(set (match_operand:DI 0 "register_operand" "")
11963 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
11964 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
11968 if (TARGET_GNU2_TLS)
11970 emit_insn (gen_tls_dynamic_gnu2_64
11971 (operands[0], operands[1]));
11974 operands[2] = ix86_tls_get_addr ();
11977 (define_insn "*tls_local_dynamic_base_32_gnu"
11978 [(set (match_operand:SI 0 "register_operand" "=a")
11979 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
11980 (match_operand:SI 2 "call_insn_operand" "")]
11981 UNSPEC_TLS_LD_BASE))
11982 (clobber (match_scratch:SI 3 "=d"))
11983 (clobber (match_scratch:SI 4 "=c"))
11984 (clobber (reg:CC FLAGS_REG))]
11985 "!TARGET_64BIT && TARGET_GNU_TLS"
11986 "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
11987 [(set_attr "type" "multi")
11988 (set_attr "length" "11")])
11990 (define_expand "tls_local_dynamic_base_32"
11991 [(parallel [(set (match_operand:SI 0 "register_operand" "")
11992 (unspec:SI [(match_dup 1) (match_dup 2)]
11993 UNSPEC_TLS_LD_BASE))
11994 (clobber (match_scratch:SI 3 ""))
11995 (clobber (match_scratch:SI 4 ""))
11996 (clobber (reg:CC FLAGS_REG))])]
12000 operands[1] = pic_offset_table_rtx;
12003 operands[1] = gen_reg_rtx (Pmode);
12004 emit_insn (gen_set_got (operands[1]));
12006 if (TARGET_GNU2_TLS)
12008 emit_insn (gen_tls_dynamic_gnu2_32
12009 (operands[0], ix86_tls_module_base (), operands[1]));
12012 operands[2] = ix86_tls_get_addr ();
12015 (define_insn "*tls_local_dynamic_base_64"
12016 [(set (match_operand:DI 0 "register_operand" "=a")
12017 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
12018 (match_operand:DI 2 "" "")))
12019 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12021 "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
12022 [(set_attr "type" "multi")
12023 (set_attr "length" "12")])
12025 (define_expand "tls_local_dynamic_base_64"
12026 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12027 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
12028 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12031 if (TARGET_GNU2_TLS)
12033 emit_insn (gen_tls_dynamic_gnu2_64
12034 (operands[0], ix86_tls_module_base ()));
12037 operands[1] = ix86_tls_get_addr ();
12040 ;; Local dynamic of a single variable is a lose. Show combine how
12041 ;; to convert that back to global dynamic.
12043 (define_insn_and_split "*tls_local_dynamic_32_once"
12044 [(set (match_operand:SI 0 "register_operand" "=a")
12045 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12046 (match_operand:SI 2 "call_insn_operand" "")]
12047 UNSPEC_TLS_LD_BASE)
12048 (const:SI (unspec:SI
12049 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12051 (clobber (match_scratch:SI 4 "=d"))
12052 (clobber (match_scratch:SI 5 "=c"))
12053 (clobber (reg:CC FLAGS_REG))]
12057 [(parallel [(set (match_dup 0)
12058 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12060 (clobber (match_dup 4))
12061 (clobber (match_dup 5))
12062 (clobber (reg:CC FLAGS_REG))])]
12065 ;; Load and add the thread base pointer from %gs:0.
12067 (define_insn "*load_tp_si"
12068 [(set (match_operand:SI 0 "register_operand" "=r")
12069 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12071 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
12072 [(set_attr "type" "imov")
12073 (set_attr "modrm" "0")
12074 (set_attr "length" "7")
12075 (set_attr "memory" "load")
12076 (set_attr "imm_disp" "false")])
12078 (define_insn "*add_tp_si"
12079 [(set (match_operand:SI 0 "register_operand" "=r")
12080 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12081 (match_operand:SI 1 "register_operand" "0")))
12082 (clobber (reg:CC FLAGS_REG))]
12084 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
12085 [(set_attr "type" "alu")
12086 (set_attr "modrm" "0")
12087 (set_attr "length" "7")
12088 (set_attr "memory" "load")
12089 (set_attr "imm_disp" "false")])
12091 (define_insn "*load_tp_di"
12092 [(set (match_operand:DI 0 "register_operand" "=r")
12093 (unspec:DI [(const_int 0)] UNSPEC_TP))]
12095 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
12096 [(set_attr "type" "imov")
12097 (set_attr "modrm" "0")
12098 (set_attr "length" "7")
12099 (set_attr "memory" "load")
12100 (set_attr "imm_disp" "false")])
12102 (define_insn "*add_tp_di"
12103 [(set (match_operand:DI 0 "register_operand" "=r")
12104 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
12105 (match_operand:DI 1 "register_operand" "0")))
12106 (clobber (reg:CC FLAGS_REG))]
12108 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
12109 [(set_attr "type" "alu")
12110 (set_attr "modrm" "0")
12111 (set_attr "length" "7")
12112 (set_attr "memory" "load")
12113 (set_attr "imm_disp" "false")])
12115 ;; GNU2 TLS patterns can be split.
12117 (define_expand "tls_dynamic_gnu2_32"
12118 [(set (match_dup 3)
12119 (plus:SI (match_operand:SI 2 "register_operand" "")
12121 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12124 [(set (match_operand:SI 0 "register_operand" "")
12125 (unspec:SI [(match_dup 1) (match_dup 3)
12126 (match_dup 2) (reg:SI SP_REG)]
12128 (clobber (reg:CC FLAGS_REG))])]
12129 "!TARGET_64BIT && TARGET_GNU2_TLS"
12131 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12132 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12135 (define_insn "*tls_dynamic_lea_32"
12136 [(set (match_operand:SI 0 "register_operand" "=r")
12137 (plus:SI (match_operand:SI 1 "register_operand" "b")
12139 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12140 UNSPEC_TLSDESC))))]
12141 "!TARGET_64BIT && TARGET_GNU2_TLS"
12142 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12143 [(set_attr "type" "lea")
12144 (set_attr "mode" "SI")
12145 (set_attr "length" "6")
12146 (set_attr "length_address" "4")])
12148 (define_insn "*tls_dynamic_call_32"
12149 [(set (match_operand:SI 0 "register_operand" "=a")
12150 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12151 (match_operand:SI 2 "register_operand" "0")
12152 ;; we have to make sure %ebx still points to the GOT
12153 (match_operand:SI 3 "register_operand" "b")
12156 (clobber (reg:CC FLAGS_REG))]
12157 "!TARGET_64BIT && TARGET_GNU2_TLS"
12158 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12159 [(set_attr "type" "call")
12160 (set_attr "length" "2")
12161 (set_attr "length_address" "0")])
12163 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12164 [(set (match_operand:SI 0 "register_operand" "=&a")
12166 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12167 (match_operand:SI 4 "" "")
12168 (match_operand:SI 2 "register_operand" "b")
12171 (const:SI (unspec:SI
12172 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12174 (clobber (reg:CC FLAGS_REG))]
12175 "!TARGET_64BIT && TARGET_GNU2_TLS"
12178 [(set (match_dup 0) (match_dup 5))]
12180 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12181 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12184 (define_expand "tls_dynamic_gnu2_64"
12185 [(set (match_dup 2)
12186 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12189 [(set (match_operand:DI 0 "register_operand" "")
12190 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12192 (clobber (reg:CC FLAGS_REG))])]
12193 "TARGET_64BIT && TARGET_GNU2_TLS"
12195 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12196 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12199 (define_insn "*tls_dynamic_lea_64"
12200 [(set (match_operand:DI 0 "register_operand" "=r")
12201 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12203 "TARGET_64BIT && TARGET_GNU2_TLS"
12204 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12205 [(set_attr "type" "lea")
12206 (set_attr "mode" "DI")
12207 (set_attr "length" "7")
12208 (set_attr "length_address" "4")])
12210 (define_insn "*tls_dynamic_call_64"
12211 [(set (match_operand:DI 0 "register_operand" "=a")
12212 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12213 (match_operand:DI 2 "register_operand" "0")
12216 (clobber (reg:CC FLAGS_REG))]
12217 "TARGET_64BIT && TARGET_GNU2_TLS"
12218 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12219 [(set_attr "type" "call")
12220 (set_attr "length" "2")
12221 (set_attr "length_address" "0")])
12223 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12224 [(set (match_operand:DI 0 "register_operand" "=&a")
12226 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12227 (match_operand:DI 3 "" "")
12230 (const:DI (unspec:DI
12231 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12233 (clobber (reg:CC FLAGS_REG))]
12234 "TARGET_64BIT && TARGET_GNU2_TLS"
12237 [(set (match_dup 0) (match_dup 4))]
12239 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12240 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12245 ;; These patterns match the binary 387 instructions for addM3, subM3,
12246 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12247 ;; SFmode. The first is the normal insn, the second the same insn but
12248 ;; with one operand a conversion, and the third the same insn but with
12249 ;; the other operand a conversion. The conversion may be SFmode or
12250 ;; SImode if the target mode DFmode, but only SImode if the target mode
12253 ;; Gcc is slightly more smart about handling normal two address instructions
12254 ;; so use special patterns for add and mull.
12256 (define_insn "*fop_<mode>_comm_mixed_avx"
12257 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12258 (match_operator:MODEF 3 "binary_fp_operator"
12259 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12260 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12261 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12262 && COMMUTATIVE_ARITH_P (operands[3])
12263 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12264 "* return output_387_binary_op (insn, operands);"
12265 [(set (attr "type")
12266 (if_then_else (eq_attr "alternative" "1")
12267 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12268 (const_string "ssemul")
12269 (const_string "sseadd"))
12270 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12271 (const_string "fmul")
12272 (const_string "fop"))))
12273 (set_attr "prefix" "orig,maybe_vex")
12274 (set_attr "mode" "<MODE>")])
12276 (define_insn "*fop_<mode>_comm_mixed"
12277 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12278 (match_operator:MODEF 3 "binary_fp_operator"
12279 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
12280 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12281 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12282 && COMMUTATIVE_ARITH_P (operands[3])
12283 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12284 "* return output_387_binary_op (insn, operands);"
12285 [(set (attr "type")
12286 (if_then_else (eq_attr "alternative" "1")
12287 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12288 (const_string "ssemul")
12289 (const_string "sseadd"))
12290 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12291 (const_string "fmul")
12292 (const_string "fop"))))
12293 (set_attr "mode" "<MODE>")])
12295 (define_insn "*fop_<mode>_comm_avx"
12296 [(set (match_operand:MODEF 0 "register_operand" "=x")
12297 (match_operator:MODEF 3 "binary_fp_operator"
12298 [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
12299 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12300 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12301 && COMMUTATIVE_ARITH_P (operands[3])
12302 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12303 "* return output_387_binary_op (insn, operands);"
12304 [(set (attr "type")
12305 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12306 (const_string "ssemul")
12307 (const_string "sseadd")))
12308 (set_attr "prefix" "vex")
12309 (set_attr "mode" "<MODE>")])
12311 (define_insn "*fop_<mode>_comm_sse"
12312 [(set (match_operand:MODEF 0 "register_operand" "=x")
12313 (match_operator:MODEF 3 "binary_fp_operator"
12314 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12315 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12316 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12317 && COMMUTATIVE_ARITH_P (operands[3])
12318 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12319 "* return output_387_binary_op (insn, operands);"
12320 [(set (attr "type")
12321 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12322 (const_string "ssemul")
12323 (const_string "sseadd")))
12324 (set_attr "mode" "<MODE>")])
12326 (define_insn "*fop_<mode>_comm_i387"
12327 [(set (match_operand:MODEF 0 "register_operand" "=f")
12328 (match_operator:MODEF 3 "binary_fp_operator"
12329 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12330 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12331 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12332 && COMMUTATIVE_ARITH_P (operands[3])
12333 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12334 "* return output_387_binary_op (insn, operands);"
12335 [(set (attr "type")
12336 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12337 (const_string "fmul")
12338 (const_string "fop")))
12339 (set_attr "mode" "<MODE>")])
12341 (define_insn "*fop_<mode>_1_mixed_avx"
12342 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12343 (match_operator:MODEF 3 "binary_fp_operator"
12344 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
12345 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12346 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12347 && !COMMUTATIVE_ARITH_P (operands[3])
12348 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12349 "* return output_387_binary_op (insn, operands);"
12350 [(set (attr "type")
12351 (cond [(and (eq_attr "alternative" "2")
12352 (match_operand:MODEF 3 "mult_operator" ""))
12353 (const_string "ssemul")
12354 (and (eq_attr "alternative" "2")
12355 (match_operand:MODEF 3 "div_operator" ""))
12356 (const_string "ssediv")
12357 (eq_attr "alternative" "2")
12358 (const_string "sseadd")
12359 (match_operand:MODEF 3 "mult_operator" "")
12360 (const_string "fmul")
12361 (match_operand:MODEF 3 "div_operator" "")
12362 (const_string "fdiv")
12364 (const_string "fop")))
12365 (set_attr "prefix" "orig,orig,maybe_vex")
12366 (set_attr "mode" "<MODE>")])
12368 (define_insn "*fop_<mode>_1_mixed"
12369 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12370 (match_operator:MODEF 3 "binary_fp_operator"
12371 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
12372 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12373 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12374 && !COMMUTATIVE_ARITH_P (operands[3])
12375 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12376 "* return output_387_binary_op (insn, operands);"
12377 [(set (attr "type")
12378 (cond [(and (eq_attr "alternative" "2")
12379 (match_operand:MODEF 3 "mult_operator" ""))
12380 (const_string "ssemul")
12381 (and (eq_attr "alternative" "2")
12382 (match_operand:MODEF 3 "div_operator" ""))
12383 (const_string "ssediv")
12384 (eq_attr "alternative" "2")
12385 (const_string "sseadd")
12386 (match_operand:MODEF 3 "mult_operator" "")
12387 (const_string "fmul")
12388 (match_operand:MODEF 3 "div_operator" "")
12389 (const_string "fdiv")
12391 (const_string "fop")))
12392 (set_attr "mode" "<MODE>")])
12394 (define_insn "*rcpsf2_sse"
12395 [(set (match_operand:SF 0 "register_operand" "=x")
12396 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12399 "%vrcpss\t{%1, %d0|%d0, %1}"
12400 [(set_attr "type" "sse")
12401 (set_attr "atom_sse_attr" "rcp")
12402 (set_attr "prefix" "maybe_vex")
12403 (set_attr "mode" "SF")])
12405 (define_insn "*fop_<mode>_1_avx"
12406 [(set (match_operand:MODEF 0 "register_operand" "=x")
12407 (match_operator:MODEF 3 "binary_fp_operator"
12408 [(match_operand:MODEF 1 "register_operand" "x")
12409 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12410 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12411 && !COMMUTATIVE_ARITH_P (operands[3])"
12412 "* return output_387_binary_op (insn, operands);"
12413 [(set (attr "type")
12414 (cond [(match_operand:MODEF 3 "mult_operator" "")
12415 (const_string "ssemul")
12416 (match_operand:MODEF 3 "div_operator" "")
12417 (const_string "ssediv")
12419 (const_string "sseadd")))
12420 (set_attr "prefix" "vex")
12421 (set_attr "mode" "<MODE>")])
12423 (define_insn "*fop_<mode>_1_sse"
12424 [(set (match_operand:MODEF 0 "register_operand" "=x")
12425 (match_operator:MODEF 3 "binary_fp_operator"
12426 [(match_operand:MODEF 1 "register_operand" "0")
12427 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12428 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12429 && !COMMUTATIVE_ARITH_P (operands[3])"
12430 "* return output_387_binary_op (insn, operands);"
12431 [(set (attr "type")
12432 (cond [(match_operand:MODEF 3 "mult_operator" "")
12433 (const_string "ssemul")
12434 (match_operand:MODEF 3 "div_operator" "")
12435 (const_string "ssediv")
12437 (const_string "sseadd")))
12438 (set_attr "mode" "<MODE>")])
12440 ;; This pattern is not fully shadowed by the pattern above.
12441 (define_insn "*fop_<mode>_1_i387"
12442 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12443 (match_operator:MODEF 3 "binary_fp_operator"
12444 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12445 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12446 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12447 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12448 && !COMMUTATIVE_ARITH_P (operands[3])
12449 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12450 "* return output_387_binary_op (insn, operands);"
12451 [(set (attr "type")
12452 (cond [(match_operand:MODEF 3 "mult_operator" "")
12453 (const_string "fmul")
12454 (match_operand:MODEF 3 "div_operator" "")
12455 (const_string "fdiv")
12457 (const_string "fop")))
12458 (set_attr "mode" "<MODE>")])
12460 ;; ??? Add SSE splitters for these!
12461 (define_insn "*fop_<MODEF:mode>_2_i387"
12462 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12463 (match_operator:MODEF 3 "binary_fp_operator"
12465 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12466 (match_operand:MODEF 2 "register_operand" "0,0")]))]
12467 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12468 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12469 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12470 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12471 [(set (attr "type")
12472 (cond [(match_operand:MODEF 3 "mult_operator" "")
12473 (const_string "fmul")
12474 (match_operand:MODEF 3 "div_operator" "")
12475 (const_string "fdiv")
12477 (const_string "fop")))
12478 (set_attr "fp_int_src" "true")
12479 (set_attr "mode" "<X87MODEI12:MODE>")])
12481 (define_insn "*fop_<MODEF:mode>_3_i387"
12482 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12483 (match_operator:MODEF 3 "binary_fp_operator"
12484 [(match_operand:MODEF 1 "register_operand" "0,0")
12486 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12487 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12488 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12489 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12490 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12491 [(set (attr "type")
12492 (cond [(match_operand:MODEF 3 "mult_operator" "")
12493 (const_string "fmul")
12494 (match_operand:MODEF 3 "div_operator" "")
12495 (const_string "fdiv")
12497 (const_string "fop")))
12498 (set_attr "fp_int_src" "true")
12499 (set_attr "mode" "<MODE>")])
12501 (define_insn "*fop_df_4_i387"
12502 [(set (match_operand:DF 0 "register_operand" "=f,f")
12503 (match_operator:DF 3 "binary_fp_operator"
12505 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12506 (match_operand:DF 2 "register_operand" "0,f")]))]
12507 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12508 && !(TARGET_SSE2 && TARGET_SSE_MATH)
12509 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
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_df_5_i387"
12521 [(set (match_operand:DF 0 "register_operand" "=f,f")
12522 (match_operator:DF 3 "binary_fp_operator"
12523 [(match_operand:DF 1 "register_operand" "0,f")
12525 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12526 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12527 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12528 "* return output_387_binary_op (insn, operands);"
12529 [(set (attr "type")
12530 (cond [(match_operand:DF 3 "mult_operator" "")
12531 (const_string "fmul")
12532 (match_operand:DF 3 "div_operator" "")
12533 (const_string "fdiv")
12535 (const_string "fop")))
12536 (set_attr "mode" "SF")])
12538 (define_insn "*fop_df_6_i387"
12539 [(set (match_operand:DF 0 "register_operand" "=f,f")
12540 (match_operator:DF 3 "binary_fp_operator"
12542 (match_operand:SF 1 "register_operand" "0,f"))
12544 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12545 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12546 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12547 "* return output_387_binary_op (insn, operands);"
12548 [(set (attr "type")
12549 (cond [(match_operand:DF 3 "mult_operator" "")
12550 (const_string "fmul")
12551 (match_operand:DF 3 "div_operator" "")
12552 (const_string "fdiv")
12554 (const_string "fop")))
12555 (set_attr "mode" "SF")])
12557 (define_insn "*fop_xf_comm_i387"
12558 [(set (match_operand:XF 0 "register_operand" "=f")
12559 (match_operator:XF 3 "binary_fp_operator"
12560 [(match_operand:XF 1 "register_operand" "%0")
12561 (match_operand:XF 2 "register_operand" "f")]))]
12563 && COMMUTATIVE_ARITH_P (operands[3])"
12564 "* return output_387_binary_op (insn, operands);"
12565 [(set (attr "type")
12566 (if_then_else (match_operand:XF 3 "mult_operator" "")
12567 (const_string "fmul")
12568 (const_string "fop")))
12569 (set_attr "mode" "XF")])
12571 (define_insn "*fop_xf_1_i387"
12572 [(set (match_operand:XF 0 "register_operand" "=f,f")
12573 (match_operator:XF 3 "binary_fp_operator"
12574 [(match_operand:XF 1 "register_operand" "0,f")
12575 (match_operand:XF 2 "register_operand" "f,0")]))]
12577 && !COMMUTATIVE_ARITH_P (operands[3])"
12578 "* return output_387_binary_op (insn, operands);"
12579 [(set (attr "type")
12580 (cond [(match_operand:XF 3 "mult_operator" "")
12581 (const_string "fmul")
12582 (match_operand:XF 3 "div_operator" "")
12583 (const_string "fdiv")
12585 (const_string "fop")))
12586 (set_attr "mode" "XF")])
12588 (define_insn "*fop_xf_2_i387"
12589 [(set (match_operand:XF 0 "register_operand" "=f,f")
12590 (match_operator:XF 3 "binary_fp_operator"
12592 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12593 (match_operand:XF 2 "register_operand" "0,0")]))]
12594 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12595 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12596 [(set (attr "type")
12597 (cond [(match_operand:XF 3 "mult_operator" "")
12598 (const_string "fmul")
12599 (match_operand:XF 3 "div_operator" "")
12600 (const_string "fdiv")
12602 (const_string "fop")))
12603 (set_attr "fp_int_src" "true")
12604 (set_attr "mode" "<MODE>")])
12606 (define_insn "*fop_xf_3_i387"
12607 [(set (match_operand:XF 0 "register_operand" "=f,f")
12608 (match_operator:XF 3 "binary_fp_operator"
12609 [(match_operand:XF 1 "register_operand" "0,0")
12611 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12612 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12613 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12614 [(set (attr "type")
12615 (cond [(match_operand:XF 3 "mult_operator" "")
12616 (const_string "fmul")
12617 (match_operand:XF 3 "div_operator" "")
12618 (const_string "fdiv")
12620 (const_string "fop")))
12621 (set_attr "fp_int_src" "true")
12622 (set_attr "mode" "<MODE>")])
12624 (define_insn "*fop_xf_4_i387"
12625 [(set (match_operand:XF 0 "register_operand" "=f,f")
12626 (match_operator:XF 3 "binary_fp_operator"
12628 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
12629 (match_operand:XF 2 "register_operand" "0,f")]))]
12631 "* return output_387_binary_op (insn, operands);"
12632 [(set (attr "type")
12633 (cond [(match_operand:XF 3 "mult_operator" "")
12634 (const_string "fmul")
12635 (match_operand:XF 3 "div_operator" "")
12636 (const_string "fdiv")
12638 (const_string "fop")))
12639 (set_attr "mode" "<MODE>")])
12641 (define_insn "*fop_xf_5_i387"
12642 [(set (match_operand:XF 0 "register_operand" "=f,f")
12643 (match_operator:XF 3 "binary_fp_operator"
12644 [(match_operand:XF 1 "register_operand" "0,f")
12646 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12648 "* return output_387_binary_op (insn, operands);"
12649 [(set (attr "type")
12650 (cond [(match_operand:XF 3 "mult_operator" "")
12651 (const_string "fmul")
12652 (match_operand:XF 3 "div_operator" "")
12653 (const_string "fdiv")
12655 (const_string "fop")))
12656 (set_attr "mode" "<MODE>")])
12658 (define_insn "*fop_xf_6_i387"
12659 [(set (match_operand:XF 0 "register_operand" "=f,f")
12660 (match_operator:XF 3 "binary_fp_operator"
12662 (match_operand:MODEF 1 "register_operand" "0,f"))
12664 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12666 "* return output_387_binary_op (insn, operands);"
12667 [(set (attr "type")
12668 (cond [(match_operand:XF 3 "mult_operator" "")
12669 (const_string "fmul")
12670 (match_operand:XF 3 "div_operator" "")
12671 (const_string "fdiv")
12673 (const_string "fop")))
12674 (set_attr "mode" "<MODE>")])
12677 [(set (match_operand 0 "register_operand" "")
12678 (match_operator 3 "binary_fp_operator"
12679 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
12680 (match_operand 2 "register_operand" "")]))]
12682 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12683 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
12686 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
12687 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12688 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12689 gen_rtx_fmt_ee (GET_CODE (operands[3]),
12690 GET_MODE (operands[3]),
12693 ix86_free_from_memory (GET_MODE (operands[1]));
12698 [(set (match_operand 0 "register_operand" "")
12699 (match_operator 3 "binary_fp_operator"
12700 [(match_operand 1 "register_operand" "")
12701 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
12703 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12704 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
12707 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
12708 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12709 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12710 gen_rtx_fmt_ee (GET_CODE (operands[3]),
12711 GET_MODE (operands[3]),
12714 ix86_free_from_memory (GET_MODE (operands[2]));
12718 ;; FPU special functions.
12720 ;; This pattern implements a no-op XFmode truncation for
12721 ;; all fancy i386 XFmode math functions.
12723 (define_insn "truncxf<mode>2_i387_noop_unspec"
12724 [(set (match_operand:MODEF 0 "register_operand" "=f")
12725 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
12726 UNSPEC_TRUNC_NOOP))]
12727 "TARGET_USE_FANCY_MATH_387"
12728 "* return output_387_reg_move (insn, operands);"
12729 [(set_attr "type" "fmov")
12730 (set_attr "mode" "<MODE>")])
12732 (define_insn "sqrtxf2"
12733 [(set (match_operand:XF 0 "register_operand" "=f")
12734 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
12735 "TARGET_USE_FANCY_MATH_387"
12737 [(set_attr "type" "fpspc")
12738 (set_attr "mode" "XF")
12739 (set_attr "athlon_decode" "direct")
12740 (set_attr "amdfam10_decode" "direct")])
12742 (define_insn "sqrt_extend<mode>xf2_i387"
12743 [(set (match_operand:XF 0 "register_operand" "=f")
12746 (match_operand:MODEF 1 "register_operand" "0"))))]
12747 "TARGET_USE_FANCY_MATH_387"
12749 [(set_attr "type" "fpspc")
12750 (set_attr "mode" "XF")
12751 (set_attr "athlon_decode" "direct")
12752 (set_attr "amdfam10_decode" "direct")])
12754 (define_insn "*rsqrtsf2_sse"
12755 [(set (match_operand:SF 0 "register_operand" "=x")
12756 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12759 "%vrsqrtss\t{%1, %d0|%d0, %1}"
12760 [(set_attr "type" "sse")
12761 (set_attr "atom_sse_attr" "rcp")
12762 (set_attr "prefix" "maybe_vex")
12763 (set_attr "mode" "SF")])
12765 (define_expand "rsqrtsf2"
12766 [(set (match_operand:SF 0 "register_operand" "")
12767 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
12771 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
12775 (define_insn "*sqrt<mode>2_sse"
12776 [(set (match_operand:MODEF 0 "register_operand" "=x")
12778 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
12779 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
12780 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
12781 [(set_attr "type" "sse")
12782 (set_attr "atom_sse_attr" "sqrt")
12783 (set_attr "prefix" "maybe_vex")
12784 (set_attr "mode" "<MODE>")
12785 (set_attr "athlon_decode" "*")
12786 (set_attr "amdfam10_decode" "*")])
12788 (define_expand "sqrt<mode>2"
12789 [(set (match_operand:MODEF 0 "register_operand" "")
12791 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
12792 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
12793 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
12795 if (<MODE>mode == SFmode
12796 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
12797 && flag_finite_math_only && !flag_trapping_math
12798 && flag_unsafe_math_optimizations)
12800 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
12804 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
12806 rtx op0 = gen_reg_rtx (XFmode);
12807 rtx op1 = force_reg (<MODE>mode, operands[1]);
12809 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
12810 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
12815 (define_insn "fpremxf4_i387"
12816 [(set (match_operand:XF 0 "register_operand" "=f")
12817 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
12818 (match_operand:XF 3 "register_operand" "1")]
12820 (set (match_operand:XF 1 "register_operand" "=u")
12821 (unspec:XF [(match_dup 2) (match_dup 3)]
12823 (set (reg:CCFP FPSR_REG)
12824 (unspec:CCFP [(match_dup 2) (match_dup 3)]
12826 "TARGET_USE_FANCY_MATH_387"
12828 [(set_attr "type" "fpspc")
12829 (set_attr "mode" "XF")])
12831 (define_expand "fmodxf3"
12832 [(use (match_operand:XF 0 "register_operand" ""))
12833 (use (match_operand:XF 1 "general_operand" ""))
12834 (use (match_operand:XF 2 "general_operand" ""))]
12835 "TARGET_USE_FANCY_MATH_387"
12837 rtx label = gen_label_rtx ();
12839 rtx op1 = gen_reg_rtx (XFmode);
12840 rtx op2 = gen_reg_rtx (XFmode);
12842 emit_move_insn (op2, operands[2]);
12843 emit_move_insn (op1, operands[1]);
12845 emit_label (label);
12846 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
12847 ix86_emit_fp_unordered_jump (label);
12848 LABEL_NUSES (label) = 1;
12850 emit_move_insn (operands[0], op1);
12854 (define_expand "fmod<mode>3"
12855 [(use (match_operand:MODEF 0 "register_operand" ""))
12856 (use (match_operand:MODEF 1 "general_operand" ""))
12857 (use (match_operand:MODEF 2 "general_operand" ""))]
12858 "TARGET_USE_FANCY_MATH_387"
12860 rtx (*gen_truncxf) (rtx, rtx);
12862 rtx label = gen_label_rtx ();
12864 rtx op1 = gen_reg_rtx (XFmode);
12865 rtx op2 = gen_reg_rtx (XFmode);
12867 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
12868 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
12870 emit_label (label);
12871 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
12872 ix86_emit_fp_unordered_jump (label);
12873 LABEL_NUSES (label) = 1;
12875 /* Truncate the result properly for strict SSE math. */
12876 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12877 && !TARGET_MIX_SSE_I387)
12878 gen_truncxf = gen_truncxf<mode>2;
12880 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
12882 emit_insn (gen_truncxf (operands[0], op1));
12886 (define_insn "fprem1xf4_i387"
12887 [(set (match_operand:XF 0 "register_operand" "=f")
12888 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
12889 (match_operand:XF 3 "register_operand" "1")]
12891 (set (match_operand:XF 1 "register_operand" "=u")
12892 (unspec:XF [(match_dup 2) (match_dup 3)]
12894 (set (reg:CCFP FPSR_REG)
12895 (unspec:CCFP [(match_dup 2) (match_dup 3)]
12897 "TARGET_USE_FANCY_MATH_387"
12899 [(set_attr "type" "fpspc")
12900 (set_attr "mode" "XF")])
12902 (define_expand "remainderxf3"
12903 [(use (match_operand:XF 0 "register_operand" ""))
12904 (use (match_operand:XF 1 "general_operand" ""))
12905 (use (match_operand:XF 2 "general_operand" ""))]
12906 "TARGET_USE_FANCY_MATH_387"
12908 rtx label = gen_label_rtx ();
12910 rtx op1 = gen_reg_rtx (XFmode);
12911 rtx op2 = gen_reg_rtx (XFmode);
12913 emit_move_insn (op2, operands[2]);
12914 emit_move_insn (op1, operands[1]);
12916 emit_label (label);
12917 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
12918 ix86_emit_fp_unordered_jump (label);
12919 LABEL_NUSES (label) = 1;
12921 emit_move_insn (operands[0], op1);
12925 (define_expand "remainder<mode>3"
12926 [(use (match_operand:MODEF 0 "register_operand" ""))
12927 (use (match_operand:MODEF 1 "general_operand" ""))
12928 (use (match_operand:MODEF 2 "general_operand" ""))]
12929 "TARGET_USE_FANCY_MATH_387"
12931 rtx (*gen_truncxf) (rtx, rtx);
12933 rtx label = gen_label_rtx ();
12935 rtx op1 = gen_reg_rtx (XFmode);
12936 rtx op2 = gen_reg_rtx (XFmode);
12938 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
12939 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
12941 emit_label (label);
12943 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
12944 ix86_emit_fp_unordered_jump (label);
12945 LABEL_NUSES (label) = 1;
12947 /* Truncate the result properly for strict SSE math. */
12948 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12949 && !TARGET_MIX_SSE_I387)
12950 gen_truncxf = gen_truncxf<mode>2;
12952 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
12954 emit_insn (gen_truncxf (operands[0], op1));
12958 (define_insn "*sinxf2_i387"
12959 [(set (match_operand:XF 0 "register_operand" "=f")
12960 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
12961 "TARGET_USE_FANCY_MATH_387
12962 && flag_unsafe_math_optimizations"
12964 [(set_attr "type" "fpspc")
12965 (set_attr "mode" "XF")])
12967 (define_insn "*sin_extend<mode>xf2_i387"
12968 [(set (match_operand:XF 0 "register_operand" "=f")
12969 (unspec:XF [(float_extend:XF
12970 (match_operand:MODEF 1 "register_operand" "0"))]
12972 "TARGET_USE_FANCY_MATH_387
12973 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12974 || TARGET_MIX_SSE_I387)
12975 && flag_unsafe_math_optimizations"
12977 [(set_attr "type" "fpspc")
12978 (set_attr "mode" "XF")])
12980 (define_insn "*cosxf2_i387"
12981 [(set (match_operand:XF 0 "register_operand" "=f")
12982 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
12983 "TARGET_USE_FANCY_MATH_387
12984 && flag_unsafe_math_optimizations"
12986 [(set_attr "type" "fpspc")
12987 (set_attr "mode" "XF")])
12989 (define_insn "*cos_extend<mode>xf2_i387"
12990 [(set (match_operand:XF 0 "register_operand" "=f")
12991 (unspec:XF [(float_extend:XF
12992 (match_operand:MODEF 1 "register_operand" "0"))]
12994 "TARGET_USE_FANCY_MATH_387
12995 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12996 || TARGET_MIX_SSE_I387)
12997 && flag_unsafe_math_optimizations"
12999 [(set_attr "type" "fpspc")
13000 (set_attr "mode" "XF")])
13002 ;; When sincos pattern is defined, sin and cos builtin functions will be
13003 ;; expanded to sincos pattern with one of its outputs left unused.
13004 ;; CSE pass will figure out if two sincos patterns can be combined,
13005 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13006 ;; depending on the unused output.
13008 (define_insn "sincosxf3"
13009 [(set (match_operand:XF 0 "register_operand" "=f")
13010 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13011 UNSPEC_SINCOS_COS))
13012 (set (match_operand:XF 1 "register_operand" "=u")
13013 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13014 "TARGET_USE_FANCY_MATH_387
13015 && flag_unsafe_math_optimizations"
13017 [(set_attr "type" "fpspc")
13018 (set_attr "mode" "XF")])
13021 [(set (match_operand:XF 0 "register_operand" "")
13022 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13023 UNSPEC_SINCOS_COS))
13024 (set (match_operand:XF 1 "register_operand" "")
13025 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13026 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13027 && !(reload_completed || reload_in_progress)"
13028 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13031 [(set (match_operand:XF 0 "register_operand" "")
13032 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13033 UNSPEC_SINCOS_COS))
13034 (set (match_operand:XF 1 "register_operand" "")
13035 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13036 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13037 && !(reload_completed || reload_in_progress)"
13038 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13040 (define_insn "sincos_extend<mode>xf3_i387"
13041 [(set (match_operand:XF 0 "register_operand" "=f")
13042 (unspec:XF [(float_extend:XF
13043 (match_operand:MODEF 2 "register_operand" "0"))]
13044 UNSPEC_SINCOS_COS))
13045 (set (match_operand:XF 1 "register_operand" "=u")
13046 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13047 "TARGET_USE_FANCY_MATH_387
13048 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13049 || TARGET_MIX_SSE_I387)
13050 && flag_unsafe_math_optimizations"
13052 [(set_attr "type" "fpspc")
13053 (set_attr "mode" "XF")])
13056 [(set (match_operand:XF 0 "register_operand" "")
13057 (unspec:XF [(float_extend:XF
13058 (match_operand:MODEF 2 "register_operand" ""))]
13059 UNSPEC_SINCOS_COS))
13060 (set (match_operand:XF 1 "register_operand" "")
13061 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13062 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13063 && !(reload_completed || reload_in_progress)"
13064 [(set (match_dup 1)
13065 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13068 [(set (match_operand:XF 0 "register_operand" "")
13069 (unspec:XF [(float_extend:XF
13070 (match_operand:MODEF 2 "register_operand" ""))]
13071 UNSPEC_SINCOS_COS))
13072 (set (match_operand:XF 1 "register_operand" "")
13073 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13074 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13075 && !(reload_completed || reload_in_progress)"
13076 [(set (match_dup 0)
13077 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13079 (define_expand "sincos<mode>3"
13080 [(use (match_operand:MODEF 0 "register_operand" ""))
13081 (use (match_operand:MODEF 1 "register_operand" ""))
13082 (use (match_operand:MODEF 2 "register_operand" ""))]
13083 "TARGET_USE_FANCY_MATH_387
13084 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13085 || TARGET_MIX_SSE_I387)
13086 && flag_unsafe_math_optimizations"
13088 rtx op0 = gen_reg_rtx (XFmode);
13089 rtx op1 = gen_reg_rtx (XFmode);
13091 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13092 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13093 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13097 (define_insn "fptanxf4_i387"
13098 [(set (match_operand:XF 0 "register_operand" "=f")
13099 (match_operand:XF 3 "const_double_operand" "F"))
13100 (set (match_operand:XF 1 "register_operand" "=u")
13101 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13103 "TARGET_USE_FANCY_MATH_387
13104 && flag_unsafe_math_optimizations
13105 && standard_80387_constant_p (operands[3]) == 2"
13107 [(set_attr "type" "fpspc")
13108 (set_attr "mode" "XF")])
13110 (define_insn "fptan_extend<mode>xf4_i387"
13111 [(set (match_operand:MODEF 0 "register_operand" "=f")
13112 (match_operand:MODEF 3 "const_double_operand" "F"))
13113 (set (match_operand:XF 1 "register_operand" "=u")
13114 (unspec:XF [(float_extend:XF
13115 (match_operand:MODEF 2 "register_operand" "0"))]
13117 "TARGET_USE_FANCY_MATH_387
13118 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13119 || TARGET_MIX_SSE_I387)
13120 && flag_unsafe_math_optimizations
13121 && standard_80387_constant_p (operands[3]) == 2"
13123 [(set_attr "type" "fpspc")
13124 (set_attr "mode" "XF")])
13126 (define_expand "tanxf2"
13127 [(use (match_operand:XF 0 "register_operand" ""))
13128 (use (match_operand:XF 1 "register_operand" ""))]
13129 "TARGET_USE_FANCY_MATH_387
13130 && flag_unsafe_math_optimizations"
13132 rtx one = gen_reg_rtx (XFmode);
13133 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13135 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13139 (define_expand "tan<mode>2"
13140 [(use (match_operand:MODEF 0 "register_operand" ""))
13141 (use (match_operand:MODEF 1 "register_operand" ""))]
13142 "TARGET_USE_FANCY_MATH_387
13143 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13144 || TARGET_MIX_SSE_I387)
13145 && flag_unsafe_math_optimizations"
13147 rtx op0 = gen_reg_rtx (XFmode);
13149 rtx one = gen_reg_rtx (<MODE>mode);
13150 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13152 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13153 operands[1], op2));
13154 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13158 (define_insn "*fpatanxf3_i387"
13159 [(set (match_operand:XF 0 "register_operand" "=f")
13160 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13161 (match_operand:XF 2 "register_operand" "u")]
13163 (clobber (match_scratch:XF 3 "=2"))]
13164 "TARGET_USE_FANCY_MATH_387
13165 && flag_unsafe_math_optimizations"
13167 [(set_attr "type" "fpspc")
13168 (set_attr "mode" "XF")])
13170 (define_insn "fpatan_extend<mode>xf3_i387"
13171 [(set (match_operand:XF 0 "register_operand" "=f")
13172 (unspec:XF [(float_extend:XF
13173 (match_operand:MODEF 1 "register_operand" "0"))
13175 (match_operand:MODEF 2 "register_operand" "u"))]
13177 (clobber (match_scratch:XF 3 "=2"))]
13178 "TARGET_USE_FANCY_MATH_387
13179 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13180 || TARGET_MIX_SSE_I387)
13181 && flag_unsafe_math_optimizations"
13183 [(set_attr "type" "fpspc")
13184 (set_attr "mode" "XF")])
13186 (define_expand "atan2xf3"
13187 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13188 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13189 (match_operand:XF 1 "register_operand" "")]
13191 (clobber (match_scratch:XF 3 ""))])]
13192 "TARGET_USE_FANCY_MATH_387
13193 && flag_unsafe_math_optimizations"
13196 (define_expand "atan2<mode>3"
13197 [(use (match_operand:MODEF 0 "register_operand" ""))
13198 (use (match_operand:MODEF 1 "register_operand" ""))
13199 (use (match_operand:MODEF 2 "register_operand" ""))]
13200 "TARGET_USE_FANCY_MATH_387
13201 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13202 || TARGET_MIX_SSE_I387)
13203 && flag_unsafe_math_optimizations"
13205 rtx op0 = gen_reg_rtx (XFmode);
13207 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13208 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13212 (define_expand "atanxf2"
13213 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13214 (unspec:XF [(match_dup 2)
13215 (match_operand:XF 1 "register_operand" "")]
13217 (clobber (match_scratch:XF 3 ""))])]
13218 "TARGET_USE_FANCY_MATH_387
13219 && flag_unsafe_math_optimizations"
13221 operands[2] = gen_reg_rtx (XFmode);
13222 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13225 (define_expand "atan<mode>2"
13226 [(use (match_operand:MODEF 0 "register_operand" ""))
13227 (use (match_operand:MODEF 1 "register_operand" ""))]
13228 "TARGET_USE_FANCY_MATH_387
13229 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13230 || TARGET_MIX_SSE_I387)
13231 && flag_unsafe_math_optimizations"
13233 rtx op0 = gen_reg_rtx (XFmode);
13235 rtx op2 = gen_reg_rtx (<MODE>mode);
13236 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13238 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13239 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13243 (define_expand "asinxf2"
13244 [(set (match_dup 2)
13245 (mult:XF (match_operand:XF 1 "register_operand" "")
13247 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13248 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13249 (parallel [(set (match_operand:XF 0 "register_operand" "")
13250 (unspec:XF [(match_dup 5) (match_dup 1)]
13252 (clobber (match_scratch:XF 6 ""))])]
13253 "TARGET_USE_FANCY_MATH_387
13254 && flag_unsafe_math_optimizations"
13258 if (optimize_insn_for_size_p ())
13261 for (i = 2; i < 6; i++)
13262 operands[i] = gen_reg_rtx (XFmode);
13264 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13267 (define_expand "asin<mode>2"
13268 [(use (match_operand:MODEF 0 "register_operand" ""))
13269 (use (match_operand:MODEF 1 "general_operand" ""))]
13270 "TARGET_USE_FANCY_MATH_387
13271 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13272 || TARGET_MIX_SSE_I387)
13273 && flag_unsafe_math_optimizations"
13275 rtx op0 = gen_reg_rtx (XFmode);
13276 rtx op1 = gen_reg_rtx (XFmode);
13278 if (optimize_insn_for_size_p ())
13281 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13282 emit_insn (gen_asinxf2 (op0, op1));
13283 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13287 (define_expand "acosxf2"
13288 [(set (match_dup 2)
13289 (mult:XF (match_operand:XF 1 "register_operand" "")
13291 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13292 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13293 (parallel [(set (match_operand:XF 0 "register_operand" "")
13294 (unspec:XF [(match_dup 1) (match_dup 5)]
13296 (clobber (match_scratch:XF 6 ""))])]
13297 "TARGET_USE_FANCY_MATH_387
13298 && flag_unsafe_math_optimizations"
13302 if (optimize_insn_for_size_p ())
13305 for (i = 2; i < 6; i++)
13306 operands[i] = gen_reg_rtx (XFmode);
13308 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13311 (define_expand "acos<mode>2"
13312 [(use (match_operand:MODEF 0 "register_operand" ""))
13313 (use (match_operand:MODEF 1 "general_operand" ""))]
13314 "TARGET_USE_FANCY_MATH_387
13315 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13316 || TARGET_MIX_SSE_I387)
13317 && flag_unsafe_math_optimizations"
13319 rtx op0 = gen_reg_rtx (XFmode);
13320 rtx op1 = gen_reg_rtx (XFmode);
13322 if (optimize_insn_for_size_p ())
13325 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13326 emit_insn (gen_acosxf2 (op0, op1));
13327 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13331 (define_insn "fyl2xxf3_i387"
13332 [(set (match_operand:XF 0 "register_operand" "=f")
13333 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13334 (match_operand:XF 2 "register_operand" "u")]
13336 (clobber (match_scratch:XF 3 "=2"))]
13337 "TARGET_USE_FANCY_MATH_387
13338 && flag_unsafe_math_optimizations"
13340 [(set_attr "type" "fpspc")
13341 (set_attr "mode" "XF")])
13343 (define_insn "fyl2x_extend<mode>xf3_i387"
13344 [(set (match_operand:XF 0 "register_operand" "=f")
13345 (unspec:XF [(float_extend:XF
13346 (match_operand:MODEF 1 "register_operand" "0"))
13347 (match_operand:XF 2 "register_operand" "u")]
13349 (clobber (match_scratch:XF 3 "=2"))]
13350 "TARGET_USE_FANCY_MATH_387
13351 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13352 || TARGET_MIX_SSE_I387)
13353 && flag_unsafe_math_optimizations"
13355 [(set_attr "type" "fpspc")
13356 (set_attr "mode" "XF")])
13358 (define_expand "logxf2"
13359 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13360 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13361 (match_dup 2)] UNSPEC_FYL2X))
13362 (clobber (match_scratch:XF 3 ""))])]
13363 "TARGET_USE_FANCY_MATH_387
13364 && flag_unsafe_math_optimizations"
13366 operands[2] = gen_reg_rtx (XFmode);
13367 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13370 (define_expand "log<mode>2"
13371 [(use (match_operand:MODEF 0 "register_operand" ""))
13372 (use (match_operand:MODEF 1 "register_operand" ""))]
13373 "TARGET_USE_FANCY_MATH_387
13374 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13375 || TARGET_MIX_SSE_I387)
13376 && flag_unsafe_math_optimizations"
13378 rtx op0 = gen_reg_rtx (XFmode);
13380 rtx op2 = gen_reg_rtx (XFmode);
13381 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13383 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13384 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13388 (define_expand "log10xf2"
13389 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13390 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13391 (match_dup 2)] UNSPEC_FYL2X))
13392 (clobber (match_scratch:XF 3 ""))])]
13393 "TARGET_USE_FANCY_MATH_387
13394 && flag_unsafe_math_optimizations"
13396 operands[2] = gen_reg_rtx (XFmode);
13397 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13400 (define_expand "log10<mode>2"
13401 [(use (match_operand:MODEF 0 "register_operand" ""))
13402 (use (match_operand:MODEF 1 "register_operand" ""))]
13403 "TARGET_USE_FANCY_MATH_387
13404 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13405 || TARGET_MIX_SSE_I387)
13406 && flag_unsafe_math_optimizations"
13408 rtx op0 = gen_reg_rtx (XFmode);
13410 rtx op2 = gen_reg_rtx (XFmode);
13411 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13413 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13414 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13418 (define_expand "log2xf2"
13419 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13420 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13421 (match_dup 2)] UNSPEC_FYL2X))
13422 (clobber (match_scratch:XF 3 ""))])]
13423 "TARGET_USE_FANCY_MATH_387
13424 && flag_unsafe_math_optimizations"
13426 operands[2] = gen_reg_rtx (XFmode);
13427 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13430 (define_expand "log2<mode>2"
13431 [(use (match_operand:MODEF 0 "register_operand" ""))
13432 (use (match_operand:MODEF 1 "register_operand" ""))]
13433 "TARGET_USE_FANCY_MATH_387
13434 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13435 || TARGET_MIX_SSE_I387)
13436 && flag_unsafe_math_optimizations"
13438 rtx op0 = gen_reg_rtx (XFmode);
13440 rtx op2 = gen_reg_rtx (XFmode);
13441 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13443 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13444 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13448 (define_insn "fyl2xp1xf3_i387"
13449 [(set (match_operand:XF 0 "register_operand" "=f")
13450 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13451 (match_operand:XF 2 "register_operand" "u")]
13453 (clobber (match_scratch:XF 3 "=2"))]
13454 "TARGET_USE_FANCY_MATH_387
13455 && flag_unsafe_math_optimizations"
13457 [(set_attr "type" "fpspc")
13458 (set_attr "mode" "XF")])
13460 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13461 [(set (match_operand:XF 0 "register_operand" "=f")
13462 (unspec:XF [(float_extend:XF
13463 (match_operand:MODEF 1 "register_operand" "0"))
13464 (match_operand:XF 2 "register_operand" "u")]
13466 (clobber (match_scratch:XF 3 "=2"))]
13467 "TARGET_USE_FANCY_MATH_387
13468 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13469 || TARGET_MIX_SSE_I387)
13470 && flag_unsafe_math_optimizations"
13472 [(set_attr "type" "fpspc")
13473 (set_attr "mode" "XF")])
13475 (define_expand "log1pxf2"
13476 [(use (match_operand:XF 0 "register_operand" ""))
13477 (use (match_operand:XF 1 "register_operand" ""))]
13478 "TARGET_USE_FANCY_MATH_387
13479 && flag_unsafe_math_optimizations"
13481 if (optimize_insn_for_size_p ())
13484 ix86_emit_i387_log1p (operands[0], operands[1]);
13488 (define_expand "log1p<mode>2"
13489 [(use (match_operand:MODEF 0 "register_operand" ""))
13490 (use (match_operand:MODEF 1 "register_operand" ""))]
13491 "TARGET_USE_FANCY_MATH_387
13492 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13493 || TARGET_MIX_SSE_I387)
13494 && flag_unsafe_math_optimizations"
13498 if (optimize_insn_for_size_p ())
13501 op0 = gen_reg_rtx (XFmode);
13503 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13505 ix86_emit_i387_log1p (op0, operands[1]);
13506 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13510 (define_insn "fxtractxf3_i387"
13511 [(set (match_operand:XF 0 "register_operand" "=f")
13512 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13513 UNSPEC_XTRACT_FRACT))
13514 (set (match_operand:XF 1 "register_operand" "=u")
13515 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13516 "TARGET_USE_FANCY_MATH_387
13517 && flag_unsafe_math_optimizations"
13519 [(set_attr "type" "fpspc")
13520 (set_attr "mode" "XF")])
13522 (define_insn "fxtract_extend<mode>xf3_i387"
13523 [(set (match_operand:XF 0 "register_operand" "=f")
13524 (unspec:XF [(float_extend:XF
13525 (match_operand:MODEF 2 "register_operand" "0"))]
13526 UNSPEC_XTRACT_FRACT))
13527 (set (match_operand:XF 1 "register_operand" "=u")
13528 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13529 "TARGET_USE_FANCY_MATH_387
13530 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13531 || TARGET_MIX_SSE_I387)
13532 && flag_unsafe_math_optimizations"
13534 [(set_attr "type" "fpspc")
13535 (set_attr "mode" "XF")])
13537 (define_expand "logbxf2"
13538 [(parallel [(set (match_dup 2)
13539 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13540 UNSPEC_XTRACT_FRACT))
13541 (set (match_operand:XF 0 "register_operand" "")
13542 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13543 "TARGET_USE_FANCY_MATH_387
13544 && flag_unsafe_math_optimizations"
13546 operands[2] = gen_reg_rtx (XFmode);
13549 (define_expand "logb<mode>2"
13550 [(use (match_operand:MODEF 0 "register_operand" ""))
13551 (use (match_operand:MODEF 1 "register_operand" ""))]
13552 "TARGET_USE_FANCY_MATH_387
13553 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13554 || TARGET_MIX_SSE_I387)
13555 && flag_unsafe_math_optimizations"
13557 rtx op0 = gen_reg_rtx (XFmode);
13558 rtx op1 = gen_reg_rtx (XFmode);
13560 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13561 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13565 (define_expand "ilogbxf2"
13566 [(use (match_operand:SI 0 "register_operand" ""))
13567 (use (match_operand:XF 1 "register_operand" ""))]
13568 "TARGET_USE_FANCY_MATH_387
13569 && flag_unsafe_math_optimizations"
13573 if (optimize_insn_for_size_p ())
13576 op0 = gen_reg_rtx (XFmode);
13577 op1 = gen_reg_rtx (XFmode);
13579 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13580 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13584 (define_expand "ilogb<mode>2"
13585 [(use (match_operand:SI 0 "register_operand" ""))
13586 (use (match_operand:MODEF 1 "register_operand" ""))]
13587 "TARGET_USE_FANCY_MATH_387
13588 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13589 || TARGET_MIX_SSE_I387)
13590 && flag_unsafe_math_optimizations"
13594 if (optimize_insn_for_size_p ())
13597 op0 = gen_reg_rtx (XFmode);
13598 op1 = gen_reg_rtx (XFmode);
13600 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13601 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13605 (define_insn "*f2xm1xf2_i387"
13606 [(set (match_operand:XF 0 "register_operand" "=f")
13607 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13609 "TARGET_USE_FANCY_MATH_387
13610 && flag_unsafe_math_optimizations"
13612 [(set_attr "type" "fpspc")
13613 (set_attr "mode" "XF")])
13615 (define_insn "*fscalexf4_i387"
13616 [(set (match_operand:XF 0 "register_operand" "=f")
13617 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13618 (match_operand:XF 3 "register_operand" "1")]
13619 UNSPEC_FSCALE_FRACT))
13620 (set (match_operand:XF 1 "register_operand" "=u")
13621 (unspec:XF [(match_dup 2) (match_dup 3)]
13622 UNSPEC_FSCALE_EXP))]
13623 "TARGET_USE_FANCY_MATH_387
13624 && flag_unsafe_math_optimizations"
13626 [(set_attr "type" "fpspc")
13627 (set_attr "mode" "XF")])
13629 (define_expand "expNcorexf3"
13630 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13631 (match_operand:XF 2 "register_operand" "")))
13632 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13633 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13634 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13635 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
13636 (parallel [(set (match_operand:XF 0 "register_operand" "")
13637 (unspec:XF [(match_dup 8) (match_dup 4)]
13638 UNSPEC_FSCALE_FRACT))
13640 (unspec:XF [(match_dup 8) (match_dup 4)]
13641 UNSPEC_FSCALE_EXP))])]
13642 "TARGET_USE_FANCY_MATH_387
13643 && flag_unsafe_math_optimizations"
13647 if (optimize_insn_for_size_p ())
13650 for (i = 3; i < 10; i++)
13651 operands[i] = gen_reg_rtx (XFmode);
13653 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
13656 (define_expand "expxf2"
13657 [(use (match_operand:XF 0 "register_operand" ""))
13658 (use (match_operand:XF 1 "register_operand" ""))]
13659 "TARGET_USE_FANCY_MATH_387
13660 && flag_unsafe_math_optimizations"
13664 if (optimize_insn_for_size_p ())
13667 op2 = gen_reg_rtx (XFmode);
13668 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
13670 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13674 (define_expand "exp<mode>2"
13675 [(use (match_operand:MODEF 0 "register_operand" ""))
13676 (use (match_operand:MODEF 1 "general_operand" ""))]
13677 "TARGET_USE_FANCY_MATH_387
13678 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13679 || TARGET_MIX_SSE_I387)
13680 && flag_unsafe_math_optimizations"
13684 if (optimize_insn_for_size_p ())
13687 op0 = gen_reg_rtx (XFmode);
13688 op1 = gen_reg_rtx (XFmode);
13690 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13691 emit_insn (gen_expxf2 (op0, op1));
13692 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13696 (define_expand "exp10xf2"
13697 [(use (match_operand:XF 0 "register_operand" ""))
13698 (use (match_operand:XF 1 "register_operand" ""))]
13699 "TARGET_USE_FANCY_MATH_387
13700 && flag_unsafe_math_optimizations"
13704 if (optimize_insn_for_size_p ())
13707 op2 = gen_reg_rtx (XFmode);
13708 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
13710 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13714 (define_expand "exp10<mode>2"
13715 [(use (match_operand:MODEF 0 "register_operand" ""))
13716 (use (match_operand:MODEF 1 "general_operand" ""))]
13717 "TARGET_USE_FANCY_MATH_387
13718 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13719 || TARGET_MIX_SSE_I387)
13720 && flag_unsafe_math_optimizations"
13724 if (optimize_insn_for_size_p ())
13727 op0 = gen_reg_rtx (XFmode);
13728 op1 = gen_reg_rtx (XFmode);
13730 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13731 emit_insn (gen_exp10xf2 (op0, op1));
13732 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13736 (define_expand "exp2xf2"
13737 [(use (match_operand:XF 0 "register_operand" ""))
13738 (use (match_operand:XF 1 "register_operand" ""))]
13739 "TARGET_USE_FANCY_MATH_387
13740 && flag_unsafe_math_optimizations"
13744 if (optimize_insn_for_size_p ())
13747 op2 = gen_reg_rtx (XFmode);
13748 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13750 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13754 (define_expand "exp2<mode>2"
13755 [(use (match_operand:MODEF 0 "register_operand" ""))
13756 (use (match_operand:MODEF 1 "general_operand" ""))]
13757 "TARGET_USE_FANCY_MATH_387
13758 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13759 || TARGET_MIX_SSE_I387)
13760 && flag_unsafe_math_optimizations"
13764 if (optimize_insn_for_size_p ())
13767 op0 = gen_reg_rtx (XFmode);
13768 op1 = gen_reg_rtx (XFmode);
13770 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13771 emit_insn (gen_exp2xf2 (op0, op1));
13772 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13776 (define_expand "expm1xf2"
13777 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13779 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13780 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13781 (set (match_dup 9) (float_extend:XF (match_dup 13)))
13782 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13783 (parallel [(set (match_dup 7)
13784 (unspec:XF [(match_dup 6) (match_dup 4)]
13785 UNSPEC_FSCALE_FRACT))
13787 (unspec:XF [(match_dup 6) (match_dup 4)]
13788 UNSPEC_FSCALE_EXP))])
13789 (parallel [(set (match_dup 10)
13790 (unspec:XF [(match_dup 9) (match_dup 8)]
13791 UNSPEC_FSCALE_FRACT))
13792 (set (match_dup 11)
13793 (unspec:XF [(match_dup 9) (match_dup 8)]
13794 UNSPEC_FSCALE_EXP))])
13795 (set (match_dup 12) (minus:XF (match_dup 10)
13796 (float_extend:XF (match_dup 13))))
13797 (set (match_operand:XF 0 "register_operand" "")
13798 (plus:XF (match_dup 12) (match_dup 7)))]
13799 "TARGET_USE_FANCY_MATH_387
13800 && flag_unsafe_math_optimizations"
13804 if (optimize_insn_for_size_p ())
13807 for (i = 2; i < 13; i++)
13808 operands[i] = gen_reg_rtx (XFmode);
13811 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
13813 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
13816 (define_expand "expm1<mode>2"
13817 [(use (match_operand:MODEF 0 "register_operand" ""))
13818 (use (match_operand:MODEF 1 "general_operand" ""))]
13819 "TARGET_USE_FANCY_MATH_387
13820 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13821 || TARGET_MIX_SSE_I387)
13822 && flag_unsafe_math_optimizations"
13826 if (optimize_insn_for_size_p ())
13829 op0 = gen_reg_rtx (XFmode);
13830 op1 = gen_reg_rtx (XFmode);
13832 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13833 emit_insn (gen_expm1xf2 (op0, op1));
13834 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13838 (define_expand "ldexpxf3"
13839 [(set (match_dup 3)
13840 (float:XF (match_operand:SI 2 "register_operand" "")))
13841 (parallel [(set (match_operand:XF 0 " register_operand" "")
13842 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13844 UNSPEC_FSCALE_FRACT))
13846 (unspec:XF [(match_dup 1) (match_dup 3)]
13847 UNSPEC_FSCALE_EXP))])]
13848 "TARGET_USE_FANCY_MATH_387
13849 && flag_unsafe_math_optimizations"
13851 if (optimize_insn_for_size_p ())
13854 operands[3] = gen_reg_rtx (XFmode);
13855 operands[4] = gen_reg_rtx (XFmode);
13858 (define_expand "ldexp<mode>3"
13859 [(use (match_operand:MODEF 0 "register_operand" ""))
13860 (use (match_operand:MODEF 1 "general_operand" ""))
13861 (use (match_operand:SI 2 "register_operand" ""))]
13862 "TARGET_USE_FANCY_MATH_387
13863 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13864 || TARGET_MIX_SSE_I387)
13865 && flag_unsafe_math_optimizations"
13869 if (optimize_insn_for_size_p ())
13872 op0 = gen_reg_rtx (XFmode);
13873 op1 = gen_reg_rtx (XFmode);
13875 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13876 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
13877 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13881 (define_expand "scalbxf3"
13882 [(parallel [(set (match_operand:XF 0 " register_operand" "")
13883 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13884 (match_operand:XF 2 "register_operand" "")]
13885 UNSPEC_FSCALE_FRACT))
13887 (unspec:XF [(match_dup 1) (match_dup 2)]
13888 UNSPEC_FSCALE_EXP))])]
13889 "TARGET_USE_FANCY_MATH_387
13890 && flag_unsafe_math_optimizations"
13892 if (optimize_insn_for_size_p ())
13895 operands[3] = gen_reg_rtx (XFmode);
13898 (define_expand "scalb<mode>3"
13899 [(use (match_operand:MODEF 0 "register_operand" ""))
13900 (use (match_operand:MODEF 1 "general_operand" ""))
13901 (use (match_operand:MODEF 2 "general_operand" ""))]
13902 "TARGET_USE_FANCY_MATH_387
13903 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13904 || TARGET_MIX_SSE_I387)
13905 && flag_unsafe_math_optimizations"
13909 if (optimize_insn_for_size_p ())
13912 op0 = gen_reg_rtx (XFmode);
13913 op1 = gen_reg_rtx (XFmode);
13914 op2 = gen_reg_rtx (XFmode);
13916 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13917 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13918 emit_insn (gen_scalbxf3 (op0, op1, op2));
13919 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13923 (define_expand "significandxf2"
13924 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13925 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13926 UNSPEC_XTRACT_FRACT))
13928 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13929 "TARGET_USE_FANCY_MATH_387
13930 && flag_unsafe_math_optimizations"
13932 operands[2] = gen_reg_rtx (XFmode);
13935 (define_expand "significand<mode>2"
13936 [(use (match_operand:MODEF 0 "register_operand" ""))
13937 (use (match_operand:MODEF 1 "register_operand" ""))]
13938 "TARGET_USE_FANCY_MATH_387
13939 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13940 || TARGET_MIX_SSE_I387)
13941 && flag_unsafe_math_optimizations"
13943 rtx op0 = gen_reg_rtx (XFmode);
13944 rtx op1 = gen_reg_rtx (XFmode);
13946 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13947 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13952 (define_insn "sse4_1_round<mode>2"
13953 [(set (match_operand:MODEF 0 "register_operand" "=x")
13954 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
13955 (match_operand:SI 2 "const_0_to_15_operand" "n")]
13958 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
13959 [(set_attr "type" "ssecvt")
13960 (set_attr "prefix_extra" "1")
13961 (set_attr "prefix" "maybe_vex")
13962 (set_attr "mode" "<MODE>")])
13964 (define_insn "rintxf2"
13965 [(set (match_operand:XF 0 "register_operand" "=f")
13966 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13968 "TARGET_USE_FANCY_MATH_387
13969 && flag_unsafe_math_optimizations"
13971 [(set_attr "type" "fpspc")
13972 (set_attr "mode" "XF")])
13974 (define_expand "rint<mode>2"
13975 [(use (match_operand:MODEF 0 "register_operand" ""))
13976 (use (match_operand:MODEF 1 "register_operand" ""))]
13977 "(TARGET_USE_FANCY_MATH_387
13978 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13979 || TARGET_MIX_SSE_I387)
13980 && flag_unsafe_math_optimizations)
13981 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13982 && !flag_trapping_math)"
13984 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13985 && !flag_trapping_math)
13987 if (!TARGET_ROUND && optimize_insn_for_size_p ())
13990 emit_insn (gen_sse4_1_round<mode>2
13991 (operands[0], operands[1], GEN_INT (0x04)));
13993 ix86_expand_rint (operand0, operand1);
13997 rtx op0 = gen_reg_rtx (XFmode);
13998 rtx op1 = gen_reg_rtx (XFmode);
14000 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14001 emit_insn (gen_rintxf2 (op0, op1));
14003 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14008 (define_expand "round<mode>2"
14009 [(match_operand:MODEF 0 "register_operand" "")
14010 (match_operand:MODEF 1 "nonimmediate_operand" "")]
14011 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14012 && !flag_trapping_math && !flag_rounding_math"
14014 if (optimize_insn_for_size_p ())
14016 if (TARGET_64BIT || (<MODE>mode != DFmode))
14017 ix86_expand_round (operand0, operand1);
14019 ix86_expand_rounddf_32 (operand0, operand1);
14023 (define_insn_and_split "*fistdi2_1"
14024 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14025 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14027 "TARGET_USE_FANCY_MATH_387
14028 && can_create_pseudo_p ()"
14033 if (memory_operand (operands[0], VOIDmode))
14034 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14037 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14038 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14043 [(set_attr "type" "fpspc")
14044 (set_attr "mode" "DI")])
14046 (define_insn "fistdi2"
14047 [(set (match_operand:DI 0 "memory_operand" "=m")
14048 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14050 (clobber (match_scratch:XF 2 "=&1f"))]
14051 "TARGET_USE_FANCY_MATH_387"
14052 "* return output_fix_trunc (insn, operands, 0);"
14053 [(set_attr "type" "fpspc")
14054 (set_attr "mode" "DI")])
14056 (define_insn "fistdi2_with_temp"
14057 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14058 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14060 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14061 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14062 "TARGET_USE_FANCY_MATH_387"
14064 [(set_attr "type" "fpspc")
14065 (set_attr "mode" "DI")])
14068 [(set (match_operand:DI 0 "register_operand" "")
14069 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14071 (clobber (match_operand:DI 2 "memory_operand" ""))
14072 (clobber (match_scratch 3 ""))]
14074 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14075 (clobber (match_dup 3))])
14076 (set (match_dup 0) (match_dup 2))])
14079 [(set (match_operand:DI 0 "memory_operand" "")
14080 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14082 (clobber (match_operand:DI 2 "memory_operand" ""))
14083 (clobber (match_scratch 3 ""))]
14085 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14086 (clobber (match_dup 3))])])
14088 (define_insn_and_split "*fist<mode>2_1"
14089 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14090 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14092 "TARGET_USE_FANCY_MATH_387
14093 && can_create_pseudo_p ()"
14098 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14099 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14103 [(set_attr "type" "fpspc")
14104 (set_attr "mode" "<MODE>")])
14106 (define_insn "fist<mode>2"
14107 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14108 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14110 "TARGET_USE_FANCY_MATH_387"
14111 "* return output_fix_trunc (insn, operands, 0);"
14112 [(set_attr "type" "fpspc")
14113 (set_attr "mode" "<MODE>")])
14115 (define_insn "fist<mode>2_with_temp"
14116 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14117 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14119 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14120 "TARGET_USE_FANCY_MATH_387"
14122 [(set_attr "type" "fpspc")
14123 (set_attr "mode" "<MODE>")])
14126 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14127 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14129 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14131 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14132 (set (match_dup 0) (match_dup 2))])
14135 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14136 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14138 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14140 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))])
14142 (define_expand "lrintxf<mode>2"
14143 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14144 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14146 "TARGET_USE_FANCY_MATH_387"
14149 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14150 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14151 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14152 UNSPEC_FIX_NOTRUNC))]
14153 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14154 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
14157 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14158 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14159 (match_operand:MODEF 1 "register_operand" "")]
14160 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14161 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14162 && !flag_trapping_math && !flag_rounding_math"
14164 if (optimize_insn_for_size_p ())
14166 ix86_expand_lround (operand0, operand1);
14170 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14171 (define_insn_and_split "frndintxf2_floor"
14172 [(set (match_operand:XF 0 "register_operand" "")
14173 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14174 UNSPEC_FRNDINT_FLOOR))
14175 (clobber (reg:CC FLAGS_REG))]
14176 "TARGET_USE_FANCY_MATH_387
14177 && flag_unsafe_math_optimizations
14178 && can_create_pseudo_p ()"
14183 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14185 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14186 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14188 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14189 operands[2], operands[3]));
14192 [(set_attr "type" "frndint")
14193 (set_attr "i387_cw" "floor")
14194 (set_attr "mode" "XF")])
14196 (define_insn "frndintxf2_floor_i387"
14197 [(set (match_operand:XF 0 "register_operand" "=f")
14198 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14199 UNSPEC_FRNDINT_FLOOR))
14200 (use (match_operand:HI 2 "memory_operand" "m"))
14201 (use (match_operand:HI 3 "memory_operand" "m"))]
14202 "TARGET_USE_FANCY_MATH_387
14203 && flag_unsafe_math_optimizations"
14204 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14205 [(set_attr "type" "frndint")
14206 (set_attr "i387_cw" "floor")
14207 (set_attr "mode" "XF")])
14209 (define_expand "floorxf2"
14210 [(use (match_operand:XF 0 "register_operand" ""))
14211 (use (match_operand:XF 1 "register_operand" ""))]
14212 "TARGET_USE_FANCY_MATH_387
14213 && flag_unsafe_math_optimizations"
14215 if (optimize_insn_for_size_p ())
14217 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14221 (define_expand "floor<mode>2"
14222 [(use (match_operand:MODEF 0 "register_operand" ""))
14223 (use (match_operand:MODEF 1 "register_operand" ""))]
14224 "(TARGET_USE_FANCY_MATH_387
14225 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14226 || TARGET_MIX_SSE_I387)
14227 && flag_unsafe_math_optimizations)
14228 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14229 && !flag_trapping_math)"
14231 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14232 && !flag_trapping_math
14233 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14235 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14238 emit_insn (gen_sse4_1_round<mode>2
14239 (operands[0], operands[1], GEN_INT (0x01)));
14240 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14241 ix86_expand_floorceil (operand0, operand1, true);
14243 ix86_expand_floorceildf_32 (operand0, operand1, true);
14249 if (optimize_insn_for_size_p ())
14252 op0 = gen_reg_rtx (XFmode);
14253 op1 = gen_reg_rtx (XFmode);
14254 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14255 emit_insn (gen_frndintxf2_floor (op0, op1));
14257 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14262 (define_insn_and_split "*fist<mode>2_floor_1"
14263 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14264 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14265 UNSPEC_FIST_FLOOR))
14266 (clobber (reg:CC FLAGS_REG))]
14267 "TARGET_USE_FANCY_MATH_387
14268 && flag_unsafe_math_optimizations
14269 && can_create_pseudo_p ()"
14274 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14276 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14277 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14278 if (memory_operand (operands[0], VOIDmode))
14279 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14280 operands[2], operands[3]));
14283 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14284 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14285 operands[2], operands[3],
14290 [(set_attr "type" "fistp")
14291 (set_attr "i387_cw" "floor")
14292 (set_attr "mode" "<MODE>")])
14294 (define_insn "fistdi2_floor"
14295 [(set (match_operand:DI 0 "memory_operand" "=m")
14296 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14297 UNSPEC_FIST_FLOOR))
14298 (use (match_operand:HI 2 "memory_operand" "m"))
14299 (use (match_operand:HI 3 "memory_operand" "m"))
14300 (clobber (match_scratch:XF 4 "=&1f"))]
14301 "TARGET_USE_FANCY_MATH_387
14302 && flag_unsafe_math_optimizations"
14303 "* return output_fix_trunc (insn, operands, 0);"
14304 [(set_attr "type" "fistp")
14305 (set_attr "i387_cw" "floor")
14306 (set_attr "mode" "DI")])
14308 (define_insn "fistdi2_floor_with_temp"
14309 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14310 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14311 UNSPEC_FIST_FLOOR))
14312 (use (match_operand:HI 2 "memory_operand" "m,m"))
14313 (use (match_operand:HI 3 "memory_operand" "m,m"))
14314 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14315 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14316 "TARGET_USE_FANCY_MATH_387
14317 && flag_unsafe_math_optimizations"
14319 [(set_attr "type" "fistp")
14320 (set_attr "i387_cw" "floor")
14321 (set_attr "mode" "DI")])
14324 [(set (match_operand:DI 0 "register_operand" "")
14325 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14326 UNSPEC_FIST_FLOOR))
14327 (use (match_operand:HI 2 "memory_operand" ""))
14328 (use (match_operand:HI 3 "memory_operand" ""))
14329 (clobber (match_operand:DI 4 "memory_operand" ""))
14330 (clobber (match_scratch 5 ""))]
14332 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14333 (use (match_dup 2))
14334 (use (match_dup 3))
14335 (clobber (match_dup 5))])
14336 (set (match_dup 0) (match_dup 4))])
14339 [(set (match_operand:DI 0 "memory_operand" "")
14340 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14341 UNSPEC_FIST_FLOOR))
14342 (use (match_operand:HI 2 "memory_operand" ""))
14343 (use (match_operand:HI 3 "memory_operand" ""))
14344 (clobber (match_operand:DI 4 "memory_operand" ""))
14345 (clobber (match_scratch 5 ""))]
14347 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14348 (use (match_dup 2))
14349 (use (match_dup 3))
14350 (clobber (match_dup 5))])])
14352 (define_insn "fist<mode>2_floor"
14353 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14354 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14355 UNSPEC_FIST_FLOOR))
14356 (use (match_operand:HI 2 "memory_operand" "m"))
14357 (use (match_operand:HI 3 "memory_operand" "m"))]
14358 "TARGET_USE_FANCY_MATH_387
14359 && flag_unsafe_math_optimizations"
14360 "* return output_fix_trunc (insn, operands, 0);"
14361 [(set_attr "type" "fistp")
14362 (set_attr "i387_cw" "floor")
14363 (set_attr "mode" "<MODE>")])
14365 (define_insn "fist<mode>2_floor_with_temp"
14366 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14367 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14368 UNSPEC_FIST_FLOOR))
14369 (use (match_operand:HI 2 "memory_operand" "m,m"))
14370 (use (match_operand:HI 3 "memory_operand" "m,m"))
14371 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14372 "TARGET_USE_FANCY_MATH_387
14373 && flag_unsafe_math_optimizations"
14375 [(set_attr "type" "fistp")
14376 (set_attr "i387_cw" "floor")
14377 (set_attr "mode" "<MODE>")])
14380 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14381 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14382 UNSPEC_FIST_FLOOR))
14383 (use (match_operand:HI 2 "memory_operand" ""))
14384 (use (match_operand:HI 3 "memory_operand" ""))
14385 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14387 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14388 UNSPEC_FIST_FLOOR))
14389 (use (match_dup 2))
14390 (use (match_dup 3))])
14391 (set (match_dup 0) (match_dup 4))])
14394 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14395 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14396 UNSPEC_FIST_FLOOR))
14397 (use (match_operand:HI 2 "memory_operand" ""))
14398 (use (match_operand:HI 3 "memory_operand" ""))
14399 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14401 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14402 UNSPEC_FIST_FLOOR))
14403 (use (match_dup 2))
14404 (use (match_dup 3))])])
14406 (define_expand "lfloorxf<mode>2"
14407 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14408 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14409 UNSPEC_FIST_FLOOR))
14410 (clobber (reg:CC FLAGS_REG))])]
14411 "TARGET_USE_FANCY_MATH_387
14412 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14413 && flag_unsafe_math_optimizations"
14416 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14417 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14418 (match_operand:MODEF 1 "register_operand" "")]
14419 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14420 && !flag_trapping_math"
14422 if (TARGET_64BIT && optimize_insn_for_size_p ())
14424 ix86_expand_lfloorceil (operand0, operand1, true);
14428 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14429 (define_insn_and_split "frndintxf2_ceil"
14430 [(set (match_operand:XF 0 "register_operand" "")
14431 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14432 UNSPEC_FRNDINT_CEIL))
14433 (clobber (reg:CC FLAGS_REG))]
14434 "TARGET_USE_FANCY_MATH_387
14435 && flag_unsafe_math_optimizations
14436 && can_create_pseudo_p ()"
14441 ix86_optimize_mode_switching[I387_CEIL] = 1;
14443 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14444 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14446 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14447 operands[2], operands[3]));
14450 [(set_attr "type" "frndint")
14451 (set_attr "i387_cw" "ceil")
14452 (set_attr "mode" "XF")])
14454 (define_insn "frndintxf2_ceil_i387"
14455 [(set (match_operand:XF 0 "register_operand" "=f")
14456 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14457 UNSPEC_FRNDINT_CEIL))
14458 (use (match_operand:HI 2 "memory_operand" "m"))
14459 (use (match_operand:HI 3 "memory_operand" "m"))]
14460 "TARGET_USE_FANCY_MATH_387
14461 && flag_unsafe_math_optimizations"
14462 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14463 [(set_attr "type" "frndint")
14464 (set_attr "i387_cw" "ceil")
14465 (set_attr "mode" "XF")])
14467 (define_expand "ceilxf2"
14468 [(use (match_operand:XF 0 "register_operand" ""))
14469 (use (match_operand:XF 1 "register_operand" ""))]
14470 "TARGET_USE_FANCY_MATH_387
14471 && flag_unsafe_math_optimizations"
14473 if (optimize_insn_for_size_p ())
14475 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
14479 (define_expand "ceil<mode>2"
14480 [(use (match_operand:MODEF 0 "register_operand" ""))
14481 (use (match_operand:MODEF 1 "register_operand" ""))]
14482 "(TARGET_USE_FANCY_MATH_387
14483 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14484 || TARGET_MIX_SSE_I387)
14485 && flag_unsafe_math_optimizations)
14486 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14487 && !flag_trapping_math)"
14489 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14490 && !flag_trapping_math
14491 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14494 emit_insn (gen_sse4_1_round<mode>2
14495 (operands[0], operands[1], GEN_INT (0x02)));
14496 else if (optimize_insn_for_size_p ())
14498 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14499 ix86_expand_floorceil (operand0, operand1, false);
14501 ix86_expand_floorceildf_32 (operand0, operand1, false);
14507 if (optimize_insn_for_size_p ())
14510 op0 = gen_reg_rtx (XFmode);
14511 op1 = gen_reg_rtx (XFmode);
14512 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14513 emit_insn (gen_frndintxf2_ceil (op0, op1));
14515 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14520 (define_insn_and_split "*fist<mode>2_ceil_1"
14521 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14522 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14524 (clobber (reg:CC FLAGS_REG))]
14525 "TARGET_USE_FANCY_MATH_387
14526 && flag_unsafe_math_optimizations
14527 && can_create_pseudo_p ()"
14532 ix86_optimize_mode_switching[I387_CEIL] = 1;
14534 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14535 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14536 if (memory_operand (operands[0], VOIDmode))
14537 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
14538 operands[2], operands[3]));
14541 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14542 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
14543 operands[2], operands[3],
14548 [(set_attr "type" "fistp")
14549 (set_attr "i387_cw" "ceil")
14550 (set_attr "mode" "<MODE>")])
14552 (define_insn "fistdi2_ceil"
14553 [(set (match_operand:DI 0 "memory_operand" "=m")
14554 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14556 (use (match_operand:HI 2 "memory_operand" "m"))
14557 (use (match_operand:HI 3 "memory_operand" "m"))
14558 (clobber (match_scratch:XF 4 "=&1f"))]
14559 "TARGET_USE_FANCY_MATH_387
14560 && flag_unsafe_math_optimizations"
14561 "* return output_fix_trunc (insn, operands, 0);"
14562 [(set_attr "type" "fistp")
14563 (set_attr "i387_cw" "ceil")
14564 (set_attr "mode" "DI")])
14566 (define_insn "fistdi2_ceil_with_temp"
14567 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14568 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14570 (use (match_operand:HI 2 "memory_operand" "m,m"))
14571 (use (match_operand:HI 3 "memory_operand" "m,m"))
14572 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14573 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14574 "TARGET_USE_FANCY_MATH_387
14575 && flag_unsafe_math_optimizations"
14577 [(set_attr "type" "fistp")
14578 (set_attr "i387_cw" "ceil")
14579 (set_attr "mode" "DI")])
14582 [(set (match_operand:DI 0 "register_operand" "")
14583 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14585 (use (match_operand:HI 2 "memory_operand" ""))
14586 (use (match_operand:HI 3 "memory_operand" ""))
14587 (clobber (match_operand:DI 4 "memory_operand" ""))
14588 (clobber (match_scratch 5 ""))]
14590 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14591 (use (match_dup 2))
14592 (use (match_dup 3))
14593 (clobber (match_dup 5))])
14594 (set (match_dup 0) (match_dup 4))])
14597 [(set (match_operand:DI 0 "memory_operand" "")
14598 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14600 (use (match_operand:HI 2 "memory_operand" ""))
14601 (use (match_operand:HI 3 "memory_operand" ""))
14602 (clobber (match_operand:DI 4 "memory_operand" ""))
14603 (clobber (match_scratch 5 ""))]
14605 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14606 (use (match_dup 2))
14607 (use (match_dup 3))
14608 (clobber (match_dup 5))])])
14610 (define_insn "fist<mode>2_ceil"
14611 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14612 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14614 (use (match_operand:HI 2 "memory_operand" "m"))
14615 (use (match_operand:HI 3 "memory_operand" "m"))]
14616 "TARGET_USE_FANCY_MATH_387
14617 && flag_unsafe_math_optimizations"
14618 "* return output_fix_trunc (insn, operands, 0);"
14619 [(set_attr "type" "fistp")
14620 (set_attr "i387_cw" "ceil")
14621 (set_attr "mode" "<MODE>")])
14623 (define_insn "fist<mode>2_ceil_with_temp"
14624 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14625 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14627 (use (match_operand:HI 2 "memory_operand" "m,m"))
14628 (use (match_operand:HI 3 "memory_operand" "m,m"))
14629 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14630 "TARGET_USE_FANCY_MATH_387
14631 && flag_unsafe_math_optimizations"
14633 [(set_attr "type" "fistp")
14634 (set_attr "i387_cw" "ceil")
14635 (set_attr "mode" "<MODE>")])
14638 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14639 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14641 (use (match_operand:HI 2 "memory_operand" ""))
14642 (use (match_operand:HI 3 "memory_operand" ""))
14643 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14645 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14647 (use (match_dup 2))
14648 (use (match_dup 3))])
14649 (set (match_dup 0) (match_dup 4))])
14652 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14653 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14655 (use (match_operand:HI 2 "memory_operand" ""))
14656 (use (match_operand:HI 3 "memory_operand" ""))
14657 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14659 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14661 (use (match_dup 2))
14662 (use (match_dup 3))])])
14664 (define_expand "lceilxf<mode>2"
14665 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14666 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14668 (clobber (reg:CC FLAGS_REG))])]
14669 "TARGET_USE_FANCY_MATH_387
14670 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14671 && flag_unsafe_math_optimizations"
14674 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
14675 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14676 (match_operand:MODEF 1 "register_operand" "")]
14677 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14678 && !flag_trapping_math"
14680 ix86_expand_lfloorceil (operand0, operand1, false);
14684 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14685 (define_insn_and_split "frndintxf2_trunc"
14686 [(set (match_operand:XF 0 "register_operand" "")
14687 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14688 UNSPEC_FRNDINT_TRUNC))
14689 (clobber (reg:CC FLAGS_REG))]
14690 "TARGET_USE_FANCY_MATH_387
14691 && flag_unsafe_math_optimizations
14692 && can_create_pseudo_p ()"
14697 ix86_optimize_mode_switching[I387_TRUNC] = 1;
14699 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14700 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
14702 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
14703 operands[2], operands[3]));
14706 [(set_attr "type" "frndint")
14707 (set_attr "i387_cw" "trunc")
14708 (set_attr "mode" "XF")])
14710 (define_insn "frndintxf2_trunc_i387"
14711 [(set (match_operand:XF 0 "register_operand" "=f")
14712 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14713 UNSPEC_FRNDINT_TRUNC))
14714 (use (match_operand:HI 2 "memory_operand" "m"))
14715 (use (match_operand:HI 3 "memory_operand" "m"))]
14716 "TARGET_USE_FANCY_MATH_387
14717 && flag_unsafe_math_optimizations"
14718 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14719 [(set_attr "type" "frndint")
14720 (set_attr "i387_cw" "trunc")
14721 (set_attr "mode" "XF")])
14723 (define_expand "btruncxf2"
14724 [(use (match_operand:XF 0 "register_operand" ""))
14725 (use (match_operand:XF 1 "register_operand" ""))]
14726 "TARGET_USE_FANCY_MATH_387
14727 && flag_unsafe_math_optimizations"
14729 if (optimize_insn_for_size_p ())
14731 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
14735 (define_expand "btrunc<mode>2"
14736 [(use (match_operand:MODEF 0 "register_operand" ""))
14737 (use (match_operand:MODEF 1 "register_operand" ""))]
14738 "(TARGET_USE_FANCY_MATH_387
14739 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14740 || TARGET_MIX_SSE_I387)
14741 && flag_unsafe_math_optimizations)
14742 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14743 && !flag_trapping_math)"
14745 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14746 && !flag_trapping_math
14747 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14750 emit_insn (gen_sse4_1_round<mode>2
14751 (operands[0], operands[1], GEN_INT (0x03)));
14752 else if (optimize_insn_for_size_p ())
14754 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14755 ix86_expand_trunc (operand0, operand1);
14757 ix86_expand_truncdf_32 (operand0, operand1);
14763 if (optimize_insn_for_size_p ())
14766 op0 = gen_reg_rtx (XFmode);
14767 op1 = gen_reg_rtx (XFmode);
14768 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14769 emit_insn (gen_frndintxf2_trunc (op0, op1));
14771 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14776 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14777 (define_insn_and_split "frndintxf2_mask_pm"
14778 [(set (match_operand:XF 0 "register_operand" "")
14779 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14780 UNSPEC_FRNDINT_MASK_PM))
14781 (clobber (reg:CC FLAGS_REG))]
14782 "TARGET_USE_FANCY_MATH_387
14783 && flag_unsafe_math_optimizations
14784 && can_create_pseudo_p ()"
14789 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
14791 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14792 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
14794 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
14795 operands[2], operands[3]));
14798 [(set_attr "type" "frndint")
14799 (set_attr "i387_cw" "mask_pm")
14800 (set_attr "mode" "XF")])
14802 (define_insn "frndintxf2_mask_pm_i387"
14803 [(set (match_operand:XF 0 "register_operand" "=f")
14804 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14805 UNSPEC_FRNDINT_MASK_PM))
14806 (use (match_operand:HI 2 "memory_operand" "m"))
14807 (use (match_operand:HI 3 "memory_operand" "m"))]
14808 "TARGET_USE_FANCY_MATH_387
14809 && flag_unsafe_math_optimizations"
14810 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
14811 [(set_attr "type" "frndint")
14812 (set_attr "i387_cw" "mask_pm")
14813 (set_attr "mode" "XF")])
14815 (define_expand "nearbyintxf2"
14816 [(use (match_operand:XF 0 "register_operand" ""))
14817 (use (match_operand:XF 1 "register_operand" ""))]
14818 "TARGET_USE_FANCY_MATH_387
14819 && flag_unsafe_math_optimizations"
14821 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
14826 (define_expand "nearbyint<mode>2"
14827 [(use (match_operand:MODEF 0 "register_operand" ""))
14828 (use (match_operand:MODEF 1 "register_operand" ""))]
14829 "TARGET_USE_FANCY_MATH_387
14830 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14831 || TARGET_MIX_SSE_I387)
14832 && flag_unsafe_math_optimizations"
14834 rtx op0 = gen_reg_rtx (XFmode);
14835 rtx op1 = gen_reg_rtx (XFmode);
14837 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14838 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
14840 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14844 (define_insn "fxam<mode>2_i387"
14845 [(set (match_operand:HI 0 "register_operand" "=a")
14847 [(match_operand:X87MODEF 1 "register_operand" "f")]
14849 "TARGET_USE_FANCY_MATH_387"
14850 "fxam\n\tfnstsw\t%0"
14851 [(set_attr "type" "multi")
14852 (set_attr "length" "4")
14853 (set_attr "unit" "i387")
14854 (set_attr "mode" "<MODE>")])
14856 (define_insn_and_split "fxam<mode>2_i387_with_temp"
14857 [(set (match_operand:HI 0 "register_operand" "")
14859 [(match_operand:MODEF 1 "memory_operand" "")]
14861 "TARGET_USE_FANCY_MATH_387
14862 && can_create_pseudo_p ()"
14865 [(set (match_dup 2)(match_dup 1))
14867 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
14869 operands[2] = gen_reg_rtx (<MODE>mode);
14871 MEM_VOLATILE_P (operands[1]) = 1;
14873 [(set_attr "type" "multi")
14874 (set_attr "unit" "i387")
14875 (set_attr "mode" "<MODE>")])
14877 (define_expand "isinfxf2"
14878 [(use (match_operand:SI 0 "register_operand" ""))
14879 (use (match_operand:XF 1 "register_operand" ""))]
14880 "TARGET_USE_FANCY_MATH_387
14881 && TARGET_C99_FUNCTIONS"
14883 rtx mask = GEN_INT (0x45);
14884 rtx val = GEN_INT (0x05);
14888 rtx scratch = gen_reg_rtx (HImode);
14889 rtx res = gen_reg_rtx (QImode);
14891 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
14893 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
14894 emit_insn (gen_cmpqi_ext_3 (scratch, val));
14895 cond = gen_rtx_fmt_ee (EQ, QImode,
14896 gen_rtx_REG (CCmode, FLAGS_REG),
14898 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
14899 emit_insn (gen_zero_extendqisi2 (operands[0], res));
14903 (define_expand "isinf<mode>2"
14904 [(use (match_operand:SI 0 "register_operand" ""))
14905 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
14906 "TARGET_USE_FANCY_MATH_387
14907 && TARGET_C99_FUNCTIONS
14908 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14910 rtx mask = GEN_INT (0x45);
14911 rtx val = GEN_INT (0x05);
14915 rtx scratch = gen_reg_rtx (HImode);
14916 rtx res = gen_reg_rtx (QImode);
14918 /* Remove excess precision by forcing value through memory. */
14919 if (memory_operand (operands[1], VOIDmode))
14920 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
14923 enum ix86_stack_slot slot = (virtuals_instantiated
14926 rtx temp = assign_386_stack_local (<MODE>mode, slot);
14928 emit_move_insn (temp, operands[1]);
14929 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
14932 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
14933 emit_insn (gen_cmpqi_ext_3 (scratch, val));
14934 cond = gen_rtx_fmt_ee (EQ, QImode,
14935 gen_rtx_REG (CCmode, FLAGS_REG),
14937 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
14938 emit_insn (gen_zero_extendqisi2 (operands[0], res));
14942 (define_expand "signbit<mode>2"
14943 [(use (match_operand:SI 0 "register_operand" ""))
14944 (use (match_operand:X87MODEF 1 "register_operand" ""))]
14945 "TARGET_USE_FANCY_MATH_387
14946 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14948 rtx mask = GEN_INT (0x0200);
14950 rtx scratch = gen_reg_rtx (HImode);
14952 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
14953 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
14957 ;; Block operation instructions
14960 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
14963 [(set_attr "length" "1")
14964 (set_attr "length_immediate" "0")
14965 (set_attr "modrm" "0")])
14967 (define_expand "movmemsi"
14968 [(use (match_operand:BLK 0 "memory_operand" ""))
14969 (use (match_operand:BLK 1 "memory_operand" ""))
14970 (use (match_operand:SI 2 "nonmemory_operand" ""))
14971 (use (match_operand:SI 3 "const_int_operand" ""))
14972 (use (match_operand:SI 4 "const_int_operand" ""))
14973 (use (match_operand:SI 5 "const_int_operand" ""))]
14976 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
14977 operands[4], operands[5]))
14983 (define_expand "movmemdi"
14984 [(use (match_operand:BLK 0 "memory_operand" ""))
14985 (use (match_operand:BLK 1 "memory_operand" ""))
14986 (use (match_operand:DI 2 "nonmemory_operand" ""))
14987 (use (match_operand:DI 3 "const_int_operand" ""))
14988 (use (match_operand:SI 4 "const_int_operand" ""))
14989 (use (match_operand:SI 5 "const_int_operand" ""))]
14992 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
14993 operands[4], operands[5]))
14999 ;; Most CPUs don't like single string operations
15000 ;; Handle this case here to simplify previous expander.
15002 (define_expand "strmov"
15003 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15004 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15005 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15006 (clobber (reg:CC FLAGS_REG))])
15007 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15008 (clobber (reg:CC FLAGS_REG))])]
15011 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15013 /* If .md ever supports :P for Pmode, these can be directly
15014 in the pattern above. */
15015 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15016 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15018 /* Can't use this if the user has appropriated esi or edi. */
15019 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15020 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15022 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15023 operands[2], operands[3],
15024 operands[5], operands[6]));
15028 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15031 (define_expand "strmov_singleop"
15032 [(parallel [(set (match_operand 1 "memory_operand" "")
15033 (match_operand 3 "memory_operand" ""))
15034 (set (match_operand 0 "register_operand" "")
15035 (match_operand 4 "" ""))
15036 (set (match_operand 2 "register_operand" "")
15037 (match_operand 5 "" ""))])]
15039 "ix86_current_function_needs_cld = 1;")
15041 (define_insn "*strmovdi_rex_1"
15042 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15043 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15044 (set (match_operand:DI 0 "register_operand" "=D")
15045 (plus:DI (match_dup 2)
15047 (set (match_operand:DI 1 "register_operand" "=S")
15048 (plus:DI (match_dup 3)
15052 [(set_attr "type" "str")
15053 (set_attr "mode" "DI")
15054 (set_attr "memory" "both")])
15056 (define_insn "*strmovsi_1"
15057 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
15058 (mem:SI (match_operand:SI 3 "register_operand" "1")))
15059 (set (match_operand:SI 0 "register_operand" "=D")
15060 (plus:SI (match_dup 2)
15062 (set (match_operand:SI 1 "register_operand" "=S")
15063 (plus:SI (match_dup 3)
15067 [(set_attr "type" "str")
15068 (set_attr "mode" "SI")
15069 (set_attr "memory" "both")])
15071 (define_insn "*strmovsi_rex_1"
15072 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
15073 (mem:SI (match_operand:DI 3 "register_operand" "1")))
15074 (set (match_operand:DI 0 "register_operand" "=D")
15075 (plus:DI (match_dup 2)
15077 (set (match_operand:DI 1 "register_operand" "=S")
15078 (plus:DI (match_dup 3)
15082 [(set_attr "type" "str")
15083 (set_attr "mode" "SI")
15084 (set_attr "memory" "both")])
15086 (define_insn "*strmovhi_1"
15087 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
15088 (mem:HI (match_operand:SI 3 "register_operand" "1")))
15089 (set (match_operand:SI 0 "register_operand" "=D")
15090 (plus:SI (match_dup 2)
15092 (set (match_operand:SI 1 "register_operand" "=S")
15093 (plus:SI (match_dup 3)
15097 [(set_attr "type" "str")
15098 (set_attr "memory" "both")
15099 (set_attr "mode" "HI")])
15101 (define_insn "*strmovhi_rex_1"
15102 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
15103 (mem:HI (match_operand:DI 3 "register_operand" "1")))
15104 (set (match_operand:DI 0 "register_operand" "=D")
15105 (plus:DI (match_dup 2)
15107 (set (match_operand:DI 1 "register_operand" "=S")
15108 (plus:DI (match_dup 3)
15112 [(set_attr "type" "str")
15113 (set_attr "memory" "both")
15114 (set_attr "mode" "HI")])
15116 (define_insn "*strmovqi_1"
15117 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
15118 (mem:QI (match_operand:SI 3 "register_operand" "1")))
15119 (set (match_operand:SI 0 "register_operand" "=D")
15120 (plus:SI (match_dup 2)
15122 (set (match_operand:SI 1 "register_operand" "=S")
15123 (plus:SI (match_dup 3)
15127 [(set_attr "type" "str")
15128 (set_attr "memory" "both")
15129 (set_attr "mode" "QI")])
15131 (define_insn "*strmovqi_rex_1"
15132 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
15133 (mem:QI (match_operand:DI 3 "register_operand" "1")))
15134 (set (match_operand:DI 0 "register_operand" "=D")
15135 (plus:DI (match_dup 2)
15137 (set (match_operand:DI 1 "register_operand" "=S")
15138 (plus:DI (match_dup 3)
15142 [(set_attr "type" "str")
15143 (set_attr "memory" "both")
15144 (set_attr "prefix_rex" "0")
15145 (set_attr "mode" "QI")])
15147 (define_expand "rep_mov"
15148 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15149 (set (match_operand 0 "register_operand" "")
15150 (match_operand 5 "" ""))
15151 (set (match_operand 2 "register_operand" "")
15152 (match_operand 6 "" ""))
15153 (set (match_operand 1 "memory_operand" "")
15154 (match_operand 3 "memory_operand" ""))
15155 (use (match_dup 4))])]
15157 "ix86_current_function_needs_cld = 1;")
15159 (define_insn "*rep_movdi_rex64"
15160 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15161 (set (match_operand:DI 0 "register_operand" "=D")
15162 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15164 (match_operand:DI 3 "register_operand" "0")))
15165 (set (match_operand:DI 1 "register_operand" "=S")
15166 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15167 (match_operand:DI 4 "register_operand" "1")))
15168 (set (mem:BLK (match_dup 3))
15169 (mem:BLK (match_dup 4)))
15170 (use (match_dup 5))]
15173 [(set_attr "type" "str")
15174 (set_attr "prefix_rep" "1")
15175 (set_attr "memory" "both")
15176 (set_attr "mode" "DI")])
15178 (define_insn "*rep_movsi"
15179 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15180 (set (match_operand:SI 0 "register_operand" "=D")
15181 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
15183 (match_operand:SI 3 "register_operand" "0")))
15184 (set (match_operand:SI 1 "register_operand" "=S")
15185 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
15186 (match_operand:SI 4 "register_operand" "1")))
15187 (set (mem:BLK (match_dup 3))
15188 (mem:BLK (match_dup 4)))
15189 (use (match_dup 5))]
15191 "rep{%;} movs{l|d}"
15192 [(set_attr "type" "str")
15193 (set_attr "prefix_rep" "1")
15194 (set_attr "memory" "both")
15195 (set_attr "mode" "SI")])
15197 (define_insn "*rep_movsi_rex64"
15198 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15199 (set (match_operand:DI 0 "register_operand" "=D")
15200 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15202 (match_operand:DI 3 "register_operand" "0")))
15203 (set (match_operand:DI 1 "register_operand" "=S")
15204 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
15205 (match_operand:DI 4 "register_operand" "1")))
15206 (set (mem:BLK (match_dup 3))
15207 (mem:BLK (match_dup 4)))
15208 (use (match_dup 5))]
15210 "rep{%;} movs{l|d}"
15211 [(set_attr "type" "str")
15212 (set_attr "prefix_rep" "1")
15213 (set_attr "memory" "both")
15214 (set_attr "mode" "SI")])
15216 (define_insn "*rep_movqi"
15217 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
15218 (set (match_operand:SI 0 "register_operand" "=D")
15219 (plus:SI (match_operand:SI 3 "register_operand" "0")
15220 (match_operand:SI 5 "register_operand" "2")))
15221 (set (match_operand:SI 1 "register_operand" "=S")
15222 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
15223 (set (mem:BLK (match_dup 3))
15224 (mem:BLK (match_dup 4)))
15225 (use (match_dup 5))]
15228 [(set_attr "type" "str")
15229 (set_attr "prefix_rep" "1")
15230 (set_attr "memory" "both")
15231 (set_attr "mode" "SI")])
15233 (define_insn "*rep_movqi_rex64"
15234 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15235 (set (match_operand:DI 0 "register_operand" "=D")
15236 (plus:DI (match_operand:DI 3 "register_operand" "0")
15237 (match_operand:DI 5 "register_operand" "2")))
15238 (set (match_operand:DI 1 "register_operand" "=S")
15239 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
15240 (set (mem:BLK (match_dup 3))
15241 (mem:BLK (match_dup 4)))
15242 (use (match_dup 5))]
15245 [(set_attr "type" "str")
15246 (set_attr "prefix_rep" "1")
15247 (set_attr "memory" "both")
15248 (set_attr "mode" "SI")])
15250 (define_expand "setmemsi"
15251 [(use (match_operand:BLK 0 "memory_operand" ""))
15252 (use (match_operand:SI 1 "nonmemory_operand" ""))
15253 (use (match_operand 2 "const_int_operand" ""))
15254 (use (match_operand 3 "const_int_operand" ""))
15255 (use (match_operand:SI 4 "const_int_operand" ""))
15256 (use (match_operand:SI 5 "const_int_operand" ""))]
15259 if (ix86_expand_setmem (operands[0], operands[1],
15260 operands[2], operands[3],
15261 operands[4], operands[5]))
15267 (define_expand "setmemdi"
15268 [(use (match_operand:BLK 0 "memory_operand" ""))
15269 (use (match_operand:DI 1 "nonmemory_operand" ""))
15270 (use (match_operand 2 "const_int_operand" ""))
15271 (use (match_operand 3 "const_int_operand" ""))
15272 (use (match_operand 4 "const_int_operand" ""))
15273 (use (match_operand 5 "const_int_operand" ""))]
15276 if (ix86_expand_setmem (operands[0], operands[1],
15277 operands[2], operands[3],
15278 operands[4], operands[5]))
15284 ;; Most CPUs don't like single string operations
15285 ;; Handle this case here to simplify previous expander.
15287 (define_expand "strset"
15288 [(set (match_operand 1 "memory_operand" "")
15289 (match_operand 2 "register_operand" ""))
15290 (parallel [(set (match_operand 0 "register_operand" "")
15292 (clobber (reg:CC FLAGS_REG))])]
15295 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15296 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15298 /* If .md ever supports :P for Pmode, this can be directly
15299 in the pattern above. */
15300 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15301 GEN_INT (GET_MODE_SIZE (GET_MODE
15303 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15305 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15311 (define_expand "strset_singleop"
15312 [(parallel [(set (match_operand 1 "memory_operand" "")
15313 (match_operand 2 "register_operand" ""))
15314 (set (match_operand 0 "register_operand" "")
15315 (match_operand 3 "" ""))])]
15317 "ix86_current_function_needs_cld = 1;")
15319 (define_insn "*strsetdi_rex_1"
15320 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15321 (match_operand:DI 2 "register_operand" "a"))
15322 (set (match_operand:DI 0 "register_operand" "=D")
15323 (plus:DI (match_dup 1)
15327 [(set_attr "type" "str")
15328 (set_attr "memory" "store")
15329 (set_attr "mode" "DI")])
15331 (define_insn "*strsetsi_1"
15332 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
15333 (match_operand:SI 2 "register_operand" "a"))
15334 (set (match_operand:SI 0 "register_operand" "=D")
15335 (plus:SI (match_dup 1)
15339 [(set_attr "type" "str")
15340 (set_attr "memory" "store")
15341 (set_attr "mode" "SI")])
15343 (define_insn "*strsetsi_rex_1"
15344 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
15345 (match_operand:SI 2 "register_operand" "a"))
15346 (set (match_operand:DI 0 "register_operand" "=D")
15347 (plus:DI (match_dup 1)
15351 [(set_attr "type" "str")
15352 (set_attr "memory" "store")
15353 (set_attr "mode" "SI")])
15355 (define_insn "*strsethi_1"
15356 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
15357 (match_operand:HI 2 "register_operand" "a"))
15358 (set (match_operand:SI 0 "register_operand" "=D")
15359 (plus:SI (match_dup 1)
15363 [(set_attr "type" "str")
15364 (set_attr "memory" "store")
15365 (set_attr "mode" "HI")])
15367 (define_insn "*strsethi_rex_1"
15368 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
15369 (match_operand:HI 2 "register_operand" "a"))
15370 (set (match_operand:DI 0 "register_operand" "=D")
15371 (plus:DI (match_dup 1)
15375 [(set_attr "type" "str")
15376 (set_attr "memory" "store")
15377 (set_attr "mode" "HI")])
15379 (define_insn "*strsetqi_1"
15380 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
15381 (match_operand:QI 2 "register_operand" "a"))
15382 (set (match_operand:SI 0 "register_operand" "=D")
15383 (plus:SI (match_dup 1)
15387 [(set_attr "type" "str")
15388 (set_attr "memory" "store")
15389 (set_attr "mode" "QI")])
15391 (define_insn "*strsetqi_rex_1"
15392 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
15393 (match_operand:QI 2 "register_operand" "a"))
15394 (set (match_operand:DI 0 "register_operand" "=D")
15395 (plus:DI (match_dup 1)
15399 [(set_attr "type" "str")
15400 (set_attr "memory" "store")
15401 (set_attr "prefix_rex" "0")
15402 (set_attr "mode" "QI")])
15404 (define_expand "rep_stos"
15405 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15406 (set (match_operand 0 "register_operand" "")
15407 (match_operand 4 "" ""))
15408 (set (match_operand 2 "memory_operand" "") (const_int 0))
15409 (use (match_operand 3 "register_operand" ""))
15410 (use (match_dup 1))])]
15412 "ix86_current_function_needs_cld = 1;")
15414 (define_insn "*rep_stosdi_rex64"
15415 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15416 (set (match_operand:DI 0 "register_operand" "=D")
15417 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15419 (match_operand:DI 3 "register_operand" "0")))
15420 (set (mem:BLK (match_dup 3))
15422 (use (match_operand:DI 2 "register_operand" "a"))
15423 (use (match_dup 4))]
15426 [(set_attr "type" "str")
15427 (set_attr "prefix_rep" "1")
15428 (set_attr "memory" "store")
15429 (set_attr "mode" "DI")])
15431 (define_insn "*rep_stossi"
15432 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15433 (set (match_operand:SI 0 "register_operand" "=D")
15434 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
15436 (match_operand:SI 3 "register_operand" "0")))
15437 (set (mem:BLK (match_dup 3))
15439 (use (match_operand:SI 2 "register_operand" "a"))
15440 (use (match_dup 4))]
15442 "rep{%;} stos{l|d}"
15443 [(set_attr "type" "str")
15444 (set_attr "prefix_rep" "1")
15445 (set_attr "memory" "store")
15446 (set_attr "mode" "SI")])
15448 (define_insn "*rep_stossi_rex64"
15449 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15450 (set (match_operand:DI 0 "register_operand" "=D")
15451 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15453 (match_operand:DI 3 "register_operand" "0")))
15454 (set (mem:BLK (match_dup 3))
15456 (use (match_operand:SI 2 "register_operand" "a"))
15457 (use (match_dup 4))]
15459 "rep{%;} stos{l|d}"
15460 [(set_attr "type" "str")
15461 (set_attr "prefix_rep" "1")
15462 (set_attr "memory" "store")
15463 (set_attr "mode" "SI")])
15465 (define_insn "*rep_stosqi"
15466 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
15467 (set (match_operand:SI 0 "register_operand" "=D")
15468 (plus:SI (match_operand:SI 3 "register_operand" "0")
15469 (match_operand:SI 4 "register_operand" "1")))
15470 (set (mem:BLK (match_dup 3))
15472 (use (match_operand:QI 2 "register_operand" "a"))
15473 (use (match_dup 4))]
15476 [(set_attr "type" "str")
15477 (set_attr "prefix_rep" "1")
15478 (set_attr "memory" "store")
15479 (set_attr "mode" "QI")])
15481 (define_insn "*rep_stosqi_rex64"
15482 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15483 (set (match_operand:DI 0 "register_operand" "=D")
15484 (plus:DI (match_operand:DI 3 "register_operand" "0")
15485 (match_operand:DI 4 "register_operand" "1")))
15486 (set (mem:BLK (match_dup 3))
15488 (use (match_operand:QI 2 "register_operand" "a"))
15489 (use (match_dup 4))]
15492 [(set_attr "type" "str")
15493 (set_attr "prefix_rep" "1")
15494 (set_attr "memory" "store")
15495 (set_attr "prefix_rex" "0")
15496 (set_attr "mode" "QI")])
15498 (define_expand "cmpstrnsi"
15499 [(set (match_operand:SI 0 "register_operand" "")
15500 (compare:SI (match_operand:BLK 1 "general_operand" "")
15501 (match_operand:BLK 2 "general_operand" "")))
15502 (use (match_operand 3 "general_operand" ""))
15503 (use (match_operand 4 "immediate_operand" ""))]
15506 rtx addr1, addr2, out, outlow, count, countreg, align;
15508 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15511 /* Can't use this if the user has appropriated esi or edi. */
15512 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15517 out = gen_reg_rtx (SImode);
15519 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15520 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15521 if (addr1 != XEXP (operands[1], 0))
15522 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15523 if (addr2 != XEXP (operands[2], 0))
15524 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15526 count = operands[3];
15527 countreg = ix86_zero_extend_to_Pmode (count);
15529 /* %%% Iff we are testing strict equality, we can use known alignment
15530 to good advantage. This may be possible with combine, particularly
15531 once cc0 is dead. */
15532 align = operands[4];
15534 if (CONST_INT_P (count))
15536 if (INTVAL (count) == 0)
15538 emit_move_insn (operands[0], const0_rtx);
15541 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15542 operands[1], operands[2]));
15546 rtx (*gen_cmp) (rtx, rtx);
15548 gen_cmp = (TARGET_64BIT
15549 ? gen_cmpdi_1 : gen_cmpsi_1);
15551 emit_insn (gen_cmp (countreg, countreg));
15552 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15553 operands[1], operands[2]));
15556 outlow = gen_lowpart (QImode, out);
15557 emit_insn (gen_cmpintqi (outlow));
15558 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15560 if (operands[0] != out)
15561 emit_move_insn (operands[0], out);
15566 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15568 (define_expand "cmpintqi"
15569 [(set (match_dup 1)
15570 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15572 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15573 (parallel [(set (match_operand:QI 0 "register_operand" "")
15574 (minus:QI (match_dup 1)
15576 (clobber (reg:CC FLAGS_REG))])]
15578 "operands[1] = gen_reg_rtx (QImode);
15579 operands[2] = gen_reg_rtx (QImode);")
15581 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15582 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
15584 (define_expand "cmpstrnqi_nz_1"
15585 [(parallel [(set (reg:CC FLAGS_REG)
15586 (compare:CC (match_operand 4 "memory_operand" "")
15587 (match_operand 5 "memory_operand" "")))
15588 (use (match_operand 2 "register_operand" ""))
15589 (use (match_operand:SI 3 "immediate_operand" ""))
15590 (clobber (match_operand 0 "register_operand" ""))
15591 (clobber (match_operand 1 "register_operand" ""))
15592 (clobber (match_dup 2))])]
15594 "ix86_current_function_needs_cld = 1;")
15596 (define_insn "*cmpstrnqi_nz_1"
15597 [(set (reg:CC FLAGS_REG)
15598 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15599 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
15600 (use (match_operand:SI 6 "register_operand" "2"))
15601 (use (match_operand:SI 3 "immediate_operand" "i"))
15602 (clobber (match_operand:SI 0 "register_operand" "=S"))
15603 (clobber (match_operand:SI 1 "register_operand" "=D"))
15604 (clobber (match_operand:SI 2 "register_operand" "=c"))]
15607 [(set_attr "type" "str")
15608 (set_attr "mode" "QI")
15609 (set_attr "prefix_rep" "1")])
15611 (define_insn "*cmpstrnqi_nz_rex_1"
15612 [(set (reg:CC FLAGS_REG)
15613 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15614 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
15615 (use (match_operand:DI 6 "register_operand" "2"))
15616 (use (match_operand:SI 3 "immediate_operand" "i"))
15617 (clobber (match_operand:DI 0 "register_operand" "=S"))
15618 (clobber (match_operand:DI 1 "register_operand" "=D"))
15619 (clobber (match_operand:DI 2 "register_operand" "=c"))]
15622 [(set_attr "type" "str")
15623 (set_attr "mode" "QI")
15624 (set_attr "prefix_rex" "0")
15625 (set_attr "prefix_rep" "1")])
15627 ;; The same, but the count is not known to not be zero.
15629 (define_expand "cmpstrnqi_1"
15630 [(parallel [(set (reg:CC FLAGS_REG)
15631 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
15633 (compare:CC (match_operand 4 "memory_operand" "")
15634 (match_operand 5 "memory_operand" ""))
15636 (use (match_operand:SI 3 "immediate_operand" ""))
15637 (use (reg:CC FLAGS_REG))
15638 (clobber (match_operand 0 "register_operand" ""))
15639 (clobber (match_operand 1 "register_operand" ""))
15640 (clobber (match_dup 2))])]
15642 "ix86_current_function_needs_cld = 1;")
15644 (define_insn "*cmpstrnqi_1"
15645 [(set (reg:CC FLAGS_REG)
15646 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
15648 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
15649 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
15651 (use (match_operand:SI 3 "immediate_operand" "i"))
15652 (use (reg:CC FLAGS_REG))
15653 (clobber (match_operand:SI 0 "register_operand" "=S"))
15654 (clobber (match_operand:SI 1 "register_operand" "=D"))
15655 (clobber (match_operand:SI 2 "register_operand" "=c"))]
15658 [(set_attr "type" "str")
15659 (set_attr "mode" "QI")
15660 (set_attr "prefix_rep" "1")])
15662 (define_insn "*cmpstrnqi_rex_1"
15663 [(set (reg:CC FLAGS_REG)
15664 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
15666 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
15667 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
15669 (use (match_operand:SI 3 "immediate_operand" "i"))
15670 (use (reg:CC FLAGS_REG))
15671 (clobber (match_operand:DI 0 "register_operand" "=S"))
15672 (clobber (match_operand:DI 1 "register_operand" "=D"))
15673 (clobber (match_operand:DI 2 "register_operand" "=c"))]
15676 [(set_attr "type" "str")
15677 (set_attr "mode" "QI")
15678 (set_attr "prefix_rex" "0")
15679 (set_attr "prefix_rep" "1")])
15681 (define_expand "strlensi"
15682 [(set (match_operand:SI 0 "register_operand" "")
15683 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
15684 (match_operand:QI 2 "immediate_operand" "")
15685 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
15688 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15694 (define_expand "strlendi"
15695 [(set (match_operand:DI 0 "register_operand" "")
15696 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
15697 (match_operand:QI 2 "immediate_operand" "")
15698 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
15701 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15707 (define_expand "strlenqi_1"
15708 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
15709 (clobber (match_operand 1 "register_operand" ""))
15710 (clobber (reg:CC FLAGS_REG))])]
15712 "ix86_current_function_needs_cld = 1;")
15714 (define_insn "*strlenqi_1"
15715 [(set (match_operand:SI 0 "register_operand" "=&c")
15716 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
15717 (match_operand:QI 2 "register_operand" "a")
15718 (match_operand:SI 3 "immediate_operand" "i")
15719 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
15720 (clobber (match_operand:SI 1 "register_operand" "=D"))
15721 (clobber (reg:CC FLAGS_REG))]
15724 [(set_attr "type" "str")
15725 (set_attr "mode" "QI")
15726 (set_attr "prefix_rep" "1")])
15728 (define_insn "*strlenqi_rex_1"
15729 [(set (match_operand:DI 0 "register_operand" "=&c")
15730 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
15731 (match_operand:QI 2 "register_operand" "a")
15732 (match_operand:DI 3 "immediate_operand" "i")
15733 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
15734 (clobber (match_operand:DI 1 "register_operand" "=D"))
15735 (clobber (reg:CC FLAGS_REG))]
15738 [(set_attr "type" "str")
15739 (set_attr "mode" "QI")
15740 (set_attr "prefix_rex" "0")
15741 (set_attr "prefix_rep" "1")])
15743 ;; Peephole optimizations to clean up after cmpstrn*. This should be
15744 ;; handled in combine, but it is not currently up to the task.
15745 ;; When used for their truth value, the cmpstrn* expanders generate
15754 ;; The intermediate three instructions are unnecessary.
15756 ;; This one handles cmpstrn*_nz_1...
15759 (set (reg:CC FLAGS_REG)
15760 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15761 (mem:BLK (match_operand 5 "register_operand" ""))))
15762 (use (match_operand 6 "register_operand" ""))
15763 (use (match_operand:SI 3 "immediate_operand" ""))
15764 (clobber (match_operand 0 "register_operand" ""))
15765 (clobber (match_operand 1 "register_operand" ""))
15766 (clobber (match_operand 2 "register_operand" ""))])
15767 (set (match_operand:QI 7 "register_operand" "")
15768 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15769 (set (match_operand:QI 8 "register_operand" "")
15770 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15771 (set (reg FLAGS_REG)
15772 (compare (match_dup 7) (match_dup 8)))
15774 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15776 (set (reg:CC FLAGS_REG)
15777 (compare:CC (mem:BLK (match_dup 4))
15778 (mem:BLK (match_dup 5))))
15779 (use (match_dup 6))
15780 (use (match_dup 3))
15781 (clobber (match_dup 0))
15782 (clobber (match_dup 1))
15783 (clobber (match_dup 2))])])
15785 ;; ...and this one handles cmpstrn*_1.
15788 (set (reg:CC FLAGS_REG)
15789 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
15791 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15792 (mem:BLK (match_operand 5 "register_operand" "")))
15794 (use (match_operand:SI 3 "immediate_operand" ""))
15795 (use (reg:CC FLAGS_REG))
15796 (clobber (match_operand 0 "register_operand" ""))
15797 (clobber (match_operand 1 "register_operand" ""))
15798 (clobber (match_operand 2 "register_operand" ""))])
15799 (set (match_operand:QI 7 "register_operand" "")
15800 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15801 (set (match_operand:QI 8 "register_operand" "")
15802 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15803 (set (reg FLAGS_REG)
15804 (compare (match_dup 7) (match_dup 8)))
15806 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15808 (set (reg:CC FLAGS_REG)
15809 (if_then_else:CC (ne (match_dup 6)
15811 (compare:CC (mem:BLK (match_dup 4))
15812 (mem:BLK (match_dup 5)))
15814 (use (match_dup 3))
15815 (use (reg:CC FLAGS_REG))
15816 (clobber (match_dup 0))
15817 (clobber (match_dup 1))
15818 (clobber (match_dup 2))])])
15820 ;; Conditional move instructions.
15822 (define_expand "mov<mode>cc"
15823 [(set (match_operand:SWIM 0 "register_operand" "")
15824 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
15825 (match_operand:SWIM 2 "general_operand" "")
15826 (match_operand:SWIM 3 "general_operand" "")))]
15828 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
15830 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
15831 ;; the register first winds up with `sbbl $0,reg', which is also weird.
15832 ;; So just document what we're doing explicitly.
15834 (define_expand "x86_mov<mode>cc_0_m1"
15836 [(set (match_operand:SWI48 0 "register_operand" "")
15837 (if_then_else:SWI48
15838 (match_operator:SWI48 2 "ix86_carry_flag_operator"
15839 [(match_operand 1 "flags_reg_operand" "")
15843 (clobber (reg:CC FLAGS_REG))])]
15847 (define_insn "*x86_mov<mode>cc_0_m1"
15848 [(set (match_operand:SWI48 0 "register_operand" "=r")
15849 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15850 [(reg FLAGS_REG) (const_int 0)])
15853 (clobber (reg:CC FLAGS_REG))]
15855 "sbb{<imodesuffix>}\t%0, %0"
15856 ; Since we don't have the proper number of operands for an alu insn,
15857 ; fill in all the blanks.
15858 [(set_attr "type" "alu")
15859 (set_attr "use_carry" "1")
15860 (set_attr "pent_pair" "pu")
15861 (set_attr "memory" "none")
15862 (set_attr "imm_disp" "false")
15863 (set_attr "mode" "<MODE>")
15864 (set_attr "length_immediate" "0")])
15866 (define_insn "*x86_mov<mode>cc_0_m1_se"
15867 [(set (match_operand:SWI48 0 "register_operand" "=r")
15868 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15869 [(reg FLAGS_REG) (const_int 0)])
15872 (clobber (reg:CC FLAGS_REG))]
15874 "sbb{<imodesuffix>}\t%0, %0"
15875 [(set_attr "type" "alu")
15876 (set_attr "use_carry" "1")
15877 (set_attr "pent_pair" "pu")
15878 (set_attr "memory" "none")
15879 (set_attr "imm_disp" "false")
15880 (set_attr "mode" "<MODE>")
15881 (set_attr "length_immediate" "0")])
15883 (define_insn "*x86_mov<mode>cc_0_m1_neg"
15884 [(set (match_operand:SWI48 0 "register_operand" "=r")
15885 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15886 [(reg FLAGS_REG) (const_int 0)])))]
15888 "sbb{<imodesuffix>}\t%0, %0"
15889 [(set_attr "type" "alu")
15890 (set_attr "use_carry" "1")
15891 (set_attr "pent_pair" "pu")
15892 (set_attr "memory" "none")
15893 (set_attr "imm_disp" "false")
15894 (set_attr "mode" "<MODE>")
15895 (set_attr "length_immediate" "0")])
15897 (define_insn "*mov<mode>cc_noc"
15898 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
15899 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
15900 [(reg FLAGS_REG) (const_int 0)])
15901 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
15902 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
15903 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
15905 cmov%O2%C1\t{%2, %0|%0, %2}
15906 cmov%O2%c1\t{%3, %0|%0, %3}"
15907 [(set_attr "type" "icmov")
15908 (set_attr "mode" "<MODE>")])
15910 (define_insn_and_split "*movqicc_noc"
15911 [(set (match_operand:QI 0 "register_operand" "=r,r")
15912 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
15913 [(match_operand 4 "flags_reg_operand" "")
15915 (match_operand:QI 2 "register_operand" "r,0")
15916 (match_operand:QI 3 "register_operand" "0,r")))]
15917 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
15919 "&& reload_completed"
15920 [(set (match_dup 0)
15921 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
15924 "operands[0] = gen_lowpart (SImode, operands[0]);
15925 operands[2] = gen_lowpart (SImode, operands[2]);
15926 operands[3] = gen_lowpart (SImode, operands[3]);"
15927 [(set_attr "type" "icmov")
15928 (set_attr "mode" "SI")])
15930 (define_expand "mov<mode>cc"
15931 [(set (match_operand:X87MODEF 0 "register_operand" "")
15932 (if_then_else:X87MODEF
15933 (match_operand 1 "ix86_fp_comparison_operator" "")
15934 (match_operand:X87MODEF 2 "register_operand" "")
15935 (match_operand:X87MODEF 3 "register_operand" "")))]
15936 "(TARGET_80387 && TARGET_CMOVE)
15937 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15938 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
15940 (define_insn "*movsfcc_1_387"
15941 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
15942 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
15943 [(reg FLAGS_REG) (const_int 0)])
15944 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
15945 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
15946 "TARGET_80387 && TARGET_CMOVE
15947 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
15949 fcmov%F1\t{%2, %0|%0, %2}
15950 fcmov%f1\t{%3, %0|%0, %3}
15951 cmov%O2%C1\t{%2, %0|%0, %2}
15952 cmov%O2%c1\t{%3, %0|%0, %3}"
15953 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
15954 (set_attr "mode" "SF,SF,SI,SI")])
15956 (define_insn "*movdfcc_1"
15957 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
15958 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
15959 [(reg FLAGS_REG) (const_int 0)])
15960 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
15961 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
15962 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
15963 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
15965 fcmov%F1\t{%2, %0|%0, %2}
15966 fcmov%f1\t{%3, %0|%0, %3}
15969 [(set_attr "type" "fcmov,fcmov,multi,multi")
15970 (set_attr "mode" "DF")])
15972 (define_insn "*movdfcc_1_rex64"
15973 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
15974 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
15975 [(reg FLAGS_REG) (const_int 0)])
15976 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
15977 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
15978 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
15979 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
15981 fcmov%F1\t{%2, %0|%0, %2}
15982 fcmov%f1\t{%3, %0|%0, %3}
15983 cmov%O2%C1\t{%2, %0|%0, %2}
15984 cmov%O2%c1\t{%3, %0|%0, %3}"
15985 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
15986 (set_attr "mode" "DF")])
15989 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
15990 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
15991 [(match_operand 4 "flags_reg_operand" "")
15993 (match_operand:DF 2 "nonimmediate_operand" "")
15994 (match_operand:DF 3 "nonimmediate_operand" "")))]
15995 "!TARGET_64BIT && reload_completed"
15996 [(set (match_dup 2)
15997 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16001 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16005 split_di (&operands[2], 2, &operands[5], &operands[7]);
16006 split_di (&operands[0], 1, &operands[2], &operands[3]);
16009 (define_insn "*movxfcc_1"
16010 [(set (match_operand:XF 0 "register_operand" "=f,f")
16011 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16012 [(reg FLAGS_REG) (const_int 0)])
16013 (match_operand:XF 2 "register_operand" "f,0")
16014 (match_operand:XF 3 "register_operand" "0,f")))]
16015 "TARGET_80387 && TARGET_CMOVE"
16017 fcmov%F1\t{%2, %0|%0, %2}
16018 fcmov%f1\t{%3, %0|%0, %3}"
16019 [(set_attr "type" "fcmov")
16020 (set_attr "mode" "XF")])
16022 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16023 ;; the scalar versions to have only XMM registers as operands.
16025 ;; XOP conditional move
16026 (define_insn "*xop_pcmov_<mode>"
16027 [(set (match_operand:MODEF 0 "register_operand" "=x")
16028 (if_then_else:MODEF
16029 (match_operand:MODEF 1 "register_operand" "x")
16030 (match_operand:MODEF 2 "register_operand" "x")
16031 (match_operand:MODEF 3 "register_operand" "x")))]
16033 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16034 [(set_attr "type" "sse4arg")])
16036 ;; These versions of the min/max patterns are intentionally ignorant of
16037 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16038 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16039 ;; are undefined in this condition, we're certain this is correct.
16041 (define_insn "*avx_<code><mode>3"
16042 [(set (match_operand:MODEF 0 "register_operand" "=x")
16044 (match_operand:MODEF 1 "nonimmediate_operand" "%x")
16045 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16046 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16047 "v<maxmin_float>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16048 [(set_attr "type" "sseadd")
16049 (set_attr "prefix" "vex")
16050 (set_attr "mode" "<MODE>")])
16052 (define_insn "<code><mode>3"
16053 [(set (match_operand:MODEF 0 "register_operand" "=x")
16055 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
16056 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16057 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16058 "<maxmin_float>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
16059 [(set_attr "type" "sseadd")
16060 (set_attr "mode" "<MODE>")])
16062 ;; These versions of the min/max patterns implement exactly the operations
16063 ;; min = (op1 < op2 ? op1 : op2)
16064 ;; max = (!(op1 < op2) ? op1 : op2)
16065 ;; Their operands are not commutative, and thus they may be used in the
16066 ;; presence of -0.0 and NaN.
16068 (define_insn "*avx_ieee_smin<mode>3"
16069 [(set (match_operand:MODEF 0 "register_operand" "=x")
16071 [(match_operand:MODEF 1 "register_operand" "x")
16072 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16074 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16075 "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16076 [(set_attr "type" "sseadd")
16077 (set_attr "prefix" "vex")
16078 (set_attr "mode" "<MODE>")])
16080 (define_insn "*ieee_smin<mode>3"
16081 [(set (match_operand:MODEF 0 "register_operand" "=x")
16083 [(match_operand:MODEF 1 "register_operand" "0")
16084 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16086 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16087 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
16088 [(set_attr "type" "sseadd")
16089 (set_attr "mode" "<MODE>")])
16091 (define_insn "*avx_ieee_smax<mode>3"
16092 [(set (match_operand:MODEF 0 "register_operand" "=x")
16094 [(match_operand:MODEF 1 "register_operand" "0")
16095 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16097 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16098 "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16099 [(set_attr "type" "sseadd")
16100 (set_attr "prefix" "vex")
16101 (set_attr "mode" "<MODE>")])
16103 (define_insn "*ieee_smax<mode>3"
16104 [(set (match_operand:MODEF 0 "register_operand" "=x")
16106 [(match_operand:MODEF 1 "register_operand" "0")
16107 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16109 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16110 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
16111 [(set_attr "type" "sseadd")
16112 (set_attr "mode" "<MODE>")])
16114 ;; Make two stack loads independent:
16116 ;; fld %st(0) -> fld bb
16117 ;; fmul bb fmul %st(1), %st
16119 ;; Actually we only match the last two instructions for simplicity.
16121 [(set (match_operand 0 "fp_register_operand" "")
16122 (match_operand 1 "fp_register_operand" ""))
16124 (match_operator 2 "binary_fp_operator"
16126 (match_operand 3 "memory_operand" "")]))]
16127 "REGNO (operands[0]) != REGNO (operands[1])"
16128 [(set (match_dup 0) (match_dup 3))
16129 (set (match_dup 0) (match_dup 4))]
16131 ;; The % modifier is not operational anymore in peephole2's, so we have to
16132 ;; swap the operands manually in the case of addition and multiplication.
16133 "if (COMMUTATIVE_ARITH_P (operands[2]))
16134 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16135 GET_MODE (operands[2]),
16136 operands[0], operands[1]);
16138 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16139 GET_MODE (operands[2]),
16140 operands[1], operands[0]);")
16142 ;; Conditional addition patterns
16143 (define_expand "add<mode>cc"
16144 [(match_operand:SWI 0 "register_operand" "")
16145 (match_operand 1 "ordered_comparison_operator" "")
16146 (match_operand:SWI 2 "register_operand" "")
16147 (match_operand:SWI 3 "const_int_operand" "")]
16149 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16151 ;; Misc patterns (?)
16153 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16154 ;; Otherwise there will be nothing to keep
16156 ;; [(set (reg ebp) (reg esp))]
16157 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16158 ;; (clobber (eflags)]
16159 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16161 ;; in proper program order.
16163 (define_insn "pro_epilogue_adjust_stack_<mode>_1"
16164 [(set (match_operand:P 0 "register_operand" "=r,r")
16165 (plus:P (match_operand:P 1 "register_operand" "0,r")
16166 (match_operand:P 2 "<immediate_operand>" "<i>,<i>")))
16167 (clobber (reg:CC FLAGS_REG))
16168 (clobber (mem:BLK (scratch)))]
16171 switch (get_attr_type (insn))
16174 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16177 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16178 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16179 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16181 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16184 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16185 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16188 [(set (attr "type")
16189 (cond [(and (eq_attr "alternative" "0")
16190 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16191 (const_string "alu")
16192 (match_operand:<MODE> 2 "const0_operand" "")
16193 (const_string "imov")
16195 (const_string "lea")))
16196 (set (attr "length_immediate")
16197 (cond [(eq_attr "type" "imov")
16199 (and (eq_attr "type" "alu")
16200 (match_operand 2 "const128_operand" ""))
16203 (const_string "*")))
16204 (set_attr "mode" "<MODE>")])
16206 (define_insn "pro_epilogue_adjust_stack_di_2"
16207 [(set (match_operand:DI 0 "register_operand" "=r,r")
16208 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
16209 (match_operand:DI 3 "immediate_operand" "i,i")))
16210 (use (match_operand:DI 2 "register_operand" "r,l"))
16211 (clobber (reg:CC FLAGS_REG))
16212 (clobber (mem:BLK (scratch)))]
16215 switch (get_attr_type (insn))
16218 return "add{q}\t{%2, %0|%0, %2}";
16221 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
16222 return "lea{q}\t{%a2, %0|%0, %a2}";
16225 gcc_unreachable ();
16228 [(set_attr "type" "alu,lea")
16229 (set_attr "mode" "DI")])
16231 (define_insn "allocate_stack_worker_32"
16232 [(set (match_operand:SI 0 "register_operand" "=a")
16233 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
16234 UNSPECV_STACK_PROBE))
16235 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
16236 (clobber (reg:CC FLAGS_REG))]
16237 "!TARGET_64BIT && ix86_target_stack_probe ()"
16239 [(set_attr "type" "multi")
16240 (set_attr "length" "5")])
16242 (define_insn "allocate_stack_worker_64"
16243 [(set (match_operand:DI 0 "register_operand" "=a")
16244 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
16245 UNSPECV_STACK_PROBE))
16246 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
16247 (clobber (reg:DI R10_REG))
16248 (clobber (reg:DI R11_REG))
16249 (clobber (reg:CC FLAGS_REG))]
16250 "TARGET_64BIT && ix86_target_stack_probe ()"
16252 [(set_attr "type" "multi")
16253 (set_attr "length" "5")])
16255 (define_expand "allocate_stack"
16256 [(match_operand 0 "register_operand" "")
16257 (match_operand 1 "general_operand" "")]
16258 "ix86_target_stack_probe ()"
16262 #ifndef CHECK_STACK_LIMIT
16263 #define CHECK_STACK_LIMIT 0
16266 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16267 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16269 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16270 stack_pointer_rtx, 0, OPTAB_DIRECT);
16271 if (x != stack_pointer_rtx)
16272 emit_move_insn (stack_pointer_rtx, x);
16276 rtx (*gen_allocate_stack_worker) (rtx, rtx);
16279 gen_allocate_stack_worker = gen_allocate_stack_worker_64;
16281 gen_allocate_stack_worker = gen_allocate_stack_worker_32;
16283 x = copy_to_mode_reg (Pmode, operands[1]);
16284 emit_insn (gen_allocate_stack_worker (x, x));
16287 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16291 ;; Use IOR for stack probes, this is shorter.
16292 (define_expand "probe_stack"
16293 [(match_operand 0 "memory_operand" "")]
16296 rtx (*gen_ior3) (rtx, rtx, rtx);
16298 gen_ior3 = (GET_MODE (operands[0]) == DImode
16299 ? gen_iordi3 : gen_iorsi3);
16301 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16305 (define_insn "adjust_stack_and_probe<mode>"
16306 [(set (match_operand:P 0 "register_operand" "=r")
16307 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16308 UNSPECV_PROBE_STACK_RANGE))
16309 (set (reg:P SP_REG)
16310 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16311 (clobber (reg:CC FLAGS_REG))
16312 (clobber (mem:BLK (scratch)))]
16314 "* return output_adjust_stack_and_probe (operands[0]);"
16315 [(set_attr "type" "multi")])
16317 (define_insn "probe_stack_range<mode>"
16318 [(set (match_operand:P 0 "register_operand" "=r")
16319 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16320 (match_operand:P 2 "const_int_operand" "n")]
16321 UNSPECV_PROBE_STACK_RANGE))
16322 (clobber (reg:CC FLAGS_REG))]
16324 "* return output_probe_stack_range (operands[0], operands[2]);"
16325 [(set_attr "type" "multi")])
16327 (define_expand "builtin_setjmp_receiver"
16328 [(label_ref (match_operand 0 "" ""))]
16329 "!TARGET_64BIT && flag_pic"
16335 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16336 rtx label_rtx = gen_label_rtx ();
16337 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16338 xops[0] = xops[1] = picreg;
16339 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16340 ix86_expand_binary_operator (MINUS, SImode, xops);
16344 emit_insn (gen_set_got (pic_offset_table_rtx));
16348 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16351 [(set (match_operand 0 "register_operand" "")
16352 (match_operator 3 "promotable_binary_operator"
16353 [(match_operand 1 "register_operand" "")
16354 (match_operand 2 "aligned_operand" "")]))
16355 (clobber (reg:CC FLAGS_REG))]
16356 "! TARGET_PARTIAL_REG_STALL && reload_completed
16357 && ((GET_MODE (operands[0]) == HImode
16358 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16359 /* ??? next two lines just !satisfies_constraint_K (...) */
16360 || !CONST_INT_P (operands[2])
16361 || satisfies_constraint_K (operands[2])))
16362 || (GET_MODE (operands[0]) == QImode
16363 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16364 [(parallel [(set (match_dup 0)
16365 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16366 (clobber (reg:CC FLAGS_REG))])]
16367 "operands[0] = gen_lowpart (SImode, operands[0]);
16368 operands[1] = gen_lowpart (SImode, operands[1]);
16369 if (GET_CODE (operands[3]) != ASHIFT)
16370 operands[2] = gen_lowpart (SImode, operands[2]);
16371 PUT_MODE (operands[3], SImode);")
16373 ; Promote the QImode tests, as i386 has encoding of the AND
16374 ; instruction with 32-bit sign-extended immediate and thus the
16375 ; instruction size is unchanged, except in the %eax case for
16376 ; which it is increased by one byte, hence the ! optimize_size.
16378 [(set (match_operand 0 "flags_reg_operand" "")
16379 (match_operator 2 "compare_operator"
16380 [(and (match_operand 3 "aligned_operand" "")
16381 (match_operand 4 "const_int_operand" ""))
16383 (set (match_operand 1 "register_operand" "")
16384 (and (match_dup 3) (match_dup 4)))]
16385 "! TARGET_PARTIAL_REG_STALL && reload_completed
16386 && optimize_insn_for_speed_p ()
16387 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16388 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16389 /* Ensure that the operand will remain sign-extended immediate. */
16390 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16391 [(parallel [(set (match_dup 0)
16392 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16395 (and:SI (match_dup 3) (match_dup 4)))])]
16398 = gen_int_mode (INTVAL (operands[4])
16399 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16400 operands[1] = gen_lowpart (SImode, operands[1]);
16401 operands[3] = gen_lowpart (SImode, operands[3]);
16404 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16405 ; the TEST instruction with 32-bit sign-extended immediate and thus
16406 ; the instruction size would at least double, which is not what we
16407 ; want even with ! optimize_size.
16409 [(set (match_operand 0 "flags_reg_operand" "")
16410 (match_operator 1 "compare_operator"
16411 [(and (match_operand:HI 2 "aligned_operand" "")
16412 (match_operand:HI 3 "const_int_operand" ""))
16414 "! TARGET_PARTIAL_REG_STALL && reload_completed
16415 && ! TARGET_FAST_PREFIX
16416 && optimize_insn_for_speed_p ()
16417 /* Ensure that the operand will remain sign-extended immediate. */
16418 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16419 [(set (match_dup 0)
16420 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16424 = gen_int_mode (INTVAL (operands[3])
16425 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16426 operands[2] = gen_lowpart (SImode, operands[2]);
16430 [(set (match_operand 0 "register_operand" "")
16431 (neg (match_operand 1 "register_operand" "")))
16432 (clobber (reg:CC FLAGS_REG))]
16433 "! TARGET_PARTIAL_REG_STALL && reload_completed
16434 && (GET_MODE (operands[0]) == HImode
16435 || (GET_MODE (operands[0]) == QImode
16436 && (TARGET_PROMOTE_QImode
16437 || optimize_insn_for_size_p ())))"
16438 [(parallel [(set (match_dup 0)
16439 (neg:SI (match_dup 1)))
16440 (clobber (reg:CC FLAGS_REG))])]
16441 "operands[0] = gen_lowpart (SImode, operands[0]);
16442 operands[1] = gen_lowpart (SImode, operands[1]);")
16445 [(set (match_operand 0 "register_operand" "")
16446 (not (match_operand 1 "register_operand" "")))]
16447 "! TARGET_PARTIAL_REG_STALL && reload_completed
16448 && (GET_MODE (operands[0]) == HImode
16449 || (GET_MODE (operands[0]) == QImode
16450 && (TARGET_PROMOTE_QImode
16451 || optimize_insn_for_size_p ())))"
16452 [(set (match_dup 0)
16453 (not:SI (match_dup 1)))]
16454 "operands[0] = gen_lowpart (SImode, operands[0]);
16455 operands[1] = gen_lowpart (SImode, operands[1]);")
16458 [(set (match_operand 0 "register_operand" "")
16459 (if_then_else (match_operator 1 "ordered_comparison_operator"
16460 [(reg FLAGS_REG) (const_int 0)])
16461 (match_operand 2 "register_operand" "")
16462 (match_operand 3 "register_operand" "")))]
16463 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16464 && (GET_MODE (operands[0]) == HImode
16465 || (GET_MODE (operands[0]) == QImode
16466 && (TARGET_PROMOTE_QImode
16467 || optimize_insn_for_size_p ())))"
16468 [(set (match_dup 0)
16469 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16470 "operands[0] = gen_lowpart (SImode, operands[0]);
16471 operands[2] = gen_lowpart (SImode, operands[2]);
16472 operands[3] = gen_lowpart (SImode, operands[3]);")
16474 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16475 ;; transform a complex memory operation into two memory to register operations.
16477 ;; Don't push memory operands
16479 [(set (match_operand:SWI 0 "push_operand" "")
16480 (match_operand:SWI 1 "memory_operand" ""))
16481 (match_scratch:SWI 2 "<r>")]
16482 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16483 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16484 [(set (match_dup 2) (match_dup 1))
16485 (set (match_dup 0) (match_dup 2))])
16487 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16490 [(set (match_operand:SF 0 "push_operand" "")
16491 (match_operand:SF 1 "memory_operand" ""))
16492 (match_scratch:SF 2 "r")]
16493 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16494 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16495 [(set (match_dup 2) (match_dup 1))
16496 (set (match_dup 0) (match_dup 2))])
16498 ;; Don't move an immediate directly to memory when the instruction
16501 [(match_scratch:SWI124 1 "<r>")
16502 (set (match_operand:SWI124 0 "memory_operand" "")
16504 "optimize_insn_for_speed_p ()
16505 && !TARGET_USE_MOV0
16506 && TARGET_SPLIT_LONG_MOVES
16507 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16508 && peep2_regno_dead_p (0, FLAGS_REG)"
16509 [(parallel [(set (match_dup 2) (const_int 0))
16510 (clobber (reg:CC FLAGS_REG))])
16511 (set (match_dup 0) (match_dup 1))]
16512 "operands[2] = gen_lowpart (SImode, operands[1]);")
16515 [(match_scratch:SWI124 2 "<r>")
16516 (set (match_operand:SWI124 0 "memory_operand" "")
16517 (match_operand:SWI124 1 "immediate_operand" ""))]
16518 "optimize_insn_for_speed_p ()
16519 && TARGET_SPLIT_LONG_MOVES
16520 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16521 [(set (match_dup 2) (match_dup 1))
16522 (set (match_dup 0) (match_dup 2))])
16524 ;; Don't compare memory with zero, load and use a test instead.
16526 [(set (match_operand 0 "flags_reg_operand" "")
16527 (match_operator 1 "compare_operator"
16528 [(match_operand:SI 2 "memory_operand" "")
16530 (match_scratch:SI 3 "r")]
16531 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16532 [(set (match_dup 3) (match_dup 2))
16533 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16535 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16536 ;; Don't split NOTs with a displacement operand, because resulting XOR
16537 ;; will not be pairable anyway.
16539 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16540 ;; represented using a modRM byte. The XOR replacement is long decoded,
16541 ;; so this split helps here as well.
16543 ;; Note: Can't do this as a regular split because we can't get proper
16544 ;; lifetime information then.
16547 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16548 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16549 "optimize_insn_for_speed_p ()
16550 && ((TARGET_NOT_UNPAIRABLE
16551 && (!MEM_P (operands[0])
16552 || !memory_displacement_operand (operands[0], <MODE>mode)))
16553 || (TARGET_NOT_VECTORMODE
16554 && long_memory_operand (operands[0], <MODE>mode)))
16555 && peep2_regno_dead_p (0, FLAGS_REG)"
16556 [(parallel [(set (match_dup 0)
16557 (xor:SWI124 (match_dup 1) (const_int -1)))
16558 (clobber (reg:CC FLAGS_REG))])])
16560 ;; Non pairable "test imm, reg" instructions can be translated to
16561 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16562 ;; byte opcode instead of two, have a short form for byte operands),
16563 ;; so do it for other CPUs as well. Given that the value was dead,
16564 ;; this should not create any new dependencies. Pass on the sub-word
16565 ;; versions if we're concerned about partial register stalls.
16568 [(set (match_operand 0 "flags_reg_operand" "")
16569 (match_operator 1 "compare_operator"
16570 [(and:SI (match_operand:SI 2 "register_operand" "")
16571 (match_operand:SI 3 "immediate_operand" ""))
16573 "ix86_match_ccmode (insn, CCNOmode)
16574 && (true_regnum (operands[2]) != AX_REG
16575 || satisfies_constraint_K (operands[3]))
16576 && peep2_reg_dead_p (1, operands[2])"
16578 [(set (match_dup 0)
16579 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16582 (and:SI (match_dup 2) (match_dup 3)))])])
16584 ;; We don't need to handle HImode case, because it will be promoted to SImode
16585 ;; on ! TARGET_PARTIAL_REG_STALL
16588 [(set (match_operand 0 "flags_reg_operand" "")
16589 (match_operator 1 "compare_operator"
16590 [(and:QI (match_operand:QI 2 "register_operand" "")
16591 (match_operand:QI 3 "immediate_operand" ""))
16593 "! TARGET_PARTIAL_REG_STALL
16594 && ix86_match_ccmode (insn, CCNOmode)
16595 && true_regnum (operands[2]) != AX_REG
16596 && peep2_reg_dead_p (1, operands[2])"
16598 [(set (match_dup 0)
16599 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16602 (and:QI (match_dup 2) (match_dup 3)))])])
16605 [(set (match_operand 0 "flags_reg_operand" "")
16606 (match_operator 1 "compare_operator"
16609 (match_operand 2 "ext_register_operand" "")
16612 (match_operand 3 "const_int_operand" ""))
16614 "! TARGET_PARTIAL_REG_STALL
16615 && ix86_match_ccmode (insn, CCNOmode)
16616 && true_regnum (operands[2]) != AX_REG
16617 && peep2_reg_dead_p (1, operands[2])"
16618 [(parallel [(set (match_dup 0)
16627 (set (zero_extract:SI (match_dup 2)
16635 (match_dup 3)))])])
16637 ;; Don't do logical operations with memory inputs.
16639 [(match_scratch:SI 2 "r")
16640 (parallel [(set (match_operand:SI 0 "register_operand" "")
16641 (match_operator:SI 3 "arith_or_logical_operator"
16643 (match_operand:SI 1 "memory_operand" "")]))
16644 (clobber (reg:CC FLAGS_REG))])]
16645 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16646 [(set (match_dup 2) (match_dup 1))
16647 (parallel [(set (match_dup 0)
16648 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16649 (clobber (reg:CC FLAGS_REG))])])
16652 [(match_scratch:SI 2 "r")
16653 (parallel [(set (match_operand:SI 0 "register_operand" "")
16654 (match_operator:SI 3 "arith_or_logical_operator"
16655 [(match_operand:SI 1 "memory_operand" "")
16657 (clobber (reg:CC FLAGS_REG))])]
16658 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16659 [(set (match_dup 2) (match_dup 1))
16660 (parallel [(set (match_dup 0)
16661 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16662 (clobber (reg:CC FLAGS_REG))])])
16664 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
16665 ;; refers to the destination of the load!
16668 [(set (match_operand:SI 0 "register_operand" "")
16669 (match_operand:SI 1 "register_operand" ""))
16670 (parallel [(set (match_dup 0)
16671 (match_operator:SI 3 "commutative_operator"
16673 (match_operand:SI 2 "memory_operand" "")]))
16674 (clobber (reg:CC FLAGS_REG))])]
16675 "REGNO (operands[0]) != REGNO (operands[1])
16676 && GENERAL_REGNO_P (REGNO (operands[0]))
16677 && GENERAL_REGNO_P (REGNO (operands[1]))"
16678 [(set (match_dup 0) (match_dup 4))
16679 (parallel [(set (match_dup 0)
16680 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16681 (clobber (reg:CC FLAGS_REG))])]
16682 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
16685 [(set (match_operand 0 "register_operand" "")
16686 (match_operand 1 "register_operand" ""))
16688 (match_operator 3 "commutative_operator"
16690 (match_operand 2 "memory_operand" "")]))]
16691 "REGNO (operands[0]) != REGNO (operands[1])
16692 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
16693 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
16694 [(set (match_dup 0) (match_dup 2))
16696 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
16698 ; Don't do logical operations with memory outputs
16700 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16701 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
16702 ; the same decoder scheduling characteristics as the original.
16705 [(match_scratch:SI 2 "r")
16706 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16707 (match_operator:SI 3 "arith_or_logical_operator"
16709 (match_operand:SI 1 "nonmemory_operand" "")]))
16710 (clobber (reg:CC FLAGS_REG))])]
16711 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16712 /* Do not split stack checking probes. */
16713 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16714 [(set (match_dup 2) (match_dup 0))
16715 (parallel [(set (match_dup 2)
16716 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16717 (clobber (reg:CC FLAGS_REG))])
16718 (set (match_dup 0) (match_dup 2))])
16721 [(match_scratch:SI 2 "r")
16722 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16723 (match_operator:SI 3 "arith_or_logical_operator"
16724 [(match_operand:SI 1 "nonmemory_operand" "")
16726 (clobber (reg:CC FLAGS_REG))])]
16727 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16728 /* Do not split stack checking probes. */
16729 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16730 [(set (match_dup 2) (match_dup 0))
16731 (parallel [(set (match_dup 2)
16732 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16733 (clobber (reg:CC FLAGS_REG))])
16734 (set (match_dup 0) (match_dup 2))])
16736 ;; Attempt to always use XOR for zeroing registers.
16738 [(set (match_operand 0 "register_operand" "")
16739 (match_operand 1 "const0_operand" ""))]
16740 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
16741 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16742 && GENERAL_REG_P (operands[0])
16743 && peep2_regno_dead_p (0, FLAGS_REG)"
16744 [(parallel [(set (match_dup 0) (const_int 0))
16745 (clobber (reg:CC FLAGS_REG))])]
16746 "operands[0] = gen_lowpart (word_mode, operands[0]);")
16749 [(set (strict_low_part (match_operand 0 "register_operand" ""))
16751 "(GET_MODE (operands[0]) == QImode
16752 || GET_MODE (operands[0]) == HImode)
16753 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16754 && peep2_regno_dead_p (0, FLAGS_REG)"
16755 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
16756 (clobber (reg:CC FLAGS_REG))])])
16758 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
16760 [(set (match_operand:SWI248 0 "register_operand" "")
16762 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
16763 && peep2_regno_dead_p (0, FLAGS_REG)"
16764 [(parallel [(set (match_dup 0) (const_int -1))
16765 (clobber (reg:CC FLAGS_REG))])]
16767 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
16768 operands[0] = gen_lowpart (SImode, operands[0]);
16771 ;; Attempt to convert simple lea to add/shift.
16772 ;; These can be created by move expanders.
16775 [(set (match_operand:SWI48 0 "register_operand" "")
16776 (plus:SWI48 (match_dup 0)
16777 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
16778 "peep2_regno_dead_p (0, FLAGS_REG)"
16779 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
16780 (clobber (reg:CC FLAGS_REG))])])
16783 [(set (match_operand:SI 0 "register_operand" "")
16784 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
16785 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
16787 && peep2_regno_dead_p (0, FLAGS_REG)
16788 && REGNO (operands[0]) == REGNO (operands[1])"
16789 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
16790 (clobber (reg:CC FLAGS_REG))])]
16791 "operands[2] = gen_lowpart (SImode, operands[2]);")
16794 [(set (match_operand:SWI48 0 "register_operand" "")
16795 (mult:SWI48 (match_dup 0)
16796 (match_operand:SWI48 1 "const_int_operand" "")))]
16797 "exact_log2 (INTVAL (operands[1])) >= 0
16798 && peep2_regno_dead_p (0, FLAGS_REG)"
16799 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
16800 (clobber (reg:CC FLAGS_REG))])]
16801 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
16804 [(set (match_operand:SI 0 "register_operand" "")
16805 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
16806 (match_operand:DI 2 "const_int_operand" "")) 0))]
16808 && exact_log2 (INTVAL (operands[2])) >= 0
16809 && REGNO (operands[0]) == REGNO (operands[1])
16810 && peep2_regno_dead_p (0, FLAGS_REG)"
16811 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
16812 (clobber (reg:CC FLAGS_REG))])]
16813 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
16815 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
16816 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
16817 ;; On many CPUs it is also faster, since special hardware to avoid esp
16818 ;; dependencies is present.
16820 ;; While some of these conversions may be done using splitters, we use
16821 ;; peepholes in order to allow combine_stack_adjustments pass to see
16822 ;; nonobfuscated RTL.
16824 ;; Convert prologue esp subtractions to push.
16825 ;; We need register to push. In order to keep verify_flow_info happy we have
16827 ;; - use scratch and clobber it in order to avoid dependencies
16828 ;; - use already live register
16829 ;; We can't use the second way right now, since there is no reliable way how to
16830 ;; verify that given register is live. First choice will also most likely in
16831 ;; fewer dependencies. On the place of esp adjustments it is very likely that
16832 ;; call clobbered registers are dead. We may want to use base pointer as an
16833 ;; alternative when no register is available later.
16836 [(match_scratch:P 1 "r")
16837 (parallel [(set (reg:P SP_REG)
16838 (plus:P (reg:P SP_REG)
16839 (match_operand:P 0 "const_int_operand" "")))
16840 (clobber (reg:CC FLAGS_REG))
16841 (clobber (mem:BLK (scratch)))])]
16842 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16843 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
16844 [(clobber (match_dup 1))
16845 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16846 (clobber (mem:BLK (scratch)))])])
16849 [(match_scratch:P 1 "r")
16850 (parallel [(set (reg:P SP_REG)
16851 (plus:P (reg:P SP_REG)
16852 (match_operand:P 0 "const_int_operand" "")))
16853 (clobber (reg:CC FLAGS_REG))
16854 (clobber (mem:BLK (scratch)))])]
16855 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16856 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
16857 [(clobber (match_dup 1))
16858 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16859 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16860 (clobber (mem:BLK (scratch)))])])
16862 ;; Convert esp subtractions to push.
16864 [(match_scratch:P 1 "r")
16865 (parallel [(set (reg:P SP_REG)
16866 (plus:P (reg:P SP_REG)
16867 (match_operand:P 0 "const_int_operand" "")))
16868 (clobber (reg:CC FLAGS_REG))])]
16869 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16870 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
16871 [(clobber (match_dup 1))
16872 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
16875 [(match_scratch:P 1 "r")
16876 (parallel [(set (reg:P SP_REG)
16877 (plus:P (reg:P SP_REG)
16878 (match_operand:P 0 "const_int_operand" "")))
16879 (clobber (reg:CC FLAGS_REG))])]
16880 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16881 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
16882 [(clobber (match_dup 1))
16883 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16884 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
16886 ;; Convert epilogue deallocator to pop.
16888 [(match_scratch:P 1 "r")
16889 (parallel [(set (reg:P SP_REG)
16890 (plus:P (reg:P SP_REG)
16891 (match_operand:P 0 "const_int_operand" "")))
16892 (clobber (reg:CC FLAGS_REG))
16893 (clobber (mem:BLK (scratch)))])]
16894 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
16895 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
16896 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
16897 (clobber (mem:BLK (scratch)))])])
16899 ;; Two pops case is tricky, since pop causes dependency
16900 ;; on destination register. We use two registers if available.
16902 [(match_scratch:P 1 "r")
16903 (match_scratch:P 2 "r")
16904 (parallel [(set (reg:P SP_REG)
16905 (plus:P (reg:P SP_REG)
16906 (match_operand:P 0 "const_int_operand" "")))
16907 (clobber (reg:CC FLAGS_REG))
16908 (clobber (mem:BLK (scratch)))])]
16909 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
16910 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
16911 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
16912 (clobber (mem:BLK (scratch)))])
16913 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
16916 [(match_scratch:P 1 "r")
16917 (parallel [(set (reg:P SP_REG)
16918 (plus:P (reg:P SP_REG)
16919 (match_operand:P 0 "const_int_operand" "")))
16920 (clobber (reg:CC FLAGS_REG))
16921 (clobber (mem:BLK (scratch)))])]
16922 "optimize_insn_for_size_p ()
16923 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
16924 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
16925 (clobber (mem:BLK (scratch)))])
16926 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
16928 ;; Convert esp additions to pop.
16930 [(match_scratch:P 1 "r")
16931 (parallel [(set (reg:P SP_REG)
16932 (plus:P (reg:P SP_REG)
16933 (match_operand:P 0 "const_int_operand" "")))
16934 (clobber (reg:CC FLAGS_REG))])]
16935 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
16936 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
16938 ;; Two pops case is tricky, since pop causes dependency
16939 ;; on destination register. We use two registers if available.
16941 [(match_scratch:P 1 "r")
16942 (match_scratch:P 2 "r")
16943 (parallel [(set (reg:P SP_REG)
16944 (plus:P (reg:P SP_REG)
16945 (match_operand:P 0 "const_int_operand" "")))
16946 (clobber (reg:CC FLAGS_REG))])]
16947 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
16948 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
16949 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
16952 [(match_scratch:P 1 "r")
16953 (parallel [(set (reg:P SP_REG)
16954 (plus:P (reg:P SP_REG)
16955 (match_operand:P 0 "const_int_operand" "")))
16956 (clobber (reg:CC FLAGS_REG))])]
16957 "optimize_insn_for_size_p ()
16958 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
16959 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
16960 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
16962 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
16963 ;; required and register dies. Similarly for 128 to -128.
16965 [(set (match_operand 0 "flags_reg_operand" "")
16966 (match_operator 1 "compare_operator"
16967 [(match_operand 2 "register_operand" "")
16968 (match_operand 3 "const_int_operand" "")]))]
16969 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
16970 && incdec_operand (operands[3], GET_MODE (operands[3])))
16971 || (!TARGET_FUSE_CMP_AND_BRANCH
16972 && INTVAL (operands[3]) == 128))
16973 && ix86_match_ccmode (insn, CCGCmode)
16974 && peep2_reg_dead_p (1, operands[2])"
16975 [(parallel [(set (match_dup 0)
16976 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
16977 (clobber (match_dup 2))])])
16979 ;; Convert imul by three, five and nine into lea
16982 [(set (match_operand:SWI48 0 "register_operand" "")
16983 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
16984 (match_operand:SWI48 2 "const_int_operand" "")))
16985 (clobber (reg:CC FLAGS_REG))])]
16986 "INTVAL (operands[2]) == 3
16987 || INTVAL (operands[2]) == 5
16988 || INTVAL (operands[2]) == 9"
16989 [(set (match_dup 0)
16990 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
16992 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
16996 [(set (match_operand:SWI48 0 "register_operand" "")
16997 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
16998 (match_operand:SWI48 2 "const_int_operand" "")))
16999 (clobber (reg:CC FLAGS_REG))])]
17000 "optimize_insn_for_speed_p ()
17001 && (INTVAL (operands[2]) == 3
17002 || INTVAL (operands[2]) == 5
17003 || INTVAL (operands[2]) == 9)"
17004 [(set (match_dup 0) (match_dup 1))
17006 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17008 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17010 ;; imul $32bit_imm, mem, reg is vector decoded, while
17011 ;; imul $32bit_imm, reg, reg is direct decoded.
17013 [(match_scratch:SWI48 3 "r")
17014 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17015 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17016 (match_operand:SWI48 2 "immediate_operand" "")))
17017 (clobber (reg:CC FLAGS_REG))])]
17018 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17019 && !satisfies_constraint_K (operands[2])"
17020 [(set (match_dup 3) (match_dup 1))
17021 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17022 (clobber (reg:CC FLAGS_REG))])])
17025 [(match_scratch:SI 3 "r")
17026 (parallel [(set (match_operand:DI 0 "register_operand" "")
17028 (mult:SI (match_operand:SI 1 "memory_operand" "")
17029 (match_operand:SI 2 "immediate_operand" ""))))
17030 (clobber (reg:CC FLAGS_REG))])]
17032 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17033 && !satisfies_constraint_K (operands[2])"
17034 [(set (match_dup 3) (match_dup 1))
17035 (parallel [(set (match_dup 0)
17036 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17037 (clobber (reg:CC FLAGS_REG))])])
17039 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17040 ;; Convert it into imul reg, reg
17041 ;; It would be better to force assembler to encode instruction using long
17042 ;; immediate, but there is apparently no way to do so.
17044 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17046 (match_operand:SWI248 1 "nonimmediate_operand" "")
17047 (match_operand:SWI248 2 "const_int_operand" "")))
17048 (clobber (reg:CC FLAGS_REG))])
17049 (match_scratch:SWI248 3 "r")]
17050 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17051 && satisfies_constraint_K (operands[2])"
17052 [(set (match_dup 3) (match_dup 2))
17053 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17054 (clobber (reg:CC FLAGS_REG))])]
17056 if (!rtx_equal_p (operands[0], operands[1]))
17057 emit_move_insn (operands[0], operands[1]);
17060 ;; After splitting up read-modify operations, array accesses with memory
17061 ;; operands might end up in form:
17063 ;; movl 4(%esp), %edx
17065 ;; instead of pre-splitting:
17067 ;; addl 4(%esp), %eax
17069 ;; movl 4(%esp), %edx
17070 ;; leal (%edx,%eax,4), %eax
17073 [(match_scratch:P 5 "r")
17074 (parallel [(set (match_operand 0 "register_operand" "")
17075 (ashift (match_operand 1 "register_operand" "")
17076 (match_operand 2 "const_int_operand" "")))
17077 (clobber (reg:CC FLAGS_REG))])
17078 (parallel [(set (match_operand 3 "register_operand" "")
17079 (plus (match_dup 0)
17080 (match_operand 4 "x86_64_general_operand" "")))
17081 (clobber (reg:CC FLAGS_REG))])]
17082 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
17083 /* Validate MODE for lea. */
17084 && ((!TARGET_PARTIAL_REG_STALL
17085 && (GET_MODE (operands[0]) == QImode
17086 || GET_MODE (operands[0]) == HImode))
17087 || GET_MODE (operands[0]) == SImode
17088 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17089 && (rtx_equal_p (operands[0], operands[3])
17090 || peep2_reg_dead_p (2, operands[0]))
17091 /* We reorder load and the shift. */
17092 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17093 [(set (match_dup 5) (match_dup 4))
17094 (set (match_dup 0) (match_dup 1))]
17096 enum machine_mode mode = GET_MODE (operands[1]) == DImode ? DImode : SImode;
17097 int scale = 1 << INTVAL (operands[2]);
17098 rtx index = gen_lowpart (Pmode, operands[1]);
17099 rtx base = gen_lowpart (Pmode, operands[5]);
17100 rtx dest = gen_lowpart (mode, operands[3]);
17102 operands[1] = gen_rtx_PLUS (Pmode, base,
17103 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17104 operands[5] = base;
17107 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17108 operands[5] = gen_rtx_SUBREG (mode, operands[5], 0);
17110 operands[0] = dest;
17113 ;; Call-value patterns last so that the wildcard operand does not
17114 ;; disrupt insn-recog's switch tables.
17116 (define_insn "*call_value_pop_0"
17117 [(set (match_operand 0 "" "")
17118 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17119 (match_operand:SI 2 "" "")))
17120 (set (reg:SI SP_REG)
17121 (plus:SI (reg:SI SP_REG)
17122 (match_operand:SI 3 "immediate_operand" "")))]
17125 if (SIBLING_CALL_P (insn))
17128 return "call\t%P1";
17130 [(set_attr "type" "callv")])
17132 (define_insn "*call_value_pop_1"
17133 [(set (match_operand 0 "" "")
17134 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17135 (match_operand:SI 2 "" "")))
17136 (set (reg:SI SP_REG)
17137 (plus:SI (reg:SI SP_REG)
17138 (match_operand:SI 3 "immediate_operand" "i")))]
17139 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17141 if (constant_call_address_operand (operands[1], Pmode))
17142 return "call\t%P1";
17143 return "call\t%A1";
17145 [(set_attr "type" "callv")])
17147 (define_insn "*sibcall_value_pop_1"
17148 [(set (match_operand 0 "" "")
17149 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17150 (match_operand:SI 2 "" "")))
17151 (set (reg:SI SP_REG)
17152 (plus:SI (reg:SI SP_REG)
17153 (match_operand:SI 3 "immediate_operand" "i,i")))]
17154 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17158 [(set_attr "type" "callv")])
17160 (define_insn "*call_value_0"
17161 [(set (match_operand 0 "" "")
17162 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17163 (match_operand:SI 2 "" "")))]
17166 if (SIBLING_CALL_P (insn))
17169 return "call\t%P1";
17171 [(set_attr "type" "callv")])
17173 (define_insn "*call_value_0_rex64"
17174 [(set (match_operand 0 "" "")
17175 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17176 (match_operand:DI 2 "const_int_operand" "")))]
17179 if (SIBLING_CALL_P (insn))
17182 return "call\t%P1";
17184 [(set_attr "type" "callv")])
17186 (define_insn "*call_value_0_rex64_ms_sysv"
17187 [(set (match_operand 0 "" "")
17188 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17189 (match_operand:DI 2 "const_int_operand" "")))
17190 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17191 (clobber (reg:TI XMM6_REG))
17192 (clobber (reg:TI XMM7_REG))
17193 (clobber (reg:TI XMM8_REG))
17194 (clobber (reg:TI XMM9_REG))
17195 (clobber (reg:TI XMM10_REG))
17196 (clobber (reg:TI XMM11_REG))
17197 (clobber (reg:TI XMM12_REG))
17198 (clobber (reg:TI XMM13_REG))
17199 (clobber (reg:TI XMM14_REG))
17200 (clobber (reg:TI XMM15_REG))
17201 (clobber (reg:DI SI_REG))
17202 (clobber (reg:DI DI_REG))]
17203 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17205 if (SIBLING_CALL_P (insn))
17208 return "call\t%P1";
17210 [(set_attr "type" "callv")])
17212 (define_insn "*call_value_1"
17213 [(set (match_operand 0 "" "")
17214 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17215 (match_operand:SI 2 "" "")))]
17216 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17218 if (constant_call_address_operand (operands[1], Pmode))
17219 return "call\t%P1";
17220 return "call\t%A1";
17222 [(set_attr "type" "callv")])
17224 (define_insn "*sibcall_value_1"
17225 [(set (match_operand 0 "" "")
17226 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17227 (match_operand:SI 2 "" "")))]
17228 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17232 [(set_attr "type" "callv")])
17234 (define_insn "*call_value_1_rex64"
17235 [(set (match_operand 0 "" "")
17236 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17237 (match_operand:DI 2 "" "")))]
17238 "TARGET_64BIT && !SIBLING_CALL_P (insn)
17239 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17241 if (constant_call_address_operand (operands[1], Pmode))
17242 return "call\t%P1";
17243 return "call\t%A1";
17245 [(set_attr "type" "callv")])
17247 (define_insn "*call_value_1_rex64_ms_sysv"
17248 [(set (match_operand 0 "" "")
17249 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17250 (match_operand:DI 2 "" "")))
17251 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17252 (clobber (reg:TI XMM6_REG))
17253 (clobber (reg:TI XMM7_REG))
17254 (clobber (reg:TI XMM8_REG))
17255 (clobber (reg:TI XMM9_REG))
17256 (clobber (reg:TI XMM10_REG))
17257 (clobber (reg:TI XMM11_REG))
17258 (clobber (reg:TI XMM12_REG))
17259 (clobber (reg:TI XMM13_REG))
17260 (clobber (reg:TI XMM14_REG))
17261 (clobber (reg:TI XMM15_REG))
17262 (clobber (reg:DI SI_REG))
17263 (clobber (reg:DI DI_REG))]
17264 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17266 if (constant_call_address_operand (operands[1], Pmode))
17267 return "call\t%P1";
17268 return "call\t%A1";
17270 [(set_attr "type" "callv")])
17272 (define_insn "*call_value_1_rex64_large"
17273 [(set (match_operand 0 "" "")
17274 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17275 (match_operand:DI 2 "" "")))]
17276 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17278 [(set_attr "type" "callv")])
17280 (define_insn "*sibcall_value_1_rex64"
17281 [(set (match_operand 0 "" "")
17282 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17283 (match_operand:DI 2 "" "")))]
17284 "TARGET_64BIT && SIBLING_CALL_P (insn)"
17288 [(set_attr "type" "callv")])
17290 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17291 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17292 ;; caught for use by garbage collectors and the like. Using an insn that
17293 ;; maps to SIGILL makes it more likely the program will rightfully die.
17294 ;; Keeping with tradition, "6" is in honor of #UD.
17295 (define_insn "trap"
17296 [(trap_if (const_int 1) (const_int 6))]
17298 { return ASM_SHORT "0x0b0f"; }
17299 [(set_attr "length" "2")])
17301 (define_expand "prefetch"
17302 [(prefetch (match_operand 0 "address_operand" "")
17303 (match_operand:SI 1 "const_int_operand" "")
17304 (match_operand:SI 2 "const_int_operand" ""))]
17305 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17307 int rw = INTVAL (operands[1]);
17308 int locality = INTVAL (operands[2]);
17310 gcc_assert (rw == 0 || rw == 1);
17311 gcc_assert (locality >= 0 && locality <= 3);
17312 gcc_assert (GET_MODE (operands[0]) == Pmode
17313 || GET_MODE (operands[0]) == VOIDmode);
17315 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17316 supported by SSE counterpart or the SSE prefetch is not available
17317 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17319 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17320 operands[2] = GEN_INT (3);
17322 operands[1] = const0_rtx;
17325 (define_insn "*prefetch_sse_<mode>"
17326 [(prefetch (match_operand:P 0 "address_operand" "p")
17328 (match_operand:SI 1 "const_int_operand" ""))]
17329 "TARGET_PREFETCH_SSE"
17331 static const char * const patterns[4] = {
17332 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17335 int locality = INTVAL (operands[1]);
17336 gcc_assert (locality >= 0 && locality <= 3);
17338 return patterns[locality];
17340 [(set_attr "type" "sse")
17341 (set_attr "atom_sse_attr" "prefetch")
17342 (set (attr "length_address")
17343 (symbol_ref "memory_address_length (operands[0])"))
17344 (set_attr "memory" "none")])
17346 (define_insn "*prefetch_3dnow_<mode>"
17347 [(prefetch (match_operand:P 0 "address_operand" "p")
17348 (match_operand:SI 1 "const_int_operand" "n")
17352 if (INTVAL (operands[1]) == 0)
17353 return "prefetch\t%a0";
17355 return "prefetchw\t%a0";
17357 [(set_attr "type" "mmx")
17358 (set (attr "length_address")
17359 (symbol_ref "memory_address_length (operands[0])"))
17360 (set_attr "memory" "none")])
17362 (define_expand "stack_protect_set"
17363 [(match_operand 0 "memory_operand" "")
17364 (match_operand 1 "memory_operand" "")]
17367 #ifdef TARGET_THREAD_SSP_OFFSET
17369 emit_insn (gen_stack_tls_protect_set_di (operands[0],
17370 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
17372 emit_insn (gen_stack_tls_protect_set_si (operands[0],
17373 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
17376 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
17378 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
17383 (define_insn "stack_protect_set_si"
17384 [(set (match_operand:SI 0 "memory_operand" "=m")
17385 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
17386 (set (match_scratch:SI 2 "=&r") (const_int 0))
17387 (clobber (reg:CC FLAGS_REG))]
17389 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
17390 [(set_attr "type" "multi")])
17392 (define_insn "stack_protect_set_di"
17393 [(set (match_operand:DI 0 "memory_operand" "=m")
17394 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
17395 (set (match_scratch:DI 2 "=&r") (const_int 0))
17396 (clobber (reg:CC FLAGS_REG))]
17398 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17399 [(set_attr "type" "multi")])
17401 (define_insn "stack_tls_protect_set_si"
17402 [(set (match_operand:SI 0 "memory_operand" "=m")
17403 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")]
17404 UNSPEC_SP_TLS_SET))
17405 (set (match_scratch:SI 2 "=&r") (const_int 0))
17406 (clobber (reg:CC FLAGS_REG))]
17408 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
17409 [(set_attr "type" "multi")])
17411 (define_insn "stack_tls_protect_set_di"
17412 [(set (match_operand:DI 0 "memory_operand" "=m")
17413 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")]
17414 UNSPEC_SP_TLS_SET))
17415 (set (match_scratch:DI 2 "=&r") (const_int 0))
17416 (clobber (reg:CC FLAGS_REG))]
17419 /* The kernel uses a different segment register for performance reasons; a
17420 system call would not have to trash the userspace segment register,
17421 which would be expensive */
17422 if (ix86_cmodel != CM_KERNEL)
17423 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
17425 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
17427 [(set_attr "type" "multi")])
17429 (define_expand "stack_protect_test"
17430 [(match_operand 0 "memory_operand" "")
17431 (match_operand 1 "memory_operand" "")
17432 (match_operand 2 "" "")]
17435 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17437 #ifdef TARGET_THREAD_SSP_OFFSET
17439 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
17440 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
17442 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
17443 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
17446 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
17448 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
17451 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17452 flags, const0_rtx, operands[2]));
17456 (define_insn "stack_protect_test_si"
17457 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17458 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
17459 (match_operand:SI 2 "memory_operand" "m")]
17461 (clobber (match_scratch:SI 3 "=&r"))]
17463 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
17464 [(set_attr "type" "multi")])
17466 (define_insn "stack_protect_test_di"
17467 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17468 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
17469 (match_operand:DI 2 "memory_operand" "m")]
17471 (clobber (match_scratch:DI 3 "=&r"))]
17473 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
17474 [(set_attr "type" "multi")])
17476 (define_insn "stack_tls_protect_test_si"
17477 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17478 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
17479 (match_operand:SI 2 "const_int_operand" "i")]
17480 UNSPEC_SP_TLS_TEST))
17481 (clobber (match_scratch:SI 3 "=r"))]
17483 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
17484 [(set_attr "type" "multi")])
17486 (define_insn "stack_tls_protect_test_di"
17487 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17488 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
17489 (match_operand:DI 2 "const_int_operand" "i")]
17490 UNSPEC_SP_TLS_TEST))
17491 (clobber (match_scratch:DI 3 "=r"))]
17494 /* The kernel uses a different segment register for performance reasons; a
17495 system call would not have to trash the userspace segment register,
17496 which would be expensive */
17497 if (ix86_cmodel != CM_KERNEL)
17498 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
17500 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
17502 [(set_attr "type" "multi")])
17504 (define_insn "sse4_2_crc32<mode>"
17505 [(set (match_operand:SI 0 "register_operand" "=r")
17507 [(match_operand:SI 1 "register_operand" "0")
17508 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17510 "TARGET_SSE4_2 || TARGET_CRC32"
17511 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17512 [(set_attr "type" "sselog1")
17513 (set_attr "prefix_rep" "1")
17514 (set_attr "prefix_extra" "1")
17515 (set (attr "prefix_data16")
17516 (if_then_else (match_operand:HI 2 "" "")
17518 (const_string "*")))
17519 (set (attr "prefix_rex")
17520 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17522 (const_string "*")))
17523 (set_attr "mode" "SI")])
17525 (define_insn "sse4_2_crc32di"
17526 [(set (match_operand:DI 0 "register_operand" "=r")
17528 [(match_operand:DI 1 "register_operand" "0")
17529 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17531 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17532 "crc32{q}\t{%2, %0|%0, %2}"
17533 [(set_attr "type" "sselog1")
17534 (set_attr "prefix_rep" "1")
17535 (set_attr "prefix_extra" "1")
17536 (set_attr "mode" "DI")])
17538 (define_expand "rdpmc"
17539 [(match_operand:DI 0 "register_operand" "")
17540 (match_operand:SI 1 "register_operand" "")]
17543 rtx reg = gen_reg_rtx (DImode);
17546 /* Force operand 1 into ECX. */
17547 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17548 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17549 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17554 rtvec vec = rtvec_alloc (2);
17555 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17556 rtx upper = gen_reg_rtx (DImode);
17557 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17558 gen_rtvec (1, const0_rtx),
17560 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17561 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17563 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17564 NULL, 1, OPTAB_DIRECT);
17565 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17569 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17570 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17574 (define_insn "*rdpmc"
17575 [(set (match_operand:DI 0 "register_operand" "=A")
17576 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17580 [(set_attr "type" "other")
17581 (set_attr "length" "2")])
17583 (define_insn "*rdpmc_rex64"
17584 [(set (match_operand:DI 0 "register_operand" "=a")
17585 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17587 (set (match_operand:DI 1 "register_operand" "=d")
17588 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17591 [(set_attr "type" "other")
17592 (set_attr "length" "2")])
17594 (define_expand "rdtsc"
17595 [(set (match_operand:DI 0 "register_operand" "")
17596 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17601 rtvec vec = rtvec_alloc (2);
17602 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17603 rtx upper = gen_reg_rtx (DImode);
17604 rtx lower = gen_reg_rtx (DImode);
17605 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17606 gen_rtvec (1, const0_rtx),
17608 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17609 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17611 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17612 NULL, 1, OPTAB_DIRECT);
17613 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17615 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17620 (define_insn "*rdtsc"
17621 [(set (match_operand:DI 0 "register_operand" "=A")
17622 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17625 [(set_attr "type" "other")
17626 (set_attr "length" "2")])
17628 (define_insn "*rdtsc_rex64"
17629 [(set (match_operand:DI 0 "register_operand" "=a")
17630 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17631 (set (match_operand:DI 1 "register_operand" "=d")
17632 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17635 [(set_attr "type" "other")
17636 (set_attr "length" "2")])
17638 (define_expand "rdtscp"
17639 [(match_operand:DI 0 "register_operand" "")
17640 (match_operand:SI 1 "memory_operand" "")]
17643 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17644 gen_rtvec (1, const0_rtx),
17646 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17647 gen_rtvec (1, const0_rtx),
17649 rtx reg = gen_reg_rtx (DImode);
17650 rtx tmp = gen_reg_rtx (SImode);
17654 rtvec vec = rtvec_alloc (3);
17655 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17656 rtx upper = gen_reg_rtx (DImode);
17657 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17658 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17659 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17661 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17662 NULL, 1, OPTAB_DIRECT);
17663 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17668 rtvec vec = rtvec_alloc (2);
17669 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17670 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17671 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17674 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17675 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17679 (define_insn "*rdtscp"
17680 [(set (match_operand:DI 0 "register_operand" "=A")
17681 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17682 (set (match_operand:SI 1 "register_operand" "=c")
17683 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17686 [(set_attr "type" "other")
17687 (set_attr "length" "3")])
17689 (define_insn "*rdtscp_rex64"
17690 [(set (match_operand:DI 0 "register_operand" "=a")
17691 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17692 (set (match_operand:DI 1 "register_operand" "=d")
17693 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17694 (set (match_operand:SI 2 "register_operand" "=c")
17695 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17698 [(set_attr "type" "other")
17699 (set_attr "length" "3")])
17701 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17703 ;; LWP instructions
17705 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17707 (define_expand "lwp_llwpcb"
17708 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17709 UNSPECV_LLWP_INTRINSIC)]
17713 (define_insn "*lwp_llwpcb<mode>1"
17714 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17715 UNSPECV_LLWP_INTRINSIC)]
17718 [(set_attr "type" "lwp")
17719 (set_attr "mode" "<MODE>")
17720 (set_attr "length" "5")])
17722 (define_expand "lwp_slwpcb"
17723 [(set (match_operand 0 "register_operand" "=r")
17724 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17728 emit_insn (gen_lwp_slwpcbdi (operands[0]));
17730 emit_insn (gen_lwp_slwpcbsi (operands[0]));
17734 (define_insn "lwp_slwpcb<mode>"
17735 [(set (match_operand:P 0 "register_operand" "=r")
17736 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17739 [(set_attr "type" "lwp")
17740 (set_attr "mode" "<MODE>")
17741 (set_attr "length" "5")])
17743 (define_expand "lwp_lwpval<mode>3"
17744 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
17745 (match_operand:SI 2 "nonimmediate_operand" "rm")
17746 (match_operand:SI 3 "const_int_operand" "i")]
17747 UNSPECV_LWPVAL_INTRINSIC)]
17749 "/* Avoid unused variable warning. */
17752 (define_insn "*lwp_lwpval<mode>3_1"
17753 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
17754 (match_operand:SI 1 "nonimmediate_operand" "rm")
17755 (match_operand:SI 2 "const_int_operand" "i")]
17756 UNSPECV_LWPVAL_INTRINSIC)]
17758 "lwpval\t{%2, %1, %0|%0, %1, %2}"
17759 [(set_attr "type" "lwp")
17760 (set_attr "mode" "<MODE>")
17761 (set (attr "length")
17762 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17764 (define_expand "lwp_lwpins<mode>3"
17765 [(set (reg:CCC FLAGS_REG)
17766 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
17767 (match_operand:SI 2 "nonimmediate_operand" "rm")
17768 (match_operand:SI 3 "const_int_operand" "i")]
17769 UNSPECV_LWPINS_INTRINSIC))
17770 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
17771 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
17775 (define_insn "*lwp_lwpins<mode>3_1"
17776 [(set (reg:CCC FLAGS_REG)
17777 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
17778 (match_operand:SI 1 "nonimmediate_operand" "rm")
17779 (match_operand:SI 2 "const_int_operand" "i")]
17780 UNSPECV_LWPINS_INTRINSIC))]
17782 "lwpins\t{%2, %1, %0|%0, %1, %2}"
17783 [(set_attr "type" "lwp")
17784 (set_attr "mode" "<MODE>")
17785 (set (attr "length")
17786 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17788 (define_insn "rdfsbase<mode>"
17789 [(set (match_operand:SWI48 0 "register_operand" "=r")
17790 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
17791 "TARGET_64BIT && TARGET_FSGSBASE"
17793 [(set_attr "type" "other")
17794 (set_attr "prefix_extra" "2")])
17796 (define_insn "rdgsbase<mode>"
17797 [(set (match_operand:SWI48 0 "register_operand" "=r")
17798 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
17799 "TARGET_64BIT && TARGET_FSGSBASE"
17801 [(set_attr "type" "other")
17802 (set_attr "prefix_extra" "2")])
17804 (define_insn "wrfsbase<mode>"
17805 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17807 "TARGET_64BIT && TARGET_FSGSBASE"
17809 [(set_attr "type" "other")
17810 (set_attr "prefix_extra" "2")])
17812 (define_insn "wrgsbase<mode>"
17813 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17815 "TARGET_64BIT && TARGET_FSGSBASE"
17817 [(set_attr "type" "other")
17818 (set_attr "prefix_extra" "2")])
17820 (define_expand "rdrand<mode>"
17821 [(set (match_operand:SWI248 0 "register_operand" "=r")
17822 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))]
17825 rtx retry_label, insn, ccc;
17827 retry_label = gen_label_rtx ();
17829 emit_label (retry_label);
17831 /* Generate rdrand. */
17832 emit_insn (gen_rdrand<mode>_1 (operands[0]));
17834 /* Retry if the carry flag isn't valid. */
17835 ccc = gen_rtx_REG (CCCmode, FLAGS_REG);
17836 ccc = gen_rtx_EQ (VOIDmode, ccc, const0_rtx);
17837 ccc = gen_rtx_IF_THEN_ELSE (VOIDmode, ccc, pc_rtx,
17838 gen_rtx_LABEL_REF (VOIDmode, retry_label));
17839 insn = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, ccc));
17840 JUMP_LABEL (insn) = retry_label;
17845 (define_insn "rdrand<mode>_1"
17846 [(set (match_operand:SWI248 0 "register_operand" "=r")
17847 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))]
17850 [(set_attr "type" "other")
17851 (set_attr "prefix_extra" "1")])
17855 (include "sync.md")