1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>. */
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;; The special asm out single letter directives following a '%' are:
30 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; F,f -- likewise, but for floating-point.
34 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
36 ;; R -- print the prefix for register names.
37 ;; z -- print the opcode suffix for the size of the current operand.
38 ;; Z -- likewise, with special suffixes for x87 instructions.
39 ;; * -- print a star (in certain assembler syntax)
40 ;; A -- print an absolute memory reference.
41 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
42 ;; s -- print a shift double count, followed by the assemblers argument
44 ;; b -- print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; w -- likewise, print the HImode name of the register.
47 ;; k -- likewise, print the SImode name of the register.
48 ;; q -- likewise, print the DImode name of the register.
49 ;; x -- likewise, print the V4SFmode name of the register.
50 ;; t -- likewise, print the V8SFmode name of the register.
51 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
52 ;; y -- print "st(0)" instead of "st" as a register.
53 ;; d -- print duplicated register operand for AVX instruction.
54 ;; D -- print condition for SSE cmp instruction.
55 ;; P -- if PIC, print an @PLT suffix.
56 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; Y -- print condition for XOP pcom* instruction.
60 ;; + -- print a branch hint as 'cs' or 'ds' prefix
61 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
62 ;; @ -- print a segment register of thread base pointer load
66 (define_c_enum "unspec" [
67 ;; Relocation specifiers
78 UNSPEC_MACHOPIC_OFFSET
87 UNSPEC_MEMORY_BLOCKAGE
96 ;; Other random patterns
105 UNSPEC_LD_MPIC ; load_macho_picbase
107 UNSPEC_DIV_ALREADY_SPLIT
109 ;; For SSE/MMX support:
127 UNSPEC_MS_TO_SYSV_CALL
129 ;; Generic math support
131 UNSPEC_IEEE_MIN ; not commutative
132 UNSPEC_IEEE_MAX ; not commutative
134 ;; x87 Floating point
150 UNSPEC_FRNDINT_MASK_PM
154 ;; x87 Double output FP
186 ;; For SSE4.1 support
196 ;; For SSE4.2 support
203 UNSPEC_XOP_UNSIGNED_CMP
214 UNSPEC_AESKEYGENASSIST
216 ;; For PCLMUL support
232 (define_c_enum "unspecv" [
235 UNSPECV_PROBE_STACK_RANGE
255 UNSPECV_LLWP_INTRINSIC
256 UNSPECV_SLWP_INTRINSIC
257 UNSPECV_LWPVAL_INTRINSIC
258 UNSPECV_LWPINS_INTRINSIC
266 ;; Constants to represent pcomtrue/pcomfalse variants
276 ;; Constants used in the XOP pperm instruction
278 [(PPERM_SRC 0x00) /* copy source */
279 (PPERM_INVERT 0x20) /* invert source */
280 (PPERM_REVERSE 0x40) /* bit reverse source */
281 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
282 (PPERM_ZERO 0x80) /* all 0's */
283 (PPERM_ONES 0xa0) /* all 1's */
284 (PPERM_SIGN 0xc0) /* propagate sign bit */
285 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
286 (PPERM_SRC1 0x00) /* use first source byte */
287 (PPERM_SRC2 0x10) /* use second source byte */
290 ;; Registers by name.
343 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
346 ;; In C guard expressions, put expressions which may be compile-time
347 ;; constants first. This allows for better optimization. For
348 ;; example, write "TARGET_64BIT && reload_completed", not
349 ;; "reload_completed && TARGET_64BIT".
353 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,atom,
354 generic64,amdfam10,bdver1"
355 (const (symbol_ref "ix86_schedule")))
357 ;; A basic instruction type. Refinements due to arguments to be
358 ;; provided in other attributes.
361 alu,alu1,negnot,imov,imovx,lea,
362 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
363 icmp,test,ibr,setcc,icmov,
364 push,pop,call,callv,leave,
366 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
367 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
368 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
369 ssemuladd,sse4arg,lwp,
370 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
371 (const_string "other"))
373 ;; Main data type used by the insn
375 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
376 (const_string "unknown"))
378 ;; The CPU unit operations uses.
379 (define_attr "unit" "integer,i387,sse,mmx,unknown"
380 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
381 (const_string "i387")
382 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
383 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
384 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
386 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
388 (eq_attr "type" "other")
389 (const_string "unknown")]
390 (const_string "integer")))
392 ;; The (bounding maximum) length of an instruction immediate.
393 (define_attr "length_immediate" ""
394 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
397 (eq_attr "unit" "i387,sse,mmx")
399 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
401 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
402 (eq_attr "type" "imov,test")
403 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
404 (eq_attr "type" "call")
405 (if_then_else (match_operand 0 "constant_call_address_operand" "")
408 (eq_attr "type" "callv")
409 (if_then_else (match_operand 1 "constant_call_address_operand" "")
412 ;; We don't know the size before shorten_branches. Expect
413 ;; the instruction to fit for better scheduling.
414 (eq_attr "type" "ibr")
417 (symbol_ref "/* Update immediate_length and other attributes! */
418 gcc_unreachable (),1")))
420 ;; The (bounding maximum) length of an instruction address.
421 (define_attr "length_address" ""
422 (cond [(eq_attr "type" "str,other,multi,fxch")
424 (and (eq_attr "type" "call")
425 (match_operand 0 "constant_call_address_operand" ""))
427 (and (eq_attr "type" "callv")
428 (match_operand 1 "constant_call_address_operand" ""))
431 (symbol_ref "ix86_attr_length_address_default (insn)")))
433 ;; Set when length prefix is used.
434 (define_attr "prefix_data16" ""
435 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
437 (eq_attr "mode" "HI")
439 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
444 ;; Set when string REP prefix is used.
445 (define_attr "prefix_rep" ""
446 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
448 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
453 ;; Set when 0f opcode prefix is used.
454 (define_attr "prefix_0f" ""
456 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
457 (eq_attr "unit" "sse,mmx"))
461 ;; Set when REX opcode prefix is used.
462 (define_attr "prefix_rex" ""
463 (cond [(eq (symbol_ref "TARGET_64BIT") (const_int 0))
465 (and (eq_attr "mode" "DI")
466 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
467 (eq_attr "unit" "!mmx")))
469 (and (eq_attr "mode" "QI")
470 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
473 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
476 (and (eq_attr "type" "imovx")
477 (match_operand:QI 1 "ext_QIreg_operand" ""))
482 ;; There are also additional prefixes in 3DNOW, SSSE3.
483 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
484 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
485 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
486 (define_attr "prefix_extra" ""
487 (cond [(eq_attr "type" "ssemuladd,sse4arg")
489 (eq_attr "type" "sseiadd1,ssecvt1")
494 ;; Prefix used: original, VEX or maybe VEX.
495 (define_attr "prefix" "orig,vex,maybe_vex"
496 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
498 (const_string "orig")))
500 ;; VEX W bit is used.
501 (define_attr "prefix_vex_w" "" (const_int 0))
503 ;; The length of VEX prefix
504 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
505 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
506 ;; still prefix_0f 1, with prefix_extra 1.
507 (define_attr "length_vex" ""
508 (if_then_else (and (eq_attr "prefix_0f" "1")
509 (eq_attr "prefix_extra" "0"))
510 (if_then_else (eq_attr "prefix_vex_w" "1")
511 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
512 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
513 (if_then_else (eq_attr "prefix_vex_w" "1")
514 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
515 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
517 ;; Set when modrm byte is used.
518 (define_attr "modrm" ""
519 (cond [(eq_attr "type" "str,leave")
521 (eq_attr "unit" "i387")
523 (and (eq_attr "type" "incdec")
524 (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
525 (ior (match_operand:SI 1 "register_operand" "")
526 (match_operand:HI 1 "register_operand" ""))))
528 (and (eq_attr "type" "push")
529 (not (match_operand 1 "memory_operand" "")))
531 (and (eq_attr "type" "pop")
532 (not (match_operand 0 "memory_operand" "")))
534 (and (eq_attr "type" "imov")
535 (and (not (eq_attr "mode" "DI"))
536 (ior (and (match_operand 0 "register_operand" "")
537 (match_operand 1 "immediate_operand" ""))
538 (ior (and (match_operand 0 "ax_reg_operand" "")
539 (match_operand 1 "memory_displacement_only_operand" ""))
540 (and (match_operand 0 "memory_displacement_only_operand" "")
541 (match_operand 1 "ax_reg_operand" ""))))))
543 (and (eq_attr "type" "call")
544 (match_operand 0 "constant_call_address_operand" ""))
546 (and (eq_attr "type" "callv")
547 (match_operand 1 "constant_call_address_operand" ""))
549 (and (eq_attr "type" "alu,alu1,icmp,test")
550 (match_operand 0 "ax_reg_operand" ""))
551 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
555 ;; The (bounding maximum) length of an instruction in bytes.
556 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
557 ;; Later we may want to split them and compute proper length as for
559 (define_attr "length" ""
560 (cond [(eq_attr "type" "other,multi,fistp,frndint")
562 (eq_attr "type" "fcmp")
564 (eq_attr "unit" "i387")
566 (plus (attr "prefix_data16")
567 (attr "length_address")))
568 (ior (eq_attr "prefix" "vex")
569 (and (eq_attr "prefix" "maybe_vex")
570 (ne (symbol_ref "TARGET_AVX") (const_int 0))))
571 (plus (attr "length_vex")
572 (plus (attr "length_immediate")
574 (attr "length_address"))))]
575 (plus (plus (attr "modrm")
576 (plus (attr "prefix_0f")
577 (plus (attr "prefix_rex")
578 (plus (attr "prefix_extra")
580 (plus (attr "prefix_rep")
581 (plus (attr "prefix_data16")
582 (plus (attr "length_immediate")
583 (attr "length_address")))))))
585 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
586 ;; `store' if there is a simple memory reference therein, or `unknown'
587 ;; if the instruction is complex.
589 (define_attr "memory" "none,load,store,both,unknown"
590 (cond [(eq_attr "type" "other,multi,str,lwp")
591 (const_string "unknown")
592 (eq_attr "type" "lea,fcmov,fpspc")
593 (const_string "none")
594 (eq_attr "type" "fistp,leave")
595 (const_string "both")
596 (eq_attr "type" "frndint")
597 (const_string "load")
598 (eq_attr "type" "push")
599 (if_then_else (match_operand 1 "memory_operand" "")
600 (const_string "both")
601 (const_string "store"))
602 (eq_attr "type" "pop")
603 (if_then_else (match_operand 0 "memory_operand" "")
604 (const_string "both")
605 (const_string "load"))
606 (eq_attr "type" "setcc")
607 (if_then_else (match_operand 0 "memory_operand" "")
608 (const_string "store")
609 (const_string "none"))
610 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
611 (if_then_else (ior (match_operand 0 "memory_operand" "")
612 (match_operand 1 "memory_operand" ""))
613 (const_string "load")
614 (const_string "none"))
615 (eq_attr "type" "ibr")
616 (if_then_else (match_operand 0 "memory_operand" "")
617 (const_string "load")
618 (const_string "none"))
619 (eq_attr "type" "call")
620 (if_then_else (match_operand 0 "constant_call_address_operand" "")
621 (const_string "none")
622 (const_string "load"))
623 (eq_attr "type" "callv")
624 (if_then_else (match_operand 1 "constant_call_address_operand" "")
625 (const_string "none")
626 (const_string "load"))
627 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
628 (match_operand 1 "memory_operand" ""))
629 (const_string "both")
630 (and (match_operand 0 "memory_operand" "")
631 (match_operand 1 "memory_operand" ""))
632 (const_string "both")
633 (match_operand 0 "memory_operand" "")
634 (const_string "store")
635 (match_operand 1 "memory_operand" "")
636 (const_string "load")
638 "!alu1,negnot,ishift1,
639 imov,imovx,icmp,test,bitmanip,
641 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
642 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
643 (match_operand 2 "memory_operand" ""))
644 (const_string "load")
645 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
646 (match_operand 3 "memory_operand" ""))
647 (const_string "load")
649 (const_string "none")))
651 ;; Indicates if an instruction has both an immediate and a displacement.
653 (define_attr "imm_disp" "false,true,unknown"
654 (cond [(eq_attr "type" "other,multi")
655 (const_string "unknown")
656 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
657 (and (match_operand 0 "memory_displacement_operand" "")
658 (match_operand 1 "immediate_operand" "")))
659 (const_string "true")
660 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
661 (and (match_operand 0 "memory_displacement_operand" "")
662 (match_operand 2 "immediate_operand" "")))
663 (const_string "true")
665 (const_string "false")))
667 ;; Indicates if an FP operation has an integer source.
669 (define_attr "fp_int_src" "false,true"
670 (const_string "false"))
672 ;; Defines rounding mode of an FP operation.
674 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
675 (const_string "any"))
677 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
678 (define_attr "use_carry" "0,1" (const_string "0"))
680 ;; Define attribute to indicate unaligned ssemov insns
681 (define_attr "movu" "0,1" (const_string "0"))
683 ;; Describe a user's asm statement.
684 (define_asm_attributes
685 [(set_attr "length" "128")
686 (set_attr "type" "multi")])
688 (define_code_iterator plusminus [plus minus])
690 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
692 ;; Base name for define_insn
693 (define_code_attr plusminus_insn
694 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
695 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
697 ;; Base name for insn mnemonic.
698 (define_code_attr plusminus_mnemonic
699 [(plus "add") (ss_plus "adds") (us_plus "addus")
700 (minus "sub") (ss_minus "subs") (us_minus "subus")])
701 (define_code_attr plusminus_carry_mnemonic
702 [(plus "adc") (minus "sbb")])
704 ;; Mark commutative operators as such in constraints.
705 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
706 (minus "") (ss_minus "") (us_minus "")])
708 ;; Mapping of signed max and min
709 (define_code_iterator smaxmin [smax smin])
711 ;; Mapping of unsigned max and min
712 (define_code_iterator umaxmin [umax umin])
714 ;; Base name for integer and FP insn mnemonic
715 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
716 (umax "maxu") (umin "minu")])
717 (define_code_attr maxmin_float [(smax "max") (smin "min")])
719 ;; Mapping of logic operators
720 (define_code_iterator any_logic [and ior xor])
721 (define_code_iterator any_or [ior xor])
723 ;; Base name for insn mnemonic.
724 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
726 ;; Mapping of shift-right operators
727 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
729 ;; Base name for define_insn
730 (define_code_attr shiftrt_insn [(lshiftrt "lshr") (ashiftrt "ashr")])
732 ;; Base name for insn mnemonic.
733 (define_code_attr shiftrt [(lshiftrt "shr") (ashiftrt "sar")])
735 ;; Mapping of rotate operators
736 (define_code_iterator any_rotate [rotate rotatert])
738 ;; Base name for define_insn
739 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
741 ;; Base name for insn mnemonic.
742 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
744 ;; Mapping of abs neg operators
745 (define_code_iterator absneg [abs neg])
747 ;; Base name for x87 insn mnemonic.
748 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
750 ;; Used in signed and unsigned widening multiplications.
751 (define_code_iterator any_extend [sign_extend zero_extend])
753 ;; Various insn prefixes for signed and unsigned operations.
754 (define_code_attr u [(sign_extend "") (zero_extend "u")
755 (div "") (udiv "u")])
756 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
758 ;; Used in signed and unsigned divisions.
759 (define_code_iterator any_div [div udiv])
761 ;; Instruction prefix for signed and unsigned operations.
762 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
763 (div "i") (udiv "")])
765 ;; 64bit single word integer modes.
766 (define_mode_iterator SWI1248x [QI HI SI DI])
768 ;; 64bit single word integer modes without QImode and HImode.
769 (define_mode_iterator SWI48x [SI DI])
771 ;; Single word integer modes.
772 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
774 ;; Single word integer modes without SImode and DImode.
775 (define_mode_iterator SWI12 [QI HI])
777 ;; Single word integer modes without DImode.
778 (define_mode_iterator SWI124 [QI HI SI])
780 ;; Single word integer modes without QImode and DImode.
781 (define_mode_iterator SWI24 [HI SI])
783 ;; Single word integer modes without QImode.
784 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
786 ;; Single word integer modes without QImode and HImode.
787 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
789 ;; All math-dependant single and double word integer modes.
790 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
791 (HI "TARGET_HIMODE_MATH")
792 SI DI (TI "TARGET_64BIT")])
794 ;; Math-dependant single word integer modes.
795 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
796 (HI "TARGET_HIMODE_MATH")
797 SI (DI "TARGET_64BIT")])
799 ;; Math-dependant single word integer modes without DImode.
800 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
801 (HI "TARGET_HIMODE_MATH")
804 ;; Math-dependant single word integer modes without QImode.
805 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
806 SI (DI "TARGET_64BIT")])
808 ;; Double word integer modes.
809 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
810 (TI "TARGET_64BIT")])
812 ;; Double word integer modes as mode attribute.
813 (define_mode_attr DWI [(SI "DI") (DI "TI")])
814 (define_mode_attr dwi [(SI "di") (DI "ti")])
816 ;; Half mode for double word integer modes.
817 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
818 (DI "TARGET_64BIT")])
820 ;; Instruction suffix for integer modes.
821 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
823 ;; Pointer size prefix for integer modes (Intel asm dialect)
824 (define_mode_attr iptrsize [(QI "BYTE")
829 ;; Register class for integer modes.
830 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
832 ;; Immediate operand constraint for integer modes.
833 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
835 ;; General operand constraint for word modes.
836 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
838 ;; Immediate operand constraint for double integer modes.
839 (define_mode_attr di [(SI "iF") (DI "e")])
841 ;; Immediate operand constraint for shifts.
842 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
844 ;; General operand predicate for integer modes.
845 (define_mode_attr general_operand
846 [(QI "general_operand")
847 (HI "general_operand")
848 (SI "general_operand")
849 (DI "x86_64_general_operand")
850 (TI "x86_64_general_operand")])
852 ;; General sign/zero extend operand predicate for integer modes.
853 (define_mode_attr general_szext_operand
854 [(QI "general_operand")
855 (HI "general_operand")
856 (SI "general_operand")
857 (DI "x86_64_szext_general_operand")])
859 ;; Immediate operand predicate for integer modes.
860 (define_mode_attr immediate_operand
861 [(QI "immediate_operand")
862 (HI "immediate_operand")
863 (SI "immediate_operand")
864 (DI "x86_64_immediate_operand")])
866 ;; Nonmemory operand predicate for integer modes.
867 (define_mode_attr nonmemory_operand
868 [(QI "nonmemory_operand")
869 (HI "nonmemory_operand")
870 (SI "nonmemory_operand")
871 (DI "x86_64_nonmemory_operand")])
873 ;; Operand predicate for shifts.
874 (define_mode_attr shift_operand
875 [(QI "nonimmediate_operand")
876 (HI "nonimmediate_operand")
877 (SI "nonimmediate_operand")
878 (DI "shiftdi_operand")
879 (TI "register_operand")])
881 ;; Operand predicate for shift argument.
882 (define_mode_attr shift_immediate_operand
883 [(QI "const_1_to_31_operand")
884 (HI "const_1_to_31_operand")
885 (SI "const_1_to_31_operand")
886 (DI "const_1_to_63_operand")])
888 ;; Input operand predicate for arithmetic left shifts.
889 (define_mode_attr ashl_input_operand
890 [(QI "nonimmediate_operand")
891 (HI "nonimmediate_operand")
892 (SI "nonimmediate_operand")
893 (DI "ashldi_input_operand")
894 (TI "reg_or_pm1_operand")])
896 ;; SSE and x87 SFmode and DFmode floating point modes
897 (define_mode_iterator MODEF [SF DF])
899 ;; All x87 floating point modes
900 (define_mode_iterator X87MODEF [SF DF XF])
902 ;; All integer modes handled by x87 fisttp operator.
903 (define_mode_iterator X87MODEI [HI SI DI])
905 ;; All integer modes handled by integer x87 operators.
906 (define_mode_iterator X87MODEI12 [HI SI])
908 ;; All integer modes handled by SSE cvtts?2si* operators.
909 (define_mode_iterator SSEMODEI24 [SI DI])
911 ;; SSE asm suffix for floating point modes
912 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
914 ;; SSE vector mode corresponding to a scalar mode
915 (define_mode_attr ssevecmode
916 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
918 ;; Instruction suffix for REX 64bit operators.
919 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
921 ;; This mode iterator allows :P to be used for patterns that operate on
922 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
923 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
925 ;; Scheduling descriptions
927 (include "pentium.md")
930 (include "athlon.md")
931 (include "bdver1.md")
936 ;; Operand and operator predicates and constraints
938 (include "predicates.md")
939 (include "constraints.md")
942 ;; Compare and branch/compare and store instructions.
944 (define_expand "cbranch<mode>4"
945 [(set (reg:CC FLAGS_REG)
946 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
947 (match_operand:SDWIM 2 "<general_operand>" "")))
948 (set (pc) (if_then_else
949 (match_operator 0 "ordered_comparison_operator"
950 [(reg:CC FLAGS_REG) (const_int 0)])
951 (label_ref (match_operand 3 "" ""))
955 if (MEM_P (operands[1]) && MEM_P (operands[2]))
956 operands[1] = force_reg (<MODE>mode, operands[1]);
957 ix86_expand_branch (GET_CODE (operands[0]),
958 operands[1], operands[2], operands[3]);
962 (define_expand "cstore<mode>4"
963 [(set (reg:CC FLAGS_REG)
964 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
965 (match_operand:SWIM 3 "<general_operand>" "")))
966 (set (match_operand:QI 0 "register_operand" "")
967 (match_operator 1 "ordered_comparison_operator"
968 [(reg:CC FLAGS_REG) (const_int 0)]))]
971 if (MEM_P (operands[2]) && MEM_P (operands[3]))
972 operands[2] = force_reg (<MODE>mode, operands[2]);
973 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
974 operands[2], operands[3]);
978 (define_expand "cmp<mode>_1"
979 [(set (reg:CC FLAGS_REG)
980 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
981 (match_operand:SWI48 1 "<general_operand>" "")))])
983 (define_insn "*cmp<mode>_ccno_1"
984 [(set (reg FLAGS_REG)
985 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
986 (match_operand:SWI 1 "const0_operand" "")))]
987 "ix86_match_ccmode (insn, CCNOmode)"
989 test{<imodesuffix>}\t%0, %0
990 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
991 [(set_attr "type" "test,icmp")
992 (set_attr "length_immediate" "0,1")
993 (set_attr "mode" "<MODE>")])
995 (define_insn "*cmp<mode>_1"
996 [(set (reg FLAGS_REG)
997 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
998 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
999 "ix86_match_ccmode (insn, CCmode)"
1000 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1001 [(set_attr "type" "icmp")
1002 (set_attr "mode" "<MODE>")])
1004 (define_insn "*cmp<mode>_minus_1"
1005 [(set (reg FLAGS_REG)
1007 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1008 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1010 "ix86_match_ccmode (insn, CCGOCmode)"
1011 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1012 [(set_attr "type" "icmp")
1013 (set_attr "mode" "<MODE>")])
1015 (define_insn "*cmpqi_ext_1"
1016 [(set (reg FLAGS_REG)
1018 (match_operand:QI 0 "general_operand" "Qm")
1021 (match_operand 1 "ext_register_operand" "Q")
1023 (const_int 8)) 0)))]
1024 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1025 "cmp{b}\t{%h1, %0|%0, %h1}"
1026 [(set_attr "type" "icmp")
1027 (set_attr "mode" "QI")])
1029 (define_insn "*cmpqi_ext_1_rex64"
1030 [(set (reg FLAGS_REG)
1032 (match_operand:QI 0 "register_operand" "Q")
1035 (match_operand 1 "ext_register_operand" "Q")
1037 (const_int 8)) 0)))]
1038 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1039 "cmp{b}\t{%h1, %0|%0, %h1}"
1040 [(set_attr "type" "icmp")
1041 (set_attr "mode" "QI")])
1043 (define_insn "*cmpqi_ext_2"
1044 [(set (reg FLAGS_REG)
1048 (match_operand 0 "ext_register_operand" "Q")
1051 (match_operand:QI 1 "const0_operand" "")))]
1052 "ix86_match_ccmode (insn, CCNOmode)"
1054 [(set_attr "type" "test")
1055 (set_attr "length_immediate" "0")
1056 (set_attr "mode" "QI")])
1058 (define_expand "cmpqi_ext_3"
1059 [(set (reg:CC FLAGS_REG)
1063 (match_operand 0 "ext_register_operand" "")
1066 (match_operand:QI 1 "immediate_operand" "")))])
1068 (define_insn "*cmpqi_ext_3_insn"
1069 [(set (reg FLAGS_REG)
1073 (match_operand 0 "ext_register_operand" "Q")
1076 (match_operand:QI 1 "general_operand" "Qmn")))]
1077 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1078 "cmp{b}\t{%1, %h0|%h0, %1}"
1079 [(set_attr "type" "icmp")
1080 (set_attr "modrm" "1")
1081 (set_attr "mode" "QI")])
1083 (define_insn "*cmpqi_ext_3_insn_rex64"
1084 [(set (reg FLAGS_REG)
1088 (match_operand 0 "ext_register_operand" "Q")
1091 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1092 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1093 "cmp{b}\t{%1, %h0|%h0, %1}"
1094 [(set_attr "type" "icmp")
1095 (set_attr "modrm" "1")
1096 (set_attr "mode" "QI")])
1098 (define_insn "*cmpqi_ext_4"
1099 [(set (reg FLAGS_REG)
1103 (match_operand 0 "ext_register_operand" "Q")
1108 (match_operand 1 "ext_register_operand" "Q")
1110 (const_int 8)) 0)))]
1111 "ix86_match_ccmode (insn, CCmode)"
1112 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1113 [(set_attr "type" "icmp")
1114 (set_attr "mode" "QI")])
1116 ;; These implement float point compares.
1117 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1118 ;; which would allow mix and match FP modes on the compares. Which is what
1119 ;; the old patterns did, but with many more of them.
1121 (define_expand "cbranchxf4"
1122 [(set (reg:CC FLAGS_REG)
1123 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1124 (match_operand:XF 2 "nonmemory_operand" "")))
1125 (set (pc) (if_then_else
1126 (match_operator 0 "ix86_fp_comparison_operator"
1129 (label_ref (match_operand 3 "" ""))
1133 ix86_expand_branch (GET_CODE (operands[0]),
1134 operands[1], operands[2], operands[3]);
1138 (define_expand "cstorexf4"
1139 [(set (reg:CC FLAGS_REG)
1140 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1141 (match_operand:XF 3 "nonmemory_operand" "")))
1142 (set (match_operand:QI 0 "register_operand" "")
1143 (match_operator 1 "ix86_fp_comparison_operator"
1148 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1149 operands[2], operands[3]);
1153 (define_expand "cbranch<mode>4"
1154 [(set (reg:CC FLAGS_REG)
1155 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1156 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1157 (set (pc) (if_then_else
1158 (match_operator 0 "ix86_fp_comparison_operator"
1161 (label_ref (match_operand 3 "" ""))
1163 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1165 ix86_expand_branch (GET_CODE (operands[0]),
1166 operands[1], operands[2], operands[3]);
1170 (define_expand "cstore<mode>4"
1171 [(set (reg:CC FLAGS_REG)
1172 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1173 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1174 (set (match_operand:QI 0 "register_operand" "")
1175 (match_operator 1 "ix86_fp_comparison_operator"
1178 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1180 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1181 operands[2], operands[3]);
1185 (define_expand "cbranchcc4"
1186 [(set (pc) (if_then_else
1187 (match_operator 0 "comparison_operator"
1188 [(match_operand 1 "flags_reg_operand" "")
1189 (match_operand 2 "const0_operand" "")])
1190 (label_ref (match_operand 3 "" ""))
1194 ix86_expand_branch (GET_CODE (operands[0]),
1195 operands[1], operands[2], operands[3]);
1199 (define_expand "cstorecc4"
1200 [(set (match_operand:QI 0 "register_operand" "")
1201 (match_operator 1 "comparison_operator"
1202 [(match_operand 2 "flags_reg_operand" "")
1203 (match_operand 3 "const0_operand" "")]))]
1206 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1207 operands[2], operands[3]);
1212 ;; FP compares, step 1:
1213 ;; Set the FP condition codes.
1215 ;; CCFPmode compare with exceptions
1216 ;; CCFPUmode compare with no exceptions
1218 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1219 ;; used to manage the reg stack popping would not be preserved.
1221 (define_insn "*cmpfp_0"
1222 [(set (match_operand:HI 0 "register_operand" "=a")
1225 (match_operand 1 "register_operand" "f")
1226 (match_operand 2 "const0_operand" ""))]
1228 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1229 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1230 "* return output_fp_compare (insn, operands, 0, 0);"
1231 [(set_attr "type" "multi")
1232 (set_attr "unit" "i387")
1234 (cond [(match_operand:SF 1 "" "")
1236 (match_operand:DF 1 "" "")
1239 (const_string "XF")))])
1241 (define_insn_and_split "*cmpfp_0_cc"
1242 [(set (reg:CCFP FLAGS_REG)
1244 (match_operand 1 "register_operand" "f")
1245 (match_operand 2 "const0_operand" "")))
1246 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1247 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1248 && TARGET_SAHF && !TARGET_CMOVE
1249 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1251 "&& reload_completed"
1254 [(compare:CCFP (match_dup 1)(match_dup 2))]
1256 (set (reg:CC FLAGS_REG)
1257 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1259 [(set_attr "type" "multi")
1260 (set_attr "unit" "i387")
1262 (cond [(match_operand:SF 1 "" "")
1264 (match_operand:DF 1 "" "")
1267 (const_string "XF")))])
1269 (define_insn "*cmpfp_xf"
1270 [(set (match_operand:HI 0 "register_operand" "=a")
1273 (match_operand:XF 1 "register_operand" "f")
1274 (match_operand:XF 2 "register_operand" "f"))]
1277 "* return output_fp_compare (insn, operands, 0, 0);"
1278 [(set_attr "type" "multi")
1279 (set_attr "unit" "i387")
1280 (set_attr "mode" "XF")])
1282 (define_insn_and_split "*cmpfp_xf_cc"
1283 [(set (reg:CCFP FLAGS_REG)
1285 (match_operand:XF 1 "register_operand" "f")
1286 (match_operand:XF 2 "register_operand" "f")))
1287 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1289 && TARGET_SAHF && !TARGET_CMOVE"
1291 "&& reload_completed"
1294 [(compare:CCFP (match_dup 1)(match_dup 2))]
1296 (set (reg:CC FLAGS_REG)
1297 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1299 [(set_attr "type" "multi")
1300 (set_attr "unit" "i387")
1301 (set_attr "mode" "XF")])
1303 (define_insn "*cmpfp_<mode>"
1304 [(set (match_operand:HI 0 "register_operand" "=a")
1307 (match_operand:MODEF 1 "register_operand" "f")
1308 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1311 "* return output_fp_compare (insn, operands, 0, 0);"
1312 [(set_attr "type" "multi")
1313 (set_attr "unit" "i387")
1314 (set_attr "mode" "<MODE>")])
1316 (define_insn_and_split "*cmpfp_<mode>_cc"
1317 [(set (reg:CCFP FLAGS_REG)
1319 (match_operand:MODEF 1 "register_operand" "f")
1320 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1321 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1323 && TARGET_SAHF && !TARGET_CMOVE"
1325 "&& reload_completed"
1328 [(compare:CCFP (match_dup 1)(match_dup 2))]
1330 (set (reg:CC FLAGS_REG)
1331 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1333 [(set_attr "type" "multi")
1334 (set_attr "unit" "i387")
1335 (set_attr "mode" "<MODE>")])
1337 (define_insn "*cmpfp_u"
1338 [(set (match_operand:HI 0 "register_operand" "=a")
1341 (match_operand 1 "register_operand" "f")
1342 (match_operand 2 "register_operand" "f"))]
1344 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1345 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1346 "* return output_fp_compare (insn, operands, 0, 1);"
1347 [(set_attr "type" "multi")
1348 (set_attr "unit" "i387")
1350 (cond [(match_operand:SF 1 "" "")
1352 (match_operand:DF 1 "" "")
1355 (const_string "XF")))])
1357 (define_insn_and_split "*cmpfp_u_cc"
1358 [(set (reg:CCFPU FLAGS_REG)
1360 (match_operand 1 "register_operand" "f")
1361 (match_operand 2 "register_operand" "f")))
1362 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1363 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1364 && TARGET_SAHF && !TARGET_CMOVE
1365 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1367 "&& reload_completed"
1370 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1372 (set (reg:CC FLAGS_REG)
1373 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1375 [(set_attr "type" "multi")
1376 (set_attr "unit" "i387")
1378 (cond [(match_operand:SF 1 "" "")
1380 (match_operand:DF 1 "" "")
1383 (const_string "XF")))])
1385 (define_insn "*cmpfp_<mode>"
1386 [(set (match_operand:HI 0 "register_operand" "=a")
1389 (match_operand 1 "register_operand" "f")
1390 (match_operator 3 "float_operator"
1391 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1393 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1394 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1395 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1396 "* return output_fp_compare (insn, operands, 0, 0);"
1397 [(set_attr "type" "multi")
1398 (set_attr "unit" "i387")
1399 (set_attr "fp_int_src" "true")
1400 (set_attr "mode" "<MODE>")])
1402 (define_insn_and_split "*cmpfp_<mode>_cc"
1403 [(set (reg:CCFP FLAGS_REG)
1405 (match_operand 1 "register_operand" "f")
1406 (match_operator 3 "float_operator"
1407 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1408 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1409 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1410 && TARGET_SAHF && !TARGET_CMOVE
1411 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1412 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1414 "&& reload_completed"
1419 (match_op_dup 3 [(match_dup 2)]))]
1421 (set (reg:CC FLAGS_REG)
1422 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1424 [(set_attr "type" "multi")
1425 (set_attr "unit" "i387")
1426 (set_attr "fp_int_src" "true")
1427 (set_attr "mode" "<MODE>")])
1429 ;; FP compares, step 2
1430 ;; Move the fpsw to ax.
1432 (define_insn "x86_fnstsw_1"
1433 [(set (match_operand:HI 0 "register_operand" "=a")
1434 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1437 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1438 (set_attr "mode" "SI")
1439 (set_attr "unit" "i387")])
1441 ;; FP compares, step 3
1442 ;; Get ax into flags, general case.
1444 (define_insn "x86_sahf_1"
1445 [(set (reg:CC FLAGS_REG)
1446 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1450 #ifndef HAVE_AS_IX86_SAHF
1452 return ASM_BYTE "0x9e";
1457 [(set_attr "length" "1")
1458 (set_attr "athlon_decode" "vector")
1459 (set_attr "amdfam10_decode" "direct")
1460 (set_attr "bdver1_decode" "direct")
1461 (set_attr "mode" "SI")])
1463 ;; Pentium Pro can do steps 1 through 3 in one go.
1464 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1465 (define_insn "*cmpfp_i_mixed"
1466 [(set (reg:CCFP FLAGS_REG)
1467 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1468 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1469 "TARGET_MIX_SSE_I387
1470 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1471 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1472 "* return output_fp_compare (insn, operands, 1, 0);"
1473 [(set_attr "type" "fcmp,ssecomi")
1474 (set_attr "prefix" "orig,maybe_vex")
1476 (if_then_else (match_operand:SF 1 "" "")
1478 (const_string "DF")))
1479 (set (attr "prefix_rep")
1480 (if_then_else (eq_attr "type" "ssecomi")
1482 (const_string "*")))
1483 (set (attr "prefix_data16")
1484 (cond [(eq_attr "type" "fcmp")
1486 (eq_attr "mode" "DF")
1489 (const_string "0")))
1490 (set_attr "athlon_decode" "vector")
1491 (set_attr "amdfam10_decode" "direct")
1492 (set_attr "bdver1_decode" "double")])
1494 (define_insn "*cmpfp_i_sse"
1495 [(set (reg:CCFP FLAGS_REG)
1496 (compare:CCFP (match_operand 0 "register_operand" "x")
1497 (match_operand 1 "nonimmediate_operand" "xm")))]
1499 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1500 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1501 "* return output_fp_compare (insn, operands, 1, 0);"
1502 [(set_attr "type" "ssecomi")
1503 (set_attr "prefix" "maybe_vex")
1505 (if_then_else (match_operand:SF 1 "" "")
1507 (const_string "DF")))
1508 (set_attr "prefix_rep" "0")
1509 (set (attr "prefix_data16")
1510 (if_then_else (eq_attr "mode" "DF")
1512 (const_string "0")))
1513 (set_attr "athlon_decode" "vector")
1514 (set_attr "amdfam10_decode" "direct")
1515 (set_attr "bdver1_decode" "double")])
1517 (define_insn "*cmpfp_i_i387"
1518 [(set (reg:CCFP FLAGS_REG)
1519 (compare:CCFP (match_operand 0 "register_operand" "f")
1520 (match_operand 1 "register_operand" "f")))]
1521 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1523 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1524 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1525 "* return output_fp_compare (insn, operands, 1, 0);"
1526 [(set_attr "type" "fcmp")
1528 (cond [(match_operand:SF 1 "" "")
1530 (match_operand:DF 1 "" "")
1533 (const_string "XF")))
1534 (set_attr "athlon_decode" "vector")
1535 (set_attr "amdfam10_decode" "direct")
1536 (set_attr "bdver1_decode" "double")])
1538 (define_insn "*cmpfp_iu_mixed"
1539 [(set (reg:CCFPU FLAGS_REG)
1540 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1541 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1542 "TARGET_MIX_SSE_I387
1543 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1544 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1545 "* return output_fp_compare (insn, operands, 1, 1);"
1546 [(set_attr "type" "fcmp,ssecomi")
1547 (set_attr "prefix" "orig,maybe_vex")
1549 (if_then_else (match_operand:SF 1 "" "")
1551 (const_string "DF")))
1552 (set (attr "prefix_rep")
1553 (if_then_else (eq_attr "type" "ssecomi")
1555 (const_string "*")))
1556 (set (attr "prefix_data16")
1557 (cond [(eq_attr "type" "fcmp")
1559 (eq_attr "mode" "DF")
1562 (const_string "0")))
1563 (set_attr "athlon_decode" "vector")
1564 (set_attr "amdfam10_decode" "direct")
1565 (set_attr "bdver1_decode" "double")])
1567 (define_insn "*cmpfp_iu_sse"
1568 [(set (reg:CCFPU FLAGS_REG)
1569 (compare:CCFPU (match_operand 0 "register_operand" "x")
1570 (match_operand 1 "nonimmediate_operand" "xm")))]
1572 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1573 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1574 "* return output_fp_compare (insn, operands, 1, 1);"
1575 [(set_attr "type" "ssecomi")
1576 (set_attr "prefix" "maybe_vex")
1578 (if_then_else (match_operand:SF 1 "" "")
1580 (const_string "DF")))
1581 (set_attr "prefix_rep" "0")
1582 (set (attr "prefix_data16")
1583 (if_then_else (eq_attr "mode" "DF")
1585 (const_string "0")))
1586 (set_attr "athlon_decode" "vector")
1587 (set_attr "amdfam10_decode" "direct")
1588 (set_attr "bdver1_decode" "double")])
1590 (define_insn "*cmpfp_iu_387"
1591 [(set (reg:CCFPU FLAGS_REG)
1592 (compare:CCFPU (match_operand 0 "register_operand" "f")
1593 (match_operand 1 "register_operand" "f")))]
1594 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1596 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1597 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1598 "* return output_fp_compare (insn, operands, 1, 1);"
1599 [(set_attr "type" "fcmp")
1601 (cond [(match_operand:SF 1 "" "")
1603 (match_operand:DF 1 "" "")
1606 (const_string "XF")))
1607 (set_attr "athlon_decode" "vector")
1608 (set_attr "amdfam10_decode" "direct")
1609 (set_attr "bdver1_decode" "direct")])
1611 ;; Push/pop instructions.
1613 (define_insn "*push<mode>2"
1614 [(set (match_operand:DWI 0 "push_operand" "=<")
1615 (match_operand:DWI 1 "general_no_elim_operand" "riF*m"))]
1620 [(set (match_operand:TI 0 "push_operand" "")
1621 (match_operand:TI 1 "general_operand" ""))]
1622 "TARGET_64BIT && reload_completed
1623 && !SSE_REG_P (operands[1])"
1625 "ix86_split_long_move (operands); DONE;")
1627 (define_insn "*pushdi2_rex64"
1628 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1629 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1634 [(set_attr "type" "push,multi")
1635 (set_attr "mode" "DI")])
1637 ;; Convert impossible pushes of immediate to existing instructions.
1638 ;; First try to get scratch register and go through it. In case this
1639 ;; fails, push sign extended lower part first and then overwrite
1640 ;; upper part by 32bit move.
1642 [(match_scratch:DI 2 "r")
1643 (set (match_operand:DI 0 "push_operand" "")
1644 (match_operand:DI 1 "immediate_operand" ""))]
1645 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1646 && !x86_64_immediate_operand (operands[1], DImode)"
1647 [(set (match_dup 2) (match_dup 1))
1648 (set (match_dup 0) (match_dup 2))])
1650 ;; We need to define this as both peepholer and splitter for case
1651 ;; peephole2 pass is not run.
1652 ;; "&& 1" is needed to keep it from matching the previous pattern.
1654 [(set (match_operand:DI 0 "push_operand" "")
1655 (match_operand:DI 1 "immediate_operand" ""))]
1656 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1657 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1658 [(set (match_dup 0) (match_dup 1))
1659 (set (match_dup 2) (match_dup 3))]
1661 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1663 operands[1] = gen_lowpart (DImode, operands[2]);
1664 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1669 [(set (match_operand:DI 0 "push_operand" "")
1670 (match_operand:DI 1 "immediate_operand" ""))]
1671 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1672 ? epilogue_completed : reload_completed)
1673 && !symbolic_operand (operands[1], DImode)
1674 && !x86_64_immediate_operand (operands[1], DImode)"
1675 [(set (match_dup 0) (match_dup 1))
1676 (set (match_dup 2) (match_dup 3))]
1678 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1680 operands[1] = gen_lowpart (DImode, operands[2]);
1681 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1686 [(set (match_operand:DI 0 "push_operand" "")
1687 (match_operand:DI 1 "general_operand" ""))]
1688 "!TARGET_64BIT && reload_completed
1689 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1691 "ix86_split_long_move (operands); DONE;")
1693 (define_insn "*pushsi2"
1694 [(set (match_operand:SI 0 "push_operand" "=<")
1695 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1698 [(set_attr "type" "push")
1699 (set_attr "mode" "SI")])
1701 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1702 ;; "push a byte/word". But actually we use pushl, which has the effect
1703 ;; of rounding the amount pushed up to a word.
1705 ;; For TARGET_64BIT we always round up to 8 bytes.
1706 (define_insn "*push<mode>2_rex64"
1707 [(set (match_operand:SWI124 0 "push_operand" "=X")
1708 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1711 [(set_attr "type" "push")
1712 (set_attr "mode" "DI")])
1714 (define_insn "*push<mode>2"
1715 [(set (match_operand:SWI12 0 "push_operand" "=X")
1716 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1719 [(set_attr "type" "push")
1720 (set_attr "mode" "SI")])
1722 (define_insn "*push<mode>2_prologue"
1723 [(set (match_operand:P 0 "push_operand" "=<")
1724 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1725 (clobber (mem:BLK (scratch)))]
1727 "push{<imodesuffix>}\t%1"
1728 [(set_attr "type" "push")
1729 (set_attr "mode" "<MODE>")])
1731 (define_insn "*pop<mode>1"
1732 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1733 (match_operand:P 1 "pop_operand" ">"))]
1735 "pop{<imodesuffix>}\t%0"
1736 [(set_attr "type" "pop")
1737 (set_attr "mode" "<MODE>")])
1739 (define_insn "*pop<mode>1_epilogue"
1740 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1741 (match_operand:P 1 "pop_operand" ">"))
1742 (clobber (mem:BLK (scratch)))]
1744 "pop{<imodesuffix>}\t%0"
1745 [(set_attr "type" "pop")
1746 (set_attr "mode" "<MODE>")])
1748 ;; Move instructions.
1750 (define_expand "movoi"
1751 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1752 (match_operand:OI 1 "general_operand" ""))]
1754 "ix86_expand_move (OImode, operands); DONE;")
1756 (define_expand "movti"
1757 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1758 (match_operand:TI 1 "nonimmediate_operand" ""))]
1759 "TARGET_64BIT || TARGET_SSE"
1762 ix86_expand_move (TImode, operands);
1763 else if (push_operand (operands[0], TImode))
1764 ix86_expand_push (TImode, operands[1]);
1766 ix86_expand_vector_move (TImode, operands);
1770 ;; This expands to what emit_move_complex would generate if we didn't
1771 ;; have a movti pattern. Having this avoids problems with reload on
1772 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1773 ;; to have around all the time.
1774 (define_expand "movcdi"
1775 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1776 (match_operand:CDI 1 "general_operand" ""))]
1779 if (push_operand (operands[0], CDImode))
1780 emit_move_complex_push (CDImode, operands[0], operands[1]);
1782 emit_move_complex_parts (operands[0], operands[1]);
1786 (define_expand "mov<mode>"
1787 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1788 (match_operand:SWI1248x 1 "general_operand" ""))]
1790 "ix86_expand_move (<MODE>mode, operands); DONE;")
1792 (define_insn "*mov<mode>_xor"
1793 [(set (match_operand:SWI48 0 "register_operand" "=r")
1794 (match_operand:SWI48 1 "const0_operand" ""))
1795 (clobber (reg:CC FLAGS_REG))]
1798 [(set_attr "type" "alu1")
1799 (set_attr "mode" "SI")
1800 (set_attr "length_immediate" "0")])
1802 (define_insn "*mov<mode>_or"
1803 [(set (match_operand:SWI48 0 "register_operand" "=r")
1804 (match_operand:SWI48 1 "const_int_operand" ""))
1805 (clobber (reg:CC FLAGS_REG))]
1807 && operands[1] == constm1_rtx"
1808 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1809 [(set_attr "type" "alu1")
1810 (set_attr "mode" "<MODE>")
1811 (set_attr "length_immediate" "1")])
1813 (define_insn "*movoi_internal_avx"
1814 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1815 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1816 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1818 switch (which_alternative)
1821 return "vxorps\t%0, %0, %0";
1824 if (misaligned_operand (operands[0], OImode)
1825 || misaligned_operand (operands[1], OImode))
1826 return "vmovdqu\t{%1, %0|%0, %1}";
1828 return "vmovdqa\t{%1, %0|%0, %1}";
1833 [(set_attr "type" "sselog1,ssemov,ssemov")
1834 (set_attr "prefix" "vex")
1835 (set_attr "mode" "OI")])
1837 (define_insn "*movti_internal_rex64"
1838 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1839 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1840 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1842 switch (which_alternative)
1848 if (get_attr_mode (insn) == MODE_V4SF)
1849 return "%vxorps\t%0, %d0";
1851 return "%vpxor\t%0, %d0";
1854 /* TDmode values are passed as TImode on the stack. Moving them
1855 to stack may result in unaligned memory access. */
1856 if (misaligned_operand (operands[0], TImode)
1857 || misaligned_operand (operands[1], TImode))
1859 if (get_attr_mode (insn) == MODE_V4SF)
1860 return "%vmovups\t{%1, %0|%0, %1}";
1862 return "%vmovdqu\t{%1, %0|%0, %1}";
1866 if (get_attr_mode (insn) == MODE_V4SF)
1867 return "%vmovaps\t{%1, %0|%0, %1}";
1869 return "%vmovdqa\t{%1, %0|%0, %1}";
1875 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1876 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1878 (cond [(eq_attr "alternative" "2,3")
1880 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1882 (const_string "V4SF")
1883 (const_string "TI"))
1884 (eq_attr "alternative" "4")
1886 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1888 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1890 (const_string "V4SF")
1891 (const_string "TI"))]
1892 (const_string "DI")))])
1895 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1896 (match_operand:TI 1 "general_operand" ""))]
1898 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1900 "ix86_split_long_move (operands); DONE;")
1902 (define_insn "*movti_internal_sse"
1903 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1904 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1905 "TARGET_SSE && !TARGET_64BIT
1906 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1908 switch (which_alternative)
1911 if (get_attr_mode (insn) == MODE_V4SF)
1912 return "%vxorps\t%0, %d0";
1914 return "%vpxor\t%0, %d0";
1917 /* TDmode values are passed as TImode on the stack. Moving them
1918 to stack may result in unaligned memory access. */
1919 if (misaligned_operand (operands[0], TImode)
1920 || misaligned_operand (operands[1], TImode))
1922 if (get_attr_mode (insn) == MODE_V4SF)
1923 return "%vmovups\t{%1, %0|%0, %1}";
1925 return "%vmovdqu\t{%1, %0|%0, %1}";
1929 if (get_attr_mode (insn) == MODE_V4SF)
1930 return "%vmovaps\t{%1, %0|%0, %1}";
1932 return "%vmovdqa\t{%1, %0|%0, %1}";
1938 [(set_attr "type" "sselog1,ssemov,ssemov")
1939 (set_attr "prefix" "maybe_vex")
1941 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1942 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
1944 (const_string "V4SF")
1945 (and (eq_attr "alternative" "2")
1946 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
1948 (const_string "V4SF")]
1949 (const_string "TI")))])
1951 (define_insn "*movdi_internal_rex64"
1952 [(set (match_operand:DI 0 "nonimmediate_operand"
1953 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
1954 (match_operand:DI 1 "general_operand"
1955 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
1956 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1958 switch (get_attr_type (insn))
1961 if (SSE_REG_P (operands[0]))
1962 return "movq2dq\t{%1, %0|%0, %1}";
1964 return "movdq2q\t{%1, %0|%0, %1}";
1969 if (get_attr_mode (insn) == MODE_TI)
1970 return "vmovdqa\t{%1, %0|%0, %1}";
1972 return "vmovq\t{%1, %0|%0, %1}";
1975 if (get_attr_mode (insn) == MODE_TI)
1976 return "movdqa\t{%1, %0|%0, %1}";
1980 /* Moves from and into integer register is done using movd
1981 opcode with REX prefix. */
1982 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1983 return "movd\t{%1, %0|%0, %1}";
1984 return "movq\t{%1, %0|%0, %1}";
1987 return "%vpxor\t%0, %d0";
1990 return "pxor\t%0, %0";
1996 return "lea{q}\t{%a1, %0|%0, %a1}";
1999 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2000 if (get_attr_mode (insn) == MODE_SI)
2001 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2002 else if (which_alternative == 2)
2003 return "movabs{q}\t{%1, %0|%0, %1}";
2005 return "mov{q}\t{%1, %0|%0, %1}";
2009 (cond [(eq_attr "alternative" "5")
2010 (const_string "mmx")
2011 (eq_attr "alternative" "6,7,8,9,10")
2012 (const_string "mmxmov")
2013 (eq_attr "alternative" "11")
2014 (const_string "sselog1")
2015 (eq_attr "alternative" "12,13,14,15,16")
2016 (const_string "ssemov")
2017 (eq_attr "alternative" "17,18")
2018 (const_string "ssecvt")
2019 (eq_attr "alternative" "4")
2020 (const_string "multi")
2021 (match_operand:DI 1 "pic_32bit_operand" "")
2022 (const_string "lea")
2024 (const_string "imov")))
2027 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2029 (const_string "*")))
2030 (set (attr "length_immediate")
2032 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2034 (const_string "*")))
2035 (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2036 (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2037 (set (attr "prefix")
2038 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2039 (const_string "maybe_vex")
2040 (const_string "orig")))
2041 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2043 ;; Convert impossible stores of immediate to existing instructions.
2044 ;; First try to get scratch register and go through it. In case this
2045 ;; fails, move by 32bit parts.
2047 [(match_scratch:DI 2 "r")
2048 (set (match_operand:DI 0 "memory_operand" "")
2049 (match_operand:DI 1 "immediate_operand" ""))]
2050 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2051 && !x86_64_immediate_operand (operands[1], DImode)"
2052 [(set (match_dup 2) (match_dup 1))
2053 (set (match_dup 0) (match_dup 2))])
2055 ;; We need to define this as both peepholer and splitter for case
2056 ;; peephole2 pass is not run.
2057 ;; "&& 1" is needed to keep it from matching the previous pattern.
2059 [(set (match_operand:DI 0 "memory_operand" "")
2060 (match_operand:DI 1 "immediate_operand" ""))]
2061 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2062 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2063 [(set (match_dup 2) (match_dup 3))
2064 (set (match_dup 4) (match_dup 5))]
2065 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2068 [(set (match_operand:DI 0 "memory_operand" "")
2069 (match_operand:DI 1 "immediate_operand" ""))]
2070 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2071 ? epilogue_completed : reload_completed)
2072 && !symbolic_operand (operands[1], DImode)
2073 && !x86_64_immediate_operand (operands[1], DImode)"
2074 [(set (match_dup 2) (match_dup 3))
2075 (set (match_dup 4) (match_dup 5))]
2076 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2078 (define_insn "*movdi_internal"
2079 [(set (match_operand:DI 0 "nonimmediate_operand"
2080 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2081 (match_operand:DI 1 "general_operand"
2082 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2083 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2088 movq\t{%1, %0|%0, %1}
2089 movq\t{%1, %0|%0, %1}
2091 %vmovq\t{%1, %0|%0, %1}
2092 %vmovdqa\t{%1, %0|%0, %1}
2093 %vmovq\t{%1, %0|%0, %1}
2095 movlps\t{%1, %0|%0, %1}
2096 movaps\t{%1, %0|%0, %1}
2097 movlps\t{%1, %0|%0, %1}"
2098 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2099 (set (attr "prefix")
2100 (if_then_else (eq_attr "alternative" "5,6,7,8")
2101 (const_string "vex")
2102 (const_string "orig")))
2103 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2106 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2107 (match_operand:DI 1 "general_operand" ""))]
2108 "!TARGET_64BIT && reload_completed
2109 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2110 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2112 "ix86_split_long_move (operands); DONE;")
2114 (define_insn "*movsi_internal"
2115 [(set (match_operand:SI 0 "nonimmediate_operand"
2116 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2117 (match_operand:SI 1 "general_operand"
2118 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2119 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2121 switch (get_attr_type (insn))
2124 if (get_attr_mode (insn) == MODE_TI)
2125 return "%vpxor\t%0, %d0";
2126 return "%vxorps\t%0, %d0";
2129 switch (get_attr_mode (insn))
2132 return "%vmovdqa\t{%1, %0|%0, %1}";
2134 return "%vmovaps\t{%1, %0|%0, %1}";
2136 return "%vmovd\t{%1, %0|%0, %1}";
2138 return "%vmovss\t{%1, %0|%0, %1}";
2144 return "pxor\t%0, %0";
2147 if (get_attr_mode (insn) == MODE_DI)
2148 return "movq\t{%1, %0|%0, %1}";
2149 return "movd\t{%1, %0|%0, %1}";
2152 return "lea{l}\t{%a1, %0|%0, %a1}";
2155 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2156 return "mov{l}\t{%1, %0|%0, %1}";
2160 (cond [(eq_attr "alternative" "2")
2161 (const_string "mmx")
2162 (eq_attr "alternative" "3,4,5")
2163 (const_string "mmxmov")
2164 (eq_attr "alternative" "6")
2165 (const_string "sselog1")
2166 (eq_attr "alternative" "7,8,9,10,11")
2167 (const_string "ssemov")
2168 (match_operand:DI 1 "pic_32bit_operand" "")
2169 (const_string "lea")
2171 (const_string "imov")))
2172 (set (attr "prefix")
2173 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2174 (const_string "orig")
2175 (const_string "maybe_vex")))
2176 (set (attr "prefix_data16")
2177 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2179 (const_string "*")))
2181 (cond [(eq_attr "alternative" "2,3")
2183 (eq_attr "alternative" "6,7")
2185 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2186 (const_string "V4SF")
2187 (const_string "TI"))
2188 (and (eq_attr "alternative" "8,9,10,11")
2189 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
2192 (const_string "SI")))])
2194 (define_insn "*movhi_internal"
2195 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2196 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2197 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2199 switch (get_attr_type (insn))
2202 /* movzwl is faster than movw on p2 due to partial word stalls,
2203 though not as fast as an aligned movl. */
2204 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2206 if (get_attr_mode (insn) == MODE_SI)
2207 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2209 return "mov{w}\t{%1, %0|%0, %1}";
2213 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
2215 (const_string "imov")
2216 (and (eq_attr "alternative" "0")
2217 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2219 (eq (symbol_ref "TARGET_HIMODE_MATH")
2221 (const_string "imov")
2222 (and (eq_attr "alternative" "1,2")
2223 (match_operand:HI 1 "aligned_operand" ""))
2224 (const_string "imov")
2225 (and (ne (symbol_ref "TARGET_MOVX")
2227 (eq_attr "alternative" "0,2"))
2228 (const_string "imovx")
2230 (const_string "imov")))
2232 (cond [(eq_attr "type" "imovx")
2234 (and (eq_attr "alternative" "1,2")
2235 (match_operand:HI 1 "aligned_operand" ""))
2237 (and (eq_attr "alternative" "0")
2238 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2240 (eq (symbol_ref "TARGET_HIMODE_MATH")
2244 (const_string "HI")))])
2246 ;; Situation is quite tricky about when to choose full sized (SImode) move
2247 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2248 ;; partial register dependency machines (such as AMD Athlon), where QImode
2249 ;; moves issue extra dependency and for partial register stalls machines
2250 ;; that don't use QImode patterns (and QImode move cause stall on the next
2253 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2254 ;; register stall machines with, where we use QImode instructions, since
2255 ;; partial register stall can be caused there. Then we use movzx.
2256 (define_insn "*movqi_internal"
2257 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2258 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2259 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2261 switch (get_attr_type (insn))
2264 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2265 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2267 if (get_attr_mode (insn) == MODE_SI)
2268 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2270 return "mov{b}\t{%1, %0|%0, %1}";
2274 (cond [(and (eq_attr "alternative" "5")
2275 (not (match_operand:QI 1 "aligned_operand" "")))
2276 (const_string "imovx")
2277 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2279 (const_string "imov")
2280 (and (eq_attr "alternative" "3")
2281 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2283 (eq (symbol_ref "TARGET_QIMODE_MATH")
2285 (const_string "imov")
2286 (eq_attr "alternative" "3,5")
2287 (const_string "imovx")
2288 (and (ne (symbol_ref "TARGET_MOVX")
2290 (eq_attr "alternative" "2"))
2291 (const_string "imovx")
2293 (const_string "imov")))
2295 (cond [(eq_attr "alternative" "3,4,5")
2297 (eq_attr "alternative" "6")
2299 (eq_attr "type" "imovx")
2301 (and (eq_attr "type" "imov")
2302 (and (eq_attr "alternative" "0,1")
2303 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2305 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2307 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2310 ;; Avoid partial register stalls when not using QImode arithmetic
2311 (and (eq_attr "type" "imov")
2312 (and (eq_attr "alternative" "0,1")
2313 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2315 (eq (symbol_ref "TARGET_QIMODE_MATH")
2319 (const_string "QI")))])
2321 ;; Stores and loads of ax to arbitrary constant address.
2322 ;; We fake an second form of instruction to force reload to load address
2323 ;; into register when rax is not available
2324 (define_insn "*movabs<mode>_1"
2325 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2326 (match_operand:SWI1248x 1 "nonmemory_operand" "a,er"))]
2327 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2329 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2330 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2331 [(set_attr "type" "imov")
2332 (set_attr "modrm" "0,*")
2333 (set_attr "length_address" "8,0")
2334 (set_attr "length_immediate" "0,*")
2335 (set_attr "memory" "store")
2336 (set_attr "mode" "<MODE>")])
2338 (define_insn "*movabs<mode>_2"
2339 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2340 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2341 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2343 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2344 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2345 [(set_attr "type" "imov")
2346 (set_attr "modrm" "0,*")
2347 (set_attr "length_address" "8,0")
2348 (set_attr "length_immediate" "0")
2349 (set_attr "memory" "load")
2350 (set_attr "mode" "<MODE>")])
2352 (define_insn "*swap<mode>"
2353 [(set (match_operand:SWI48 0 "register_operand" "+r")
2354 (match_operand:SWI48 1 "register_operand" "+r"))
2358 "xchg{<imodesuffix>}\t%1, %0"
2359 [(set_attr "type" "imov")
2360 (set_attr "mode" "<MODE>")
2361 (set_attr "pent_pair" "np")
2362 (set_attr "athlon_decode" "vector")
2363 (set_attr "amdfam10_decode" "double")
2364 (set_attr "bdver1_decode" "double")])
2366 (define_insn "*swap<mode>_1"
2367 [(set (match_operand:SWI12 0 "register_operand" "+r")
2368 (match_operand:SWI12 1 "register_operand" "+r"))
2371 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2373 [(set_attr "type" "imov")
2374 (set_attr "mode" "SI")
2375 (set_attr "pent_pair" "np")
2376 (set_attr "athlon_decode" "vector")
2377 (set_attr "amdfam10_decode" "double")
2378 (set_attr "bdver1_decode" "double")])
2380 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2381 ;; is disabled for AMDFAM10
2382 (define_insn "*swap<mode>_2"
2383 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2384 (match_operand:SWI12 1 "register_operand" "+<r>"))
2387 "TARGET_PARTIAL_REG_STALL"
2388 "xchg{<imodesuffix>}\t%1, %0"
2389 [(set_attr "type" "imov")
2390 (set_attr "mode" "<MODE>")
2391 (set_attr "pent_pair" "np")
2392 (set_attr "athlon_decode" "vector")])
2394 (define_expand "movstrict<mode>"
2395 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2396 (match_operand:SWI12 1 "general_operand" ""))]
2399 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2401 /* Don't generate memory->memory moves, go through a register */
2402 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2403 operands[1] = force_reg (<MODE>mode, operands[1]);
2406 (define_insn "*movstrict<mode>_1"
2407 [(set (strict_low_part
2408 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2409 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2410 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2411 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2412 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2413 [(set_attr "type" "imov")
2414 (set_attr "mode" "<MODE>")])
2416 (define_insn "*movstrict<mode>_xor"
2417 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2418 (match_operand:SWI12 1 "const0_operand" ""))
2419 (clobber (reg:CC FLAGS_REG))]
2421 "xor{<imodesuffix>}\t%0, %0"
2422 [(set_attr "type" "alu1")
2423 (set_attr "mode" "<MODE>")
2424 (set_attr "length_immediate" "0")])
2426 (define_insn "*mov<mode>_extv_1"
2427 [(set (match_operand:SWI24 0 "register_operand" "=R")
2428 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2432 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2433 [(set_attr "type" "imovx")
2434 (set_attr "mode" "SI")])
2436 (define_insn "*movqi_extv_1_rex64"
2437 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2438 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2443 switch (get_attr_type (insn))
2446 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2448 return "mov{b}\t{%h1, %0|%0, %h1}";
2452 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2453 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2454 (ne (symbol_ref "TARGET_MOVX")
2456 (const_string "imovx")
2457 (const_string "imov")))
2459 (if_then_else (eq_attr "type" "imovx")
2461 (const_string "QI")))])
2463 (define_insn "*movqi_extv_1"
2464 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2465 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2470 switch (get_attr_type (insn))
2473 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2475 return "mov{b}\t{%h1, %0|%0, %h1}";
2479 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2480 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2481 (ne (symbol_ref "TARGET_MOVX")
2483 (const_string "imovx")
2484 (const_string "imov")))
2486 (if_then_else (eq_attr "type" "imovx")
2488 (const_string "QI")))])
2490 (define_insn "*mov<mode>_extzv_1"
2491 [(set (match_operand:SWI48 0 "register_operand" "=R")
2492 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2496 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2497 [(set_attr "type" "imovx")
2498 (set_attr "mode" "SI")])
2500 (define_insn "*movqi_extzv_2_rex64"
2501 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2503 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2508 switch (get_attr_type (insn))
2511 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2513 return "mov{b}\t{%h1, %0|%0, %h1}";
2517 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2518 (ne (symbol_ref "TARGET_MOVX")
2520 (const_string "imovx")
2521 (const_string "imov")))
2523 (if_then_else (eq_attr "type" "imovx")
2525 (const_string "QI")))])
2527 (define_insn "*movqi_extzv_2"
2528 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2530 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2535 switch (get_attr_type (insn))
2538 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2540 return "mov{b}\t{%h1, %0|%0, %h1}";
2544 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2545 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2546 (ne (symbol_ref "TARGET_MOVX")
2548 (const_string "imovx")
2549 (const_string "imov")))
2551 (if_then_else (eq_attr "type" "imovx")
2553 (const_string "QI")))])
2555 (define_expand "mov<mode>_insv_1"
2556 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2559 (match_operand:SWI48 1 "nonmemory_operand" ""))])
2561 (define_insn "*mov<mode>_insv_1_rex64"
2562 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2565 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2567 "mov{b}\t{%b1, %h0|%h0, %b1}"
2568 [(set_attr "type" "imov")
2569 (set_attr "mode" "QI")])
2571 (define_insn "*movsi_insv_1"
2572 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2575 (match_operand:SI 1 "general_operand" "Qmn"))]
2577 "mov{b}\t{%b1, %h0|%h0, %b1}"
2578 [(set_attr "type" "imov")
2579 (set_attr "mode" "QI")])
2581 (define_insn "*movqi_insv_2"
2582 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2585 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2588 "mov{b}\t{%h1, %h0|%h0, %h1}"
2589 [(set_attr "type" "imov")
2590 (set_attr "mode" "QI")])
2592 ;; Floating point push instructions.
2594 (define_insn "*pushtf"
2595 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2596 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2599 /* This insn should be already split before reg-stack. */
2602 [(set_attr "type" "multi")
2603 (set_attr "unit" "sse,*,*")
2604 (set_attr "mode" "TF,SI,SI")])
2607 [(set (match_operand:TF 0 "push_operand" "")
2608 (match_operand:TF 1 "sse_reg_operand" ""))]
2609 "TARGET_SSE2 && reload_completed"
2610 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2611 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2614 [(set (match_operand:TF 0 "push_operand" "")
2615 (match_operand:TF 1 "general_operand" ""))]
2616 "TARGET_SSE2 && reload_completed
2617 && !SSE_REG_P (operands[1])"
2619 "ix86_split_long_move (operands); DONE;")
2621 (define_insn "*pushxf"
2622 [(set (match_operand:XF 0 "push_operand" "=<,<")
2623 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2624 "optimize_function_for_speed_p (cfun)"
2626 /* This insn should be already split before reg-stack. */
2629 [(set_attr "type" "multi")
2630 (set_attr "unit" "i387,*")
2631 (set_attr "mode" "XF,SI")])
2633 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2634 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2635 ;; Pushing using integer instructions is longer except for constants
2636 ;; and direct memory references (assuming that any given constant is pushed
2637 ;; only once, but this ought to be handled elsewhere).
2639 (define_insn "*pushxf_nointeger"
2640 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
2641 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
2642 "optimize_function_for_size_p (cfun)"
2644 /* This insn should be already split before reg-stack. */
2647 [(set_attr "type" "multi")
2648 (set_attr "unit" "i387,*,*")
2649 (set_attr "mode" "XF,SI,SI")])
2652 [(set (match_operand:XF 0 "push_operand" "")
2653 (match_operand:XF 1 "fp_register_operand" ""))]
2655 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2656 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2657 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2660 [(set (match_operand:XF 0 "push_operand" "")
2661 (match_operand:XF 1 "general_operand" ""))]
2663 && !FP_REG_P (operands[1])"
2665 "ix86_split_long_move (operands); DONE;")
2667 (define_insn "*pushdf"
2668 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2669 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,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,DF")])
2679 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2680 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2681 ;; On the average, pushdf using integers can be still shorter. Allow this
2682 ;; pattern for optimize_size too.
2684 (define_insn "*pushdf_nointeger"
2685 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2686 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2687 "!(TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES)"
2689 /* This insn should be already split before reg-stack. */
2692 [(set_attr "type" "multi")
2693 (set_attr "unit" "i387,*,*,*")
2694 (set_attr "mode" "DF,SI,SI,DF")])
2696 ;; %%% Kill this when call knows how to work this out.
2698 [(set (match_operand:DF 0 "push_operand" "")
2699 (match_operand:DF 1 "any_fp_register_operand" ""))]
2701 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2702 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2705 [(set (match_operand:DF 0 "push_operand" "")
2706 (match_operand:DF 1 "general_operand" ""))]
2708 && !ANY_FP_REG_P (operands[1])"
2710 "ix86_split_long_move (operands); DONE;")
2712 (define_insn "*pushsf_rex64"
2713 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2714 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2717 /* Anything else should be already split before reg-stack. */
2718 gcc_assert (which_alternative == 1);
2719 return "push{q}\t%q1";
2721 [(set_attr "type" "multi,push,multi")
2722 (set_attr "unit" "i387,*,*")
2723 (set_attr "mode" "SF,DI,SF")])
2725 (define_insn "*pushsf"
2726 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2727 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2730 /* Anything else should be already split before reg-stack. */
2731 gcc_assert (which_alternative == 1);
2732 return "push{l}\t%1";
2734 [(set_attr "type" "multi,push,multi")
2735 (set_attr "unit" "i387,*,*")
2736 (set_attr "mode" "SF,SI,SF")])
2739 [(set (match_operand:SF 0 "push_operand" "")
2740 (match_operand:SF 1 "memory_operand" ""))]
2742 && MEM_P (operands[1])
2743 && (operands[2] = find_constant_src (insn))"
2747 ;; %%% Kill this when call knows how to work this out.
2749 [(set (match_operand:SF 0 "push_operand" "")
2750 (match_operand:SF 1 "any_fp_register_operand" ""))]
2752 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2753 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2754 "operands[2] = GEN_INT (-GET_MODE_SIZE (<MODE>mode));")
2756 ;; Floating point move instructions.
2758 (define_expand "movtf"
2759 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2760 (match_operand:TF 1 "nonimmediate_operand" ""))]
2763 ix86_expand_move (TFmode, operands);
2767 (define_expand "mov<mode>"
2768 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2769 (match_operand:X87MODEF 1 "general_operand" ""))]
2771 "ix86_expand_move (<MODE>mode, operands); DONE;")
2773 (define_insn "*movtf_internal"
2774 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
2775 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
2777 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2779 switch (which_alternative)
2783 if (get_attr_mode (insn) == MODE_V4SF)
2784 return "%vmovaps\t{%1, %0|%0, %1}";
2786 return "%vmovdqa\t{%1, %0|%0, %1}";
2788 if (get_attr_mode (insn) == MODE_V4SF)
2789 return "%vxorps\t%0, %d0";
2791 return "%vpxor\t%0, %d0";
2799 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2800 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2802 (cond [(eq_attr "alternative" "0,2")
2804 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2806 (const_string "V4SF")
2807 (const_string "TI"))
2808 (eq_attr "alternative" "1")
2810 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2812 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2814 (const_string "V4SF")
2815 (const_string "TI"))]
2816 (const_string "DI")))])
2819 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2820 (match_operand:TF 1 "general_operand" ""))]
2822 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
2824 "ix86_split_long_move (operands); DONE;")
2826 (define_insn "*movxf_internal"
2827 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
2828 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
2829 "optimize_function_for_speed_p (cfun)
2830 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2831 && (reload_in_progress || reload_completed
2832 || GET_CODE (operands[1]) != CONST_DOUBLE
2833 || memory_operand (operands[0], XFmode))"
2835 switch (which_alternative)
2839 return output_387_reg_move (insn, operands);
2842 return standard_80387_constant_opcode (operands[1]);
2851 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2852 (set_attr "mode" "XF,XF,XF,SI,SI")])
2854 ;; Do not use integer registers when optimizing for size
2855 (define_insn "*movxf_internal_nointeger"
2856 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
2857 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
2858 "optimize_function_for_size_p (cfun)
2859 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2860 && (reload_in_progress || reload_completed
2861 || standard_80387_constant_p (operands[1])
2862 || GET_CODE (operands[1]) != CONST_DOUBLE
2863 || memory_operand (operands[0], XFmode))"
2865 switch (which_alternative)
2869 return output_387_reg_move (insn, operands);
2872 return standard_80387_constant_opcode (operands[1]);
2880 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2881 (set_attr "mode" "XF,XF,XF,SI,SI")])
2884 [(set (match_operand:XF 0 "nonimmediate_operand" "")
2885 (match_operand:XF 1 "general_operand" ""))]
2887 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2888 && ! (FP_REG_P (operands[0]) ||
2889 (GET_CODE (operands[0]) == SUBREG
2890 && FP_REG_P (SUBREG_REG (operands[0]))))
2891 && ! (FP_REG_P (operands[1]) ||
2892 (GET_CODE (operands[1]) == SUBREG
2893 && FP_REG_P (SUBREG_REG (operands[1]))))"
2895 "ix86_split_long_move (operands); DONE;")
2897 (define_insn "*movdf_internal_rex64"
2898 [(set (match_operand:DF 0 "nonimmediate_operand"
2899 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
2900 (match_operand:DF 1 "general_operand"
2901 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
2902 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2903 && (reload_in_progress || reload_completed
2904 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2905 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
2906 && optimize_function_for_size_p (cfun)
2907 && standard_80387_constant_p (operands[1]))
2908 || GET_CODE (operands[1]) != CONST_DOUBLE
2909 || memory_operand (operands[0], DFmode))"
2911 switch (which_alternative)
2915 return output_387_reg_move (insn, operands);
2918 return standard_80387_constant_opcode (operands[1]);
2925 switch (get_attr_mode (insn))
2928 return "%vxorps\t%0, %d0";
2930 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2931 return "%vxorps\t%0, %d0";
2933 return "%vxorpd\t%0, %d0";
2935 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2936 return "%vxorps\t%0, %d0";
2938 return "%vpxor\t%0, %d0";
2945 switch (get_attr_mode (insn))
2948 return "%vmovaps\t{%1, %0|%0, %1}";
2950 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2951 return "%vmovaps\t{%1, %0|%0, %1}";
2953 return "%vmovapd\t{%1, %0|%0, %1}";
2955 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2956 return "%vmovaps\t{%1, %0|%0, %1}";
2958 return "%vmovdqa\t{%1, %0|%0, %1}";
2960 return "%vmovq\t{%1, %0|%0, %1}";
2964 if (REG_P (operands[0]) && REG_P (operands[1]))
2965 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2967 return "vmovsd\t{%1, %0|%0, %1}";
2970 return "movsd\t{%1, %0|%0, %1}";
2972 return "%vmovlpd\t{%1, %d0|%d0, %1}";
2974 return "%vmovlps\t{%1, %d0|%d0, %1}";
2981 return "%vmovd\t{%1, %0|%0, %1}";
2987 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
2988 (set (attr "prefix")
2989 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
2990 (const_string "orig")
2991 (const_string "maybe_vex")))
2992 (set (attr "prefix_data16")
2993 (if_then_else (eq_attr "mode" "V1DF")
2995 (const_string "*")))
2997 (cond [(eq_attr "alternative" "0,1,2")
2999 (eq_attr "alternative" "3,4,9,10")
3002 /* For SSE1, we have many fewer alternatives. */
3003 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3004 (cond [(eq_attr "alternative" "5,6")
3005 (const_string "V4SF")
3007 (const_string "V2SF"))
3009 /* xorps is one byte shorter. */
3010 (eq_attr "alternative" "5")
3011 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3013 (const_string "V4SF")
3014 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3018 (const_string "V2DF"))
3020 /* For architectures resolving dependencies on
3021 whole SSE registers use APD move to break dependency
3022 chains, otherwise use short move to avoid extra work.
3024 movaps encodes one byte shorter. */
3025 (eq_attr "alternative" "6")
3027 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3029 (const_string "V4SF")
3030 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3032 (const_string "V2DF")
3034 (const_string "DF"))
3035 /* For architectures resolving dependencies on register
3036 parts we may avoid extra work to zero out upper part
3038 (eq_attr "alternative" "7")
3040 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3042 (const_string "V1DF")
3043 (const_string "DF"))
3045 (const_string "DF")))])
3047 (define_insn "*movdf_internal"
3048 [(set (match_operand:DF 0 "nonimmediate_operand"
3049 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3050 (match_operand:DF 1 "general_operand"
3051 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3052 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3053 && optimize_function_for_speed_p (cfun)
3054 && TARGET_INTEGER_DFMODE_MOVES
3055 && (reload_in_progress || reload_completed
3056 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3057 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3058 && optimize_function_for_size_p (cfun)
3059 && standard_80387_constant_p (operands[1]))
3060 || GET_CODE (operands[1]) != CONST_DOUBLE
3061 || memory_operand (operands[0], DFmode))"
3063 switch (which_alternative)
3067 return output_387_reg_move (insn, operands);
3070 return standard_80387_constant_opcode (operands[1]);
3077 switch (get_attr_mode (insn))
3080 return "xorps\t%0, %0";
3082 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3083 return "xorps\t%0, %0";
3085 return "xorpd\t%0, %0";
3087 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3088 return "xorps\t%0, %0";
3090 return "pxor\t%0, %0";
3097 switch (get_attr_mode (insn))
3100 return "movaps\t{%1, %0|%0, %1}";
3102 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3103 return "movaps\t{%1, %0|%0, %1}";
3105 return "movapd\t{%1, %0|%0, %1}";
3107 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3108 return "movaps\t{%1, %0|%0, %1}";
3110 return "movdqa\t{%1, %0|%0, %1}";
3112 return "movq\t{%1, %0|%0, %1}";
3114 return "movsd\t{%1, %0|%0, %1}";
3116 return "movlpd\t{%1, %0|%0, %1}";
3118 return "movlps\t{%1, %0|%0, %1}";
3127 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3128 (set (attr "prefix_data16")
3129 (if_then_else (eq_attr "mode" "V1DF")
3131 (const_string "*")))
3133 (cond [(eq_attr "alternative" "0,1,2")
3135 (eq_attr "alternative" "3,4")
3138 /* For SSE1, we have many fewer alternatives. */
3139 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3140 (cond [(eq_attr "alternative" "5,6")
3141 (const_string "V4SF")
3143 (const_string "V2SF"))
3145 /* xorps is one byte shorter. */
3146 (eq_attr "alternative" "5")
3147 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3149 (const_string "V4SF")
3150 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3154 (const_string "V2DF"))
3156 /* For architectures resolving dependencies on
3157 whole SSE registers use APD move to break dependency
3158 chains, otherwise use short move to avoid extra work.
3160 movaps encodes one byte shorter. */
3161 (eq_attr "alternative" "6")
3163 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3165 (const_string "V4SF")
3166 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3168 (const_string "V2DF")
3170 (const_string "DF"))
3171 /* For architectures resolving dependencies on register
3172 parts we may avoid extra work to zero out upper part
3174 (eq_attr "alternative" "7")
3176 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3178 (const_string "V1DF")
3179 (const_string "DF"))
3181 (const_string "DF")))])
3183 ;; Moving is usually shorter when only FP registers are used. This separate
3184 ;; movdf pattern avoids the use of integer registers for FP operations
3185 ;; when optimizing for size.
3187 (define_insn "*movdf_internal_nointeger"
3188 [(set (match_operand:DF 0 "nonimmediate_operand"
3189 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
3190 (match_operand:DF 1 "general_operand"
3191 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
3192 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3193 && ((optimize_function_for_size_p (cfun)
3194 || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3195 && (reload_in_progress || reload_completed
3196 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3197 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3198 && optimize_function_for_size_p (cfun)
3199 && !memory_operand (operands[0], DFmode)
3200 && standard_80387_constant_p (operands[1]))
3201 || GET_CODE (operands[1]) != CONST_DOUBLE
3202 || ((optimize_function_for_size_p (cfun)
3203 || !TARGET_MEMORY_MISMATCH_STALL
3204 || reload_in_progress || reload_completed)
3205 && memory_operand (operands[0], DFmode)))"
3207 switch (which_alternative)
3211 return output_387_reg_move (insn, operands);
3214 return standard_80387_constant_opcode (operands[1]);
3221 switch (get_attr_mode (insn))
3224 return "%vxorps\t%0, %d0";
3226 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3227 return "%vxorps\t%0, %d0";
3229 return "%vxorpd\t%0, %d0";
3231 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3232 return "%vxorps\t%0, %d0";
3234 return "%vpxor\t%0, %d0";
3241 switch (get_attr_mode (insn))
3244 return "%vmovaps\t{%1, %0|%0, %1}";
3246 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3247 return "%vmovaps\t{%1, %0|%0, %1}";
3249 return "%vmovapd\t{%1, %0|%0, %1}";
3251 if (TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3252 return "%vmovaps\t{%1, %0|%0, %1}";
3254 return "%vmovdqa\t{%1, %0|%0, %1}";
3256 return "%vmovq\t{%1, %0|%0, %1}";
3260 if (REG_P (operands[0]) && REG_P (operands[1]))
3261 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3263 return "vmovsd\t{%1, %0|%0, %1}";
3266 return "movsd\t{%1, %0|%0, %1}";
3270 if (REG_P (operands[0]))
3271 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3273 return "vmovlpd\t{%1, %0|%0, %1}";
3276 return "movlpd\t{%1, %0|%0, %1}";
3280 if (REG_P (operands[0]))
3281 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3283 return "vmovlps\t{%1, %0|%0, %1}";
3286 return "movlps\t{%1, %0|%0, %1}";
3295 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3296 (set (attr "prefix")
3297 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3298 (const_string "orig")
3299 (const_string "maybe_vex")))
3300 (set (attr "prefix_data16")
3301 (if_then_else (eq_attr "mode" "V1DF")
3303 (const_string "*")))
3305 (cond [(eq_attr "alternative" "0,1,2")
3307 (eq_attr "alternative" "3,4")
3310 /* For SSE1, we have many fewer alternatives. */
3311 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3312 (cond [(eq_attr "alternative" "5,6")
3313 (const_string "V4SF")
3315 (const_string "V2SF"))
3317 /* xorps is one byte shorter. */
3318 (eq_attr "alternative" "5")
3319 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3321 (const_string "V4SF")
3322 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3326 (const_string "V2DF"))
3328 /* For architectures resolving dependencies on
3329 whole SSE registers use APD move to break dependency
3330 chains, otherwise use short move to avoid extra work.
3332 movaps encodes one byte shorter. */
3333 (eq_attr "alternative" "6")
3335 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3337 (const_string "V4SF")
3338 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3340 (const_string "V2DF")
3342 (const_string "DF"))
3343 /* For architectures resolving dependencies on register
3344 parts we may avoid extra work to zero out upper part
3346 (eq_attr "alternative" "7")
3348 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3350 (const_string "V1DF")
3351 (const_string "DF"))
3353 (const_string "DF")))])
3356 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3357 (match_operand:DF 1 "general_operand" ""))]
3359 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3360 && ! (ANY_FP_REG_P (operands[0]) ||
3361 (GET_CODE (operands[0]) == SUBREG
3362 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3363 && ! (ANY_FP_REG_P (operands[1]) ||
3364 (GET_CODE (operands[1]) == SUBREG
3365 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3367 "ix86_split_long_move (operands); DONE;")
3369 (define_insn "*movsf_internal"
3370 [(set (match_operand:SF 0 "nonimmediate_operand"
3371 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3372 (match_operand:SF 1 "general_operand"
3373 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3374 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3375 && (reload_in_progress || reload_completed
3376 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3377 || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
3378 && standard_80387_constant_p (operands[1]))
3379 || GET_CODE (operands[1]) != CONST_DOUBLE
3380 || memory_operand (operands[0], SFmode))"
3382 switch (which_alternative)
3386 return output_387_reg_move (insn, operands);
3389 return standard_80387_constant_opcode (operands[1]);
3393 return "mov{l}\t{%1, %0|%0, %1}";
3395 if (get_attr_mode (insn) == MODE_TI)
3396 return "%vpxor\t%0, %d0";
3398 return "%vxorps\t%0, %d0";
3400 if (get_attr_mode (insn) == MODE_V4SF)
3401 return "%vmovaps\t{%1, %0|%0, %1}";
3403 return "%vmovss\t{%1, %d0|%d0, %1}";
3406 return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
3407 : "vmovss\t{%1, %0|%0, %1}";
3409 return "movss\t{%1, %0|%0, %1}";
3411 return "%vmovss\t{%1, %0|%0, %1}";
3413 case 9: case 10: case 14: case 15:
3414 return "movd\t{%1, %0|%0, %1}";
3416 return "%vmovd\t{%1, %0|%0, %1}";
3419 return "movq\t{%1, %0|%0, %1}";
3425 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3426 (set (attr "prefix")
3427 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3428 (const_string "maybe_vex")
3429 (const_string "orig")))
3431 (cond [(eq_attr "alternative" "3,4,9,10")
3433 (eq_attr "alternative" "5")
3435 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3437 (ne (symbol_ref "TARGET_SSE2")
3439 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3442 (const_string "V4SF"))
3443 /* For architectures resolving dependencies on
3444 whole SSE registers use APS move to break dependency
3445 chains, otherwise use short move to avoid extra work.
3447 Do the same for architectures resolving dependencies on
3448 the parts. While in DF mode it is better to always handle
3449 just register parts, the SF mode is different due to lack
3450 of instructions to load just part of the register. It is
3451 better to maintain the whole registers in single format
3452 to avoid problems on using packed logical operations. */
3453 (eq_attr "alternative" "6")
3455 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3457 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3459 (const_string "V4SF")
3460 (const_string "SF"))
3461 (eq_attr "alternative" "11")
3462 (const_string "DI")]
3463 (const_string "SF")))])
3466 [(set (match_operand 0 "register_operand" "")
3467 (match_operand 1 "memory_operand" ""))]
3469 && MEM_P (operands[1])
3470 && (GET_MODE (operands[0]) == TFmode
3471 || GET_MODE (operands[0]) == XFmode
3472 || GET_MODE (operands[0]) == DFmode
3473 || GET_MODE (operands[0]) == SFmode)
3474 && (operands[2] = find_constant_src (insn))"
3475 [(set (match_dup 0) (match_dup 2))]
3477 rtx c = operands[2];
3478 rtx r = operands[0];
3480 if (GET_CODE (r) == SUBREG)
3485 if (!standard_sse_constant_p (c))
3488 else if (FP_REG_P (r))
3490 if (!standard_80387_constant_p (c))
3493 else if (MMX_REG_P (r))
3498 [(set (match_operand 0 "register_operand" "")
3499 (float_extend (match_operand 1 "memory_operand" "")))]
3501 && MEM_P (operands[1])
3502 && (GET_MODE (operands[0]) == TFmode
3503 || GET_MODE (operands[0]) == XFmode
3504 || GET_MODE (operands[0]) == DFmode
3505 || GET_MODE (operands[0]) == SFmode)
3506 && (operands[2] = find_constant_src (insn))"
3507 [(set (match_dup 0) (match_dup 2))]
3509 rtx c = operands[2];
3510 rtx r = operands[0];
3512 if (GET_CODE (r) == SUBREG)
3517 if (!standard_sse_constant_p (c))
3520 else if (FP_REG_P (r))
3522 if (!standard_80387_constant_p (c))
3525 else if (MMX_REG_P (r))
3529 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3531 [(set (match_operand:X87MODEF 0 "register_operand" "")
3532 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3533 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3534 && (standard_80387_constant_p (operands[1]) == 8
3535 || standard_80387_constant_p (operands[1]) == 9)"
3536 [(set (match_dup 0)(match_dup 1))
3538 (neg:X87MODEF (match_dup 0)))]
3542 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3543 if (real_isnegzero (&r))
3544 operands[1] = CONST0_RTX (<MODE>mode);
3546 operands[1] = CONST1_RTX (<MODE>mode);
3549 (define_insn "swapxf"
3550 [(set (match_operand:XF 0 "register_operand" "+f")
3551 (match_operand:XF 1 "register_operand" "+f"))
3556 if (STACK_TOP_P (operands[0]))
3561 [(set_attr "type" "fxch")
3562 (set_attr "mode" "XF")])
3564 (define_insn "*swap<mode>"
3565 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3566 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3569 "TARGET_80387 || reload_completed"
3571 if (STACK_TOP_P (operands[0]))
3576 [(set_attr "type" "fxch")
3577 (set_attr "mode" "<MODE>")])
3579 ;; Zero extension instructions
3581 (define_expand "zero_extendsidi2"
3582 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3583 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3588 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3593 (define_insn "*zero_extendsidi2_rex64"
3594 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3596 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3599 mov\t{%k1, %k0|%k0, %k1}
3601 movd\t{%1, %0|%0, %1}
3602 movd\t{%1, %0|%0, %1}
3603 %vmovd\t{%1, %0|%0, %1}
3604 %vmovd\t{%1, %0|%0, %1}"
3605 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3606 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3607 (set_attr "prefix_0f" "0,*,*,*,*,*")
3608 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3611 [(set (match_operand:DI 0 "memory_operand" "")
3612 (zero_extend:DI (match_dup 0)))]
3614 [(set (match_dup 4) (const_int 0))]
3615 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3617 ;; %%% Kill me once multi-word ops are sane.
3618 (define_insn "zero_extendsidi2_1"
3619 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3621 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3622 (clobber (reg:CC FLAGS_REG))]
3628 movd\t{%1, %0|%0, %1}
3629 movd\t{%1, %0|%0, %1}
3630 %vmovd\t{%1, %0|%0, %1}
3631 %vmovd\t{%1, %0|%0, %1}"
3632 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3633 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3634 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3637 [(set (match_operand:DI 0 "register_operand" "")
3638 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3639 (clobber (reg:CC FLAGS_REG))]
3640 "!TARGET_64BIT && reload_completed
3641 && true_regnum (operands[0]) == true_regnum (operands[1])"
3642 [(set (match_dup 4) (const_int 0))]
3643 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3646 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3647 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3648 (clobber (reg:CC FLAGS_REG))]
3649 "!TARGET_64BIT && reload_completed
3650 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3651 [(set (match_dup 3) (match_dup 1))
3652 (set (match_dup 4) (const_int 0))]
3653 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3655 (define_insn "zero_extend<mode>di2"
3656 [(set (match_operand:DI 0 "register_operand" "=r")
3658 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3660 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3661 [(set_attr "type" "imovx")
3662 (set_attr "mode" "SI")])
3664 (define_expand "zero_extendhisi2"
3665 [(set (match_operand:SI 0 "register_operand" "")
3666 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3669 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3671 operands[1] = force_reg (HImode, operands[1]);
3672 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3677 (define_insn_and_split "zero_extendhisi2_and"
3678 [(set (match_operand:SI 0 "register_operand" "=r")
3679 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3680 (clobber (reg:CC FLAGS_REG))]
3681 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3683 "&& reload_completed"
3684 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3685 (clobber (reg:CC FLAGS_REG))])]
3687 [(set_attr "type" "alu1")
3688 (set_attr "mode" "SI")])
3690 (define_insn "*zero_extendhisi2_movzwl"
3691 [(set (match_operand:SI 0 "register_operand" "=r")
3692 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3693 "!TARGET_ZERO_EXTEND_WITH_AND
3694 || optimize_function_for_size_p (cfun)"
3695 "movz{wl|x}\t{%1, %0|%0, %1}"
3696 [(set_attr "type" "imovx")
3697 (set_attr "mode" "SI")])
3699 (define_expand "zero_extendqi<mode>2"
3701 [(set (match_operand:SWI24 0 "register_operand" "")
3702 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3703 (clobber (reg:CC FLAGS_REG))])])
3705 (define_insn "*zero_extendqi<mode>2_and"
3706 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3707 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3708 (clobber (reg:CC FLAGS_REG))]
3709 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3711 [(set_attr "type" "alu1")
3712 (set_attr "mode" "<MODE>")])
3714 ;; When source and destination does not overlap, clear destination
3715 ;; first and then do the movb
3717 [(set (match_operand:SWI24 0 "register_operand" "")
3718 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3719 (clobber (reg:CC FLAGS_REG))]
3721 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3722 && ANY_QI_REG_P (operands[0])
3723 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3724 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3725 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3727 operands[2] = gen_lowpart (QImode, operands[0]);
3728 ix86_expand_clear (operands[0]);
3731 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3732 [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3733 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3734 (clobber (reg:CC FLAGS_REG))]
3735 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3737 [(set_attr "type" "imovx,alu1")
3738 (set_attr "mode" "<MODE>")])
3740 ;; For the movzbl case strip only the clobber
3742 [(set (match_operand:SWI24 0 "register_operand" "")
3743 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3744 (clobber (reg:CC FLAGS_REG))]
3746 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3747 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3749 (zero_extend:SWI24 (match_dup 1)))])
3751 ; zero extend to SImode to avoid partial register stalls
3752 (define_insn "*zero_extendqi<mode>2_movzbl"
3753 [(set (match_operand:SWI24 0 "register_operand" "=r")
3754 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3756 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3757 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3758 [(set_attr "type" "imovx")
3759 (set_attr "mode" "SI")])
3761 ;; Rest is handled by single and.
3763 [(set (match_operand:SWI24 0 "register_operand" "")
3764 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3765 (clobber (reg:CC FLAGS_REG))]
3767 && true_regnum (operands[0]) == true_regnum (operands[1])"
3768 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3769 (clobber (reg:CC FLAGS_REG))])])
3771 ;; Sign extension instructions
3773 (define_expand "extendsidi2"
3774 [(set (match_operand:DI 0 "register_operand" "")
3775 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3780 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3785 (define_insn "*extendsidi2_rex64"
3786 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3787 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3791 movs{lq|x}\t{%1, %0|%0, %1}"
3792 [(set_attr "type" "imovx")
3793 (set_attr "mode" "DI")
3794 (set_attr "prefix_0f" "0")
3795 (set_attr "modrm" "0,1")])
3797 (define_insn "extendsidi2_1"
3798 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3799 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3800 (clobber (reg:CC FLAGS_REG))
3801 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3805 ;; Extend to memory case when source register does 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" ""))]
3812 && dead_or_set_p (insn, operands[1])
3813 && !reg_mentioned_p (operands[1], operands[0]))"
3814 [(set (match_dup 3) (match_dup 1))
3815 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3816 (clobber (reg:CC FLAGS_REG))])
3817 (set (match_dup 4) (match_dup 1))]
3818 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3820 ;; Extend to memory case when source register does not die.
3822 [(set (match_operand:DI 0 "memory_operand" "")
3823 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3824 (clobber (reg:CC FLAGS_REG))
3825 (clobber (match_operand:SI 2 "register_operand" ""))]
3829 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3831 emit_move_insn (operands[3], operands[1]);
3833 /* Generate a cltd if possible and doing so it profitable. */
3834 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3835 && true_regnum (operands[1]) == AX_REG
3836 && true_regnum (operands[2]) == DX_REG)
3838 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3842 emit_move_insn (operands[2], operands[1]);
3843 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3845 emit_move_insn (operands[4], operands[2]);
3849 ;; Extend to register case. Optimize case where source and destination
3850 ;; registers match and cases where we can use cltd.
3852 [(set (match_operand:DI 0 "register_operand" "")
3853 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3854 (clobber (reg:CC FLAGS_REG))
3855 (clobber (match_scratch:SI 2 ""))]
3859 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3861 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3862 emit_move_insn (operands[3], operands[1]);
3864 /* Generate a cltd if possible and doing so it profitable. */
3865 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3866 && true_regnum (operands[3]) == AX_REG
3867 && true_regnum (operands[4]) == DX_REG)
3869 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3873 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3874 emit_move_insn (operands[4], operands[1]);
3876 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3880 (define_insn "extend<mode>di2"
3881 [(set (match_operand:DI 0 "register_operand" "=r")
3883 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3885 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3886 [(set_attr "type" "imovx")
3887 (set_attr "mode" "DI")])
3889 (define_insn "extendhisi2"
3890 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3891 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3894 switch (get_attr_prefix_0f (insn))
3897 return "{cwtl|cwde}";
3899 return "movs{wl|x}\t{%1, %0|%0, %1}";
3902 [(set_attr "type" "imovx")
3903 (set_attr "mode" "SI")
3904 (set (attr "prefix_0f")
3905 ;; movsx is short decodable while cwtl is vector decoded.
3906 (if_then_else (and (eq_attr "cpu" "!k6")
3907 (eq_attr "alternative" "0"))
3909 (const_string "1")))
3911 (if_then_else (eq_attr "prefix_0f" "0")
3913 (const_string "1")))])
3915 (define_insn "*extendhisi2_zext"
3916 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3919 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3922 switch (get_attr_prefix_0f (insn))
3925 return "{cwtl|cwde}";
3927 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3930 [(set_attr "type" "imovx")
3931 (set_attr "mode" "SI")
3932 (set (attr "prefix_0f")
3933 ;; movsx is short decodable while cwtl is vector decoded.
3934 (if_then_else (and (eq_attr "cpu" "!k6")
3935 (eq_attr "alternative" "0"))
3937 (const_string "1")))
3939 (if_then_else (eq_attr "prefix_0f" "0")
3941 (const_string "1")))])
3943 (define_insn "extendqisi2"
3944 [(set (match_operand:SI 0 "register_operand" "=r")
3945 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3947 "movs{bl|x}\t{%1, %0|%0, %1}"
3948 [(set_attr "type" "imovx")
3949 (set_attr "mode" "SI")])
3951 (define_insn "*extendqisi2_zext"
3952 [(set (match_operand:DI 0 "register_operand" "=r")
3954 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3956 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3957 [(set_attr "type" "imovx")
3958 (set_attr "mode" "SI")])
3960 (define_insn "extendqihi2"
3961 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3962 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3965 switch (get_attr_prefix_0f (insn))
3968 return "{cbtw|cbw}";
3970 return "movs{bw|x}\t{%1, %0|%0, %1}";
3973 [(set_attr "type" "imovx")
3974 (set_attr "mode" "HI")
3975 (set (attr "prefix_0f")
3976 ;; movsx is short decodable while cwtl is vector decoded.
3977 (if_then_else (and (eq_attr "cpu" "!k6")
3978 (eq_attr "alternative" "0"))
3980 (const_string "1")))
3982 (if_then_else (eq_attr "prefix_0f" "0")
3984 (const_string "1")))])
3986 ;; Conversions between float and double.
3988 ;; These are all no-ops in the model used for the 80387.
3989 ;; So just emit moves.
3991 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3993 [(set (match_operand:DF 0 "push_operand" "")
3994 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3996 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3997 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4000 [(set (match_operand:XF 0 "push_operand" "")
4001 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
4003 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4004 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4005 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
4007 (define_expand "extendsfdf2"
4008 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4009 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4010 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4012 /* ??? Needed for compress_float_constant since all fp constants
4013 are LEGITIMATE_CONSTANT_P. */
4014 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4016 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4017 && standard_80387_constant_p (operands[1]) > 0)
4019 operands[1] = simplify_const_unary_operation
4020 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4021 emit_move_insn_1 (operands[0], operands[1]);
4024 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4028 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4030 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4032 We do the conversion post reload to avoid producing of 128bit spills
4033 that might lead to ICE on 32bit target. The sequence unlikely combine
4036 [(set (match_operand:DF 0 "register_operand" "")
4038 (match_operand:SF 1 "nonimmediate_operand" "")))]
4039 "TARGET_USE_VECTOR_FP_CONVERTS
4040 && optimize_insn_for_speed_p ()
4041 && reload_completed && SSE_REG_P (operands[0])"
4046 (parallel [(const_int 0) (const_int 1)]))))]
4048 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4049 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4050 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4051 Try to avoid move when unpacking can be done in source. */
4052 if (REG_P (operands[1]))
4054 /* If it is unsafe to overwrite upper half of source, we need
4055 to move to destination and unpack there. */
4056 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4057 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4058 && true_regnum (operands[0]) != true_regnum (operands[1]))
4060 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4061 emit_move_insn (tmp, operands[1]);
4064 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4065 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4069 emit_insn (gen_vec_setv4sf_0 (operands[3],
4070 CONST0_RTX (V4SFmode), operands[1]));
4073 (define_insn "*extendsfdf2_mixed"
4074 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4076 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4077 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4079 switch (which_alternative)
4083 return output_387_reg_move (insn, operands);
4086 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4092 [(set_attr "type" "fmov,fmov,ssecvt")
4093 (set_attr "prefix" "orig,orig,maybe_vex")
4094 (set_attr "mode" "SF,XF,DF")])
4096 (define_insn "*extendsfdf2_sse"
4097 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4098 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4099 "TARGET_SSE2 && TARGET_SSE_MATH"
4100 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4101 [(set_attr "type" "ssecvt")
4102 (set_attr "prefix" "maybe_vex")
4103 (set_attr "mode" "DF")])
4105 (define_insn "*extendsfdf2_i387"
4106 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4107 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4109 "* return output_387_reg_move (insn, operands);"
4110 [(set_attr "type" "fmov")
4111 (set_attr "mode" "SF,XF")])
4113 (define_expand "extend<mode>xf2"
4114 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4115 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4118 /* ??? Needed for compress_float_constant since all fp constants
4119 are LEGITIMATE_CONSTANT_P. */
4120 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4122 if (standard_80387_constant_p (operands[1]) > 0)
4124 operands[1] = simplify_const_unary_operation
4125 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4126 emit_move_insn_1 (operands[0], operands[1]);
4129 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4133 (define_insn "*extend<mode>xf2_i387"
4134 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4136 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4138 "* return output_387_reg_move (insn, operands);"
4139 [(set_attr "type" "fmov")
4140 (set_attr "mode" "<MODE>,XF")])
4142 ;; %%% This seems bad bad news.
4143 ;; This cannot output into an f-reg because there is no way to be sure
4144 ;; of truncating in that case. Otherwise this is just like a simple move
4145 ;; insn. So we pretend we can output to a reg in order to get better
4146 ;; register preferencing, but we really use a stack slot.
4148 ;; Conversion from DFmode to SFmode.
4150 (define_expand "truncdfsf2"
4151 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4153 (match_operand:DF 1 "nonimmediate_operand" "")))]
4154 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4156 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4158 else if (flag_unsafe_math_optimizations)
4162 enum ix86_stack_slot slot = (virtuals_instantiated
4165 rtx temp = assign_386_stack_local (SFmode, slot);
4166 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4171 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4173 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4175 We do the conversion post reload to avoid producing of 128bit spills
4176 that might lead to ICE on 32bit target. The sequence unlikely combine
4179 [(set (match_operand:SF 0 "register_operand" "")
4181 (match_operand:DF 1 "nonimmediate_operand" "")))]
4182 "TARGET_USE_VECTOR_FP_CONVERTS
4183 && optimize_insn_for_speed_p ()
4184 && reload_completed && SSE_REG_P (operands[0])"
4187 (float_truncate:V2SF
4191 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4192 operands[3] = CONST0_RTX (V2SFmode);
4193 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4194 /* Use movsd for loading from memory, unpcklpd for registers.
4195 Try to avoid move when unpacking can be done in source, or SSE3
4196 movddup is available. */
4197 if (REG_P (operands[1]))
4200 && true_regnum (operands[0]) != true_regnum (operands[1])
4201 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4202 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4204 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4205 emit_move_insn (tmp, operands[1]);
4208 else if (!TARGET_SSE3)
4209 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4210 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4213 emit_insn (gen_sse2_loadlpd (operands[4],
4214 CONST0_RTX (V2DFmode), operands[1]));
4217 (define_expand "truncdfsf2_with_temp"
4218 [(parallel [(set (match_operand:SF 0 "" "")
4219 (float_truncate:SF (match_operand:DF 1 "" "")))
4220 (clobber (match_operand:SF 2 "" ""))])])
4222 (define_insn "*truncdfsf_fast_mixed"
4223 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4225 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4226 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4228 switch (which_alternative)
4231 return output_387_reg_move (insn, operands);
4233 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4238 [(set_attr "type" "fmov,ssecvt")
4239 (set_attr "prefix" "orig,maybe_vex")
4240 (set_attr "mode" "SF")])
4242 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4243 ;; because nothing we do here is unsafe.
4244 (define_insn "*truncdfsf_fast_sse"
4245 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4247 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4248 "TARGET_SSE2 && TARGET_SSE_MATH"
4249 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4250 [(set_attr "type" "ssecvt")
4251 (set_attr "prefix" "maybe_vex")
4252 (set_attr "mode" "SF")])
4254 (define_insn "*truncdfsf_fast_i387"
4255 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4257 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4258 "TARGET_80387 && flag_unsafe_math_optimizations"
4259 "* return output_387_reg_move (insn, operands);"
4260 [(set_attr "type" "fmov")
4261 (set_attr "mode" "SF")])
4263 (define_insn "*truncdfsf_mixed"
4264 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4266 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4267 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4268 "TARGET_MIX_SSE_I387"
4270 switch (which_alternative)
4273 return output_387_reg_move (insn, operands);
4275 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4281 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4282 (set_attr "unit" "*,*,i387,i387,i387")
4283 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4284 (set_attr "mode" "SF")])
4286 (define_insn "*truncdfsf_i387"
4287 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4289 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4290 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4293 switch (which_alternative)
4296 return output_387_reg_move (insn, operands);
4302 [(set_attr "type" "fmov,multi,multi,multi")
4303 (set_attr "unit" "*,i387,i387,i387")
4304 (set_attr "mode" "SF")])
4306 (define_insn "*truncdfsf2_i387_1"
4307 [(set (match_operand:SF 0 "memory_operand" "=m")
4309 (match_operand:DF 1 "register_operand" "f")))]
4311 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4312 && !TARGET_MIX_SSE_I387"
4313 "* return output_387_reg_move (insn, operands);"
4314 [(set_attr "type" "fmov")
4315 (set_attr "mode" "SF")])
4318 [(set (match_operand:SF 0 "register_operand" "")
4320 (match_operand:DF 1 "fp_register_operand" "")))
4321 (clobber (match_operand 2 "" ""))]
4323 [(set (match_dup 2) (match_dup 1))
4324 (set (match_dup 0) (match_dup 2))]
4325 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4327 ;; Conversion from XFmode to {SF,DF}mode
4329 (define_expand "truncxf<mode>2"
4330 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4331 (float_truncate:MODEF
4332 (match_operand:XF 1 "register_operand" "")))
4333 (clobber (match_dup 2))])]
4336 if (flag_unsafe_math_optimizations)
4338 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4339 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4340 if (reg != operands[0])
4341 emit_move_insn (operands[0], reg);
4346 enum ix86_stack_slot slot = (virtuals_instantiated
4349 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4353 (define_insn "*truncxfsf2_mixed"
4354 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4356 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4357 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4360 gcc_assert (!which_alternative);
4361 return output_387_reg_move (insn, operands);
4363 [(set_attr "type" "fmov,multi,multi,multi")
4364 (set_attr "unit" "*,i387,i387,i387")
4365 (set_attr "mode" "SF")])
4367 (define_insn "*truncxfdf2_mixed"
4368 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4370 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4371 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4374 gcc_assert (!which_alternative);
4375 return output_387_reg_move (insn, operands);
4377 [(set_attr "type" "fmov,multi,multi,multi")
4378 (set_attr "unit" "*,i387,i387,i387")
4379 (set_attr "mode" "DF")])
4381 (define_insn "truncxf<mode>2_i387_noop"
4382 [(set (match_operand:MODEF 0 "register_operand" "=f")
4383 (float_truncate:MODEF
4384 (match_operand:XF 1 "register_operand" "f")))]
4385 "TARGET_80387 && flag_unsafe_math_optimizations"
4386 "* return output_387_reg_move (insn, operands);"
4387 [(set_attr "type" "fmov")
4388 (set_attr "mode" "<MODE>")])
4390 (define_insn "*truncxf<mode>2_i387"
4391 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4392 (float_truncate:MODEF
4393 (match_operand:XF 1 "register_operand" "f")))]
4395 "* return output_387_reg_move (insn, operands);"
4396 [(set_attr "type" "fmov")
4397 (set_attr "mode" "<MODE>")])
4400 [(set (match_operand:MODEF 0 "register_operand" "")
4401 (float_truncate:MODEF
4402 (match_operand:XF 1 "register_operand" "")))
4403 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4404 "TARGET_80387 && reload_completed"
4405 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4406 (set (match_dup 0) (match_dup 2))])
4409 [(set (match_operand:MODEF 0 "memory_operand" "")
4410 (float_truncate:MODEF
4411 (match_operand:XF 1 "register_operand" "")))
4412 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4414 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4416 ;; Signed conversion to DImode.
4418 (define_expand "fix_truncxfdi2"
4419 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4420 (fix:DI (match_operand:XF 1 "register_operand" "")))
4421 (clobber (reg:CC FLAGS_REG))])]
4426 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4431 (define_expand "fix_trunc<mode>di2"
4432 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4433 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4434 (clobber (reg:CC FLAGS_REG))])]
4435 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4438 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4440 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4443 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4445 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4446 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4447 if (out != operands[0])
4448 emit_move_insn (operands[0], out);
4453 ;; Signed conversion to SImode.
4455 (define_expand "fix_truncxfsi2"
4456 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4457 (fix:SI (match_operand:XF 1 "register_operand" "")))
4458 (clobber (reg:CC FLAGS_REG))])]
4463 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4468 (define_expand "fix_trunc<mode>si2"
4469 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4470 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4471 (clobber (reg:CC FLAGS_REG))])]
4472 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4475 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4477 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4480 if (SSE_FLOAT_MODE_P (<MODE>mode))
4482 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4483 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4484 if (out != operands[0])
4485 emit_move_insn (operands[0], out);
4490 ;; Signed conversion to HImode.
4492 (define_expand "fix_trunc<mode>hi2"
4493 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4494 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4495 (clobber (reg:CC FLAGS_REG))])]
4497 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4501 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4506 ;; Unsigned conversion to SImode.
4508 (define_expand "fixuns_trunc<mode>si2"
4510 [(set (match_operand:SI 0 "register_operand" "")
4512 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4514 (clobber (match_scratch:<ssevecmode> 3 ""))
4515 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4516 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4518 enum machine_mode mode = <MODE>mode;
4519 enum machine_mode vecmode = <ssevecmode>mode;
4520 REAL_VALUE_TYPE TWO31r;
4523 if (optimize_insn_for_size_p ())
4526 real_ldexp (&TWO31r, &dconst1, 31);
4527 two31 = const_double_from_real_value (TWO31r, mode);
4528 two31 = ix86_build_const_vector (vecmode, true, two31);
4529 operands[2] = force_reg (vecmode, two31);
4532 (define_insn_and_split "*fixuns_trunc<mode>_1"
4533 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4535 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4536 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4537 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4538 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4539 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4540 && optimize_function_for_speed_p (cfun)"
4542 "&& reload_completed"
4545 ix86_split_convert_uns_si_sse (operands);
4549 ;; Unsigned conversion to HImode.
4550 ;; Without these patterns, we'll try the unsigned SI conversion which
4551 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4553 (define_expand "fixuns_trunc<mode>hi2"
4555 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4556 (set (match_operand:HI 0 "nonimmediate_operand" "")
4557 (subreg:HI (match_dup 2) 0))]
4558 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4559 "operands[2] = gen_reg_rtx (SImode);")
4561 ;; When SSE is available, it is always faster to use it!
4562 (define_insn "fix_trunc<mode>di_sse"
4563 [(set (match_operand:DI 0 "register_operand" "=r,r")
4564 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4565 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4566 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4567 "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4568 [(set_attr "type" "sseicvt")
4569 (set_attr "prefix" "maybe_vex")
4570 (set_attr "prefix_rex" "1")
4571 (set_attr "mode" "<MODE>")
4572 (set_attr "athlon_decode" "double,vector")
4573 (set_attr "amdfam10_decode" "double,double")
4574 (set_attr "bdver1_decode" "double,double")])
4576 (define_insn "fix_trunc<mode>si_sse"
4577 [(set (match_operand:SI 0 "register_operand" "=r,r")
4578 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4579 "SSE_FLOAT_MODE_P (<MODE>mode)
4580 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4581 "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4582 [(set_attr "type" "sseicvt")
4583 (set_attr "prefix" "maybe_vex")
4584 (set_attr "mode" "<MODE>")
4585 (set_attr "athlon_decode" "double,vector")
4586 (set_attr "amdfam10_decode" "double,double")
4587 (set_attr "bdver1_decode" "double,double")])
4589 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4591 [(set (match_operand:MODEF 0 "register_operand" "")
4592 (match_operand:MODEF 1 "memory_operand" ""))
4593 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4594 (fix:SSEMODEI24 (match_dup 0)))]
4595 "TARGET_SHORTEN_X87_SSE
4596 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4597 && peep2_reg_dead_p (2, operands[0])"
4598 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))])
4600 ;; Avoid vector decoded forms of the instruction.
4602 [(match_scratch:DF 2 "Y2")
4603 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4604 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4605 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4606 [(set (match_dup 2) (match_dup 1))
4607 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4610 [(match_scratch:SF 2 "x")
4611 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4612 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4613 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4614 [(set (match_dup 2) (match_dup 1))
4615 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))])
4617 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4618 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4619 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4620 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4622 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4623 && (TARGET_64BIT || <MODE>mode != DImode))
4625 && can_create_pseudo_p ()"
4630 if (memory_operand (operands[0], VOIDmode))
4631 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4634 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4635 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4641 [(set_attr "type" "fisttp")
4642 (set_attr "mode" "<MODE>")])
4644 (define_insn "fix_trunc<mode>_i387_fisttp"
4645 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4646 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4647 (clobber (match_scratch:XF 2 "=&1f"))]
4648 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4650 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4651 && (TARGET_64BIT || <MODE>mode != DImode))
4652 && TARGET_SSE_MATH)"
4653 "* return output_fix_trunc (insn, operands, 1);"
4654 [(set_attr "type" "fisttp")
4655 (set_attr "mode" "<MODE>")])
4657 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4658 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4659 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4660 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4661 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4662 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4664 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4665 && (TARGET_64BIT || <MODE>mode != DImode))
4666 && TARGET_SSE_MATH)"
4668 [(set_attr "type" "fisttp")
4669 (set_attr "mode" "<MODE>")])
4672 [(set (match_operand:X87MODEI 0 "register_operand" "")
4673 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4674 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4675 (clobber (match_scratch 3 ""))]
4677 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4678 (clobber (match_dup 3))])
4679 (set (match_dup 0) (match_dup 2))])
4682 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4683 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4684 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4685 (clobber (match_scratch 3 ""))]
4687 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
4688 (clobber (match_dup 3))])])
4690 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4691 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4692 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4693 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4694 ;; function in i386.c.
4695 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4696 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4697 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4698 (clobber (reg:CC FLAGS_REG))]
4699 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4701 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4702 && (TARGET_64BIT || <MODE>mode != DImode))
4703 && can_create_pseudo_p ()"
4708 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4710 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4711 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4712 if (memory_operand (operands[0], VOIDmode))
4713 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4714 operands[2], operands[3]));
4717 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4718 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4719 operands[2], operands[3],
4724 [(set_attr "type" "fistp")
4725 (set_attr "i387_cw" "trunc")
4726 (set_attr "mode" "<MODE>")])
4728 (define_insn "fix_truncdi_i387"
4729 [(set (match_operand:DI 0 "memory_operand" "=m")
4730 (fix:DI (match_operand 1 "register_operand" "f")))
4731 (use (match_operand:HI 2 "memory_operand" "m"))
4732 (use (match_operand:HI 3 "memory_operand" "m"))
4733 (clobber (match_scratch:XF 4 "=&1f"))]
4734 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4736 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4737 "* return output_fix_trunc (insn, operands, 0);"
4738 [(set_attr "type" "fistp")
4739 (set_attr "i387_cw" "trunc")
4740 (set_attr "mode" "DI")])
4742 (define_insn "fix_truncdi_i387_with_temp"
4743 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4744 (fix:DI (match_operand 1 "register_operand" "f,f")))
4745 (use (match_operand:HI 2 "memory_operand" "m,m"))
4746 (use (match_operand:HI 3 "memory_operand" "m,m"))
4747 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4748 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4749 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4751 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4753 [(set_attr "type" "fistp")
4754 (set_attr "i387_cw" "trunc")
4755 (set_attr "mode" "DI")])
4758 [(set (match_operand:DI 0 "register_operand" "")
4759 (fix:DI (match_operand 1 "register_operand" "")))
4760 (use (match_operand:HI 2 "memory_operand" ""))
4761 (use (match_operand:HI 3 "memory_operand" ""))
4762 (clobber (match_operand:DI 4 "memory_operand" ""))
4763 (clobber (match_scratch 5 ""))]
4765 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4768 (clobber (match_dup 5))])
4769 (set (match_dup 0) (match_dup 4))])
4772 [(set (match_operand:DI 0 "memory_operand" "")
4773 (fix:DI (match_operand 1 "register_operand" "")))
4774 (use (match_operand:HI 2 "memory_operand" ""))
4775 (use (match_operand:HI 3 "memory_operand" ""))
4776 (clobber (match_operand:DI 4 "memory_operand" ""))
4777 (clobber (match_scratch 5 ""))]
4779 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4782 (clobber (match_dup 5))])])
4784 (define_insn "fix_trunc<mode>_i387"
4785 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
4786 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
4787 (use (match_operand:HI 2 "memory_operand" "m"))
4788 (use (match_operand:HI 3 "memory_operand" "m"))]
4789 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4791 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4792 "* return output_fix_trunc (insn, operands, 0);"
4793 [(set_attr "type" "fistp")
4794 (set_attr "i387_cw" "trunc")
4795 (set_attr "mode" "<MODE>")])
4797 (define_insn "fix_trunc<mode>_i387_with_temp"
4798 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
4799 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
4800 (use (match_operand:HI 2 "memory_operand" "m,m"))
4801 (use (match_operand:HI 3 "memory_operand" "m,m"))
4802 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
4803 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4805 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4807 [(set_attr "type" "fistp")
4808 (set_attr "i387_cw" "trunc")
4809 (set_attr "mode" "<MODE>")])
4812 [(set (match_operand:X87MODEI12 0 "register_operand" "")
4813 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4814 (use (match_operand:HI 2 "memory_operand" ""))
4815 (use (match_operand:HI 3 "memory_operand" ""))
4816 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4818 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
4820 (use (match_dup 3))])
4821 (set (match_dup 0) (match_dup 4))])
4824 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
4825 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
4826 (use (match_operand:HI 2 "memory_operand" ""))
4827 (use (match_operand:HI 3 "memory_operand" ""))
4828 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
4830 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
4832 (use (match_dup 3))])])
4834 (define_insn "x86_fnstcw_1"
4835 [(set (match_operand:HI 0 "memory_operand" "=m")
4836 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4839 [(set (attr "length")
4840 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4841 (set_attr "mode" "HI")
4842 (set_attr "unit" "i387")
4843 (set_attr "bdver1_decode" "vector")])
4845 (define_insn "x86_fldcw_1"
4846 [(set (reg:HI FPCR_REG)
4847 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4850 [(set (attr "length")
4851 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4852 (set_attr "mode" "HI")
4853 (set_attr "unit" "i387")
4854 (set_attr "athlon_decode" "vector")
4855 (set_attr "amdfam10_decode" "vector")
4856 (set_attr "bdver1_decode" "vector")])
4858 ;; Conversion between fixed point and floating point.
4860 ;; Even though we only accept memory inputs, the backend _really_
4861 ;; wants to be able to do this between registers.
4863 (define_expand "floathi<mode>2"
4864 [(set (match_operand:X87MODEF 0 "register_operand" "")
4865 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4867 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4868 || TARGET_MIX_SSE_I387)")
4870 ;; Pre-reload splitter to add memory clobber to the pattern.
4871 (define_insn_and_split "*floathi<mode>2_1"
4872 [(set (match_operand:X87MODEF 0 "register_operand" "")
4873 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4875 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4876 || TARGET_MIX_SSE_I387)
4877 && can_create_pseudo_p ()"
4880 [(parallel [(set (match_dup 0)
4881 (float:X87MODEF (match_dup 1)))
4882 (clobber (match_dup 2))])]
4883 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4885 (define_insn "*floathi<mode>2_i387_with_temp"
4886 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4887 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4888 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
4890 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4891 || TARGET_MIX_SSE_I387)"
4893 [(set_attr "type" "fmov,multi")
4894 (set_attr "mode" "<MODE>")
4895 (set_attr "unit" "*,i387")
4896 (set_attr "fp_int_src" "true")])
4898 (define_insn "*floathi<mode>2_i387"
4899 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4900 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4902 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4903 || TARGET_MIX_SSE_I387)"
4905 [(set_attr "type" "fmov")
4906 (set_attr "mode" "<MODE>")
4907 (set_attr "fp_int_src" "true")])
4910 [(set (match_operand:X87MODEF 0 "register_operand" "")
4911 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4912 (clobber (match_operand:HI 2 "memory_operand" ""))]
4914 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4915 || TARGET_MIX_SSE_I387)
4916 && reload_completed"
4917 [(set (match_dup 2) (match_dup 1))
4918 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4921 [(set (match_operand:X87MODEF 0 "register_operand" "")
4922 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4923 (clobber (match_operand:HI 2 "memory_operand" ""))]
4925 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4926 || TARGET_MIX_SSE_I387)
4927 && reload_completed"
4928 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4930 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
4931 [(set (match_operand:X87MODEF 0 "register_operand" "")
4933 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
4935 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4936 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4938 if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4939 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4940 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
4942 rtx reg = gen_reg_rtx (XFmode);
4945 emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
4947 if (<X87MODEF:MODE>mode == SFmode)
4948 insn = gen_truncxfsf2 (operands[0], reg);
4949 else if (<X87MODEF:MODE>mode == DFmode)
4950 insn = gen_truncxfdf2 (operands[0], reg);
4959 ;; Pre-reload splitter to add memory clobber to the pattern.
4960 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
4961 [(set (match_operand:X87MODEF 0 "register_operand" "")
4962 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
4964 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
4965 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4966 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4967 || TARGET_MIX_SSE_I387))
4968 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
4969 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4970 && ((<SSEMODEI24:MODE>mode == SImode
4971 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4972 && optimize_function_for_speed_p (cfun)
4973 && flag_trapping_math)
4974 || !(TARGET_INTER_UNIT_CONVERSIONS
4975 || optimize_function_for_size_p (cfun)))))
4976 && can_create_pseudo_p ()"
4979 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4980 (clobber (match_dup 2))])]
4982 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
4984 /* Avoid store forwarding (partial memory) stall penalty
4985 by passing DImode value through XMM registers. */
4986 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
4987 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4988 && optimize_function_for_speed_p (cfun))
4990 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4997 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4998 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5000 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5001 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5002 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5003 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5005 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5006 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5007 (set_attr "unit" "*,i387,*,*,*")
5008 (set_attr "athlon_decode" "*,*,double,direct,double")
5009 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5010 (set_attr "bdver1_decode" "*,*,double,direct,double")
5011 (set_attr "fp_int_src" "true")])
5013 (define_insn "*floatsi<mode>2_vector_mixed"
5014 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5015 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5016 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5017 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5021 [(set_attr "type" "fmov,sseicvt")
5022 (set_attr "mode" "<MODE>,<ssevecmode>")
5023 (set_attr "unit" "i387,*")
5024 (set_attr "athlon_decode" "*,direct")
5025 (set_attr "amdfam10_decode" "*,double")
5026 (set_attr "bdver1_decode" "*,direct")
5027 (set_attr "fp_int_src" "true")])
5029 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5030 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5032 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5033 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5034 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5035 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5037 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5038 (set_attr "mode" "<MODEF:MODE>")
5039 (set_attr "unit" "*,i387,*,*")
5040 (set_attr "athlon_decode" "*,*,double,direct")
5041 (set_attr "amdfam10_decode" "*,*,vector,double")
5042 (set_attr "bdver1_decode" "*,*,double,direct")
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 "bdver1_decode" "*,double,direct")
5096 (set_attr "fp_int_src" "true")])
5098 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5099 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5101 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5102 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5103 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5104 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5107 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5108 [(set_attr "type" "fmov,sseicvt")
5109 (set_attr "prefix" "orig,maybe_vex")
5110 (set_attr "mode" "<MODEF:MODE>")
5111 (set (attr "prefix_rex")
5113 (and (eq_attr "prefix" "maybe_vex")
5114 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5116 (const_string "*")))
5117 (set_attr "athlon_decode" "*,direct")
5118 (set_attr "amdfam10_decode" "*,double")
5119 (set_attr "bdver1_decode" "*,direct")
5120 (set_attr "fp_int_src" "true")])
5122 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5123 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5125 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5126 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5127 "TARGET_SSE2 && TARGET_SSE_MATH
5128 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5130 [(set_attr "type" "sseicvt")
5131 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5132 (set_attr "athlon_decode" "double,direct,double")
5133 (set_attr "amdfam10_decode" "vector,double,double")
5134 (set_attr "bdver1_decode" "double,direct,double")
5135 (set_attr "fp_int_src" "true")])
5137 (define_insn "*floatsi<mode>2_vector_sse"
5138 [(set (match_operand:MODEF 0 "register_operand" "=x")
5139 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5140 "TARGET_SSE2 && TARGET_SSE_MATH
5141 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5143 [(set_attr "type" "sseicvt")
5144 (set_attr "mode" "<MODE>")
5145 (set_attr "athlon_decode" "direct")
5146 (set_attr "amdfam10_decode" "double")
5147 (set_attr "bdver1_decode" "direct")
5148 (set_attr "fp_int_src" "true")])
5151 [(set (match_operand:MODEF 0 "register_operand" "")
5152 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5153 (clobber (match_operand:SI 2 "memory_operand" ""))]
5154 "TARGET_SSE2 && TARGET_SSE_MATH
5155 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5157 && (SSE_REG_P (operands[0])
5158 || (GET_CODE (operands[0]) == SUBREG
5159 && SSE_REG_P (operands[0])))"
5162 rtx op1 = operands[1];
5164 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5166 if (GET_CODE (op1) == SUBREG)
5167 op1 = SUBREG_REG (op1);
5169 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5171 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5172 emit_insn (gen_sse2_loadld (operands[4],
5173 CONST0_RTX (V4SImode), operands[1]));
5175 /* We can ignore possible trapping value in the
5176 high part of SSE register for non-trapping math. */
5177 else if (SSE_REG_P (op1) && !flag_trapping_math)
5178 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5181 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5182 emit_move_insn (operands[2], operands[1]);
5183 emit_insn (gen_sse2_loadld (operands[4],
5184 CONST0_RTX (V4SImode), operands[2]));
5187 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5192 [(set (match_operand:MODEF 0 "register_operand" "")
5193 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5194 (clobber (match_operand:SI 2 "memory_operand" ""))]
5195 "TARGET_SSE2 && TARGET_SSE_MATH
5196 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5198 && (SSE_REG_P (operands[0])
5199 || (GET_CODE (operands[0]) == SUBREG
5200 && SSE_REG_P (operands[0])))"
5203 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5205 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5207 emit_insn (gen_sse2_loadld (operands[4],
5208 CONST0_RTX (V4SImode), operands[1]));
5210 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5215 [(set (match_operand:MODEF 0 "register_operand" "")
5216 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5217 "TARGET_SSE2 && TARGET_SSE_MATH
5218 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5220 && (SSE_REG_P (operands[0])
5221 || (GET_CODE (operands[0]) == SUBREG
5222 && SSE_REG_P (operands[0])))"
5225 rtx op1 = operands[1];
5227 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5229 if (GET_CODE (op1) == SUBREG)
5230 op1 = SUBREG_REG (op1);
5232 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5234 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5235 emit_insn (gen_sse2_loadld (operands[4],
5236 CONST0_RTX (V4SImode), operands[1]));
5238 /* We can ignore possible trapping value in the
5239 high part of SSE register for non-trapping math. */
5240 else if (SSE_REG_P (op1) && !flag_trapping_math)
5241 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5245 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5250 [(set (match_operand:MODEF 0 "register_operand" "")
5251 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5252 "TARGET_SSE2 && TARGET_SSE_MATH
5253 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5255 && (SSE_REG_P (operands[0])
5256 || (GET_CODE (operands[0]) == SUBREG
5257 && SSE_REG_P (operands[0])))"
5260 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5262 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5264 emit_insn (gen_sse2_loadld (operands[4],
5265 CONST0_RTX (V4SImode), operands[1]));
5267 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5271 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5272 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5274 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5275 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5276 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5277 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5279 [(set_attr "type" "sseicvt")
5280 (set_attr "mode" "<MODEF:MODE>")
5281 (set_attr "athlon_decode" "double,direct")
5282 (set_attr "amdfam10_decode" "vector,double")
5283 (set_attr "bdver1_decode" "double,direct")
5284 (set_attr "fp_int_src" "true")])
5286 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5287 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5289 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5290 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5291 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5292 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5293 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5294 [(set_attr "type" "sseicvt")
5295 (set_attr "prefix" "maybe_vex")
5296 (set_attr "mode" "<MODEF:MODE>")
5297 (set (attr "prefix_rex")
5299 (and (eq_attr "prefix" "maybe_vex")
5300 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5302 (const_string "*")))
5303 (set_attr "athlon_decode" "double,direct")
5304 (set_attr "amdfam10_decode" "vector,double")
5305 (set_attr "bdver1_decode" "double,direct")
5306 (set_attr "fp_int_src" "true")])
5309 [(set (match_operand:MODEF 0 "register_operand" "")
5310 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5311 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5312 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5313 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5314 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5316 && (SSE_REG_P (operands[0])
5317 || (GET_CODE (operands[0]) == SUBREG
5318 && SSE_REG_P (operands[0])))"
5319 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5321 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5322 [(set (match_operand:MODEF 0 "register_operand" "=x")
5324 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5325 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5326 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5327 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5328 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5329 [(set_attr "type" "sseicvt")
5330 (set_attr "prefix" "maybe_vex")
5331 (set_attr "mode" "<MODEF:MODE>")
5332 (set (attr "prefix_rex")
5334 (and (eq_attr "prefix" "maybe_vex")
5335 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5337 (const_string "*")))
5338 (set_attr "athlon_decode" "direct")
5339 (set_attr "amdfam10_decode" "double")
5340 (set_attr "bdver1_decode" "direct")
5341 (set_attr "fp_int_src" "true")])
5344 [(set (match_operand:MODEF 0 "register_operand" "")
5345 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5346 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5347 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5348 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5349 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5351 && (SSE_REG_P (operands[0])
5352 || (GET_CODE (operands[0]) == SUBREG
5353 && SSE_REG_P (operands[0])))"
5354 [(set (match_dup 2) (match_dup 1))
5355 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5358 [(set (match_operand:MODEF 0 "register_operand" "")
5359 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5360 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5361 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5362 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5364 && (SSE_REG_P (operands[0])
5365 || (GET_CODE (operands[0]) == SUBREG
5366 && SSE_REG_P (operands[0])))"
5367 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5369 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5370 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5372 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5373 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5375 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5379 [(set_attr "type" "fmov,multi")
5380 (set_attr "mode" "<X87MODEF:MODE>")
5381 (set_attr "unit" "*,i387")
5382 (set_attr "fp_int_src" "true")])
5384 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5385 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5387 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5389 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5391 [(set_attr "type" "fmov")
5392 (set_attr "mode" "<X87MODEF:MODE>")
5393 (set_attr "fp_int_src" "true")])
5396 [(set (match_operand:X87MODEF 0 "register_operand" "")
5397 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5398 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5400 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5402 && FP_REG_P (operands[0])"
5403 [(set (match_dup 2) (match_dup 1))
5404 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5407 [(set (match_operand:X87MODEF 0 "register_operand" "")
5408 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5409 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5411 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5413 && FP_REG_P (operands[0])"
5414 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5416 ;; Avoid store forwarding (partial memory) stall penalty
5417 ;; by passing DImode value through XMM registers. */
5419 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5420 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5422 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5423 (clobber (match_scratch:V4SI 3 "=X,x"))
5424 (clobber (match_scratch:V4SI 4 "=X,x"))
5425 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5426 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5427 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5428 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5430 [(set_attr "type" "multi")
5431 (set_attr "mode" "<X87MODEF:MODE>")
5432 (set_attr "unit" "i387")
5433 (set_attr "fp_int_src" "true")])
5436 [(set (match_operand:X87MODEF 0 "register_operand" "")
5437 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5438 (clobber (match_scratch:V4SI 3 ""))
5439 (clobber (match_scratch:V4SI 4 ""))
5440 (clobber (match_operand:DI 2 "memory_operand" ""))]
5441 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5442 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5443 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5445 && FP_REG_P (operands[0])"
5446 [(set (match_dup 2) (match_dup 3))
5447 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5449 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5450 Assemble the 64-bit DImode value in an xmm register. */
5451 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5452 gen_rtx_SUBREG (SImode, operands[1], 0)));
5453 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5454 gen_rtx_SUBREG (SImode, operands[1], 4)));
5455 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5458 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5462 [(set (match_operand:X87MODEF 0 "register_operand" "")
5463 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5464 (clobber (match_scratch:V4SI 3 ""))
5465 (clobber (match_scratch:V4SI 4 ""))
5466 (clobber (match_operand:DI 2 "memory_operand" ""))]
5467 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5468 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5469 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5471 && FP_REG_P (operands[0])"
5472 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5474 ;; Avoid store forwarding (partial memory) stall penalty by extending
5475 ;; SImode value to DImode through XMM register instead of pushing two
5476 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5477 ;; targets benefit from this optimization. Also note that fild
5478 ;; loads from memory only.
5480 (define_insn "*floatunssi<mode>2_1"
5481 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5482 (unsigned_float:X87MODEF
5483 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5484 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5485 (clobber (match_scratch:SI 3 "=X,x"))]
5487 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5490 [(set_attr "type" "multi")
5491 (set_attr "mode" "<MODE>")])
5494 [(set (match_operand:X87MODEF 0 "register_operand" "")
5495 (unsigned_float:X87MODEF
5496 (match_operand:SI 1 "register_operand" "")))
5497 (clobber (match_operand:DI 2 "memory_operand" ""))
5498 (clobber (match_scratch:SI 3 ""))]
5500 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5502 && reload_completed"
5503 [(set (match_dup 2) (match_dup 1))
5505 (float:X87MODEF (match_dup 2)))]
5506 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5509 [(set (match_operand:X87MODEF 0 "register_operand" "")
5510 (unsigned_float:X87MODEF
5511 (match_operand:SI 1 "memory_operand" "")))
5512 (clobber (match_operand:DI 2 "memory_operand" ""))
5513 (clobber (match_scratch:SI 3 ""))]
5515 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5517 && reload_completed"
5518 [(set (match_dup 2) (match_dup 3))
5520 (float:X87MODEF (match_dup 2)))]
5522 emit_move_insn (operands[3], operands[1]);
5523 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5526 (define_expand "floatunssi<mode>2"
5528 [(set (match_operand:X87MODEF 0 "register_operand" "")
5529 (unsigned_float:X87MODEF
5530 (match_operand:SI 1 "nonimmediate_operand" "")))
5531 (clobber (match_dup 2))
5532 (clobber (match_scratch:SI 3 ""))])]
5534 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5536 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5538 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5540 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5545 enum ix86_stack_slot slot = (virtuals_instantiated
5548 operands[2] = assign_386_stack_local (DImode, slot);
5552 (define_expand "floatunsdisf2"
5553 [(use (match_operand:SF 0 "register_operand" ""))
5554 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5555 "TARGET_64BIT && TARGET_SSE_MATH"
5556 "x86_emit_floatuns (operands); DONE;")
5558 (define_expand "floatunsdidf2"
5559 [(use (match_operand:DF 0 "register_operand" ""))
5560 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5561 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5562 && TARGET_SSE2 && TARGET_SSE_MATH"
5565 x86_emit_floatuns (operands);
5567 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5573 (define_expand "add<mode>3"
5574 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5575 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5576 (match_operand:SDWIM 2 "<general_operand>" "")))]
5578 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5580 (define_insn_and_split "*add<dwi>3_doubleword"
5581 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5583 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5584 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5585 (clobber (reg:CC FLAGS_REG))]
5586 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5589 [(parallel [(set (reg:CC FLAGS_REG)
5590 (unspec:CC [(match_dup 1) (match_dup 2)]
5593 (plus:DWIH (match_dup 1) (match_dup 2)))])
5594 (parallel [(set (match_dup 3)
5598 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5600 (clobber (reg:CC FLAGS_REG))])]
5601 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5603 (define_insn "*add<mode>3_cc"
5604 [(set (reg:CC FLAGS_REG)
5606 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5607 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5609 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5610 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5611 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5612 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5613 [(set_attr "type" "alu")
5614 (set_attr "mode" "<MODE>")])
5616 (define_insn "addqi3_cc"
5617 [(set (reg:CC FLAGS_REG)
5619 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5620 (match_operand:QI 2 "general_operand" "qn,qm")]
5622 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5623 (plus:QI (match_dup 1) (match_dup 2)))]
5624 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5625 "add{b}\t{%2, %0|%0, %2}"
5626 [(set_attr "type" "alu")
5627 (set_attr "mode" "QI")])
5629 (define_insn "*lea_1"
5630 [(set (match_operand:P 0 "register_operand" "=r")
5631 (match_operand:P 1 "no_seg_address_operand" "p"))]
5633 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5634 [(set_attr "type" "lea")
5635 (set_attr "mode" "<MODE>")])
5637 (define_insn "*lea_2"
5638 [(set (match_operand:SI 0 "register_operand" "=r")
5639 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5641 "lea{l}\t{%a1, %0|%0, %a1}"
5642 [(set_attr "type" "lea")
5643 (set_attr "mode" "SI")])
5645 (define_insn "*lea_2_zext"
5646 [(set (match_operand:DI 0 "register_operand" "=r")
5648 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5650 "lea{l}\t{%a1, %k0|%k0, %a1}"
5651 [(set_attr "type" "lea")
5652 (set_attr "mode" "SI")])
5654 (define_insn "*add<mode>_1"
5655 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5657 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5658 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5659 (clobber (reg:CC FLAGS_REG))]
5660 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5662 switch (get_attr_type (insn))
5668 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5669 if (operands[2] == const1_rtx)
5670 return "inc{<imodesuffix>}\t%0";
5673 gcc_assert (operands[2] == constm1_rtx);
5674 return "dec{<imodesuffix>}\t%0";
5678 /* For most processors, ADD is faster than LEA. This alternative
5679 was added to use ADD as much as possible. */
5680 if (which_alternative == 2)
5683 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5686 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5687 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5688 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5690 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5694 (cond [(eq_attr "alternative" "3")
5695 (const_string "lea")
5696 (match_operand:SWI48 2 "incdec_operand" "")
5697 (const_string "incdec")
5699 (const_string "alu")))
5700 (set (attr "length_immediate")
5702 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5704 (const_string "*")))
5705 (set_attr "mode" "<MODE>")])
5707 ;; It may seem that nonimmediate operand is proper one for operand 1.
5708 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5709 ;; we take care in ix86_binary_operator_ok to not allow two memory
5710 ;; operands so proper swapping will be done in reload. This allow
5711 ;; patterns constructed from addsi_1 to match.
5713 (define_insn "*addsi_1_zext"
5714 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5716 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5717 (match_operand:SI 2 "general_operand" "g,0,li"))))
5718 (clobber (reg:CC FLAGS_REG))]
5719 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5721 switch (get_attr_type (insn))
5727 if (operands[2] == const1_rtx)
5728 return "inc{l}\t%k0";
5731 gcc_assert (operands[2] == constm1_rtx);
5732 return "dec{l}\t%k0";
5736 /* For most processors, ADD is faster than LEA. This alternative
5737 was added to use ADD as much as possible. */
5738 if (which_alternative == 1)
5741 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5744 if (x86_maybe_negate_const_int (&operands[2], SImode))
5745 return "sub{l}\t{%2, %k0|%k0, %2}";
5747 return "add{l}\t{%2, %k0|%k0, %2}";
5751 (cond [(eq_attr "alternative" "2")
5752 (const_string "lea")
5753 (match_operand:SI 2 "incdec_operand" "")
5754 (const_string "incdec")
5756 (const_string "alu")))
5757 (set (attr "length_immediate")
5759 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5761 (const_string "*")))
5762 (set_attr "mode" "SI")])
5764 (define_insn "*addhi_1"
5765 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
5766 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
5767 (match_operand:HI 2 "general_operand" "rn,rm")))
5768 (clobber (reg:CC FLAGS_REG))]
5769 "TARGET_PARTIAL_REG_STALL
5770 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5772 switch (get_attr_type (insn))
5775 if (operands[2] == const1_rtx)
5776 return "inc{w}\t%0";
5779 gcc_assert (operands[2] == constm1_rtx);
5780 return "dec{w}\t%0";
5784 if (x86_maybe_negate_const_int (&operands[2], HImode))
5785 return "sub{w}\t{%2, %0|%0, %2}";
5787 return "add{w}\t{%2, %0|%0, %2}";
5791 (if_then_else (match_operand:HI 2 "incdec_operand" "")
5792 (const_string "incdec")
5793 (const_string "alu")))
5794 (set (attr "length_immediate")
5796 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5798 (const_string "*")))
5799 (set_attr "mode" "HI")])
5801 (define_insn "*addhi_1_lea"
5802 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,rm,r,r")
5803 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,r")
5804 (match_operand:HI 2 "general_operand" "rmn,rn,0,ln")))
5805 (clobber (reg:CC FLAGS_REG))]
5806 "!TARGET_PARTIAL_REG_STALL
5807 && ix86_binary_operator_ok (PLUS, HImode, operands)"
5809 switch (get_attr_type (insn))
5815 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5816 if (operands[2] == const1_rtx)
5817 return "inc{w}\t%0";
5820 gcc_assert (operands[2] == constm1_rtx);
5821 return "dec{w}\t%0";
5825 /* For most processors, ADD is faster than LEA. This alternative
5826 was added to use ADD as much as possible. */
5827 if (which_alternative == 2)
5830 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5833 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5834 if (x86_maybe_negate_const_int (&operands[2], HImode))
5835 return "sub{w}\t{%2, %0|%0, %2}";
5837 return "add{w}\t{%2, %0|%0, %2}";
5841 (cond [(eq_attr "alternative" "3")
5842 (const_string "lea")
5843 (match_operand:HI 2 "incdec_operand" "")
5844 (const_string "incdec")
5846 (const_string "alu")))
5847 (set (attr "length_immediate")
5849 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5851 (const_string "*")))
5852 (set_attr "mode" "HI,HI,HI,SI")])
5854 ;; %%% Potential partial reg stall on alternative 2. What to do?
5855 (define_insn "*addqi_1"
5856 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
5857 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
5858 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
5859 (clobber (reg:CC FLAGS_REG))]
5860 "TARGET_PARTIAL_REG_STALL
5861 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5863 int widen = (which_alternative == 2);
5864 switch (get_attr_type (insn))
5867 if (operands[2] == const1_rtx)
5868 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5871 gcc_assert (operands[2] == constm1_rtx);
5872 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5876 if (x86_maybe_negate_const_int (&operands[2], QImode))
5879 return "sub{l}\t{%2, %k0|%k0, %2}";
5881 return "sub{b}\t{%2, %0|%0, %2}";
5884 return "add{l}\t{%k2, %k0|%k0, %k2}";
5886 return "add{b}\t{%2, %0|%0, %2}";
5890 (if_then_else (match_operand:QI 2 "incdec_operand" "")
5891 (const_string "incdec")
5892 (const_string "alu")))
5893 (set (attr "length_immediate")
5895 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5897 (const_string "*")))
5898 (set_attr "mode" "QI,QI,SI")])
5900 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5901 (define_insn "*addqi_1_lea"
5902 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,q,r,r,r")
5903 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,r")
5904 (match_operand:QI 2 "general_operand" "qmn,qn,0,rn,0,ln")))
5905 (clobber (reg:CC FLAGS_REG))]
5906 "!TARGET_PARTIAL_REG_STALL
5907 && ix86_binary_operator_ok (PLUS, QImode, operands)"
5909 int widen = (which_alternative == 3 || which_alternative == 4);
5911 switch (get_attr_type (insn))
5917 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5918 if (operands[2] == const1_rtx)
5919 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5922 gcc_assert (operands[2] == constm1_rtx);
5923 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5927 /* For most processors, ADD is faster than LEA. These alternatives
5928 were added to use ADD as much as possible. */
5929 if (which_alternative == 2 || which_alternative == 4)
5932 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5935 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5936 if (x86_maybe_negate_const_int (&operands[2], QImode))
5939 return "sub{l}\t{%2, %k0|%k0, %2}";
5941 return "sub{b}\t{%2, %0|%0, %2}";
5944 return "add{l}\t{%k2, %k0|%k0, %k2}";
5946 return "add{b}\t{%2, %0|%0, %2}";
5950 (cond [(eq_attr "alternative" "5")
5951 (const_string "lea")
5952 (match_operand:QI 2 "incdec_operand" "")
5953 (const_string "incdec")
5955 (const_string "alu")))
5956 (set (attr "length_immediate")
5958 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5960 (const_string "*")))
5961 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5963 (define_insn "*addqi_1_slp"
5964 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5965 (plus:QI (match_dup 0)
5966 (match_operand:QI 1 "general_operand" "qn,qnm")))
5967 (clobber (reg:CC FLAGS_REG))]
5968 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5969 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5971 switch (get_attr_type (insn))
5974 if (operands[1] == const1_rtx)
5975 return "inc{b}\t%0";
5978 gcc_assert (operands[1] == constm1_rtx);
5979 return "dec{b}\t%0";
5983 if (x86_maybe_negate_const_int (&operands[1], QImode))
5984 return "sub{b}\t{%1, %0|%0, %1}";
5986 return "add{b}\t{%1, %0|%0, %1}";
5990 (if_then_else (match_operand:QI 1 "incdec_operand" "")
5991 (const_string "incdec")
5992 (const_string "alu1")))
5993 (set (attr "memory")
5994 (if_then_else (match_operand 1 "memory_operand" "")
5995 (const_string "load")
5996 (const_string "none")))
5997 (set_attr "mode" "QI")])
5999 ;; Convert lea to the lea pattern to avoid flags dependency.
6001 [(set (match_operand 0 "register_operand" "")
6002 (plus (match_operand 1 "register_operand" "")
6003 (match_operand 2 "nonmemory_operand" "")))
6004 (clobber (reg:CC FLAGS_REG))]
6005 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
6009 enum machine_mode mode = GET_MODE (operands[0]);
6011 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6012 may confuse gen_lowpart. */
6015 operands[1] = gen_lowpart (Pmode, operands[1]);
6016 operands[2] = gen_lowpart (Pmode, operands[2]);
6019 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6021 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6022 operands[0] = gen_lowpart (SImode, operands[0]);
6024 if (TARGET_64BIT && mode != Pmode)
6025 pat = gen_rtx_SUBREG (SImode, pat, 0);
6027 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6031 ;; Convert lea to the lea pattern to avoid flags dependency.
6032 ;; ??? This pattern handles immediate operands that do not satisfy immediate
6033 ;; operand predicate (LEGITIMATE_CONSTANT_P) in the previous pattern.
6035 [(set (match_operand:DI 0 "register_operand" "")
6036 (plus:DI (match_operand:DI 1 "register_operand" "")
6037 (match_operand:DI 2 "x86_64_immediate_operand" "")))
6038 (clobber (reg:CC FLAGS_REG))]
6039 "TARGET_64BIT && reload_completed
6040 && true_regnum (operands[0]) != true_regnum (operands[1])"
6042 (plus:DI (match_dup 1) (match_dup 2)))])
6044 ;; Convert lea to the lea pattern to avoid flags dependency.
6046 [(set (match_operand:DI 0 "register_operand" "")
6048 (plus:SI (match_operand:SI 1 "register_operand" "")
6049 (match_operand:SI 2 "nonmemory_operand" ""))))
6050 (clobber (reg:CC FLAGS_REG))]
6051 "TARGET_64BIT && reload_completed
6052 && ix86_lea_for_add_ok (insn, operands)"
6054 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6056 operands[1] = gen_lowpart (DImode, operands[1]);
6057 operands[2] = gen_lowpart (DImode, operands[2]);
6060 (define_insn "*add<mode>_2"
6061 [(set (reg FLAGS_REG)
6064 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6065 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
6067 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
6068 (plus:SWI (match_dup 1) (match_dup 2)))]
6069 "ix86_match_ccmode (insn, CCGOCmode)
6070 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6072 switch (get_attr_type (insn))
6075 if (operands[2] == const1_rtx)
6076 return "inc{<imodesuffix>}\t%0";
6079 gcc_assert (operands[2] == constm1_rtx);
6080 return "dec{<imodesuffix>}\t%0";
6084 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6085 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6087 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6091 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6092 (const_string "incdec")
6093 (const_string "alu")))
6094 (set (attr "length_immediate")
6096 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6098 (const_string "*")))
6099 (set_attr "mode" "<MODE>")])
6101 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6102 (define_insn "*addsi_2_zext"
6103 [(set (reg FLAGS_REG)
6105 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6106 (match_operand:SI 2 "general_operand" "g"))
6108 (set (match_operand:DI 0 "register_operand" "=r")
6109 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6110 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6111 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6113 switch (get_attr_type (insn))
6116 if (operands[2] == const1_rtx)
6117 return "inc{l}\t%k0";
6120 gcc_assert (operands[2] == constm1_rtx);
6121 return "dec{l}\t%k0";
6125 if (x86_maybe_negate_const_int (&operands[2], SImode))
6126 return "sub{l}\t{%2, %k0|%k0, %2}";
6128 return "add{l}\t{%2, %k0|%k0, %2}";
6132 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6133 (const_string "incdec")
6134 (const_string "alu")))
6135 (set (attr "length_immediate")
6137 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6139 (const_string "*")))
6140 (set_attr "mode" "SI")])
6142 (define_insn "*add<mode>_3"
6143 [(set (reg FLAGS_REG)
6145 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
6146 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
6147 (clobber (match_scratch:SWI 0 "=<r>"))]
6148 "ix86_match_ccmode (insn, CCZmode)
6149 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6151 switch (get_attr_type (insn))
6154 if (operands[2] == const1_rtx)
6155 return "inc{<imodesuffix>}\t%0";
6158 gcc_assert (operands[2] == constm1_rtx);
6159 return "dec{<imodesuffix>}\t%0";
6163 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6164 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6166 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6170 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6171 (const_string "incdec")
6172 (const_string "alu")))
6173 (set (attr "length_immediate")
6175 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6177 (const_string "*")))
6178 (set_attr "mode" "<MODE>")])
6180 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6181 (define_insn "*addsi_3_zext"
6182 [(set (reg FLAGS_REG)
6184 (neg:SI (match_operand:SI 2 "general_operand" "g"))
6185 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6186 (set (match_operand:DI 0 "register_operand" "=r")
6187 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6188 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6189 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6191 switch (get_attr_type (insn))
6194 if (operands[2] == const1_rtx)
6195 return "inc{l}\t%k0";
6198 gcc_assert (operands[2] == constm1_rtx);
6199 return "dec{l}\t%k0";
6203 if (x86_maybe_negate_const_int (&operands[2], SImode))
6204 return "sub{l}\t{%2, %k0|%k0, %2}";
6206 return "add{l}\t{%2, %k0|%k0, %2}";
6210 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6211 (const_string "incdec")
6212 (const_string "alu")))
6213 (set (attr "length_immediate")
6215 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6217 (const_string "*")))
6218 (set_attr "mode" "SI")])
6220 ; For comparisons against 1, -1 and 128, we may generate better code
6221 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6222 ; is matched then. We can't accept general immediate, because for
6223 ; case of overflows, the result is messed up.
6224 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6225 ; only for comparisons not depending on it.
6227 (define_insn "*adddi_4"
6228 [(set (reg FLAGS_REG)
6230 (match_operand:DI 1 "nonimmediate_operand" "0")
6231 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6232 (clobber (match_scratch:DI 0 "=rm"))]
6234 && ix86_match_ccmode (insn, CCGCmode)"
6236 switch (get_attr_type (insn))
6239 if (operands[2] == constm1_rtx)
6240 return "inc{q}\t%0";
6243 gcc_assert (operands[2] == const1_rtx);
6244 return "dec{q}\t%0";
6248 if (x86_maybe_negate_const_int (&operands[2], DImode))
6249 return "add{q}\t{%2, %0|%0, %2}";
6251 return "sub{q}\t{%2, %0|%0, %2}";
6255 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6256 (const_string "incdec")
6257 (const_string "alu")))
6258 (set (attr "length_immediate")
6260 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6262 (const_string "*")))
6263 (set_attr "mode" "DI")])
6265 ; For comparisons against 1, -1 and 128, we may generate better code
6266 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6267 ; is matched then. We can't accept general immediate, because for
6268 ; case of overflows, the result is messed up.
6269 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6270 ; only for comparisons not depending on it.
6272 (define_insn "*add<mode>_4"
6273 [(set (reg FLAGS_REG)
6275 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6276 (match_operand:SWI124 2 "const_int_operand" "n")))
6277 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6278 "ix86_match_ccmode (insn, CCGCmode)"
6280 switch (get_attr_type (insn))
6283 if (operands[2] == constm1_rtx)
6284 return "inc{<imodesuffix>}\t%0";
6287 gcc_assert (operands[2] == const1_rtx);
6288 return "dec{<imodesuffix>}\t%0";
6292 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6293 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6295 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6299 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6300 (const_string "incdec")
6301 (const_string "alu")))
6302 (set (attr "length_immediate")
6304 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6306 (const_string "*")))
6307 (set_attr "mode" "<MODE>")])
6309 (define_insn "*add<mode>_5"
6310 [(set (reg FLAGS_REG)
6313 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6314 (match_operand:SWI 2 "<general_operand>" "<g>"))
6316 (clobber (match_scratch:SWI 0 "=<r>"))]
6317 "ix86_match_ccmode (insn, CCGOCmode)
6318 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6320 switch (get_attr_type (insn))
6323 if (operands[2] == const1_rtx)
6324 return "inc{<imodesuffix>}\t%0";
6327 gcc_assert (operands[2] == constm1_rtx);
6328 return "dec{<imodesuffix>}\t%0";
6332 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6333 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6335 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6339 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6340 (const_string "incdec")
6341 (const_string "alu")))
6342 (set (attr "length_immediate")
6344 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6346 (const_string "*")))
6347 (set_attr "mode" "<MODE>")])
6349 (define_insn "*addqi_ext_1_rex64"
6350 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6355 (match_operand 1 "ext_register_operand" "0")
6358 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6359 (clobber (reg:CC FLAGS_REG))]
6362 switch (get_attr_type (insn))
6365 if (operands[2] == const1_rtx)
6366 return "inc{b}\t%h0";
6369 gcc_assert (operands[2] == constm1_rtx);
6370 return "dec{b}\t%h0";
6374 return "add{b}\t{%2, %h0|%h0, %2}";
6378 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6379 (const_string "incdec")
6380 (const_string "alu")))
6381 (set_attr "modrm" "1")
6382 (set_attr "mode" "QI")])
6384 (define_insn "addqi_ext_1"
6385 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6390 (match_operand 1 "ext_register_operand" "0")
6393 (match_operand:QI 2 "general_operand" "Qmn")))
6394 (clobber (reg:CC FLAGS_REG))]
6397 switch (get_attr_type (insn))
6400 if (operands[2] == const1_rtx)
6401 return "inc{b}\t%h0";
6404 gcc_assert (operands[2] == constm1_rtx);
6405 return "dec{b}\t%h0";
6409 return "add{b}\t{%2, %h0|%h0, %2}";
6413 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6414 (const_string "incdec")
6415 (const_string "alu")))
6416 (set_attr "modrm" "1")
6417 (set_attr "mode" "QI")])
6419 (define_insn "*addqi_ext_2"
6420 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6425 (match_operand 1 "ext_register_operand" "%0")
6429 (match_operand 2 "ext_register_operand" "Q")
6432 (clobber (reg:CC FLAGS_REG))]
6434 "add{b}\t{%h2, %h0|%h0, %h2}"
6435 [(set_attr "type" "alu")
6436 (set_attr "mode" "QI")])
6438 ;; The lea patterns for non-Pmodes needs to be matched by
6439 ;; several insns converted to real lea by splitters.
6441 (define_insn_and_split "*lea_general_1"
6442 [(set (match_operand 0 "register_operand" "=r")
6443 (plus (plus (match_operand 1 "index_register_operand" "l")
6444 (match_operand 2 "register_operand" "r"))
6445 (match_operand 3 "immediate_operand" "i")))]
6446 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6447 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6448 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6449 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6450 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6451 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6452 || GET_MODE (operands[3]) == VOIDmode)"
6454 "&& reload_completed"
6458 operands[0] = gen_lowpart (SImode, operands[0]);
6459 operands[1] = gen_lowpart (Pmode, operands[1]);
6460 operands[2] = gen_lowpart (Pmode, operands[2]);
6461 operands[3] = gen_lowpart (Pmode, operands[3]);
6462 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6464 if (Pmode != SImode)
6465 pat = gen_rtx_SUBREG (SImode, pat, 0);
6466 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6469 [(set_attr "type" "lea")
6470 (set_attr "mode" "SI")])
6472 (define_insn_and_split "*lea_general_1_zext"
6473 [(set (match_operand:DI 0 "register_operand" "=r")
6476 (match_operand:SI 1 "index_register_operand" "l")
6477 (match_operand:SI 2 "register_operand" "r"))
6478 (match_operand:SI 3 "immediate_operand" "i"))))]
6481 "&& reload_completed"
6483 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6485 (match_dup 3)) 0)))]
6487 operands[1] = gen_lowpart (Pmode, operands[1]);
6488 operands[2] = gen_lowpart (Pmode, operands[2]);
6489 operands[3] = gen_lowpart (Pmode, operands[3]);
6491 [(set_attr "type" "lea")
6492 (set_attr "mode" "SI")])
6494 (define_insn_and_split "*lea_general_2"
6495 [(set (match_operand 0 "register_operand" "=r")
6496 (plus (mult (match_operand 1 "index_register_operand" "l")
6497 (match_operand 2 "const248_operand" "i"))
6498 (match_operand 3 "nonmemory_operand" "ri")))]
6499 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6500 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6501 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6502 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6503 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6504 || GET_MODE (operands[3]) == VOIDmode)"
6506 "&& reload_completed"
6510 operands[0] = gen_lowpart (SImode, operands[0]);
6511 operands[1] = gen_lowpart (Pmode, operands[1]);
6512 operands[3] = gen_lowpart (Pmode, operands[3]);
6513 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6515 if (Pmode != SImode)
6516 pat = gen_rtx_SUBREG (SImode, pat, 0);
6517 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6520 [(set_attr "type" "lea")
6521 (set_attr "mode" "SI")])
6523 (define_insn_and_split "*lea_general_2_zext"
6524 [(set (match_operand:DI 0 "register_operand" "=r")
6527 (match_operand:SI 1 "index_register_operand" "l")
6528 (match_operand:SI 2 "const248_operand" "n"))
6529 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6532 "&& reload_completed"
6534 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6536 (match_dup 3)) 0)))]
6538 operands[1] = gen_lowpart (Pmode, operands[1]);
6539 operands[3] = gen_lowpart (Pmode, operands[3]);
6541 [(set_attr "type" "lea")
6542 (set_attr "mode" "SI")])
6544 (define_insn_and_split "*lea_general_3"
6545 [(set (match_operand 0 "register_operand" "=r")
6546 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6547 (match_operand 2 "const248_operand" "i"))
6548 (match_operand 3 "register_operand" "r"))
6549 (match_operand 4 "immediate_operand" "i")))]
6550 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6551 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6552 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6553 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6554 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6556 "&& reload_completed"
6560 operands[0] = gen_lowpart (SImode, operands[0]);
6561 operands[1] = gen_lowpart (Pmode, operands[1]);
6562 operands[3] = gen_lowpart (Pmode, operands[3]);
6563 operands[4] = gen_lowpart (Pmode, operands[4]);
6564 pat = gen_rtx_PLUS (Pmode,
6565 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6569 if (Pmode != SImode)
6570 pat = gen_rtx_SUBREG (SImode, pat, 0);
6571 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6574 [(set_attr "type" "lea")
6575 (set_attr "mode" "SI")])
6577 (define_insn_and_split "*lea_general_3_zext"
6578 [(set (match_operand:DI 0 "register_operand" "=r")
6582 (match_operand:SI 1 "index_register_operand" "l")
6583 (match_operand:SI 2 "const248_operand" "n"))
6584 (match_operand:SI 3 "register_operand" "r"))
6585 (match_operand:SI 4 "immediate_operand" "i"))))]
6588 "&& reload_completed"
6590 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6593 (match_dup 4)) 0)))]
6595 operands[1] = gen_lowpart (Pmode, operands[1]);
6596 operands[3] = gen_lowpart (Pmode, operands[3]);
6597 operands[4] = gen_lowpart (Pmode, operands[4]);
6599 [(set_attr "type" "lea")
6600 (set_attr "mode" "SI")])
6602 ;; Subtract instructions
6604 (define_expand "sub<mode>3"
6605 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6606 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6607 (match_operand:SDWIM 2 "<general_operand>" "")))]
6609 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6611 (define_insn_and_split "*sub<dwi>3_doubleword"
6612 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6614 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6615 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6616 (clobber (reg:CC FLAGS_REG))]
6617 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6620 [(parallel [(set (reg:CC FLAGS_REG)
6621 (compare:CC (match_dup 1) (match_dup 2)))
6623 (minus:DWIH (match_dup 1) (match_dup 2)))])
6624 (parallel [(set (match_dup 3)
6628 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6630 (clobber (reg:CC FLAGS_REG))])]
6631 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6633 (define_insn "*sub<mode>_1"
6634 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6636 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6637 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6638 (clobber (reg:CC FLAGS_REG))]
6639 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6640 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6641 [(set_attr "type" "alu")
6642 (set_attr "mode" "<MODE>")])
6644 (define_insn "*subsi_1_zext"
6645 [(set (match_operand:DI 0 "register_operand" "=r")
6647 (minus:SI (match_operand:SI 1 "register_operand" "0")
6648 (match_operand:SI 2 "general_operand" "g"))))
6649 (clobber (reg:CC FLAGS_REG))]
6650 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6651 "sub{l}\t{%2, %k0|%k0, %2}"
6652 [(set_attr "type" "alu")
6653 (set_attr "mode" "SI")])
6655 (define_insn "*subqi_1_slp"
6656 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6657 (minus:QI (match_dup 0)
6658 (match_operand:QI 1 "general_operand" "qn,qm")))
6659 (clobber (reg:CC FLAGS_REG))]
6660 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6661 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6662 "sub{b}\t{%1, %0|%0, %1}"
6663 [(set_attr "type" "alu1")
6664 (set_attr "mode" "QI")])
6666 (define_insn "*sub<mode>_2"
6667 [(set (reg FLAGS_REG)
6670 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6671 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6673 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6674 (minus:SWI (match_dup 1) (match_dup 2)))]
6675 "ix86_match_ccmode (insn, CCGOCmode)
6676 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6677 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6678 [(set_attr "type" "alu")
6679 (set_attr "mode" "<MODE>")])
6681 (define_insn "*subsi_2_zext"
6682 [(set (reg FLAGS_REG)
6684 (minus:SI (match_operand:SI 1 "register_operand" "0")
6685 (match_operand:SI 2 "general_operand" "g"))
6687 (set (match_operand:DI 0 "register_operand" "=r")
6689 (minus:SI (match_dup 1)
6691 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6692 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6693 "sub{l}\t{%2, %k0|%k0, %2}"
6694 [(set_attr "type" "alu")
6695 (set_attr "mode" "SI")])
6697 (define_insn "*sub<mode>_3"
6698 [(set (reg FLAGS_REG)
6699 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6700 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6701 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6702 (minus:SWI (match_dup 1) (match_dup 2)))]
6703 "ix86_match_ccmode (insn, CCmode)
6704 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6705 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6706 [(set_attr "type" "alu")
6707 (set_attr "mode" "<MODE>")])
6709 (define_insn "*subsi_3_zext"
6710 [(set (reg FLAGS_REG)
6711 (compare (match_operand:SI 1 "register_operand" "0")
6712 (match_operand:SI 2 "general_operand" "g")))
6713 (set (match_operand:DI 0 "register_operand" "=r")
6715 (minus:SI (match_dup 1)
6717 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6718 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6719 "sub{l}\t{%2, %1|%1, %2}"
6720 [(set_attr "type" "alu")
6721 (set_attr "mode" "SI")])
6723 ;; Add with carry and subtract with borrow
6725 (define_expand "<plusminus_insn><mode>3_carry"
6727 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6729 (match_operand:SWI 1 "nonimmediate_operand" "")
6730 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6731 [(match_operand 3 "flags_reg_operand" "")
6733 (match_operand:SWI 2 "<general_operand>" ""))))
6734 (clobber (reg:CC FLAGS_REG))])]
6735 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6737 (define_insn "*<plusminus_insn><mode>3_carry"
6738 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6740 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6742 (match_operator 3 "ix86_carry_flag_operator"
6743 [(reg FLAGS_REG) (const_int 0)])
6744 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6745 (clobber (reg:CC FLAGS_REG))]
6746 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6747 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6748 [(set_attr "type" "alu")
6749 (set_attr "use_carry" "1")
6750 (set_attr "pent_pair" "pu")
6751 (set_attr "mode" "<MODE>")])
6753 (define_insn "*addsi3_carry_zext"
6754 [(set (match_operand:DI 0 "register_operand" "=r")
6756 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6757 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6758 [(reg FLAGS_REG) (const_int 0)])
6759 (match_operand:SI 2 "general_operand" "g")))))
6760 (clobber (reg:CC FLAGS_REG))]
6761 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6762 "adc{l}\t{%2, %k0|%k0, %2}"
6763 [(set_attr "type" "alu")
6764 (set_attr "use_carry" "1")
6765 (set_attr "pent_pair" "pu")
6766 (set_attr "mode" "SI")])
6768 (define_insn "*subsi3_carry_zext"
6769 [(set (match_operand:DI 0 "register_operand" "=r")
6771 (minus:SI (match_operand:SI 1 "register_operand" "0")
6772 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6773 [(reg FLAGS_REG) (const_int 0)])
6774 (match_operand:SI 2 "general_operand" "g")))))
6775 (clobber (reg:CC FLAGS_REG))]
6776 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6777 "sbb{l}\t{%2, %k0|%k0, %2}"
6778 [(set_attr "type" "alu")
6779 (set_attr "pent_pair" "pu")
6780 (set_attr "mode" "SI")])
6782 ;; Overflow setting add and subtract instructions
6784 (define_insn "*add<mode>3_cconly_overflow"
6785 [(set (reg:CCC FLAGS_REG)
6788 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6789 (match_operand:SWI 2 "<general_operand>" "<g>"))
6791 (clobber (match_scratch:SWI 0 "=<r>"))]
6792 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6793 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6794 [(set_attr "type" "alu")
6795 (set_attr "mode" "<MODE>")])
6797 (define_insn "*sub<mode>3_cconly_overflow"
6798 [(set (reg:CCC FLAGS_REG)
6801 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6802 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6805 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6806 [(set_attr "type" "icmp")
6807 (set_attr "mode" "<MODE>")])
6809 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6810 [(set (reg:CCC FLAGS_REG)
6813 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6814 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6816 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6817 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6818 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6819 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6820 [(set_attr "type" "alu")
6821 (set_attr "mode" "<MODE>")])
6823 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6824 [(set (reg:CCC FLAGS_REG)
6827 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6828 (match_operand:SI 2 "general_operand" "g"))
6830 (set (match_operand:DI 0 "register_operand" "=r")
6831 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6832 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6833 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6834 [(set_attr "type" "alu")
6835 (set_attr "mode" "SI")])
6837 ;; The patterns that match these are at the end of this file.
6839 (define_expand "<plusminus_insn>xf3"
6840 [(set (match_operand:XF 0 "register_operand" "")
6842 (match_operand:XF 1 "register_operand" "")
6843 (match_operand:XF 2 "register_operand" "")))]
6846 (define_expand "<plusminus_insn><mode>3"
6847 [(set (match_operand:MODEF 0 "register_operand" "")
6849 (match_operand:MODEF 1 "register_operand" "")
6850 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6851 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6852 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6854 ;; Multiply instructions
6856 (define_expand "mul<mode>3"
6857 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6859 (match_operand:SWIM248 1 "register_operand" "")
6860 (match_operand:SWIM248 2 "<general_operand>" "")))
6861 (clobber (reg:CC FLAGS_REG))])])
6863 (define_expand "mulqi3"
6864 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6866 (match_operand:QI 1 "register_operand" "")
6867 (match_operand:QI 2 "nonimmediate_operand" "")))
6868 (clobber (reg:CC FLAGS_REG))])]
6869 "TARGET_QIMODE_MATH")
6872 ;; IMUL reg32/64, reg32/64, imm8 Direct
6873 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6874 ;; IMUL reg32/64, reg32/64, imm32 Direct
6875 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6876 ;; IMUL reg32/64, reg32/64 Direct
6877 ;; IMUL reg32/64, mem32/64 Direct
6879 ;; On BDVER1, all above IMULs use DirectPath
6881 (define_insn "*mul<mode>3_1"
6882 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6884 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6885 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6886 (clobber (reg:CC FLAGS_REG))]
6887 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6889 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6890 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6891 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6892 [(set_attr "type" "imul")
6893 (set_attr "prefix_0f" "0,0,1")
6894 (set (attr "athlon_decode")
6895 (cond [(eq_attr "cpu" "athlon")
6896 (const_string "vector")
6897 (eq_attr "alternative" "1")
6898 (const_string "vector")
6899 (and (eq_attr "alternative" "2")
6900 (match_operand 1 "memory_operand" ""))
6901 (const_string "vector")]
6902 (const_string "direct")))
6903 (set (attr "amdfam10_decode")
6904 (cond [(and (eq_attr "alternative" "0,1")
6905 (match_operand 1 "memory_operand" ""))
6906 (const_string "vector")]
6907 (const_string "direct")))
6908 (set_attr "bdver1_decode" "direct")
6909 (set_attr "mode" "<MODE>")])
6911 (define_insn "*mulsi3_1_zext"
6912 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6914 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6915 (match_operand:SI 2 "general_operand" "K,i,mr"))))
6916 (clobber (reg:CC FLAGS_REG))]
6918 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6920 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6921 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6922 imul{l}\t{%2, %k0|%k0, %2}"
6923 [(set_attr "type" "imul")
6924 (set_attr "prefix_0f" "0,0,1")
6925 (set (attr "athlon_decode")
6926 (cond [(eq_attr "cpu" "athlon")
6927 (const_string "vector")
6928 (eq_attr "alternative" "1")
6929 (const_string "vector")
6930 (and (eq_attr "alternative" "2")
6931 (match_operand 1 "memory_operand" ""))
6932 (const_string "vector")]
6933 (const_string "direct")))
6934 (set (attr "amdfam10_decode")
6935 (cond [(and (eq_attr "alternative" "0,1")
6936 (match_operand 1 "memory_operand" ""))
6937 (const_string "vector")]
6938 (const_string "direct")))
6939 (set_attr "bdver1_decode" "direct")
6940 (set_attr "mode" "SI")])
6943 ;; IMUL reg16, reg16, imm8 VectorPath
6944 ;; IMUL reg16, mem16, imm8 VectorPath
6945 ;; IMUL reg16, reg16, imm16 VectorPath
6946 ;; IMUL reg16, mem16, imm16 VectorPath
6947 ;; IMUL reg16, reg16 Direct
6948 ;; IMUL reg16, mem16 Direct
6950 ;; On BDVER1, all HI MULs use DoublePath
6952 (define_insn "*mulhi3_1"
6953 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6954 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6955 (match_operand:HI 2 "general_operand" "K,n,mr")))
6956 (clobber (reg:CC FLAGS_REG))]
6958 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6960 imul{w}\t{%2, %1, %0|%0, %1, %2}
6961 imul{w}\t{%2, %1, %0|%0, %1, %2}
6962 imul{w}\t{%2, %0|%0, %2}"
6963 [(set_attr "type" "imul")
6964 (set_attr "prefix_0f" "0,0,1")
6965 (set (attr "athlon_decode")
6966 (cond [(eq_attr "cpu" "athlon")
6967 (const_string "vector")
6968 (eq_attr "alternative" "1,2")
6969 (const_string "vector")]
6970 (const_string "direct")))
6971 (set (attr "amdfam10_decode")
6972 (cond [(eq_attr "alternative" "0,1")
6973 (const_string "vector")]
6974 (const_string "direct")))
6975 (set_attr "bdver1_decode" "double")
6976 (set_attr "mode" "HI")])
6978 ;;On AMDFAM10 and BDVER1
6982 (define_insn "*mulqi3_1"
6983 [(set (match_operand:QI 0 "register_operand" "=a")
6984 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6985 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6986 (clobber (reg:CC FLAGS_REG))]
6988 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6990 [(set_attr "type" "imul")
6991 (set_attr "length_immediate" "0")
6992 (set (attr "athlon_decode")
6993 (if_then_else (eq_attr "cpu" "athlon")
6994 (const_string "vector")
6995 (const_string "direct")))
6996 (set_attr "amdfam10_decode" "direct")
6997 (set_attr "bdver1_decode" "direct")
6998 (set_attr "mode" "QI")])
7000 (define_expand "<u>mul<mode><dwi>3"
7001 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7004 (match_operand:DWIH 1 "nonimmediate_operand" ""))
7006 (match_operand:DWIH 2 "register_operand" ""))))
7007 (clobber (reg:CC FLAGS_REG))])])
7009 (define_expand "<u>mulqihi3"
7010 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7013 (match_operand:QI 1 "nonimmediate_operand" ""))
7015 (match_operand:QI 2 "register_operand" ""))))
7016 (clobber (reg:CC FLAGS_REG))])]
7017 "TARGET_QIMODE_MATH")
7019 (define_insn "*<u>mul<mode><dwi>3_1"
7020 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7023 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7025 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7026 (clobber (reg:CC FLAGS_REG))]
7027 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7028 "<sgnprefix>mul{<imodesuffix>}\t%2"
7029 [(set_attr "type" "imul")
7030 (set_attr "length_immediate" "0")
7031 (set (attr "athlon_decode")
7032 (if_then_else (eq_attr "cpu" "athlon")
7033 (const_string "vector")
7034 (const_string "double")))
7035 (set_attr "amdfam10_decode" "double")
7036 (set_attr "bdver1_decode" "direct")
7037 (set_attr "mode" "<MODE>")])
7039 (define_insn "*<u>mulqihi3_1"
7040 [(set (match_operand:HI 0 "register_operand" "=a")
7043 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7045 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7046 (clobber (reg:CC FLAGS_REG))]
7048 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7049 "<sgnprefix>mul{b}\t%2"
7050 [(set_attr "type" "imul")
7051 (set_attr "length_immediate" "0")
7052 (set (attr "athlon_decode")
7053 (if_then_else (eq_attr "cpu" "athlon")
7054 (const_string "vector")
7055 (const_string "direct")))
7056 (set_attr "amdfam10_decode" "direct")
7057 (set_attr "bdver1_decode" "direct")
7058 (set_attr "mode" "QI")])
7060 (define_expand "<s>mul<mode>3_highpart"
7061 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7066 (match_operand:SWI48 1 "nonimmediate_operand" ""))
7068 (match_operand:SWI48 2 "register_operand" "")))
7070 (clobber (match_scratch:SWI48 3 ""))
7071 (clobber (reg:CC FLAGS_REG))])]
7073 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7075 (define_insn "*<s>muldi3_highpart_1"
7076 [(set (match_operand:DI 0 "register_operand" "=d")
7081 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7083 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7085 (clobber (match_scratch:DI 3 "=1"))
7086 (clobber (reg:CC FLAGS_REG))]
7088 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7089 "<sgnprefix>mul{q}\t%2"
7090 [(set_attr "type" "imul")
7091 (set_attr "length_immediate" "0")
7092 (set (attr "athlon_decode")
7093 (if_then_else (eq_attr "cpu" "athlon")
7094 (const_string "vector")
7095 (const_string "double")))
7096 (set_attr "amdfam10_decode" "double")
7097 (set_attr "bdver1_decode" "direct")
7098 (set_attr "mode" "DI")])
7100 (define_insn "*<s>mulsi3_highpart_1"
7101 [(set (match_operand:SI 0 "register_operand" "=d")
7106 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7108 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7110 (clobber (match_scratch:SI 3 "=1"))
7111 (clobber (reg:CC FLAGS_REG))]
7112 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7113 "<sgnprefix>mul{l}\t%2"
7114 [(set_attr "type" "imul")
7115 (set_attr "length_immediate" "0")
7116 (set (attr "athlon_decode")
7117 (if_then_else (eq_attr "cpu" "athlon")
7118 (const_string "vector")
7119 (const_string "double")))
7120 (set_attr "amdfam10_decode" "double")
7121 (set_attr "bdver1_decode" "direct")
7122 (set_attr "mode" "SI")])
7124 (define_insn "*<s>mulsi3_highpart_zext"
7125 [(set (match_operand:DI 0 "register_operand" "=d")
7126 (zero_extend:DI (truncate:SI
7128 (mult:DI (any_extend:DI
7129 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7131 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7133 (clobber (match_scratch:SI 3 "=1"))
7134 (clobber (reg:CC FLAGS_REG))]
7136 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7137 "<sgnprefix>mul{l}\t%2"
7138 [(set_attr "type" "imul")
7139 (set_attr "length_immediate" "0")
7140 (set (attr "athlon_decode")
7141 (if_then_else (eq_attr "cpu" "athlon")
7142 (const_string "vector")
7143 (const_string "double")))
7144 (set_attr "amdfam10_decode" "double")
7145 (set_attr "bdver1_decode" "direct")
7146 (set_attr "mode" "SI")])
7148 ;; The patterns that match these are at the end of this file.
7150 (define_expand "mulxf3"
7151 [(set (match_operand:XF 0 "register_operand" "")
7152 (mult:XF (match_operand:XF 1 "register_operand" "")
7153 (match_operand:XF 2 "register_operand" "")))]
7156 (define_expand "mul<mode>3"
7157 [(set (match_operand:MODEF 0 "register_operand" "")
7158 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7159 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7160 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7161 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7163 ;; Divide instructions
7165 ;; The patterns that match these are at the end of this file.
7167 (define_expand "divxf3"
7168 [(set (match_operand:XF 0 "register_operand" "")
7169 (div:XF (match_operand:XF 1 "register_operand" "")
7170 (match_operand:XF 2 "register_operand" "")))]
7173 (define_expand "divdf3"
7174 [(set (match_operand:DF 0 "register_operand" "")
7175 (div:DF (match_operand:DF 1 "register_operand" "")
7176 (match_operand:DF 2 "nonimmediate_operand" "")))]
7177 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7178 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7180 (define_expand "divsf3"
7181 [(set (match_operand:SF 0 "register_operand" "")
7182 (div:SF (match_operand:SF 1 "register_operand" "")
7183 (match_operand:SF 2 "nonimmediate_operand" "")))]
7184 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7187 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7188 && flag_finite_math_only && !flag_trapping_math
7189 && flag_unsafe_math_optimizations)
7191 ix86_emit_swdivsf (operands[0], operands[1],
7192 operands[2], SFmode);
7197 ;; Divmod instructions.
7199 (define_expand "divmod<mode>4"
7200 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7202 (match_operand:SWIM248 1 "register_operand" "")
7203 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7204 (set (match_operand:SWIM248 3 "register_operand" "")
7205 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7206 (clobber (reg:CC FLAGS_REG))])])
7208 ;; Split with 8bit unsigned divide:
7209 ;; if (dividend an divisor are in [0-255])
7210 ;; use 8bit unsigned integer divide
7212 ;; use original integer divide
7214 [(set (match_operand:SWI48 0 "register_operand" "")
7215 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7216 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7217 (set (match_operand:SWI48 1 "register_operand" "")
7218 (mod:SWI48 (match_dup 2) (match_dup 3)))
7219 (clobber (reg:CC FLAGS_REG))]
7220 "TARGET_USE_8BIT_IDIV
7221 && TARGET_QIMODE_MATH
7222 && can_create_pseudo_p ()
7223 && !optimize_insn_for_size_p ()"
7225 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7227 (define_insn_and_split "divmod<mode>4_1"
7228 [(set (match_operand:SWI48 0 "register_operand" "=a")
7229 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7230 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7231 (set (match_operand:SWI48 1 "register_operand" "=&d")
7232 (mod:SWI48 (match_dup 2) (match_dup 3)))
7233 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7234 (clobber (reg:CC FLAGS_REG))]
7238 [(parallel [(set (match_dup 1)
7239 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7240 (clobber (reg:CC FLAGS_REG))])
7241 (parallel [(set (match_dup 0)
7242 (div:SWI48 (match_dup 2) (match_dup 3)))
7244 (mod:SWI48 (match_dup 2) (match_dup 3)))
7246 (clobber (reg:CC FLAGS_REG))])]
7248 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7250 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7251 operands[4] = operands[2];
7254 /* Avoid use of cltd in favor of a mov+shift. */
7255 emit_move_insn (operands[1], operands[2]);
7256 operands[4] = operands[1];
7259 [(set_attr "type" "multi")
7260 (set_attr "mode" "<MODE>")])
7262 (define_insn_and_split "*divmod<mode>4"
7263 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7264 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7265 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7266 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7267 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7268 (clobber (reg:CC FLAGS_REG))]
7272 [(parallel [(set (match_dup 1)
7273 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7274 (clobber (reg:CC FLAGS_REG))])
7275 (parallel [(set (match_dup 0)
7276 (div:SWIM248 (match_dup 2) (match_dup 3)))
7278 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7280 (clobber (reg:CC FLAGS_REG))])]
7282 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7284 if (<MODE>mode != HImode
7285 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7286 operands[4] = operands[2];
7289 /* Avoid use of cltd in favor of a mov+shift. */
7290 emit_move_insn (operands[1], operands[2]);
7291 operands[4] = operands[1];
7294 [(set_attr "type" "multi")
7295 (set_attr "mode" "<MODE>")])
7297 (define_insn "*divmod<mode>4_noext"
7298 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7299 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7300 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7301 (set (match_operand:SWIM248 1 "register_operand" "=d")
7302 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7303 (use (match_operand:SWIM248 4 "register_operand" "1"))
7304 (clobber (reg:CC FLAGS_REG))]
7306 "idiv{<imodesuffix>}\t%3"
7307 [(set_attr "type" "idiv")
7308 (set_attr "mode" "<MODE>")])
7310 (define_expand "divmodqi4"
7311 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7313 (match_operand:QI 1 "register_operand" "")
7314 (match_operand:QI 2 "nonimmediate_operand" "")))
7315 (set (match_operand:QI 3 "register_operand" "")
7316 (mod:QI (match_dup 1) (match_dup 2)))
7317 (clobber (reg:CC FLAGS_REG))])]
7318 "TARGET_QIMODE_MATH"
7323 tmp0 = gen_reg_rtx (HImode);
7324 tmp1 = gen_reg_rtx (HImode);
7326 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7328 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7329 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7331 /* Extract remainder from AH. */
7332 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7333 insn = emit_move_insn (operands[3], tmp1);
7335 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7336 set_unique_reg_note (insn, REG_EQUAL, mod);
7338 /* Extract quotient from AL. */
7339 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7341 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7342 set_unique_reg_note (insn, REG_EQUAL, div);
7347 ;; Divide AX by r/m8, with result stored in
7350 ;; Change div/mod to HImode and extend the second argument to HImode
7351 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7352 ;; combine may fail.
7353 (define_insn "divmodhiqi3"
7354 [(set (match_operand:HI 0 "register_operand" "=a")
7359 (mod:HI (match_operand:HI 1 "register_operand" "0")
7361 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7365 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7366 (clobber (reg:CC FLAGS_REG))]
7367 "TARGET_QIMODE_MATH"
7369 [(set_attr "type" "idiv")
7370 (set_attr "mode" "QI")])
7372 (define_expand "udivmod<mode>4"
7373 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7375 (match_operand:SWIM248 1 "register_operand" "")
7376 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7377 (set (match_operand:SWIM248 3 "register_operand" "")
7378 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7379 (clobber (reg:CC FLAGS_REG))])])
7381 ;; Split with 8bit unsigned divide:
7382 ;; if (dividend an divisor are in [0-255])
7383 ;; use 8bit unsigned integer divide
7385 ;; use original integer divide
7387 [(set (match_operand:SWI48 0 "register_operand" "")
7388 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7389 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7390 (set (match_operand:SWI48 1 "register_operand" "")
7391 (umod:SWI48 (match_dup 2) (match_dup 3)))
7392 (clobber (reg:CC FLAGS_REG))]
7393 "TARGET_USE_8BIT_IDIV
7394 && TARGET_QIMODE_MATH
7395 && can_create_pseudo_p ()
7396 && !optimize_insn_for_size_p ()"
7398 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7400 (define_insn_and_split "udivmod<mode>4_1"
7401 [(set (match_operand:SWI48 0 "register_operand" "=a")
7402 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7403 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7404 (set (match_operand:SWI48 1 "register_operand" "=&d")
7405 (umod:SWI48 (match_dup 2) (match_dup 3)))
7406 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7407 (clobber (reg:CC FLAGS_REG))]
7411 [(set (match_dup 1) (const_int 0))
7412 (parallel [(set (match_dup 0)
7413 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7415 (umod:SWI48 (match_dup 2) (match_dup 3)))
7417 (clobber (reg:CC FLAGS_REG))])]
7419 [(set_attr "type" "multi")
7420 (set_attr "mode" "<MODE>")])
7422 (define_insn_and_split "*udivmod<mode>4"
7423 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7424 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7425 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7426 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7427 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7428 (clobber (reg:CC FLAGS_REG))]
7432 [(set (match_dup 1) (const_int 0))
7433 (parallel [(set (match_dup 0)
7434 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7436 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7438 (clobber (reg:CC FLAGS_REG))])]
7440 [(set_attr "type" "multi")
7441 (set_attr "mode" "<MODE>")])
7443 (define_insn "*udivmod<mode>4_noext"
7444 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7445 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7446 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7447 (set (match_operand:SWIM248 1 "register_operand" "=d")
7448 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7449 (use (match_operand:SWIM248 4 "register_operand" "1"))
7450 (clobber (reg:CC FLAGS_REG))]
7452 "div{<imodesuffix>}\t%3"
7453 [(set_attr "type" "idiv")
7454 (set_attr "mode" "<MODE>")])
7456 (define_expand "udivmodqi4"
7457 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7459 (match_operand:QI 1 "register_operand" "")
7460 (match_operand:QI 2 "nonimmediate_operand" "")))
7461 (set (match_operand:QI 3 "register_operand" "")
7462 (umod:QI (match_dup 1) (match_dup 2)))
7463 (clobber (reg:CC FLAGS_REG))])]
7464 "TARGET_QIMODE_MATH"
7469 tmp0 = gen_reg_rtx (HImode);
7470 tmp1 = gen_reg_rtx (HImode);
7472 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7474 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7475 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7477 /* Extract remainder from AH. */
7478 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7479 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7480 insn = emit_move_insn (operands[3], tmp1);
7482 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7483 set_unique_reg_note (insn, REG_EQUAL, mod);
7485 /* Extract quotient from AL. */
7486 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7488 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7489 set_unique_reg_note (insn, REG_EQUAL, div);
7494 (define_insn "udivmodhiqi3"
7495 [(set (match_operand:HI 0 "register_operand" "=a")
7500 (mod:HI (match_operand:HI 1 "register_operand" "0")
7502 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7506 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7507 (clobber (reg:CC FLAGS_REG))]
7508 "TARGET_QIMODE_MATH"
7510 [(set_attr "type" "idiv")
7511 (set_attr "mode" "QI")])
7513 ;; We cannot use div/idiv for double division, because it causes
7514 ;; "division by zero" on the overflow and that's not what we expect
7515 ;; from truncate. Because true (non truncating) double division is
7516 ;; never generated, we can't create this insn anyway.
7519 ; [(set (match_operand:SI 0 "register_operand" "=a")
7521 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7523 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7524 ; (set (match_operand:SI 3 "register_operand" "=d")
7526 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7527 ; (clobber (reg:CC FLAGS_REG))]
7529 ; "div{l}\t{%2, %0|%0, %2}"
7530 ; [(set_attr "type" "idiv")])
7532 ;;- Logical AND instructions
7534 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7535 ;; Note that this excludes ah.
7537 (define_expand "testsi_ccno_1"
7538 [(set (reg:CCNO FLAGS_REG)
7540 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7541 (match_operand:SI 1 "nonmemory_operand" ""))
7544 (define_expand "testqi_ccz_1"
7545 [(set (reg:CCZ FLAGS_REG)
7546 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7547 (match_operand:QI 1 "nonmemory_operand" ""))
7550 (define_expand "testdi_ccno_1"
7551 [(set (reg:CCNO FLAGS_REG)
7553 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7554 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7556 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7558 (define_insn "*testdi_1"
7559 [(set (reg FLAGS_REG)
7562 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7563 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7565 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7566 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7568 test{l}\t{%k1, %k0|%k0, %k1}
7569 test{l}\t{%k1, %k0|%k0, %k1}
7570 test{q}\t{%1, %0|%0, %1}
7571 test{q}\t{%1, %0|%0, %1}
7572 test{q}\t{%1, %0|%0, %1}"
7573 [(set_attr "type" "test")
7574 (set_attr "modrm" "0,1,0,1,1")
7575 (set_attr "mode" "SI,SI,DI,DI,DI")])
7577 (define_insn "*testqi_1_maybe_si"
7578 [(set (reg FLAGS_REG)
7581 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7582 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7584 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7585 && ix86_match_ccmode (insn,
7586 CONST_INT_P (operands[1])
7587 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7589 if (which_alternative == 3)
7591 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7592 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7593 return "test{l}\t{%1, %k0|%k0, %1}";
7595 return "test{b}\t{%1, %0|%0, %1}";
7597 [(set_attr "type" "test")
7598 (set_attr "modrm" "0,1,1,1")
7599 (set_attr "mode" "QI,QI,QI,SI")
7600 (set_attr "pent_pair" "uv,np,uv,np")])
7602 (define_insn "*test<mode>_1"
7603 [(set (reg FLAGS_REG)
7606 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7607 (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
7609 "ix86_match_ccmode (insn, CCNOmode)
7610 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7611 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7612 [(set_attr "type" "test")
7613 (set_attr "modrm" "0,1,1")
7614 (set_attr "mode" "<MODE>")
7615 (set_attr "pent_pair" "uv,np,uv")])
7617 (define_expand "testqi_ext_ccno_0"
7618 [(set (reg:CCNO FLAGS_REG)
7622 (match_operand 0 "ext_register_operand" "")
7625 (match_operand 1 "const_int_operand" ""))
7628 (define_insn "*testqi_ext_0"
7629 [(set (reg FLAGS_REG)
7633 (match_operand 0 "ext_register_operand" "Q")
7636 (match_operand 1 "const_int_operand" "n"))
7638 "ix86_match_ccmode (insn, CCNOmode)"
7639 "test{b}\t{%1, %h0|%h0, %1}"
7640 [(set_attr "type" "test")
7641 (set_attr "mode" "QI")
7642 (set_attr "length_immediate" "1")
7643 (set_attr "modrm" "1")
7644 (set_attr "pent_pair" "np")])
7646 (define_insn "*testqi_ext_1_rex64"
7647 [(set (reg FLAGS_REG)
7651 (match_operand 0 "ext_register_operand" "Q")
7655 (match_operand:QI 1 "register_operand" "Q")))
7657 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7658 "test{b}\t{%1, %h0|%h0, %1}"
7659 [(set_attr "type" "test")
7660 (set_attr "mode" "QI")])
7662 (define_insn "*testqi_ext_1"
7663 [(set (reg FLAGS_REG)
7667 (match_operand 0 "ext_register_operand" "Q")
7671 (match_operand:QI 1 "general_operand" "Qm")))
7673 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7674 "test{b}\t{%1, %h0|%h0, %1}"
7675 [(set_attr "type" "test")
7676 (set_attr "mode" "QI")])
7678 (define_insn "*testqi_ext_2"
7679 [(set (reg FLAGS_REG)
7683 (match_operand 0 "ext_register_operand" "Q")
7687 (match_operand 1 "ext_register_operand" "Q")
7691 "ix86_match_ccmode (insn, CCNOmode)"
7692 "test{b}\t{%h1, %h0|%h0, %h1}"
7693 [(set_attr "type" "test")
7694 (set_attr "mode" "QI")])
7696 (define_insn "*testqi_ext_3_rex64"
7697 [(set (reg FLAGS_REG)
7698 (compare (zero_extract:DI
7699 (match_operand 0 "nonimmediate_operand" "rm")
7700 (match_operand:DI 1 "const_int_operand" "")
7701 (match_operand:DI 2 "const_int_operand" ""))
7704 && ix86_match_ccmode (insn, CCNOmode)
7705 && INTVAL (operands[1]) > 0
7706 && INTVAL (operands[2]) >= 0
7707 /* Ensure that resulting mask is zero or sign extended operand. */
7708 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7709 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7710 && INTVAL (operands[1]) > 32))
7711 && (GET_MODE (operands[0]) == SImode
7712 || GET_MODE (operands[0]) == DImode
7713 || GET_MODE (operands[0]) == HImode
7714 || GET_MODE (operands[0]) == QImode)"
7717 ;; Combine likes to form bit extractions for some tests. Humor it.
7718 (define_insn "*testqi_ext_3"
7719 [(set (reg FLAGS_REG)
7720 (compare (zero_extract:SI
7721 (match_operand 0 "nonimmediate_operand" "rm")
7722 (match_operand:SI 1 "const_int_operand" "")
7723 (match_operand:SI 2 "const_int_operand" ""))
7725 "ix86_match_ccmode (insn, CCNOmode)
7726 && INTVAL (operands[1]) > 0
7727 && INTVAL (operands[2]) >= 0
7728 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7729 && (GET_MODE (operands[0]) == SImode
7730 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7731 || GET_MODE (operands[0]) == HImode
7732 || GET_MODE (operands[0]) == QImode)"
7736 [(set (match_operand 0 "flags_reg_operand" "")
7737 (match_operator 1 "compare_operator"
7739 (match_operand 2 "nonimmediate_operand" "")
7740 (match_operand 3 "const_int_operand" "")
7741 (match_operand 4 "const_int_operand" ""))
7743 "ix86_match_ccmode (insn, CCNOmode)"
7744 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7746 rtx val = operands[2];
7747 HOST_WIDE_INT len = INTVAL (operands[3]);
7748 HOST_WIDE_INT pos = INTVAL (operands[4]);
7750 enum machine_mode mode, submode;
7752 mode = GET_MODE (val);
7755 /* ??? Combine likes to put non-volatile mem extractions in QImode
7756 no matter the size of the test. So find a mode that works. */
7757 if (! MEM_VOLATILE_P (val))
7759 mode = smallest_mode_for_size (pos + len, MODE_INT);
7760 val = adjust_address (val, mode, 0);
7763 else if (GET_CODE (val) == SUBREG
7764 && (submode = GET_MODE (SUBREG_REG (val)),
7765 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7766 && pos + len <= GET_MODE_BITSIZE (submode)
7767 && GET_MODE_CLASS (submode) == MODE_INT)
7769 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7771 val = SUBREG_REG (val);
7773 else if (mode == HImode && pos + len <= 8)
7775 /* Small HImode tests can be converted to QImode. */
7777 val = gen_lowpart (QImode, val);
7780 if (len == HOST_BITS_PER_WIDE_INT)
7783 mask = ((HOST_WIDE_INT)1 << len) - 1;
7786 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7789 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7790 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7791 ;; this is relatively important trick.
7792 ;; Do the conversion only post-reload to avoid limiting of the register class
7795 [(set (match_operand 0 "flags_reg_operand" "")
7796 (match_operator 1 "compare_operator"
7797 [(and (match_operand 2 "register_operand" "")
7798 (match_operand 3 "const_int_operand" ""))
7801 && QI_REG_P (operands[2])
7802 && GET_MODE (operands[2]) != QImode
7803 && ((ix86_match_ccmode (insn, CCZmode)
7804 && !(INTVAL (operands[3]) & ~(255 << 8)))
7805 || (ix86_match_ccmode (insn, CCNOmode)
7806 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7809 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7812 "operands[2] = gen_lowpart (SImode, operands[2]);
7813 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
7816 [(set (match_operand 0 "flags_reg_operand" "")
7817 (match_operator 1 "compare_operator"
7818 [(and (match_operand 2 "nonimmediate_operand" "")
7819 (match_operand 3 "const_int_operand" ""))
7822 && GET_MODE (operands[2]) != QImode
7823 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7824 && ((ix86_match_ccmode (insn, CCZmode)
7825 && !(INTVAL (operands[3]) & ~255))
7826 || (ix86_match_ccmode (insn, CCNOmode)
7827 && !(INTVAL (operands[3]) & ~127)))"
7829 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7831 "operands[2] = gen_lowpart (QImode, operands[2]);
7832 operands[3] = gen_lowpart (QImode, operands[3]);")
7834 ;; %%% This used to optimize known byte-wide and operations to memory,
7835 ;; and sometimes to QImode registers. If this is considered useful,
7836 ;; it should be done with splitters.
7838 (define_expand "and<mode>3"
7839 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7840 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7841 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7843 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7845 (define_insn "*anddi_1"
7846 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7848 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7849 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7850 (clobber (reg:CC FLAGS_REG))]
7851 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7853 switch (get_attr_type (insn))
7857 enum machine_mode mode;
7859 gcc_assert (CONST_INT_P (operands[2]));
7860 if (INTVAL (operands[2]) == 0xff)
7864 gcc_assert (INTVAL (operands[2]) == 0xffff);
7868 operands[1] = gen_lowpart (mode, operands[1]);
7870 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7872 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7876 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7877 if (get_attr_mode (insn) == MODE_SI)
7878 return "and{l}\t{%k2, %k0|%k0, %k2}";
7880 return "and{q}\t{%2, %0|%0, %2}";
7883 [(set_attr "type" "alu,alu,alu,imovx")
7884 (set_attr "length_immediate" "*,*,*,0")
7885 (set (attr "prefix_rex")
7887 (and (eq_attr "type" "imovx")
7888 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7889 (match_operand 1 "ext_QIreg_nomode_operand" "")))
7891 (const_string "*")))
7892 (set_attr "mode" "SI,DI,DI,SI")])
7894 (define_insn "*andsi_1"
7895 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7896 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7897 (match_operand:SI 2 "general_operand" "ri,rm,L")))
7898 (clobber (reg:CC FLAGS_REG))]
7899 "ix86_binary_operator_ok (AND, SImode, operands)"
7901 switch (get_attr_type (insn))
7905 enum machine_mode mode;
7907 gcc_assert (CONST_INT_P (operands[2]));
7908 if (INTVAL (operands[2]) == 0xff)
7912 gcc_assert (INTVAL (operands[2]) == 0xffff);
7916 operands[1] = gen_lowpart (mode, operands[1]);
7918 return "movz{bl|x}\t{%1, %0|%0, %1}";
7920 return "movz{wl|x}\t{%1, %0|%0, %1}";
7924 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7925 return "and{l}\t{%2, %0|%0, %2}";
7928 [(set_attr "type" "alu,alu,imovx")
7929 (set (attr "prefix_rex")
7931 (and (eq_attr "type" "imovx")
7932 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
7933 (match_operand 1 "ext_QIreg_nomode_operand" "")))
7935 (const_string "*")))
7936 (set_attr "length_immediate" "*,*,0")
7937 (set_attr "mode" "SI")])
7939 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7940 (define_insn "*andsi_1_zext"
7941 [(set (match_operand:DI 0 "register_operand" "=r")
7943 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7944 (match_operand:SI 2 "general_operand" "g"))))
7945 (clobber (reg:CC FLAGS_REG))]
7946 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7947 "and{l}\t{%2, %k0|%k0, %2}"
7948 [(set_attr "type" "alu")
7949 (set_attr "mode" "SI")])
7951 (define_insn "*andhi_1"
7952 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7953 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7954 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7955 (clobber (reg:CC FLAGS_REG))]
7956 "ix86_binary_operator_ok (AND, HImode, operands)"
7958 switch (get_attr_type (insn))
7961 gcc_assert (CONST_INT_P (operands[2]));
7962 gcc_assert (INTVAL (operands[2]) == 0xff);
7963 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7966 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7968 return "and{w}\t{%2, %0|%0, %2}";
7971 [(set_attr "type" "alu,alu,imovx")
7972 (set_attr "length_immediate" "*,*,0")
7973 (set (attr "prefix_rex")
7975 (and (eq_attr "type" "imovx")
7976 (match_operand 1 "ext_QIreg_nomode_operand" ""))
7978 (const_string "*")))
7979 (set_attr "mode" "HI,HI,SI")])
7981 ;; %%% Potential partial reg stall on alternative 2. What to do?
7982 (define_insn "*andqi_1"
7983 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7984 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7985 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7986 (clobber (reg:CC FLAGS_REG))]
7987 "ix86_binary_operator_ok (AND, QImode, operands)"
7989 and{b}\t{%2, %0|%0, %2}
7990 and{b}\t{%2, %0|%0, %2}
7991 and{l}\t{%k2, %k0|%k0, %k2}"
7992 [(set_attr "type" "alu")
7993 (set_attr "mode" "QI,QI,SI")])
7995 (define_insn "*andqi_1_slp"
7996 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7997 (and:QI (match_dup 0)
7998 (match_operand:QI 1 "general_operand" "qn,qmn")))
7999 (clobber (reg:CC FLAGS_REG))]
8000 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8001 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8002 "and{b}\t{%1, %0|%0, %1}"
8003 [(set_attr "type" "alu1")
8004 (set_attr "mode" "QI")])
8007 [(set (match_operand 0 "register_operand" "")
8009 (const_int -65536)))
8010 (clobber (reg:CC FLAGS_REG))]
8011 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8012 || optimize_function_for_size_p (cfun)"
8013 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8014 "operands[1] = gen_lowpart (HImode, operands[0]);")
8017 [(set (match_operand 0 "ext_register_operand" "")
8020 (clobber (reg:CC FLAGS_REG))]
8021 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8022 && reload_completed"
8023 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8024 "operands[1] = gen_lowpart (QImode, operands[0]);")
8027 [(set (match_operand 0 "ext_register_operand" "")
8029 (const_int -65281)))
8030 (clobber (reg:CC FLAGS_REG))]
8031 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8032 && reload_completed"
8033 [(parallel [(set (zero_extract:SI (match_dup 0)
8037 (zero_extract:SI (match_dup 0)
8040 (zero_extract:SI (match_dup 0)
8043 (clobber (reg:CC FLAGS_REG))])]
8044 "operands[0] = gen_lowpart (SImode, operands[0]);")
8046 (define_insn "*anddi_2"
8047 [(set (reg FLAGS_REG)
8050 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8051 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8053 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8054 (and:DI (match_dup 1) (match_dup 2)))]
8055 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8056 && ix86_binary_operator_ok (AND, DImode, operands)"
8058 and{l}\t{%k2, %k0|%k0, %k2}
8059 and{q}\t{%2, %0|%0, %2}
8060 and{q}\t{%2, %0|%0, %2}"
8061 [(set_attr "type" "alu")
8062 (set_attr "mode" "SI,DI,DI")])
8064 (define_insn "*andqi_2_maybe_si"
8065 [(set (reg FLAGS_REG)
8067 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8068 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8070 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8071 (and:QI (match_dup 1) (match_dup 2)))]
8072 "ix86_binary_operator_ok (AND, QImode, operands)
8073 && ix86_match_ccmode (insn,
8074 CONST_INT_P (operands[2])
8075 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8077 if (which_alternative == 2)
8079 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8080 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8081 return "and{l}\t{%2, %k0|%k0, %2}";
8083 return "and{b}\t{%2, %0|%0, %2}";
8085 [(set_attr "type" "alu")
8086 (set_attr "mode" "QI,QI,SI")])
8088 (define_insn "*and<mode>_2"
8089 [(set (reg FLAGS_REG)
8090 (compare (and:SWI124
8091 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8092 (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
8094 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8095 (and:SWI124 (match_dup 1) (match_dup 2)))]
8096 "ix86_match_ccmode (insn, CCNOmode)
8097 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8098 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8099 [(set_attr "type" "alu")
8100 (set_attr "mode" "<MODE>")])
8102 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8103 (define_insn "*andsi_2_zext"
8104 [(set (reg FLAGS_REG)
8106 (match_operand:SI 1 "nonimmediate_operand" "%0")
8107 (match_operand:SI 2 "general_operand" "g"))
8109 (set (match_operand:DI 0 "register_operand" "=r")
8110 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8111 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8112 && ix86_binary_operator_ok (AND, SImode, operands)"
8113 "and{l}\t{%2, %k0|%k0, %2}"
8114 [(set_attr "type" "alu")
8115 (set_attr "mode" "SI")])
8117 (define_insn "*andqi_2_slp"
8118 [(set (reg FLAGS_REG)
8120 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8121 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8123 (set (strict_low_part (match_dup 0))
8124 (and:QI (match_dup 0) (match_dup 1)))]
8125 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8126 && ix86_match_ccmode (insn, CCNOmode)
8127 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8128 "and{b}\t{%1, %0|%0, %1}"
8129 [(set_attr "type" "alu1")
8130 (set_attr "mode" "QI")])
8132 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8133 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8134 ;; for a QImode operand, which of course failed.
8135 (define_insn "andqi_ext_0"
8136 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8141 (match_operand 1 "ext_register_operand" "0")
8144 (match_operand 2 "const_int_operand" "n")))
8145 (clobber (reg:CC FLAGS_REG))]
8147 "and{b}\t{%2, %h0|%h0, %2}"
8148 [(set_attr "type" "alu")
8149 (set_attr "length_immediate" "1")
8150 (set_attr "modrm" "1")
8151 (set_attr "mode" "QI")])
8153 ;; Generated by peephole translating test to and. This shows up
8154 ;; often in fp comparisons.
8155 (define_insn "*andqi_ext_0_cc"
8156 [(set (reg FLAGS_REG)
8160 (match_operand 1 "ext_register_operand" "0")
8163 (match_operand 2 "const_int_operand" "n"))
8165 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8174 "ix86_match_ccmode (insn, CCNOmode)"
8175 "and{b}\t{%2, %h0|%h0, %2}"
8176 [(set_attr "type" "alu")
8177 (set_attr "length_immediate" "1")
8178 (set_attr "modrm" "1")
8179 (set_attr "mode" "QI")])
8181 (define_insn "*andqi_ext_1_rex64"
8182 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8187 (match_operand 1 "ext_register_operand" "0")
8191 (match_operand 2 "ext_register_operand" "Q"))))
8192 (clobber (reg:CC FLAGS_REG))]
8194 "and{b}\t{%2, %h0|%h0, %2}"
8195 [(set_attr "type" "alu")
8196 (set_attr "length_immediate" "0")
8197 (set_attr "mode" "QI")])
8199 (define_insn "*andqi_ext_1"
8200 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8205 (match_operand 1 "ext_register_operand" "0")
8209 (match_operand:QI 2 "general_operand" "Qm"))))
8210 (clobber (reg:CC FLAGS_REG))]
8212 "and{b}\t{%2, %h0|%h0, %2}"
8213 [(set_attr "type" "alu")
8214 (set_attr "length_immediate" "0")
8215 (set_attr "mode" "QI")])
8217 (define_insn "*andqi_ext_2"
8218 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8223 (match_operand 1 "ext_register_operand" "%0")
8227 (match_operand 2 "ext_register_operand" "Q")
8230 (clobber (reg:CC FLAGS_REG))]
8232 "and{b}\t{%h2, %h0|%h0, %h2}"
8233 [(set_attr "type" "alu")
8234 (set_attr "length_immediate" "0")
8235 (set_attr "mode" "QI")])
8237 ;; Convert wide AND instructions with immediate operand to shorter QImode
8238 ;; equivalents when possible.
8239 ;; Don't do the splitting with memory operands, since it introduces risk
8240 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8241 ;; for size, but that can (should?) be handled by generic code instead.
8243 [(set (match_operand 0 "register_operand" "")
8244 (and (match_operand 1 "register_operand" "")
8245 (match_operand 2 "const_int_operand" "")))
8246 (clobber (reg:CC FLAGS_REG))]
8248 && QI_REG_P (operands[0])
8249 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8250 && !(~INTVAL (operands[2]) & ~(255 << 8))
8251 && GET_MODE (operands[0]) != QImode"
8252 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8253 (and:SI (zero_extract:SI (match_dup 1)
8254 (const_int 8) (const_int 8))
8256 (clobber (reg:CC FLAGS_REG))])]
8257 "operands[0] = gen_lowpart (SImode, operands[0]);
8258 operands[1] = gen_lowpart (SImode, operands[1]);
8259 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8261 ;; Since AND can be encoded with sign extended immediate, this is only
8262 ;; profitable when 7th bit is not set.
8264 [(set (match_operand 0 "register_operand" "")
8265 (and (match_operand 1 "general_operand" "")
8266 (match_operand 2 "const_int_operand" "")))
8267 (clobber (reg:CC FLAGS_REG))]
8269 && ANY_QI_REG_P (operands[0])
8270 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8271 && !(~INTVAL (operands[2]) & ~255)
8272 && !(INTVAL (operands[2]) & 128)
8273 && GET_MODE (operands[0]) != QImode"
8274 [(parallel [(set (strict_low_part (match_dup 0))
8275 (and:QI (match_dup 1)
8277 (clobber (reg:CC FLAGS_REG))])]
8278 "operands[0] = gen_lowpart (QImode, operands[0]);
8279 operands[1] = gen_lowpart (QImode, operands[1]);
8280 operands[2] = gen_lowpart (QImode, operands[2]);")
8282 ;; Logical inclusive and exclusive OR instructions
8284 ;; %%% This used to optimize known byte-wide and operations to memory.
8285 ;; If this is considered useful, it should be done with splitters.
8287 (define_expand "<code><mode>3"
8288 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8289 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8290 (match_operand:SWIM 2 "<general_operand>" "")))]
8292 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8294 (define_insn "*<code><mode>_1"
8295 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8297 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8298 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8299 (clobber (reg:CC FLAGS_REG))]
8300 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8301 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8302 [(set_attr "type" "alu")
8303 (set_attr "mode" "<MODE>")])
8305 ;; %%% Potential partial reg stall on alternative 2. What to do?
8306 (define_insn "*<code>qi_1"
8307 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8308 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8309 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8310 (clobber (reg:CC FLAGS_REG))]
8311 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8313 <logic>{b}\t{%2, %0|%0, %2}
8314 <logic>{b}\t{%2, %0|%0, %2}
8315 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8316 [(set_attr "type" "alu")
8317 (set_attr "mode" "QI,QI,SI")])
8319 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8320 (define_insn "*<code>si_1_zext"
8321 [(set (match_operand:DI 0 "register_operand" "=r")
8323 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8324 (match_operand:SI 2 "general_operand" "g"))))
8325 (clobber (reg:CC FLAGS_REG))]
8326 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8327 "<logic>{l}\t{%2, %k0|%k0, %2}"
8328 [(set_attr "type" "alu")
8329 (set_attr "mode" "SI")])
8331 (define_insn "*<code>si_1_zext_imm"
8332 [(set (match_operand:DI 0 "register_operand" "=r")
8334 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8335 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8336 (clobber (reg:CC FLAGS_REG))]
8337 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8338 "<logic>{l}\t{%2, %k0|%k0, %2}"
8339 [(set_attr "type" "alu")
8340 (set_attr "mode" "SI")])
8342 (define_insn "*<code>qi_1_slp"
8343 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8344 (any_or:QI (match_dup 0)
8345 (match_operand:QI 1 "general_operand" "qmn,qn")))
8346 (clobber (reg:CC FLAGS_REG))]
8347 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8348 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8349 "<logic>{b}\t{%1, %0|%0, %1}"
8350 [(set_attr "type" "alu1")
8351 (set_attr "mode" "QI")])
8353 (define_insn "*<code><mode>_2"
8354 [(set (reg FLAGS_REG)
8355 (compare (any_or:SWI
8356 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8357 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8359 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8360 (any_or:SWI (match_dup 1) (match_dup 2)))]
8361 "ix86_match_ccmode (insn, CCNOmode)
8362 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8363 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8364 [(set_attr "type" "alu")
8365 (set_attr "mode" "<MODE>")])
8367 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8368 ;; ??? Special case for immediate operand is missing - it is tricky.
8369 (define_insn "*<code>si_2_zext"
8370 [(set (reg FLAGS_REG)
8371 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8372 (match_operand:SI 2 "general_operand" "g"))
8374 (set (match_operand:DI 0 "register_operand" "=r")
8375 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8376 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8377 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8378 "<logic>{l}\t{%2, %k0|%k0, %2}"
8379 [(set_attr "type" "alu")
8380 (set_attr "mode" "SI")])
8382 (define_insn "*<code>si_2_zext_imm"
8383 [(set (reg FLAGS_REG)
8385 (match_operand:SI 1 "nonimmediate_operand" "%0")
8386 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8388 (set (match_operand:DI 0 "register_operand" "=r")
8389 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8390 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8391 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8392 "<logic>{l}\t{%2, %k0|%k0, %2}"
8393 [(set_attr "type" "alu")
8394 (set_attr "mode" "SI")])
8396 (define_insn "*<code>qi_2_slp"
8397 [(set (reg FLAGS_REG)
8398 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8399 (match_operand:QI 1 "general_operand" "qmn,qn"))
8401 (set (strict_low_part (match_dup 0))
8402 (any_or:QI (match_dup 0) (match_dup 1)))]
8403 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8404 && ix86_match_ccmode (insn, CCNOmode)
8405 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8406 "<logic>{b}\t{%1, %0|%0, %1}"
8407 [(set_attr "type" "alu1")
8408 (set_attr "mode" "QI")])
8410 (define_insn "*<code><mode>_3"
8411 [(set (reg FLAGS_REG)
8412 (compare (any_or:SWI
8413 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8414 (match_operand:SWI 2 "<general_operand>" "<g>"))
8416 (clobber (match_scratch:SWI 0 "=<r>"))]
8417 "ix86_match_ccmode (insn, CCNOmode)
8418 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8419 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8420 [(set_attr "type" "alu")
8421 (set_attr "mode" "<MODE>")])
8423 (define_insn "*<code>qi_ext_0"
8424 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8429 (match_operand 1 "ext_register_operand" "0")
8432 (match_operand 2 "const_int_operand" "n")))
8433 (clobber (reg:CC FLAGS_REG))]
8434 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8435 "<logic>{b}\t{%2, %h0|%h0, %2}"
8436 [(set_attr "type" "alu")
8437 (set_attr "length_immediate" "1")
8438 (set_attr "modrm" "1")
8439 (set_attr "mode" "QI")])
8441 (define_insn "*<code>qi_ext_1_rex64"
8442 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8447 (match_operand 1 "ext_register_operand" "0")
8451 (match_operand 2 "ext_register_operand" "Q"))))
8452 (clobber (reg:CC FLAGS_REG))]
8454 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8455 "<logic>{b}\t{%2, %h0|%h0, %2}"
8456 [(set_attr "type" "alu")
8457 (set_attr "length_immediate" "0")
8458 (set_attr "mode" "QI")])
8460 (define_insn "*<code>qi_ext_1"
8461 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8466 (match_operand 1 "ext_register_operand" "0")
8470 (match_operand:QI 2 "general_operand" "Qm"))))
8471 (clobber (reg:CC FLAGS_REG))]
8473 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8474 "<logic>{b}\t{%2, %h0|%h0, %2}"
8475 [(set_attr "type" "alu")
8476 (set_attr "length_immediate" "0")
8477 (set_attr "mode" "QI")])
8479 (define_insn "*<code>qi_ext_2"
8480 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8484 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8487 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8490 (clobber (reg:CC FLAGS_REG))]
8491 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8492 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8493 [(set_attr "type" "alu")
8494 (set_attr "length_immediate" "0")
8495 (set_attr "mode" "QI")])
8498 [(set (match_operand 0 "register_operand" "")
8499 (any_or (match_operand 1 "register_operand" "")
8500 (match_operand 2 "const_int_operand" "")))
8501 (clobber (reg:CC FLAGS_REG))]
8503 && QI_REG_P (operands[0])
8504 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8505 && !(INTVAL (operands[2]) & ~(255 << 8))
8506 && GET_MODE (operands[0]) != QImode"
8507 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8508 (any_or:SI (zero_extract:SI (match_dup 1)
8509 (const_int 8) (const_int 8))
8511 (clobber (reg:CC FLAGS_REG))])]
8512 "operands[0] = gen_lowpart (SImode, operands[0]);
8513 operands[1] = gen_lowpart (SImode, operands[1]);
8514 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8516 ;; Since OR can be encoded with sign extended immediate, this is only
8517 ;; profitable when 7th bit is set.
8519 [(set (match_operand 0 "register_operand" "")
8520 (any_or (match_operand 1 "general_operand" "")
8521 (match_operand 2 "const_int_operand" "")))
8522 (clobber (reg:CC FLAGS_REG))]
8524 && ANY_QI_REG_P (operands[0])
8525 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8526 && !(INTVAL (operands[2]) & ~255)
8527 && (INTVAL (operands[2]) & 128)
8528 && GET_MODE (operands[0]) != QImode"
8529 [(parallel [(set (strict_low_part (match_dup 0))
8530 (any_or:QI (match_dup 1)
8532 (clobber (reg:CC FLAGS_REG))])]
8533 "operands[0] = gen_lowpart (QImode, operands[0]);
8534 operands[1] = gen_lowpart (QImode, operands[1]);
8535 operands[2] = gen_lowpart (QImode, operands[2]);")
8537 (define_expand "xorqi_cc_ext_1"
8539 (set (reg:CCNO FLAGS_REG)
8543 (match_operand 1 "ext_register_operand" "")
8546 (match_operand:QI 2 "general_operand" ""))
8548 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8558 (define_insn "*xorqi_cc_ext_1_rex64"
8559 [(set (reg FLAGS_REG)
8563 (match_operand 1 "ext_register_operand" "0")
8566 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8568 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8577 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8578 "xor{b}\t{%2, %h0|%h0, %2}"
8579 [(set_attr "type" "alu")
8580 (set_attr "modrm" "1")
8581 (set_attr "mode" "QI")])
8583 (define_insn "*xorqi_cc_ext_1"
8584 [(set (reg FLAGS_REG)
8588 (match_operand 1 "ext_register_operand" "0")
8591 (match_operand:QI 2 "general_operand" "qmn"))
8593 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8602 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8603 "xor{b}\t{%2, %h0|%h0, %2}"
8604 [(set_attr "type" "alu")
8605 (set_attr "modrm" "1")
8606 (set_attr "mode" "QI")])
8608 ;; Negation instructions
8610 (define_expand "neg<mode>2"
8611 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8612 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8614 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8616 (define_insn_and_split "*neg<dwi>2_doubleword"
8617 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8618 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8619 (clobber (reg:CC FLAGS_REG))]
8620 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8624 [(set (reg:CCZ FLAGS_REG)
8625 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8626 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8629 (plus:DWIH (match_dup 3)
8630 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8632 (clobber (reg:CC FLAGS_REG))])
8635 (neg:DWIH (match_dup 2)))
8636 (clobber (reg:CC FLAGS_REG))])]
8637 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8639 (define_insn "*neg<mode>2_1"
8640 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8641 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8642 (clobber (reg:CC FLAGS_REG))]
8643 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8644 "neg{<imodesuffix>}\t%0"
8645 [(set_attr "type" "negnot")
8646 (set_attr "mode" "<MODE>")])
8648 ;; Combine is quite creative about this pattern.
8649 (define_insn "*negsi2_1_zext"
8650 [(set (match_operand:DI 0 "register_operand" "=r")
8652 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8655 (clobber (reg:CC FLAGS_REG))]
8656 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8658 [(set_attr "type" "negnot")
8659 (set_attr "mode" "SI")])
8661 ;; The problem with neg is that it does not perform (compare x 0),
8662 ;; it really performs (compare 0 x), which leaves us with the zero
8663 ;; flag being the only useful item.
8665 (define_insn "*neg<mode>2_cmpz"
8666 [(set (reg:CCZ FLAGS_REG)
8668 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8670 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8671 (neg:SWI (match_dup 1)))]
8672 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8673 "neg{<imodesuffix>}\t%0"
8674 [(set_attr "type" "negnot")
8675 (set_attr "mode" "<MODE>")])
8677 (define_insn "*negsi2_cmpz_zext"
8678 [(set (reg:CCZ FLAGS_REG)
8682 (match_operand:DI 1 "register_operand" "0")
8686 (set (match_operand:DI 0 "register_operand" "=r")
8687 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8690 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8692 [(set_attr "type" "negnot")
8693 (set_attr "mode" "SI")])
8695 ;; Changing of sign for FP values is doable using integer unit too.
8697 (define_expand "<code><mode>2"
8698 [(set (match_operand:X87MODEF 0 "register_operand" "")
8699 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8700 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8701 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8703 (define_insn "*absneg<mode>2_mixed"
8704 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8705 (match_operator:MODEF 3 "absneg_operator"
8706 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8707 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8708 (clobber (reg:CC FLAGS_REG))]
8709 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8712 (define_insn "*absneg<mode>2_sse"
8713 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8714 (match_operator:MODEF 3 "absneg_operator"
8715 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8716 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8717 (clobber (reg:CC FLAGS_REG))]
8718 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8721 (define_insn "*absneg<mode>2_i387"
8722 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8723 (match_operator:X87MODEF 3 "absneg_operator"
8724 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8725 (use (match_operand 2 "" ""))
8726 (clobber (reg:CC FLAGS_REG))]
8727 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8730 (define_expand "<code>tf2"
8731 [(set (match_operand:TF 0 "register_operand" "")
8732 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8734 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8736 (define_insn "*absnegtf2_sse"
8737 [(set (match_operand:TF 0 "register_operand" "=x,x")
8738 (match_operator:TF 3 "absneg_operator"
8739 [(match_operand:TF 1 "register_operand" "0,x")]))
8740 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8741 (clobber (reg:CC FLAGS_REG))]
8745 ;; Splitters for fp abs and neg.
8748 [(set (match_operand 0 "fp_register_operand" "")
8749 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8750 (use (match_operand 2 "" ""))
8751 (clobber (reg:CC FLAGS_REG))]
8753 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8756 [(set (match_operand 0 "register_operand" "")
8757 (match_operator 3 "absneg_operator"
8758 [(match_operand 1 "register_operand" "")]))
8759 (use (match_operand 2 "nonimmediate_operand" ""))
8760 (clobber (reg:CC FLAGS_REG))]
8761 "reload_completed && SSE_REG_P (operands[0])"
8762 [(set (match_dup 0) (match_dup 3))]
8764 enum machine_mode mode = GET_MODE (operands[0]);
8765 enum machine_mode vmode = GET_MODE (operands[2]);
8768 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8769 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8770 if (operands_match_p (operands[0], operands[2]))
8773 operands[1] = operands[2];
8776 if (GET_CODE (operands[3]) == ABS)
8777 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8779 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8784 [(set (match_operand:SF 0 "register_operand" "")
8785 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8786 (use (match_operand:V4SF 2 "" ""))
8787 (clobber (reg:CC FLAGS_REG))]
8789 [(parallel [(set (match_dup 0) (match_dup 1))
8790 (clobber (reg:CC FLAGS_REG))])]
8793 operands[0] = gen_lowpart (SImode, operands[0]);
8794 if (GET_CODE (operands[1]) == ABS)
8796 tmp = gen_int_mode (0x7fffffff, SImode);
8797 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8801 tmp = gen_int_mode (0x80000000, SImode);
8802 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8808 [(set (match_operand:DF 0 "register_operand" "")
8809 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8810 (use (match_operand 2 "" ""))
8811 (clobber (reg:CC FLAGS_REG))]
8813 [(parallel [(set (match_dup 0) (match_dup 1))
8814 (clobber (reg:CC FLAGS_REG))])]
8819 tmp = gen_lowpart (DImode, operands[0]);
8820 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8823 if (GET_CODE (operands[1]) == ABS)
8826 tmp = gen_rtx_NOT (DImode, tmp);
8830 operands[0] = gen_highpart (SImode, operands[0]);
8831 if (GET_CODE (operands[1]) == ABS)
8833 tmp = gen_int_mode (0x7fffffff, SImode);
8834 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8838 tmp = gen_int_mode (0x80000000, SImode);
8839 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8846 [(set (match_operand:XF 0 "register_operand" "")
8847 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8848 (use (match_operand 2 "" ""))
8849 (clobber (reg:CC FLAGS_REG))]
8851 [(parallel [(set (match_dup 0) (match_dup 1))
8852 (clobber (reg:CC FLAGS_REG))])]
8855 operands[0] = gen_rtx_REG (SImode,
8856 true_regnum (operands[0])
8857 + (TARGET_64BIT ? 1 : 2));
8858 if (GET_CODE (operands[1]) == ABS)
8860 tmp = GEN_INT (0x7fff);
8861 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8865 tmp = GEN_INT (0x8000);
8866 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8871 ;; Conditionalize these after reload. If they match before reload, we
8872 ;; lose the clobber and ability to use integer instructions.
8874 (define_insn "*<code><mode>2_1"
8875 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8876 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8878 && (reload_completed
8879 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8880 "f<absneg_mnemonic>"
8881 [(set_attr "type" "fsgn")
8882 (set_attr "mode" "<MODE>")])
8884 (define_insn "*<code>extendsfdf2"
8885 [(set (match_operand:DF 0 "register_operand" "=f")
8886 (absneg:DF (float_extend:DF
8887 (match_operand:SF 1 "register_operand" "0"))))]
8888 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8889 "f<absneg_mnemonic>"
8890 [(set_attr "type" "fsgn")
8891 (set_attr "mode" "DF")])
8893 (define_insn "*<code>extendsfxf2"
8894 [(set (match_operand:XF 0 "register_operand" "=f")
8895 (absneg:XF (float_extend:XF
8896 (match_operand:SF 1 "register_operand" "0"))))]
8898 "f<absneg_mnemonic>"
8899 [(set_attr "type" "fsgn")
8900 (set_attr "mode" "XF")])
8902 (define_insn "*<code>extenddfxf2"
8903 [(set (match_operand:XF 0 "register_operand" "=f")
8904 (absneg:XF (float_extend:XF
8905 (match_operand:DF 1 "register_operand" "0"))))]
8907 "f<absneg_mnemonic>"
8908 [(set_attr "type" "fsgn")
8909 (set_attr "mode" "XF")])
8911 ;; Copysign instructions
8913 (define_mode_iterator CSGNMODE [SF DF TF])
8914 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8916 (define_expand "copysign<mode>3"
8917 [(match_operand:CSGNMODE 0 "register_operand" "")
8918 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8919 (match_operand:CSGNMODE 2 "register_operand" "")]
8920 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8921 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8922 "ix86_expand_copysign (operands); DONE;")
8924 (define_insn_and_split "copysign<mode>3_const"
8925 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8927 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8928 (match_operand:CSGNMODE 2 "register_operand" "0")
8929 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8931 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8932 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8934 "&& reload_completed"
8936 "ix86_split_copysign_const (operands); DONE;")
8938 (define_insn "copysign<mode>3_var"
8939 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8941 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8942 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8943 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8944 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8946 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8947 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8948 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8952 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8954 [(match_operand:CSGNMODE 2 "register_operand" "")
8955 (match_operand:CSGNMODE 3 "register_operand" "")
8956 (match_operand:<CSGNVMODE> 4 "" "")
8957 (match_operand:<CSGNVMODE> 5 "" "")]
8959 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8960 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8961 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8962 && reload_completed"
8964 "ix86_split_copysign_var (operands); DONE;")
8966 ;; One complement instructions
8968 (define_expand "one_cmpl<mode>2"
8969 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8970 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8972 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8974 (define_insn "*one_cmpl<mode>2_1"
8975 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8976 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8977 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8978 "not{<imodesuffix>}\t%0"
8979 [(set_attr "type" "negnot")
8980 (set_attr "mode" "<MODE>")])
8982 ;; %%% Potential partial reg stall on alternative 1. What to do?
8983 (define_insn "*one_cmplqi2_1"
8984 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8985 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8986 "ix86_unary_operator_ok (NOT, QImode, operands)"
8990 [(set_attr "type" "negnot")
8991 (set_attr "mode" "QI,SI")])
8993 ;; ??? Currently never generated - xor is used instead.
8994 (define_insn "*one_cmplsi2_1_zext"
8995 [(set (match_operand:DI 0 "register_operand" "=r")
8997 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8998 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9000 [(set_attr "type" "negnot")
9001 (set_attr "mode" "SI")])
9003 (define_insn "*one_cmpl<mode>2_2"
9004 [(set (reg FLAGS_REG)
9005 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9007 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9008 (not:SWI (match_dup 1)))]
9009 "ix86_match_ccmode (insn, CCNOmode)
9010 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9012 [(set_attr "type" "alu1")
9013 (set_attr "mode" "<MODE>")])
9016 [(set (match_operand 0 "flags_reg_operand" "")
9017 (match_operator 2 "compare_operator"
9018 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
9020 (set (match_operand:SWI 1 "nonimmediate_operand" "")
9021 (not:SWI (match_dup 3)))]
9022 "ix86_match_ccmode (insn, CCNOmode)"
9023 [(parallel [(set (match_dup 0)
9024 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9027 (xor:SWI (match_dup 3) (const_int -1)))])])
9029 ;; ??? Currently never generated - xor is used instead.
9030 (define_insn "*one_cmplsi2_2_zext"
9031 [(set (reg FLAGS_REG)
9032 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9034 (set (match_operand:DI 0 "register_operand" "=r")
9035 (zero_extend:DI (not:SI (match_dup 1))))]
9036 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9037 && ix86_unary_operator_ok (NOT, SImode, operands)"
9039 [(set_attr "type" "alu1")
9040 (set_attr "mode" "SI")])
9043 [(set (match_operand 0 "flags_reg_operand" "")
9044 (match_operator 2 "compare_operator"
9045 [(not:SI (match_operand:SI 3 "register_operand" ""))
9047 (set (match_operand:DI 1 "register_operand" "")
9048 (zero_extend:DI (not:SI (match_dup 3))))]
9049 "ix86_match_ccmode (insn, CCNOmode)"
9050 [(parallel [(set (match_dup 0)
9051 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9054 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9056 ;; Shift instructions
9058 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9059 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9060 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9061 ;; from the assembler input.
9063 ;; This instruction shifts the target reg/mem as usual, but instead of
9064 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9065 ;; is a left shift double, bits are taken from the high order bits of
9066 ;; reg, else if the insn is a shift right double, bits are taken from the
9067 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9068 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9070 ;; Since sh[lr]d does not change the `reg' operand, that is done
9071 ;; separately, making all shifts emit pairs of shift double and normal
9072 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9073 ;; support a 63 bit shift, each shift where the count is in a reg expands
9074 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9076 ;; If the shift count is a constant, we need never emit more than one
9077 ;; shift pair, instead using moves and sign extension for counts greater
9080 (define_expand "ashl<mode>3"
9081 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9082 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
9083 (match_operand:QI 2 "nonmemory_operand" "")))]
9085 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9087 (define_insn "*ashl<mode>3_doubleword"
9088 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9089 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9090 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9091 (clobber (reg:CC FLAGS_REG))]
9094 [(set_attr "type" "multi")])
9097 [(set (match_operand:DWI 0 "register_operand" "")
9098 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
9099 (match_operand:QI 2 "nonmemory_operand" "")))
9100 (clobber (reg:CC FLAGS_REG))]
9101 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9103 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9105 ;; By default we don't ask for a scratch register, because when DWImode
9106 ;; values are manipulated, registers are already at a premium. But if
9107 ;; we have one handy, we won't turn it away.
9110 [(match_scratch:DWIH 3 "r")
9111 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9113 (match_operand:<DWI> 1 "nonmemory_operand" "")
9114 (match_operand:QI 2 "nonmemory_operand" "")))
9115 (clobber (reg:CC FLAGS_REG))])
9119 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9121 (define_insn "x86_64_shld"
9122 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9123 (ior:DI (ashift:DI (match_dup 0)
9124 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9125 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9126 (minus:QI (const_int 64) (match_dup 2)))))
9127 (clobber (reg:CC FLAGS_REG))]
9129 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9130 [(set_attr "type" "ishift")
9131 (set_attr "prefix_0f" "1")
9132 (set_attr "mode" "DI")
9133 (set_attr "athlon_decode" "vector")
9134 (set_attr "amdfam10_decode" "vector")
9135 (set_attr "bdver1_decode" "vector")])
9137 (define_insn "x86_shld"
9138 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9139 (ior:SI (ashift:SI (match_dup 0)
9140 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9141 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9142 (minus:QI (const_int 32) (match_dup 2)))))
9143 (clobber (reg:CC FLAGS_REG))]
9145 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9146 [(set_attr "type" "ishift")
9147 (set_attr "prefix_0f" "1")
9148 (set_attr "mode" "SI")
9149 (set_attr "pent_pair" "np")
9150 (set_attr "athlon_decode" "vector")
9151 (set_attr "amdfam10_decode" "vector")
9152 (set_attr "bdver1_decode" "vector")])
9154 (define_expand "x86_shift<mode>_adj_1"
9155 [(set (reg:CCZ FLAGS_REG)
9156 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9159 (set (match_operand:SWI48 0 "register_operand" "")
9160 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9161 (match_operand:SWI48 1 "register_operand" "")
9164 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9165 (match_operand:SWI48 3 "register_operand" "r")
9168 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9170 (define_expand "x86_shift<mode>_adj_2"
9171 [(use (match_operand:SWI48 0 "register_operand" ""))
9172 (use (match_operand:SWI48 1 "register_operand" ""))
9173 (use (match_operand:QI 2 "register_operand" ""))]
9176 rtx label = gen_label_rtx ();
9179 emit_insn (gen_testqi_ccz_1 (operands[2],
9180 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9182 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9183 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9184 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9185 gen_rtx_LABEL_REF (VOIDmode, label),
9187 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9188 JUMP_LABEL (tmp) = label;
9190 emit_move_insn (operands[0], operands[1]);
9191 ix86_expand_clear (operands[1]);
9194 LABEL_NUSES (label) = 1;
9199 ;; Avoid useless masking of count operand.
9200 (define_insn_and_split "*ashl<mode>3_mask"
9201 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9203 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9206 (match_operand:SI 2 "nonimmediate_operand" "c")
9207 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9208 (clobber (reg:CC FLAGS_REG))]
9209 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9210 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9211 == GET_MODE_BITSIZE (<MODE>mode)-1"
9214 [(parallel [(set (match_dup 0)
9215 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9216 (clobber (reg:CC FLAGS_REG))])]
9218 if (can_create_pseudo_p ())
9219 operands [2] = force_reg (SImode, operands[2]);
9221 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9223 [(set_attr "type" "ishift")
9224 (set_attr "mode" "<MODE>")])
9226 (define_insn "*ashl<mode>3_1"
9227 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9228 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l")
9229 (match_operand:QI 2 "nonmemory_operand" "c<S>,M")))
9230 (clobber (reg:CC FLAGS_REG))]
9231 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9233 switch (get_attr_type (insn))
9239 gcc_assert (operands[2] == const1_rtx);
9240 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9241 return "add{<imodesuffix>}\t%0, %0";
9244 if (operands[2] == const1_rtx
9245 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9246 return "sal{<imodesuffix>}\t%0";
9248 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9252 (cond [(eq_attr "alternative" "1")
9253 (const_string "lea")
9254 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9256 (match_operand 0 "register_operand" ""))
9257 (match_operand 2 "const1_operand" ""))
9258 (const_string "alu")
9260 (const_string "ishift")))
9261 (set (attr "length_immediate")
9263 (ior (eq_attr "type" "alu")
9264 (and (eq_attr "type" "ishift")
9265 (and (match_operand 2 "const1_operand" "")
9266 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9269 (const_string "*")))
9270 (set_attr "mode" "<MODE>")])
9272 (define_insn "*ashlsi3_1_zext"
9273 [(set (match_operand:DI 0 "register_operand" "=r,r")
9275 (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9276 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9277 (clobber (reg:CC FLAGS_REG))]
9278 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9280 switch (get_attr_type (insn))
9286 gcc_assert (operands[2] == const1_rtx);
9287 return "add{l}\t%k0, %k0";
9290 if (operands[2] == const1_rtx
9291 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9292 return "sal{l}\t%k0";
9294 return "sal{l}\t{%2, %k0|%k0, %2}";
9298 (cond [(eq_attr "alternative" "1")
9299 (const_string "lea")
9300 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9302 (match_operand 2 "const1_operand" ""))
9303 (const_string "alu")
9305 (const_string "ishift")))
9306 (set (attr "length_immediate")
9308 (ior (eq_attr "type" "alu")
9309 (and (eq_attr "type" "ishift")
9310 (and (match_operand 2 "const1_operand" "")
9311 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9314 (const_string "*")))
9315 (set_attr "mode" "SI")])
9317 (define_insn "*ashlhi3_1"
9318 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9319 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
9320 (match_operand:QI 2 "nonmemory_operand" "cI")))
9321 (clobber (reg:CC FLAGS_REG))]
9322 "TARGET_PARTIAL_REG_STALL
9323 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9325 switch (get_attr_type (insn))
9328 gcc_assert (operands[2] == const1_rtx);
9329 return "add{w}\t%0, %0";
9332 if (operands[2] == const1_rtx
9333 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9334 return "sal{w}\t%0";
9336 return "sal{w}\t{%2, %0|%0, %2}";
9340 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9342 (match_operand 0 "register_operand" ""))
9343 (match_operand 2 "const1_operand" ""))
9344 (const_string "alu")
9346 (const_string "ishift")))
9347 (set (attr "length_immediate")
9349 (ior (eq_attr "type" "alu")
9350 (and (eq_attr "type" "ishift")
9351 (and (match_operand 2 "const1_operand" "")
9352 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9355 (const_string "*")))
9356 (set_attr "mode" "HI")])
9358 (define_insn "*ashlhi3_1_lea"
9359 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
9360 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9361 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9362 (clobber (reg:CC FLAGS_REG))]
9363 "!TARGET_PARTIAL_REG_STALL
9364 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9366 switch (get_attr_type (insn))
9372 gcc_assert (operands[2] == const1_rtx);
9373 return "add{w}\t%0, %0";
9376 if (operands[2] == const1_rtx
9377 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9378 return "sal{w}\t%0";
9380 return "sal{w}\t{%2, %0|%0, %2}";
9384 (cond [(eq_attr "alternative" "1")
9385 (const_string "lea")
9386 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9388 (match_operand 0 "register_operand" ""))
9389 (match_operand 2 "const1_operand" ""))
9390 (const_string "alu")
9392 (const_string "ishift")))
9393 (set (attr "length_immediate")
9395 (ior (eq_attr "type" "alu")
9396 (and (eq_attr "type" "ishift")
9397 (and (match_operand 2 "const1_operand" "")
9398 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9401 (const_string "*")))
9402 (set_attr "mode" "HI,SI")])
9404 (define_insn "*ashlqi3_1"
9405 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9406 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
9407 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
9408 (clobber (reg:CC FLAGS_REG))]
9409 "TARGET_PARTIAL_REG_STALL
9410 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9412 switch (get_attr_type (insn))
9415 gcc_assert (operands[2] == const1_rtx);
9416 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9417 return "add{l}\t%k0, %k0";
9419 return "add{b}\t%0, %0";
9422 if (operands[2] == const1_rtx
9423 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9425 if (get_attr_mode (insn) == MODE_SI)
9426 return "sal{l}\t%k0";
9428 return "sal{b}\t%0";
9432 if (get_attr_mode (insn) == MODE_SI)
9433 return "sal{l}\t{%2, %k0|%k0, %2}";
9435 return "sal{b}\t{%2, %0|%0, %2}";
9440 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9442 (match_operand 0 "register_operand" ""))
9443 (match_operand 2 "const1_operand" ""))
9444 (const_string "alu")
9446 (const_string "ishift")))
9447 (set (attr "length_immediate")
9449 (ior (eq_attr "type" "alu")
9450 (and (eq_attr "type" "ishift")
9451 (and (match_operand 2 "const1_operand" "")
9452 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9455 (const_string "*")))
9456 (set_attr "mode" "QI,SI")])
9458 ;; %%% Potential partial reg stall on alternative 2. What to do?
9459 (define_insn "*ashlqi3_1_lea"
9460 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
9461 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9462 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9463 (clobber (reg:CC FLAGS_REG))]
9464 "!TARGET_PARTIAL_REG_STALL
9465 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9467 switch (get_attr_type (insn))
9473 gcc_assert (operands[2] == const1_rtx);
9474 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9475 return "add{l}\t%k0, %k0";
9477 return "add{b}\t%0, %0";
9480 if (operands[2] == const1_rtx
9481 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9483 if (get_attr_mode (insn) == MODE_SI)
9484 return "sal{l}\t%k0";
9486 return "sal{b}\t%0";
9490 if (get_attr_mode (insn) == MODE_SI)
9491 return "sal{l}\t{%2, %k0|%k0, %2}";
9493 return "sal{b}\t{%2, %0|%0, %2}";
9498 (cond [(eq_attr "alternative" "2")
9499 (const_string "lea")
9500 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9502 (match_operand 0 "register_operand" ""))
9503 (match_operand 2 "const1_operand" ""))
9504 (const_string "alu")
9506 (const_string "ishift")))
9507 (set (attr "length_immediate")
9509 (ior (eq_attr "type" "alu")
9510 (and (eq_attr "type" "ishift")
9511 (and (match_operand 2 "const1_operand" "")
9512 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9515 (const_string "*")))
9516 (set_attr "mode" "QI,SI,SI")])
9518 (define_insn "*ashlqi3_1_slp"
9519 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9520 (ashift:QI (match_dup 0)
9521 (match_operand:QI 1 "nonmemory_operand" "cI")))
9522 (clobber (reg:CC FLAGS_REG))]
9523 "(optimize_function_for_size_p (cfun)
9524 || !TARGET_PARTIAL_FLAG_REG_STALL
9525 || (operands[1] == const1_rtx
9527 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9529 switch (get_attr_type (insn))
9532 gcc_assert (operands[1] == const1_rtx);
9533 return "add{b}\t%0, %0";
9536 if (operands[1] == const1_rtx
9537 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9538 return "sal{b}\t%0";
9540 return "sal{b}\t{%1, %0|%0, %1}";
9544 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9546 (match_operand 0 "register_operand" ""))
9547 (match_operand 1 "const1_operand" ""))
9548 (const_string "alu")
9550 (const_string "ishift1")))
9551 (set (attr "length_immediate")
9553 (ior (eq_attr "type" "alu")
9554 (and (eq_attr "type" "ishift1")
9555 (and (match_operand 1 "const1_operand" "")
9556 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9559 (const_string "*")))
9560 (set_attr "mode" "QI")])
9562 ;; Convert lea to the lea pattern to avoid flags dependency.
9564 [(set (match_operand 0 "register_operand" "")
9565 (ashift (match_operand 1 "index_register_operand" "")
9566 (match_operand:QI 2 "const_int_operand" "")))
9567 (clobber (reg:CC FLAGS_REG))]
9569 && true_regnum (operands[0]) != true_regnum (operands[1])"
9573 enum machine_mode mode = GET_MODE (operands[0]);
9576 operands[1] = gen_lowpart (Pmode, operands[1]);
9577 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9579 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9581 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9582 operands[0] = gen_lowpart (SImode, operands[0]);
9584 if (TARGET_64BIT && mode != Pmode)
9585 pat = gen_rtx_SUBREG (SImode, pat, 0);
9587 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9591 ;; Convert lea to the lea pattern to avoid flags dependency.
9593 [(set (match_operand:DI 0 "register_operand" "")
9595 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9596 (match_operand:QI 2 "const_int_operand" ""))))
9597 (clobber (reg:CC FLAGS_REG))]
9598 "TARGET_64BIT && reload_completed
9599 && true_regnum (operands[0]) != true_regnum (operands[1])"
9601 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9603 operands[1] = gen_lowpart (DImode, operands[1]);
9604 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9607 ;; This pattern can't accept a variable shift count, since shifts by
9608 ;; zero don't affect the flags. We assume that shifts by constant
9609 ;; zero are optimized away.
9610 (define_insn "*ashl<mode>3_cmp"
9611 [(set (reg FLAGS_REG)
9613 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9614 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9616 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9617 (ashift:SWI (match_dup 1) (match_dup 2)))]
9618 "(optimize_function_for_size_p (cfun)
9619 || !TARGET_PARTIAL_FLAG_REG_STALL
9620 || (operands[2] == const1_rtx
9622 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9623 && ix86_match_ccmode (insn, CCGOCmode)
9624 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9626 switch (get_attr_type (insn))
9629 gcc_assert (operands[2] == const1_rtx);
9630 return "add{<imodesuffix>}\t%0, %0";
9633 if (operands[2] == const1_rtx
9634 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9635 return "sal{<imodesuffix>}\t%0";
9637 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9641 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9643 (match_operand 0 "register_operand" ""))
9644 (match_operand 2 "const1_operand" ""))
9645 (const_string "alu")
9647 (const_string "ishift")))
9648 (set (attr "length_immediate")
9650 (ior (eq_attr "type" "alu")
9651 (and (eq_attr "type" "ishift")
9652 (and (match_operand 2 "const1_operand" "")
9653 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9656 (const_string "*")))
9657 (set_attr "mode" "<MODE>")])
9659 (define_insn "*ashlsi3_cmp_zext"
9660 [(set (reg FLAGS_REG)
9662 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9663 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9665 (set (match_operand:DI 0 "register_operand" "=r")
9666 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9668 && (optimize_function_for_size_p (cfun)
9669 || !TARGET_PARTIAL_FLAG_REG_STALL
9670 || (operands[2] == const1_rtx
9672 || TARGET_DOUBLE_WITH_ADD)))
9673 && ix86_match_ccmode (insn, CCGOCmode)
9674 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9676 switch (get_attr_type (insn))
9679 gcc_assert (operands[2] == const1_rtx);
9680 return "add{l}\t%k0, %k0";
9683 if (operands[2] == const1_rtx
9684 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9685 return "sal{l}\t%k0";
9687 return "sal{l}\t{%2, %k0|%k0, %2}";
9691 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9693 (match_operand 2 "const1_operand" ""))
9694 (const_string "alu")
9696 (const_string "ishift")))
9697 (set (attr "length_immediate")
9699 (ior (eq_attr "type" "alu")
9700 (and (eq_attr "type" "ishift")
9701 (and (match_operand 2 "const1_operand" "")
9702 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9705 (const_string "*")))
9706 (set_attr "mode" "SI")])
9708 (define_insn "*ashl<mode>3_cconly"
9709 [(set (reg FLAGS_REG)
9711 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9712 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9714 (clobber (match_scratch:SWI 0 "=<r>"))]
9715 "(optimize_function_for_size_p (cfun)
9716 || !TARGET_PARTIAL_FLAG_REG_STALL
9717 || (operands[2] == const1_rtx
9719 || TARGET_DOUBLE_WITH_ADD)))
9720 && ix86_match_ccmode (insn, CCGOCmode)
9721 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9723 switch (get_attr_type (insn))
9726 gcc_assert (operands[2] == const1_rtx);
9727 return "add{<imodesuffix>}\t%0, %0";
9730 if (operands[2] == const1_rtx
9731 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9732 return "sal{<imodesuffix>}\t%0";
9734 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9738 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9740 (match_operand 0 "register_operand" ""))
9741 (match_operand 2 "const1_operand" ""))
9742 (const_string "alu")
9744 (const_string "ishift")))
9745 (set (attr "length_immediate")
9747 (ior (eq_attr "type" "alu")
9748 (and (eq_attr "type" "ishift")
9749 (and (match_operand 2 "const1_operand" "")
9750 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9753 (const_string "*")))
9754 (set_attr "mode" "<MODE>")])
9756 ;; See comment above `ashl<mode>3' about how this works.
9758 (define_expand "<shiftrt_insn><mode>3"
9759 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9760 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9761 (match_operand:QI 2 "nonmemory_operand" "")))]
9763 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9765 ;; Avoid useless masking of count operand.
9766 (define_insn_and_split "*<shiftrt_insn><mode>3_mask"
9767 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9769 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9772 (match_operand:SI 2 "nonimmediate_operand" "c")
9773 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9774 (clobber (reg:CC FLAGS_REG))]
9775 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9776 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9777 == GET_MODE_BITSIZE (<MODE>mode)-1"
9780 [(parallel [(set (match_dup 0)
9781 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9782 (clobber (reg:CC FLAGS_REG))])]
9784 if (can_create_pseudo_p ())
9785 operands [2] = force_reg (SImode, operands[2]);
9787 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9789 [(set_attr "type" "ishift")
9790 (set_attr "mode" "<MODE>")])
9792 (define_insn_and_split "*<shiftrt_insn><mode>3_doubleword"
9793 [(set (match_operand:DWI 0 "register_operand" "=r")
9794 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9795 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9796 (clobber (reg:CC FLAGS_REG))]
9799 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9801 "ix86_split_<shiftrt_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9802 [(set_attr "type" "multi")])
9804 ;; By default we don't ask for a scratch register, because when DWImode
9805 ;; values are manipulated, registers are already at a premium. But if
9806 ;; we have one handy, we won't turn it away.
9809 [(match_scratch:DWIH 3 "r")
9810 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9812 (match_operand:<DWI> 1 "register_operand" "")
9813 (match_operand:QI 2 "nonmemory_operand" "")))
9814 (clobber (reg:CC FLAGS_REG))])
9818 "ix86_split_<shiftrt_insn> (operands, operands[3], <DWI>mode); DONE;")
9820 (define_insn "x86_64_shrd"
9821 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9822 (ior:DI (ashiftrt:DI (match_dup 0)
9823 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9824 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9825 (minus:QI (const_int 64) (match_dup 2)))))
9826 (clobber (reg:CC FLAGS_REG))]
9828 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9829 [(set_attr "type" "ishift")
9830 (set_attr "prefix_0f" "1")
9831 (set_attr "mode" "DI")
9832 (set_attr "athlon_decode" "vector")
9833 (set_attr "amdfam10_decode" "vector")
9834 (set_attr "bdver1_decode" "vector")])
9836 (define_insn "x86_shrd"
9837 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9838 (ior:SI (ashiftrt:SI (match_dup 0)
9839 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9840 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9841 (minus:QI (const_int 32) (match_dup 2)))))
9842 (clobber (reg:CC FLAGS_REG))]
9844 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9845 [(set_attr "type" "ishift")
9846 (set_attr "prefix_0f" "1")
9847 (set_attr "mode" "SI")
9848 (set_attr "pent_pair" "np")
9849 (set_attr "athlon_decode" "vector")
9850 (set_attr "amdfam10_decode" "vector")
9851 (set_attr "bdver1_decode" "vector")])
9853 (define_insn "ashrdi3_cvt"
9854 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9855 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9856 (match_operand:QI 2 "const_int_operand" "")))
9857 (clobber (reg:CC FLAGS_REG))]
9858 "TARGET_64BIT && INTVAL (operands[2]) == 63
9859 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9860 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9863 sar{q}\t{%2, %0|%0, %2}"
9864 [(set_attr "type" "imovx,ishift")
9865 (set_attr "prefix_0f" "0,*")
9866 (set_attr "length_immediate" "0,*")
9867 (set_attr "modrm" "0,1")
9868 (set_attr "mode" "DI")])
9870 (define_insn "ashrsi3_cvt"
9871 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9872 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9873 (match_operand:QI 2 "const_int_operand" "")))
9874 (clobber (reg:CC FLAGS_REG))]
9875 "INTVAL (operands[2]) == 31
9876 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9877 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9880 sar{l}\t{%2, %0|%0, %2}"
9881 [(set_attr "type" "imovx,ishift")
9882 (set_attr "prefix_0f" "0,*")
9883 (set_attr "length_immediate" "0,*")
9884 (set_attr "modrm" "0,1")
9885 (set_attr "mode" "SI")])
9887 (define_insn "*ashrsi3_cvt_zext"
9888 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9890 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9891 (match_operand:QI 2 "const_int_operand" ""))))
9892 (clobber (reg:CC FLAGS_REG))]
9893 "TARGET_64BIT && INTVAL (operands[2]) == 31
9894 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9895 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9898 sar{l}\t{%2, %k0|%k0, %2}"
9899 [(set_attr "type" "imovx,ishift")
9900 (set_attr "prefix_0f" "0,*")
9901 (set_attr "length_immediate" "0,*")
9902 (set_attr "modrm" "0,1")
9903 (set_attr "mode" "SI")])
9905 (define_expand "x86_shift<mode>_adj_3"
9906 [(use (match_operand:SWI48 0 "register_operand" ""))
9907 (use (match_operand:SWI48 1 "register_operand" ""))
9908 (use (match_operand:QI 2 "register_operand" ""))]
9911 rtx label = gen_label_rtx ();
9914 emit_insn (gen_testqi_ccz_1 (operands[2],
9915 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9917 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9918 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9919 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9920 gen_rtx_LABEL_REF (VOIDmode, label),
9922 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9923 JUMP_LABEL (tmp) = label;
9925 emit_move_insn (operands[0], operands[1]);
9926 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9927 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9929 LABEL_NUSES (label) = 1;
9934 (define_insn "*<shiftrt_insn><mode>3_1"
9935 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9936 (any_shiftrt:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9937 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9938 (clobber (reg:CC FLAGS_REG))]
9939 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9941 if (operands[2] == const1_rtx
9942 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9943 return "<shiftrt>{<imodesuffix>}\t%0";
9945 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
9947 [(set_attr "type" "ishift")
9948 (set (attr "length_immediate")
9950 (and (match_operand 2 "const1_operand" "")
9951 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9954 (const_string "*")))
9955 (set_attr "mode" "<MODE>")])
9957 (define_insn "*<shiftrt_insn>si3_1_zext"
9958 [(set (match_operand:DI 0 "register_operand" "=r")
9960 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9961 (match_operand:QI 2 "nonmemory_operand" "cI"))))
9962 (clobber (reg:CC FLAGS_REG))]
9963 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9965 if (operands[2] == const1_rtx
9966 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9967 return "<shiftrt>{l}\t%k0";
9969 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
9971 [(set_attr "type" "ishift")
9972 (set (attr "length_immediate")
9974 (and (match_operand 2 "const1_operand" "")
9975 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9978 (const_string "*")))
9979 (set_attr "mode" "SI")])
9981 (define_insn "*<shiftrt_insn>qi3_1_slp"
9982 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9983 (any_shiftrt:QI (match_dup 0)
9984 (match_operand:QI 1 "nonmemory_operand" "cI")))
9985 (clobber (reg:CC FLAGS_REG))]
9986 "(optimize_function_for_size_p (cfun)
9987 || !TARGET_PARTIAL_REG_STALL
9988 || (operands[1] == const1_rtx
9991 if (operands[1] == const1_rtx
9992 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9993 return "<shiftrt>{b}\t%0";
9995 return "<shiftrt>{b}\t{%1, %0|%0, %1}";
9997 [(set_attr "type" "ishift1")
9998 (set (attr "length_immediate")
10000 (and (match_operand 1 "const1_operand" "")
10001 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10004 (const_string "*")))
10005 (set_attr "mode" "QI")])
10007 ;; This pattern can't accept a variable shift count, since shifts by
10008 ;; zero don't affect the flags. We assume that shifts by constant
10009 ;; zero are optimized away.
10010 (define_insn "*<shiftrt_insn><mode>3_cmp"
10011 [(set (reg FLAGS_REG)
10014 (match_operand:SWI 1 "nonimmediate_operand" "0")
10015 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10017 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10018 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10019 "(optimize_function_for_size_p (cfun)
10020 || !TARGET_PARTIAL_FLAG_REG_STALL
10021 || (operands[2] == const1_rtx
10023 && ix86_match_ccmode (insn, CCGOCmode)
10024 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10026 if (operands[2] == const1_rtx
10027 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10028 return "<shiftrt>{<imodesuffix>}\t%0";
10030 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10032 [(set_attr "type" "ishift")
10033 (set (attr "length_immediate")
10035 (and (match_operand 2 "const1_operand" "")
10036 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10039 (const_string "*")))
10040 (set_attr "mode" "<MODE>")])
10042 (define_insn "*<shiftrt_insn>si3_cmp_zext"
10043 [(set (reg FLAGS_REG)
10045 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10046 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10048 (set (match_operand:DI 0 "register_operand" "=r")
10049 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10051 && (optimize_function_for_size_p (cfun)
10052 || !TARGET_PARTIAL_FLAG_REG_STALL
10053 || (operands[2] == const1_rtx
10055 && ix86_match_ccmode (insn, CCGOCmode)
10056 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10058 if (operands[2] == const1_rtx
10059 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10060 return "<shiftrt>{l}\t%k0";
10062 return "<shiftrt>{l}\t{%2, %k0|%k0, %2}";
10064 [(set_attr "type" "ishift")
10065 (set (attr "length_immediate")
10067 (and (match_operand 2 "const1_operand" "")
10068 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10071 (const_string "*")))
10072 (set_attr "mode" "SI")])
10074 (define_insn "*<shiftrt_insn><mode>3_cconly"
10075 [(set (reg FLAGS_REG)
10078 (match_operand:SWI 1 "nonimmediate_operand" "0")
10079 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10081 (clobber (match_scratch:SWI 0 "=<r>"))]
10082 "(optimize_function_for_size_p (cfun)
10083 || !TARGET_PARTIAL_FLAG_REG_STALL
10084 || (operands[2] == const1_rtx
10086 && ix86_match_ccmode (insn, CCGOCmode)
10087 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10089 if (operands[2] == const1_rtx
10090 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10091 return "<shiftrt>{<imodesuffix>}\t%0";
10093 return "<shiftrt>{<imodesuffix>}\t{%2, %0|%0, %2}";
10095 [(set_attr "type" "ishift")
10096 (set (attr "length_immediate")
10098 (and (match_operand 2 "const1_operand" "")
10099 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10102 (const_string "*")))
10103 (set_attr "mode" "<MODE>")])
10105 ;; Rotate instructions
10107 (define_expand "<rotate_insn>ti3"
10108 [(set (match_operand:TI 0 "register_operand" "")
10109 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10110 (match_operand:QI 2 "nonmemory_operand" "")))]
10113 if (const_1_to_63_operand (operands[2], VOIDmode))
10114 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10115 (operands[0], operands[1], operands[2]));
10122 (define_expand "<rotate_insn>di3"
10123 [(set (match_operand:DI 0 "shiftdi_operand" "")
10124 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10125 (match_operand:QI 2 "nonmemory_operand" "")))]
10129 ix86_expand_binary_operator (<CODE>, DImode, operands);
10130 else if (const_1_to_31_operand (operands[2], VOIDmode))
10131 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10132 (operands[0], operands[1], operands[2]));
10139 (define_expand "<rotate_insn><mode>3"
10140 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10141 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10142 (match_operand:QI 2 "nonmemory_operand" "")))]
10144 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10146 ;; Avoid useless masking of count operand.
10147 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10148 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10150 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10153 (match_operand:SI 2 "nonimmediate_operand" "c")
10154 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10155 (clobber (reg:CC FLAGS_REG))]
10156 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10157 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10158 == GET_MODE_BITSIZE (<MODE>mode)-1"
10161 [(parallel [(set (match_dup 0)
10162 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10163 (clobber (reg:CC FLAGS_REG))])]
10165 if (can_create_pseudo_p ())
10166 operands [2] = force_reg (SImode, operands[2]);
10168 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10170 [(set_attr "type" "rotate")
10171 (set_attr "mode" "<MODE>")])
10173 ;; Implement rotation using two double-precision
10174 ;; shift instructions and a scratch register.
10176 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10177 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10178 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10179 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10180 (clobber (reg:CC FLAGS_REG))
10181 (clobber (match_scratch:DWIH 3 "=&r"))]
10185 [(set (match_dup 3) (match_dup 4))
10187 [(set (match_dup 4)
10188 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10189 (lshiftrt:DWIH (match_dup 5)
10190 (minus:QI (match_dup 6) (match_dup 2)))))
10191 (clobber (reg:CC FLAGS_REG))])
10193 [(set (match_dup 5)
10194 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10195 (lshiftrt:DWIH (match_dup 3)
10196 (minus:QI (match_dup 6) (match_dup 2)))))
10197 (clobber (reg:CC FLAGS_REG))])]
10199 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10201 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10204 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10205 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10206 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10207 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10208 (clobber (reg:CC FLAGS_REG))
10209 (clobber (match_scratch:DWIH 3 "=&r"))]
10213 [(set (match_dup 3) (match_dup 4))
10215 [(set (match_dup 4)
10216 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10217 (ashift:DWIH (match_dup 5)
10218 (minus:QI (match_dup 6) (match_dup 2)))))
10219 (clobber (reg:CC FLAGS_REG))])
10221 [(set (match_dup 5)
10222 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10223 (ashift:DWIH (match_dup 3)
10224 (minus:QI (match_dup 6) (match_dup 2)))))
10225 (clobber (reg:CC FLAGS_REG))])]
10227 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10229 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10232 (define_insn "*<rotate_insn><mode>3_1"
10233 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10234 (any_rotate:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
10235 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10236 (clobber (reg:CC FLAGS_REG))]
10237 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10239 if (operands[2] == const1_rtx
10240 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10241 return "<rotate>{<imodesuffix>}\t%0";
10243 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10245 [(set_attr "type" "rotate")
10246 (set (attr "length_immediate")
10248 (and (match_operand 2 "const1_operand" "")
10249 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10252 (const_string "*")))
10253 (set_attr "mode" "<MODE>")])
10255 (define_insn "*<rotate_insn>si3_1_zext"
10256 [(set (match_operand:DI 0 "register_operand" "=r")
10258 (any_rotate:SI (match_operand:SI 1 "register_operand" "0")
10259 (match_operand:QI 2 "nonmemory_operand" "cI"))))
10260 (clobber (reg:CC FLAGS_REG))]
10261 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10263 if (operands[2] == const1_rtx
10264 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10265 return "<rotate>{l}\t%k0";
10267 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10269 [(set_attr "type" "rotate")
10270 (set (attr "length_immediate")
10272 (and (match_operand 2 "const1_operand" "")
10273 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10276 (const_string "*")))
10277 (set_attr "mode" "SI")])
10279 (define_insn "*<rotate_insn>qi3_1_slp"
10280 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10281 (any_rotate:QI (match_dup 0)
10282 (match_operand:QI 1 "nonmemory_operand" "cI")))
10283 (clobber (reg:CC FLAGS_REG))]
10284 "(optimize_function_for_size_p (cfun)
10285 || !TARGET_PARTIAL_REG_STALL
10286 || (operands[1] == const1_rtx
10287 && TARGET_SHIFT1))"
10289 if (operands[1] == const1_rtx
10290 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10291 return "<rotate>{b}\t%0";
10293 return "<rotate>{b}\t{%1, %0|%0, %1}";
10295 [(set_attr "type" "rotate1")
10296 (set (attr "length_immediate")
10298 (and (match_operand 1 "const1_operand" "")
10299 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10302 (const_string "*")))
10303 (set_attr "mode" "QI")])
10306 [(set (match_operand:HI 0 "register_operand" "")
10307 (any_rotate:HI (match_dup 0) (const_int 8)))
10308 (clobber (reg:CC FLAGS_REG))]
10310 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10311 [(parallel [(set (strict_low_part (match_dup 0))
10312 (bswap:HI (match_dup 0)))
10313 (clobber (reg:CC FLAGS_REG))])])
10315 ;; Bit set / bit test instructions
10317 (define_expand "extv"
10318 [(set (match_operand:SI 0 "register_operand" "")
10319 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10320 (match_operand:SI 2 "const8_operand" "")
10321 (match_operand:SI 3 "const8_operand" "")))]
10324 /* Handle extractions from %ah et al. */
10325 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10328 /* From mips.md: extract_bit_field doesn't verify that our source
10329 matches the predicate, so check it again here. */
10330 if (! ext_register_operand (operands[1], VOIDmode))
10334 (define_expand "extzv"
10335 [(set (match_operand:SI 0 "register_operand" "")
10336 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10337 (match_operand:SI 2 "const8_operand" "")
10338 (match_operand:SI 3 "const8_operand" "")))]
10341 /* Handle extractions from %ah et al. */
10342 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10345 /* From mips.md: extract_bit_field doesn't verify that our source
10346 matches the predicate, so check it again here. */
10347 if (! ext_register_operand (operands[1], VOIDmode))
10351 (define_expand "insv"
10352 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
10353 (match_operand 1 "const8_operand" "")
10354 (match_operand 2 "const8_operand" ""))
10355 (match_operand 3 "register_operand" ""))]
10358 rtx (*gen_mov_insv_1) (rtx, rtx);
10360 /* Handle insertions to %ah et al. */
10361 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10364 /* From mips.md: insert_bit_field doesn't verify that our source
10365 matches the predicate, so check it again here. */
10366 if (! ext_register_operand (operands[0], VOIDmode))
10369 gen_mov_insv_1 = (TARGET_64BIT
10370 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10372 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10376 ;; %%% bts, btr, btc, bt.
10377 ;; In general these instructions are *slow* when applied to memory,
10378 ;; since they enforce atomic operation. When applied to registers,
10379 ;; it depends on the cpu implementation. They're never faster than
10380 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10381 ;; no point. But in 64-bit, we can't hold the relevant immediates
10382 ;; within the instruction itself, so operating on bits in the high
10383 ;; 32-bits of a register becomes easier.
10385 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10386 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10387 ;; negdf respectively, so they can never be disabled entirely.
10389 (define_insn "*btsq"
10390 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10392 (match_operand:DI 1 "const_0_to_63_operand" ""))
10394 (clobber (reg:CC FLAGS_REG))]
10395 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10396 "bts{q}\t{%1, %0|%0, %1}"
10397 [(set_attr "type" "alu1")
10398 (set_attr "prefix_0f" "1")
10399 (set_attr "mode" "DI")])
10401 (define_insn "*btrq"
10402 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10404 (match_operand:DI 1 "const_0_to_63_operand" ""))
10406 (clobber (reg:CC FLAGS_REG))]
10407 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10408 "btr{q}\t{%1, %0|%0, %1}"
10409 [(set_attr "type" "alu1")
10410 (set_attr "prefix_0f" "1")
10411 (set_attr "mode" "DI")])
10413 (define_insn "*btcq"
10414 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10416 (match_operand:DI 1 "const_0_to_63_operand" ""))
10417 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10418 (clobber (reg:CC FLAGS_REG))]
10419 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10420 "btc{q}\t{%1, %0|%0, %1}"
10421 [(set_attr "type" "alu1")
10422 (set_attr "prefix_0f" "1")
10423 (set_attr "mode" "DI")])
10425 ;; Allow Nocona to avoid these instructions if a register is available.
10428 [(match_scratch:DI 2 "r")
10429 (parallel [(set (zero_extract:DI
10430 (match_operand:DI 0 "register_operand" "")
10432 (match_operand:DI 1 "const_0_to_63_operand" ""))
10434 (clobber (reg:CC FLAGS_REG))])]
10435 "TARGET_64BIT && !TARGET_USE_BT"
10438 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10441 if (HOST_BITS_PER_WIDE_INT >= 64)
10442 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10443 else if (i < HOST_BITS_PER_WIDE_INT)
10444 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10446 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10448 op1 = immed_double_const (lo, hi, DImode);
10451 emit_move_insn (operands[2], op1);
10455 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10460 [(match_scratch:DI 2 "r")
10461 (parallel [(set (zero_extract:DI
10462 (match_operand:DI 0 "register_operand" "")
10464 (match_operand:DI 1 "const_0_to_63_operand" ""))
10466 (clobber (reg:CC FLAGS_REG))])]
10467 "TARGET_64BIT && !TARGET_USE_BT"
10470 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10473 if (HOST_BITS_PER_WIDE_INT >= 64)
10474 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10475 else if (i < HOST_BITS_PER_WIDE_INT)
10476 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10478 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10480 op1 = immed_double_const (~lo, ~hi, DImode);
10483 emit_move_insn (operands[2], op1);
10487 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10492 [(match_scratch:DI 2 "r")
10493 (parallel [(set (zero_extract:DI
10494 (match_operand:DI 0 "register_operand" "")
10496 (match_operand:DI 1 "const_0_to_63_operand" ""))
10497 (not:DI (zero_extract:DI
10498 (match_dup 0) (const_int 1) (match_dup 1))))
10499 (clobber (reg:CC FLAGS_REG))])]
10500 "TARGET_64BIT && !TARGET_USE_BT"
10503 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10506 if (HOST_BITS_PER_WIDE_INT >= 64)
10507 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10508 else if (i < HOST_BITS_PER_WIDE_INT)
10509 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10511 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10513 op1 = immed_double_const (lo, hi, DImode);
10516 emit_move_insn (operands[2], op1);
10520 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10524 (define_insn "*bt<mode>"
10525 [(set (reg:CCC FLAGS_REG)
10527 (zero_extract:SWI48
10528 (match_operand:SWI48 0 "register_operand" "r")
10530 (match_operand:SWI48 1 "nonmemory_operand" "rN"))
10532 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10533 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10534 [(set_attr "type" "alu1")
10535 (set_attr "prefix_0f" "1")
10536 (set_attr "mode" "<MODE>")])
10538 ;; Store-flag instructions.
10540 ;; For all sCOND expanders, also expand the compare or test insn that
10541 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10543 (define_insn_and_split "*setcc_di_1"
10544 [(set (match_operand:DI 0 "register_operand" "=q")
10545 (match_operator:DI 1 "ix86_comparison_operator"
10546 [(reg FLAGS_REG) (const_int 0)]))]
10547 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10549 "&& reload_completed"
10550 [(set (match_dup 2) (match_dup 1))
10551 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10553 PUT_MODE (operands[1], QImode);
10554 operands[2] = gen_lowpart (QImode, operands[0]);
10557 (define_insn_and_split "*setcc_si_1_and"
10558 [(set (match_operand:SI 0 "register_operand" "=q")
10559 (match_operator:SI 1 "ix86_comparison_operator"
10560 [(reg FLAGS_REG) (const_int 0)]))
10561 (clobber (reg:CC FLAGS_REG))]
10562 "!TARGET_PARTIAL_REG_STALL
10563 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10565 "&& reload_completed"
10566 [(set (match_dup 2) (match_dup 1))
10567 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10568 (clobber (reg:CC FLAGS_REG))])]
10570 PUT_MODE (operands[1], QImode);
10571 operands[2] = gen_lowpart (QImode, operands[0]);
10574 (define_insn_and_split "*setcc_si_1_movzbl"
10575 [(set (match_operand:SI 0 "register_operand" "=q")
10576 (match_operator:SI 1 "ix86_comparison_operator"
10577 [(reg FLAGS_REG) (const_int 0)]))]
10578 "!TARGET_PARTIAL_REG_STALL
10579 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10581 "&& reload_completed"
10582 [(set (match_dup 2) (match_dup 1))
10583 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10585 PUT_MODE (operands[1], QImode);
10586 operands[2] = gen_lowpart (QImode, operands[0]);
10589 (define_insn "*setcc_qi"
10590 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10591 (match_operator:QI 1 "ix86_comparison_operator"
10592 [(reg FLAGS_REG) (const_int 0)]))]
10595 [(set_attr "type" "setcc")
10596 (set_attr "mode" "QI")])
10598 (define_insn "*setcc_qi_slp"
10599 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10600 (match_operator:QI 1 "ix86_comparison_operator"
10601 [(reg FLAGS_REG) (const_int 0)]))]
10604 [(set_attr "type" "setcc")
10605 (set_attr "mode" "QI")])
10607 ;; In general it is not safe to assume too much about CCmode registers,
10608 ;; so simplify-rtx stops when it sees a second one. Under certain
10609 ;; conditions this is safe on x86, so help combine not create
10616 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10617 (ne:QI (match_operator 1 "ix86_comparison_operator"
10618 [(reg FLAGS_REG) (const_int 0)])
10621 [(set (match_dup 0) (match_dup 1))]
10622 "PUT_MODE (operands[1], QImode);")
10625 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10626 (ne:QI (match_operator 1 "ix86_comparison_operator"
10627 [(reg FLAGS_REG) (const_int 0)])
10630 [(set (match_dup 0) (match_dup 1))]
10631 "PUT_MODE (operands[1], QImode);")
10634 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10635 (eq:QI (match_operator 1 "ix86_comparison_operator"
10636 [(reg FLAGS_REG) (const_int 0)])
10639 [(set (match_dup 0) (match_dup 1))]
10641 rtx new_op1 = copy_rtx (operands[1]);
10642 operands[1] = new_op1;
10643 PUT_MODE (new_op1, QImode);
10644 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10645 GET_MODE (XEXP (new_op1, 0))));
10647 /* Make sure that (a) the CCmode we have for the flags is strong
10648 enough for the reversed compare or (b) we have a valid FP compare. */
10649 if (! ix86_comparison_operator (new_op1, VOIDmode))
10654 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10655 (eq:QI (match_operator 1 "ix86_comparison_operator"
10656 [(reg FLAGS_REG) (const_int 0)])
10659 [(set (match_dup 0) (match_dup 1))]
10661 rtx new_op1 = copy_rtx (operands[1]);
10662 operands[1] = new_op1;
10663 PUT_MODE (new_op1, QImode);
10664 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10665 GET_MODE (XEXP (new_op1, 0))));
10667 /* Make sure that (a) the CCmode we have for the flags is strong
10668 enough for the reversed compare or (b) we have a valid FP compare. */
10669 if (! ix86_comparison_operator (new_op1, VOIDmode))
10673 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10674 ;; subsequent logical operations are used to imitate conditional moves.
10675 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10678 (define_insn "*avx_setcc<mode>"
10679 [(set (match_operand:MODEF 0 "register_operand" "=x")
10680 (match_operator:MODEF 1 "avx_comparison_float_operator"
10681 [(match_operand:MODEF 2 "register_operand" "x")
10682 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10684 "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
10685 [(set_attr "type" "ssecmp")
10686 (set_attr "prefix" "vex")
10687 (set_attr "length_immediate" "1")
10688 (set_attr "mode" "<MODE>")])
10690 (define_insn "*sse_setcc<mode>"
10691 [(set (match_operand:MODEF 0 "register_operand" "=x")
10692 (match_operator:MODEF 1 "sse_comparison_operator"
10693 [(match_operand:MODEF 2 "register_operand" "0")
10694 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
10695 "SSE_FLOAT_MODE_P (<MODE>mode)"
10696 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
10697 [(set_attr "type" "ssecmp")
10698 (set_attr "length_immediate" "1")
10699 (set_attr "mode" "<MODE>")])
10701 ;; Basic conditional jump instructions.
10702 ;; We ignore the overflow flag for signed branch instructions.
10704 (define_insn "*jcc_1"
10706 (if_then_else (match_operator 1 "ix86_comparison_operator"
10707 [(reg FLAGS_REG) (const_int 0)])
10708 (label_ref (match_operand 0 "" ""))
10712 [(set_attr "type" "ibr")
10713 (set_attr "modrm" "0")
10714 (set (attr "length")
10715 (if_then_else (and (ge (minus (match_dup 0) (pc))
10717 (lt (minus (match_dup 0) (pc))
10722 (define_insn "*jcc_2"
10724 (if_then_else (match_operator 1 "ix86_comparison_operator"
10725 [(reg FLAGS_REG) (const_int 0)])
10727 (label_ref (match_operand 0 "" ""))))]
10730 [(set_attr "type" "ibr")
10731 (set_attr "modrm" "0")
10732 (set (attr "length")
10733 (if_then_else (and (ge (minus (match_dup 0) (pc))
10735 (lt (minus (match_dup 0) (pc))
10740 ;; In general it is not safe to assume too much about CCmode registers,
10741 ;; so simplify-rtx stops when it sees a second one. Under certain
10742 ;; conditions this is safe on x86, so help combine not create
10750 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10751 [(reg FLAGS_REG) (const_int 0)])
10753 (label_ref (match_operand 1 "" ""))
10757 (if_then_else (match_dup 0)
10758 (label_ref (match_dup 1))
10760 "PUT_MODE (operands[0], VOIDmode);")
10764 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10765 [(reg FLAGS_REG) (const_int 0)])
10767 (label_ref (match_operand 1 "" ""))
10771 (if_then_else (match_dup 0)
10772 (label_ref (match_dup 1))
10775 rtx new_op0 = copy_rtx (operands[0]);
10776 operands[0] = new_op0;
10777 PUT_MODE (new_op0, VOIDmode);
10778 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10779 GET_MODE (XEXP (new_op0, 0))));
10781 /* Make sure that (a) the CCmode we have for the flags is strong
10782 enough for the reversed compare or (b) we have a valid FP compare. */
10783 if (! ix86_comparison_operator (new_op0, VOIDmode))
10787 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10788 ;; pass generates from shift insn with QImode operand. Actually, the mode
10789 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10790 ;; appropriate modulo of the bit offset value.
10792 (define_insn_and_split "*jcc_bt<mode>"
10794 (if_then_else (match_operator 0 "bt_comparison_operator"
10795 [(zero_extract:SWI48
10796 (match_operand:SWI48 1 "register_operand" "r")
10799 (match_operand:QI 2 "register_operand" "r")))
10801 (label_ref (match_operand 3 "" ""))
10803 (clobber (reg:CC FLAGS_REG))]
10804 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10807 [(set (reg:CCC FLAGS_REG)
10809 (zero_extract:SWI48
10815 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10816 (label_ref (match_dup 3))
10819 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10821 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10824 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10825 ;; also for DImode, this is what combine produces.
10826 (define_insn_and_split "*jcc_bt<mode>_mask"
10828 (if_then_else (match_operator 0 "bt_comparison_operator"
10829 [(zero_extract:SWI48
10830 (match_operand:SWI48 1 "register_operand" "r")
10833 (match_operand:SI 2 "register_operand" "r")
10834 (match_operand:SI 3 "const_int_operand" "n")))])
10835 (label_ref (match_operand 4 "" ""))
10837 (clobber (reg:CC FLAGS_REG))]
10838 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10839 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10840 == GET_MODE_BITSIZE (<MODE>mode)-1"
10843 [(set (reg:CCC FLAGS_REG)
10845 (zero_extract:SWI48
10851 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10852 (label_ref (match_dup 4))
10855 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10857 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10860 (define_insn_and_split "*jcc_btsi_1"
10862 (if_then_else (match_operator 0 "bt_comparison_operator"
10865 (match_operand:SI 1 "register_operand" "r")
10866 (match_operand:QI 2 "register_operand" "r"))
10869 (label_ref (match_operand 3 "" ""))
10871 (clobber (reg:CC FLAGS_REG))]
10872 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10875 [(set (reg:CCC FLAGS_REG)
10883 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10884 (label_ref (match_dup 3))
10887 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10889 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10892 ;; avoid useless masking of bit offset operand
10893 (define_insn_and_split "*jcc_btsi_mask_1"
10896 (match_operator 0 "bt_comparison_operator"
10899 (match_operand:SI 1 "register_operand" "r")
10902 (match_operand:SI 2 "register_operand" "r")
10903 (match_operand:SI 3 "const_int_operand" "n")) 0))
10906 (label_ref (match_operand 4 "" ""))
10908 (clobber (reg:CC FLAGS_REG))]
10909 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10910 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10913 [(set (reg:CCC FLAGS_REG)
10921 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10922 (label_ref (match_dup 4))
10924 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10926 ;; Define combination compare-and-branch fp compare instructions to help
10929 (define_insn "*fp_jcc_1_387"
10931 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10932 [(match_operand 1 "register_operand" "f")
10933 (match_operand 2 "nonimmediate_operand" "fm")])
10934 (label_ref (match_operand 3 "" ""))
10936 (clobber (reg:CCFP FPSR_REG))
10937 (clobber (reg:CCFP FLAGS_REG))
10938 (clobber (match_scratch:HI 4 "=a"))]
10940 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10941 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10942 && SELECT_CC_MODE (GET_CODE (operands[0]),
10943 operands[1], operands[2]) == CCFPmode
10947 (define_insn "*fp_jcc_1r_387"
10949 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10950 [(match_operand 1 "register_operand" "f")
10951 (match_operand 2 "nonimmediate_operand" "fm")])
10953 (label_ref (match_operand 3 "" ""))))
10954 (clobber (reg:CCFP FPSR_REG))
10955 (clobber (reg:CCFP FLAGS_REG))
10956 (clobber (match_scratch:HI 4 "=a"))]
10958 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10959 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10960 && SELECT_CC_MODE (GET_CODE (operands[0]),
10961 operands[1], operands[2]) == CCFPmode
10965 (define_insn "*fp_jcc_2_387"
10967 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10968 [(match_operand 1 "register_operand" "f")
10969 (match_operand 2 "register_operand" "f")])
10970 (label_ref (match_operand 3 "" ""))
10972 (clobber (reg:CCFP FPSR_REG))
10973 (clobber (reg:CCFP FLAGS_REG))
10974 (clobber (match_scratch:HI 4 "=a"))]
10975 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10976 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10980 (define_insn "*fp_jcc_2r_387"
10982 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10983 [(match_operand 1 "register_operand" "f")
10984 (match_operand 2 "register_operand" "f")])
10986 (label_ref (match_operand 3 "" ""))))
10987 (clobber (reg:CCFP FPSR_REG))
10988 (clobber (reg:CCFP FLAGS_REG))
10989 (clobber (match_scratch:HI 4 "=a"))]
10990 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10991 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10995 (define_insn "*fp_jcc_3_387"
10997 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10998 [(match_operand 1 "register_operand" "f")
10999 (match_operand 2 "const0_operand" "")])
11000 (label_ref (match_operand 3 "" ""))
11002 (clobber (reg:CCFP FPSR_REG))
11003 (clobber (reg:CCFP FLAGS_REG))
11004 (clobber (match_scratch:HI 4 "=a"))]
11005 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11006 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11007 && SELECT_CC_MODE (GET_CODE (operands[0]),
11008 operands[1], operands[2]) == CCFPmode
11014 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11015 [(match_operand 1 "register_operand" "")
11016 (match_operand 2 "nonimmediate_operand" "")])
11017 (match_operand 3 "" "")
11018 (match_operand 4 "" "")))
11019 (clobber (reg:CCFP FPSR_REG))
11020 (clobber (reg:CCFP FLAGS_REG))]
11024 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11025 operands[3], operands[4], NULL_RTX, NULL_RTX);
11031 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11032 [(match_operand 1 "register_operand" "")
11033 (match_operand 2 "general_operand" "")])
11034 (match_operand 3 "" "")
11035 (match_operand 4 "" "")))
11036 (clobber (reg:CCFP FPSR_REG))
11037 (clobber (reg:CCFP FLAGS_REG))
11038 (clobber (match_scratch:HI 5 "=a"))]
11042 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11043 operands[3], operands[4], operands[5], NULL_RTX);
11047 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11048 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11049 ;; with a precedence over other operators and is always put in the first
11050 ;; place. Swap condition and operands to match ficom instruction.
11052 (define_insn "*fp_jcc_4_<mode>_387"
11055 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11056 [(match_operator 1 "float_operator"
11057 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
11058 (match_operand 3 "register_operand" "f,f")])
11059 (label_ref (match_operand 4 "" ""))
11061 (clobber (reg:CCFP FPSR_REG))
11062 (clobber (reg:CCFP FLAGS_REG))
11063 (clobber (match_scratch:HI 5 "=a,a"))]
11064 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11065 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11066 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11067 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11074 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11075 [(match_operator 1 "float_operator"
11076 [(match_operand:X87MODEI12 2 "memory_operand" "")])
11077 (match_operand 3 "register_operand" "")])
11078 (match_operand 4 "" "")
11079 (match_operand 5 "" "")))
11080 (clobber (reg:CCFP FPSR_REG))
11081 (clobber (reg:CCFP FLAGS_REG))
11082 (clobber (match_scratch:HI 6 "=a"))]
11086 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11088 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11089 operands[3], operands[7],
11090 operands[4], operands[5], operands[6], NULL_RTX);
11094 ;; %%% Kill this when reload knows how to do it.
11098 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11099 [(match_operator 1 "float_operator"
11100 [(match_operand:X87MODEI12 2 "register_operand" "")])
11101 (match_operand 3 "register_operand" "")])
11102 (match_operand 4 "" "")
11103 (match_operand 5 "" "")))
11104 (clobber (reg:CCFP FPSR_REG))
11105 (clobber (reg:CCFP FLAGS_REG))
11106 (clobber (match_scratch:HI 6 "=a"))]
11110 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11111 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11113 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11114 operands[3], operands[7],
11115 operands[4], operands[5], operands[6], operands[2]);
11119 ;; Unconditional and other jump instructions
11121 (define_insn "jump"
11123 (label_ref (match_operand 0 "" "")))]
11126 [(set_attr "type" "ibr")
11127 (set (attr "length")
11128 (if_then_else (and (ge (minus (match_dup 0) (pc))
11130 (lt (minus (match_dup 0) (pc))
11134 (set_attr "modrm" "0")])
11136 (define_expand "indirect_jump"
11137 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
11141 (define_insn "*indirect_jump"
11142 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
11145 [(set_attr "type" "ibr")
11146 (set_attr "length_immediate" "0")])
11148 (define_expand "tablejump"
11149 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
11150 (use (label_ref (match_operand 1 "" "")))])]
11153 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11154 relative. Convert the relative address to an absolute address. */
11158 enum rtx_code code;
11160 /* We can't use @GOTOFF for text labels on VxWorks;
11161 see gotoff_operand. */
11162 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11166 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11168 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11172 op1 = pic_offset_table_rtx;
11177 op0 = pic_offset_table_rtx;
11181 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11186 (define_insn "*tablejump_1"
11187 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
11188 (use (label_ref (match_operand 1 "" "")))]
11191 [(set_attr "type" "ibr")
11192 (set_attr "length_immediate" "0")])
11194 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11197 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11198 (set (match_operand:QI 1 "register_operand" "")
11199 (match_operator:QI 2 "ix86_comparison_operator"
11200 [(reg FLAGS_REG) (const_int 0)]))
11201 (set (match_operand 3 "q_regs_operand" "")
11202 (zero_extend (match_dup 1)))]
11203 "(peep2_reg_dead_p (3, operands[1])
11204 || operands_match_p (operands[1], operands[3]))
11205 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11206 [(set (match_dup 4) (match_dup 0))
11207 (set (strict_low_part (match_dup 5))
11210 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11211 operands[5] = gen_lowpart (QImode, operands[3]);
11212 ix86_expand_clear (operands[3]);
11215 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11218 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11219 (set (match_operand:QI 1 "register_operand" "")
11220 (match_operator:QI 2 "ix86_comparison_operator"
11221 [(reg FLAGS_REG) (const_int 0)]))
11222 (parallel [(set (match_operand 3 "q_regs_operand" "")
11223 (zero_extend (match_dup 1)))
11224 (clobber (reg:CC FLAGS_REG))])]
11225 "(peep2_reg_dead_p (3, operands[1])
11226 || operands_match_p (operands[1], operands[3]))
11227 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11228 [(set (match_dup 4) (match_dup 0))
11229 (set (strict_low_part (match_dup 5))
11232 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11233 operands[5] = gen_lowpart (QImode, operands[3]);
11234 ix86_expand_clear (operands[3]);
11237 ;; Call instructions.
11239 ;; The predicates normally associated with named expanders are not properly
11240 ;; checked for calls. This is a bug in the generic code, but it isn't that
11241 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11243 ;; P6 processors will jump to the address after the decrement when %esp
11244 ;; is used as a call operand, so they will execute return address as a code.
11245 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11247 ;; Call subroutine returning no value.
11249 (define_expand "call_pop"
11250 [(parallel [(call (match_operand:QI 0 "" "")
11251 (match_operand:SI 1 "" ""))
11252 (set (reg:SI SP_REG)
11253 (plus:SI (reg:SI SP_REG)
11254 (match_operand:SI 3 "" "")))])]
11257 ix86_expand_call (NULL, operands[0], operands[1],
11258 operands[2], operands[3], 0);
11262 (define_insn "*call_pop_0"
11263 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
11264 (match_operand:SI 1 "" ""))
11265 (set (reg:SI SP_REG)
11266 (plus:SI (reg:SI SP_REG)
11267 (match_operand:SI 2 "immediate_operand" "")))]
11270 if (SIBLING_CALL_P (insn))
11273 return "call\t%P0";
11275 [(set_attr "type" "call")])
11277 (define_insn "*call_pop_1"
11278 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11279 (match_operand:SI 1 "" ""))
11280 (set (reg:SI SP_REG)
11281 (plus:SI (reg:SI SP_REG)
11282 (match_operand:SI 2 "immediate_operand" "i")))]
11283 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11285 if (constant_call_address_operand (operands[0], Pmode))
11286 return "call\t%P0";
11287 return "call\t%A0";
11289 [(set_attr "type" "call")])
11291 (define_insn "*sibcall_pop_1"
11292 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11293 (match_operand:SI 1 "" ""))
11294 (set (reg:SI SP_REG)
11295 (plus:SI (reg:SI SP_REG)
11296 (match_operand:SI 2 "immediate_operand" "i,i")))]
11297 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11301 [(set_attr "type" "call")])
11303 (define_expand "call"
11304 [(call (match_operand:QI 0 "" "")
11305 (match_operand 1 "" ""))
11306 (use (match_operand 2 "" ""))]
11309 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
11313 (define_expand "sibcall"
11314 [(call (match_operand:QI 0 "" "")
11315 (match_operand 1 "" ""))
11316 (use (match_operand 2 "" ""))]
11319 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
11323 (define_insn "*call_0"
11324 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
11325 (match_operand 1 "" ""))]
11328 if (SIBLING_CALL_P (insn))
11331 return "call\t%P0";
11333 [(set_attr "type" "call")])
11335 (define_insn "*call_1"
11336 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
11337 (match_operand 1 "" ""))]
11338 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11340 if (constant_call_address_operand (operands[0], Pmode))
11341 return "call\t%P0";
11342 return "call\t%A0";
11344 [(set_attr "type" "call")])
11346 (define_insn "*sibcall_1"
11347 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
11348 (match_operand 1 "" ""))]
11349 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11353 [(set_attr "type" "call")])
11355 (define_insn "*call_1_rex64"
11356 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11357 (match_operand 1 "" ""))]
11358 "TARGET_64BIT && !SIBLING_CALL_P (insn)
11359 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
11361 if (constant_call_address_operand (operands[0], Pmode))
11362 return "call\t%P0";
11363 return "call\t%A0";
11365 [(set_attr "type" "call")])
11367 (define_insn "*call_1_rex64_ms_sysv"
11368 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
11369 (match_operand 1 "" ""))
11370 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11371 (clobber (reg:TI XMM6_REG))
11372 (clobber (reg:TI XMM7_REG))
11373 (clobber (reg:TI XMM8_REG))
11374 (clobber (reg:TI XMM9_REG))
11375 (clobber (reg:TI XMM10_REG))
11376 (clobber (reg:TI XMM11_REG))
11377 (clobber (reg:TI XMM12_REG))
11378 (clobber (reg:TI XMM13_REG))
11379 (clobber (reg:TI XMM14_REG))
11380 (clobber (reg:TI XMM15_REG))
11381 (clobber (reg:DI SI_REG))
11382 (clobber (reg:DI DI_REG))]
11383 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11385 if (constant_call_address_operand (operands[0], Pmode))
11386 return "call\t%P0";
11387 return "call\t%A0";
11389 [(set_attr "type" "call")])
11391 (define_insn "*call_1_rex64_large"
11392 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
11393 (match_operand 1 "" ""))]
11394 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11396 [(set_attr "type" "call")])
11398 (define_insn "*sibcall_1_rex64"
11399 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
11400 (match_operand 1 "" ""))]
11401 "TARGET_64BIT && SIBLING_CALL_P (insn)"
11405 [(set_attr "type" "call")])
11407 ;; Call subroutine, returning value in operand 0
11408 (define_expand "call_value_pop"
11409 [(parallel [(set (match_operand 0 "" "")
11410 (call (match_operand:QI 1 "" "")
11411 (match_operand:SI 2 "" "")))
11412 (set (reg:SI SP_REG)
11413 (plus:SI (reg:SI SP_REG)
11414 (match_operand:SI 4 "" "")))])]
11417 ix86_expand_call (operands[0], operands[1], operands[2],
11418 operands[3], operands[4], 0);
11422 (define_expand "call_value"
11423 [(set (match_operand 0 "" "")
11424 (call (match_operand:QI 1 "" "")
11425 (match_operand:SI 2 "" "")))
11426 (use (match_operand:SI 3 "" ""))]
11427 ;; Operand 3 is not used on the i386.
11430 ix86_expand_call (operands[0], operands[1], operands[2],
11431 operands[3], NULL, 0);
11435 (define_expand "sibcall_value"
11436 [(set (match_operand 0 "" "")
11437 (call (match_operand:QI 1 "" "")
11438 (match_operand:SI 2 "" "")))
11439 (use (match_operand:SI 3 "" ""))]
11440 ;; Operand 3 is not used on the i386.
11443 ix86_expand_call (operands[0], operands[1], operands[2],
11444 operands[3], NULL, 1);
11448 ;; Call subroutine returning any type.
11450 (define_expand "untyped_call"
11451 [(parallel [(call (match_operand 0 "" "")
11453 (match_operand 1 "" "")
11454 (match_operand 2 "" "")])]
11459 /* In order to give reg-stack an easier job in validating two
11460 coprocessor registers as containing a possible return value,
11461 simply pretend the untyped call returns a complex long double
11464 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11465 and should have the default ABI. */
11467 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11468 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11469 operands[0], const0_rtx,
11470 GEN_INT ((TARGET_64BIT
11471 ? (ix86_abi == SYSV_ABI
11472 ? X86_64_SSE_REGPARM_MAX
11473 : X86_64_MS_SSE_REGPARM_MAX)
11474 : X86_32_SSE_REGPARM_MAX)
11478 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11480 rtx set = XVECEXP (operands[2], 0, i);
11481 emit_move_insn (SET_DEST (set), SET_SRC (set));
11484 /* The optimizer does not know that the call sets the function value
11485 registers we stored in the result block. We avoid problems by
11486 claiming that all hard registers are used and clobbered at this
11488 emit_insn (gen_blockage ());
11493 ;; Prologue and epilogue instructions
11495 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11496 ;; all of memory. This blocks insns from being moved across this point.
11498 (define_insn "blockage"
11499 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11502 [(set_attr "length" "0")])
11504 ;; Do not schedule instructions accessing memory across this point.
11506 (define_expand "memory_blockage"
11507 [(set (match_dup 0)
11508 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11511 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11512 MEM_VOLATILE_P (operands[0]) = 1;
11515 (define_insn "*memory_blockage"
11516 [(set (match_operand:BLK 0 "" "")
11517 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11520 [(set_attr "length" "0")])
11522 ;; As USE insns aren't meaningful after reload, this is used instead
11523 ;; to prevent deleting instructions setting registers for PIC code
11524 (define_insn "prologue_use"
11525 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11528 [(set_attr "length" "0")])
11530 ;; Insn emitted into the body of a function to return from a function.
11531 ;; This is only done if the function's epilogue is known to be simple.
11532 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11534 (define_expand "return"
11536 "ix86_can_use_return_insn_p ()"
11538 if (crtl->args.pops_args)
11540 rtx popc = GEN_INT (crtl->args.pops_args);
11541 emit_jump_insn (gen_return_pop_internal (popc));
11546 (define_insn "return_internal"
11550 [(set_attr "length" "1")
11551 (set_attr "atom_unit" "jeu")
11552 (set_attr "length_immediate" "0")
11553 (set_attr "modrm" "0")])
11555 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11556 ;; instruction Athlon and K8 have.
11558 (define_insn "return_internal_long"
11560 (unspec [(const_int 0)] UNSPEC_REP)]
11563 [(set_attr "length" "2")
11564 (set_attr "atom_unit" "jeu")
11565 (set_attr "length_immediate" "0")
11566 (set_attr "prefix_rep" "1")
11567 (set_attr "modrm" "0")])
11569 (define_insn "return_pop_internal"
11571 (use (match_operand:SI 0 "const_int_operand" ""))]
11574 [(set_attr "length" "3")
11575 (set_attr "atom_unit" "jeu")
11576 (set_attr "length_immediate" "2")
11577 (set_attr "modrm" "0")])
11579 (define_insn "return_indirect_internal"
11581 (use (match_operand:SI 0 "register_operand" "r"))]
11584 [(set_attr "type" "ibr")
11585 (set_attr "length_immediate" "0")])
11591 [(set_attr "length" "1")
11592 (set_attr "length_immediate" "0")
11593 (set_attr "modrm" "0")])
11595 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11596 (define_insn "nops"
11597 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11601 int num = INTVAL (operands[0]);
11603 gcc_assert (num >= 1 && num <= 8);
11606 fputs ("\tnop\n", asm_out_file);
11610 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11611 (set_attr "length_immediate" "0")
11612 (set_attr "modrm" "0")])
11614 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11615 ;; branch prediction penalty for the third jump in a 16-byte
11619 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11622 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11623 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11625 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11626 The align insn is used to avoid 3 jump instructions in the row to improve
11627 branch prediction and the benefits hardly outweigh the cost of extra 8
11628 nops on the average inserted by full alignment pseudo operation. */
11632 [(set_attr "length" "16")])
11634 (define_expand "prologue"
11637 "ix86_expand_prologue (); DONE;")
11639 (define_insn "set_got"
11640 [(set (match_operand:SI 0 "register_operand" "=r")
11641 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11642 (clobber (reg:CC FLAGS_REG))]
11644 "* return output_set_got (operands[0], NULL_RTX);"
11645 [(set_attr "type" "multi")
11646 (set_attr "length" "12")])
11648 (define_insn "set_got_labelled"
11649 [(set (match_operand:SI 0 "register_operand" "=r")
11650 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11652 (clobber (reg:CC FLAGS_REG))]
11654 "* return output_set_got (operands[0], operands[1]);"
11655 [(set_attr "type" "multi")
11656 (set_attr "length" "12")])
11658 (define_insn "set_got_rex64"
11659 [(set (match_operand:DI 0 "register_operand" "=r")
11660 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11662 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11663 [(set_attr "type" "lea")
11664 (set_attr "length_address" "4")
11665 (set_attr "mode" "DI")])
11667 (define_insn "set_rip_rex64"
11668 [(set (match_operand:DI 0 "register_operand" "=r")
11669 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11671 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11672 [(set_attr "type" "lea")
11673 (set_attr "length_address" "4")
11674 (set_attr "mode" "DI")])
11676 (define_insn "set_got_offset_rex64"
11677 [(set (match_operand:DI 0 "register_operand" "=r")
11679 [(label_ref (match_operand 1 "" ""))]
11680 UNSPEC_SET_GOT_OFFSET))]
11682 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11683 [(set_attr "type" "imov")
11684 (set_attr "length_immediate" "0")
11685 (set_attr "length_address" "8")
11686 (set_attr "mode" "DI")])
11688 (define_expand "epilogue"
11691 "ix86_expand_epilogue (1); DONE;")
11693 (define_expand "sibcall_epilogue"
11696 "ix86_expand_epilogue (0); DONE;")
11698 (define_expand "eh_return"
11699 [(use (match_operand 0 "register_operand" ""))]
11702 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11704 /* Tricky bit: we write the address of the handler to which we will
11705 be returning into someone else's stack frame, one word below the
11706 stack address we wish to restore. */
11707 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11708 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11709 tmp = gen_rtx_MEM (Pmode, tmp);
11710 emit_move_insn (tmp, ra);
11712 emit_jump_insn (gen_eh_return_internal ());
11717 (define_insn_and_split "eh_return_internal"
11721 "epilogue_completed"
11723 "ix86_expand_epilogue (2); DONE;")
11725 (define_insn "leave"
11726 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11727 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11728 (clobber (mem:BLK (scratch)))]
11731 [(set_attr "type" "leave")])
11733 (define_insn "leave_rex64"
11734 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11735 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11736 (clobber (mem:BLK (scratch)))]
11739 [(set_attr "type" "leave")])
11741 ;; Handle -fsplit-stack.
11743 (define_expand "split_stack_prologue"
11747 ix86_expand_split_stack_prologue ();
11751 ;; In order to support the call/return predictor, we use a return
11752 ;; instruction which the middle-end doesn't see.
11753 (define_insn "split_stack_return"
11754 [(unspec [(match_operand:SI 0 "const_int_operand" "")]
11755 UNSPEC_STACK_CHECK)]
11758 if (operands[0] == const0_rtx)
11763 [(set_attr "atom_unit" "jeu")
11764 (set_attr "modrm" "0")
11765 (set (attr "length")
11766 (if_then_else (match_operand:SI 0 "const0_operand" "")
11769 (set (attr "length_immediate")
11770 (if_then_else (match_operand:SI 0 "const0_operand" "")
11774 ;; If there are operand 0 bytes available on the stack, jump to
11777 (define_expand "split_stack_space_check"
11778 [(set (pc) (if_then_else
11779 (ltu (minus (reg SP_REG)
11780 (match_operand 0 "register_operand" ""))
11781 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11782 (label_ref (match_operand 1 "" ""))
11786 rtx reg, size, limit;
11788 reg = gen_reg_rtx (Pmode);
11789 size = force_reg (Pmode, operands[0]);
11790 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11791 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11792 UNSPEC_STACK_CHECK);
11793 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11794 ix86_expand_branch (GEU, reg, limit, operands[1]);
11799 ;; Bit manipulation instructions.
11801 (define_expand "ffs<mode>2"
11802 [(set (match_dup 2) (const_int -1))
11803 (parallel [(set (reg:CCZ FLAGS_REG)
11805 (match_operand:SWI48 1 "nonimmediate_operand" "")
11807 (set (match_operand:SWI48 0 "register_operand" "")
11808 (ctz:SWI48 (match_dup 1)))])
11809 (set (match_dup 0) (if_then_else:SWI48
11810 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11813 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11814 (clobber (reg:CC FLAGS_REG))])]
11817 if (<MODE>mode == SImode && !TARGET_CMOVE)
11819 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11822 operands[2] = gen_reg_rtx (<MODE>mode);
11825 (define_insn_and_split "ffssi2_no_cmove"
11826 [(set (match_operand:SI 0 "register_operand" "=r")
11827 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11828 (clobber (match_scratch:SI 2 "=&q"))
11829 (clobber (reg:CC FLAGS_REG))]
11832 "&& reload_completed"
11833 [(parallel [(set (reg:CCZ FLAGS_REG)
11834 (compare:CCZ (match_dup 1) (const_int 0)))
11835 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11836 (set (strict_low_part (match_dup 3))
11837 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11838 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11839 (clobber (reg:CC FLAGS_REG))])
11840 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11841 (clobber (reg:CC FLAGS_REG))])
11842 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11843 (clobber (reg:CC FLAGS_REG))])]
11845 operands[3] = gen_lowpart (QImode, operands[2]);
11846 ix86_expand_clear (operands[2]);
11849 (define_insn "*ffs<mode>_1"
11850 [(set (reg:CCZ FLAGS_REG)
11851 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11853 (set (match_operand:SWI48 0 "register_operand" "=r")
11854 (ctz:SWI48 (match_dup 1)))]
11856 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11857 [(set_attr "type" "alu1")
11858 (set_attr "prefix_0f" "1")
11859 (set_attr "mode" "<MODE>")])
11861 (define_insn "ctz<mode>2"
11862 [(set (match_operand:SWI48 0 "register_operand" "=r")
11863 (ctz:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
11864 (clobber (reg:CC FLAGS_REG))]
11866 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11867 [(set_attr "type" "alu1")
11868 (set_attr "prefix_0f" "1")
11869 (set_attr "mode" "<MODE>")])
11871 (define_expand "clz<mode>2"
11873 [(set (match_operand:SWI248 0 "register_operand" "")
11876 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
11877 (clobber (reg:CC FLAGS_REG))])
11879 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
11880 (clobber (reg:CC FLAGS_REG))])]
11885 emit_insn (gen_clz<mode>2_abm (operands[0], operands[1]));
11888 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11891 (define_insn "clz<mode>2_abm"
11892 [(set (match_operand:SWI248 0 "register_operand" "=r")
11893 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11894 (clobber (reg:CC FLAGS_REG))]
11896 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11897 [(set_attr "prefix_rep" "1")
11898 (set_attr "type" "bitmanip")
11899 (set_attr "mode" "<MODE>")])
11901 (define_insn "bsr_rex64"
11902 [(set (match_operand:DI 0 "register_operand" "=r")
11903 (minus:DI (const_int 63)
11904 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
11905 (clobber (reg:CC FLAGS_REG))]
11907 "bsr{q}\t{%1, %0|%0, %1}"
11908 [(set_attr "type" "alu1")
11909 (set_attr "prefix_0f" "1")
11910 (set_attr "mode" "DI")])
11913 [(set (match_operand:SI 0 "register_operand" "=r")
11914 (minus:SI (const_int 31)
11915 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
11916 (clobber (reg:CC FLAGS_REG))]
11918 "bsr{l}\t{%1, %0|%0, %1}"
11919 [(set_attr "type" "alu1")
11920 (set_attr "prefix_0f" "1")
11921 (set_attr "mode" "SI")])
11923 (define_insn "*bsrhi"
11924 [(set (match_operand:HI 0 "register_operand" "=r")
11925 (minus:HI (const_int 15)
11926 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
11927 (clobber (reg:CC FLAGS_REG))]
11929 "bsr{w}\t{%1, %0|%0, %1}"
11930 [(set_attr "type" "alu1")
11931 (set_attr "prefix_0f" "1")
11932 (set_attr "mode" "HI")])
11934 (define_insn "popcount<mode>2"
11935 [(set (match_operand:SWI248 0 "register_operand" "=r")
11937 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11938 (clobber (reg:CC FLAGS_REG))]
11942 return "popcnt\t{%1, %0|%0, %1}";
11944 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11947 [(set_attr "prefix_rep" "1")
11948 (set_attr "type" "bitmanip")
11949 (set_attr "mode" "<MODE>")])
11951 (define_insn "*popcount<mode>2_cmp"
11952 [(set (reg FLAGS_REG)
11955 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
11957 (set (match_operand:SWI248 0 "register_operand" "=r")
11958 (popcount:SWI248 (match_dup 1)))]
11959 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
11962 return "popcnt\t{%1, %0|%0, %1}";
11964 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11967 [(set_attr "prefix_rep" "1")
11968 (set_attr "type" "bitmanip")
11969 (set_attr "mode" "<MODE>")])
11971 (define_insn "*popcountsi2_cmp_zext"
11972 [(set (reg FLAGS_REG)
11974 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
11976 (set (match_operand:DI 0 "register_operand" "=r")
11977 (zero_extend:DI(popcount:SI (match_dup 1))))]
11978 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
11981 return "popcnt\t{%1, %0|%0, %1}";
11983 return "popcnt{l}\t{%1, %0|%0, %1}";
11986 [(set_attr "prefix_rep" "1")
11987 (set_attr "type" "bitmanip")
11988 (set_attr "mode" "SI")])
11990 (define_expand "bswap<mode>2"
11991 [(set (match_operand:SWI48 0 "register_operand" "")
11992 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
11995 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
11997 rtx x = operands[0];
11999 emit_move_insn (x, operands[1]);
12000 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12001 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12002 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12007 (define_insn "*bswap<mode>2_movbe"
12008 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12009 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12011 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12014 movbe\t{%1, %0|%0, %1}
12015 movbe\t{%1, %0|%0, %1}"
12016 [(set_attr "type" "bitmanip,imov,imov")
12017 (set_attr "modrm" "0,1,1")
12018 (set_attr "prefix_0f" "*,1,1")
12019 (set_attr "prefix_extra" "*,1,1")
12020 (set_attr "mode" "<MODE>")])
12022 (define_insn "*bswap<mode>2_1"
12023 [(set (match_operand:SWI48 0 "register_operand" "=r")
12024 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12027 [(set_attr "type" "bitmanip")
12028 (set_attr "modrm" "0")
12029 (set_attr "mode" "<MODE>")])
12031 (define_insn "*bswaphi_lowpart_1"
12032 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12033 (bswap:HI (match_dup 0)))
12034 (clobber (reg:CC FLAGS_REG))]
12035 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12037 xchg{b}\t{%h0, %b0|%b0, %h0}
12038 rol{w}\t{$8, %0|%0, 8}"
12039 [(set_attr "length" "2,4")
12040 (set_attr "mode" "QI,HI")])
12042 (define_insn "bswaphi_lowpart"
12043 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12044 (bswap:HI (match_dup 0)))
12045 (clobber (reg:CC FLAGS_REG))]
12047 "rol{w}\t{$8, %0|%0, 8}"
12048 [(set_attr "length" "4")
12049 (set_attr "mode" "HI")])
12051 (define_expand "paritydi2"
12052 [(set (match_operand:DI 0 "register_operand" "")
12053 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12056 rtx scratch = gen_reg_rtx (QImode);
12059 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12060 NULL_RTX, operands[1]));
12062 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12063 gen_rtx_REG (CCmode, FLAGS_REG),
12065 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12068 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12071 rtx tmp = gen_reg_rtx (SImode);
12073 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12074 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12079 (define_expand "paritysi2"
12080 [(set (match_operand:SI 0 "register_operand" "")
12081 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12084 rtx scratch = gen_reg_rtx (QImode);
12087 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12089 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12090 gen_rtx_REG (CCmode, FLAGS_REG),
12092 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12094 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12098 (define_insn_and_split "paritydi2_cmp"
12099 [(set (reg:CC FLAGS_REG)
12100 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12102 (clobber (match_scratch:DI 0 "=r"))
12103 (clobber (match_scratch:SI 1 "=&r"))
12104 (clobber (match_scratch:HI 2 "=Q"))]
12107 "&& reload_completed"
12109 [(set (match_dup 1)
12110 (xor:SI (match_dup 1) (match_dup 4)))
12111 (clobber (reg:CC FLAGS_REG))])
12113 [(set (reg:CC FLAGS_REG)
12114 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12115 (clobber (match_dup 1))
12116 (clobber (match_dup 2))])]
12118 operands[4] = gen_lowpart (SImode, operands[3]);
12122 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12123 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12126 operands[1] = gen_highpart (SImode, operands[3]);
12129 (define_insn_and_split "paritysi2_cmp"
12130 [(set (reg:CC FLAGS_REG)
12131 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12133 (clobber (match_scratch:SI 0 "=r"))
12134 (clobber (match_scratch:HI 1 "=&Q"))]
12137 "&& reload_completed"
12139 [(set (match_dup 1)
12140 (xor:HI (match_dup 1) (match_dup 3)))
12141 (clobber (reg:CC FLAGS_REG))])
12143 [(set (reg:CC FLAGS_REG)
12144 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12145 (clobber (match_dup 1))])]
12147 operands[3] = gen_lowpart (HImode, operands[2]);
12149 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12150 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12153 (define_insn "*parityhi2_cmp"
12154 [(set (reg:CC FLAGS_REG)
12155 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12157 (clobber (match_scratch:HI 0 "=Q"))]
12159 "xor{b}\t{%h0, %b0|%b0, %h0}"
12160 [(set_attr "length" "2")
12161 (set_attr "mode" "HI")])
12163 ;; Thread-local storage patterns for ELF.
12165 ;; Note that these code sequences must appear exactly as shown
12166 ;; in order to allow linker relaxation.
12168 (define_insn "*tls_global_dynamic_32_gnu"
12169 [(set (match_operand:SI 0 "register_operand" "=a")
12170 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12171 (match_operand:SI 2 "tls_symbolic_operand" "")
12172 (match_operand:SI 3 "call_insn_operand" "")]
12174 (clobber (match_scratch:SI 4 "=d"))
12175 (clobber (match_scratch:SI 5 "=c"))
12176 (clobber (reg:CC FLAGS_REG))]
12177 "!TARGET_64BIT && TARGET_GNU_TLS"
12178 "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
12179 [(set_attr "type" "multi")
12180 (set_attr "length" "12")])
12182 (define_expand "tls_global_dynamic_32"
12183 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12186 (match_operand:SI 1 "tls_symbolic_operand" "")
12189 (clobber (match_scratch:SI 4 ""))
12190 (clobber (match_scratch:SI 5 ""))
12191 (clobber (reg:CC FLAGS_REG))])]
12195 operands[2] = pic_offset_table_rtx;
12198 operands[2] = gen_reg_rtx (Pmode);
12199 emit_insn (gen_set_got (operands[2]));
12201 if (TARGET_GNU2_TLS)
12203 emit_insn (gen_tls_dynamic_gnu2_32
12204 (operands[0], operands[1], operands[2]));
12207 operands[3] = ix86_tls_get_addr ();
12210 (define_insn "*tls_global_dynamic_64"
12211 [(set (match_operand:DI 0 "register_operand" "=a")
12212 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
12213 (match_operand:DI 3 "" "")))
12214 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12217 { 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"; }
12218 [(set_attr "type" "multi")
12219 (set_attr "length" "16")])
12221 (define_expand "tls_global_dynamic_64"
12222 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12223 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
12224 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12228 if (TARGET_GNU2_TLS)
12230 emit_insn (gen_tls_dynamic_gnu2_64
12231 (operands[0], operands[1]));
12234 operands[2] = ix86_tls_get_addr ();
12237 (define_insn "*tls_local_dynamic_base_32_gnu"
12238 [(set (match_operand:SI 0 "register_operand" "=a")
12239 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12240 (match_operand:SI 2 "call_insn_operand" "")]
12241 UNSPEC_TLS_LD_BASE))
12242 (clobber (match_scratch:SI 3 "=d"))
12243 (clobber (match_scratch:SI 4 "=c"))
12244 (clobber (reg:CC FLAGS_REG))]
12245 "!TARGET_64BIT && TARGET_GNU_TLS"
12246 "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
12247 [(set_attr "type" "multi")
12248 (set_attr "length" "11")])
12250 (define_expand "tls_local_dynamic_base_32"
12251 [(parallel [(set (match_operand:SI 0 "register_operand" "")
12252 (unspec:SI [(match_dup 1) (match_dup 2)]
12253 UNSPEC_TLS_LD_BASE))
12254 (clobber (match_scratch:SI 3 ""))
12255 (clobber (match_scratch:SI 4 ""))
12256 (clobber (reg:CC FLAGS_REG))])]
12260 operands[1] = pic_offset_table_rtx;
12263 operands[1] = gen_reg_rtx (Pmode);
12264 emit_insn (gen_set_got (operands[1]));
12266 if (TARGET_GNU2_TLS)
12268 emit_insn (gen_tls_dynamic_gnu2_32
12269 (operands[0], ix86_tls_module_base (), operands[1]));
12272 operands[2] = ix86_tls_get_addr ();
12275 (define_insn "*tls_local_dynamic_base_64"
12276 [(set (match_operand:DI 0 "register_operand" "=a")
12277 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
12278 (match_operand:DI 2 "" "")))
12279 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12281 "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
12282 [(set_attr "type" "multi")
12283 (set_attr "length" "12")])
12285 (define_expand "tls_local_dynamic_base_64"
12286 [(parallel [(set (match_operand:DI 0 "register_operand" "")
12287 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
12288 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12291 if (TARGET_GNU2_TLS)
12293 emit_insn (gen_tls_dynamic_gnu2_64
12294 (operands[0], ix86_tls_module_base ()));
12297 operands[1] = ix86_tls_get_addr ();
12300 ;; Local dynamic of a single variable is a lose. Show combine how
12301 ;; to convert that back to global dynamic.
12303 (define_insn_and_split "*tls_local_dynamic_32_once"
12304 [(set (match_operand:SI 0 "register_operand" "=a")
12305 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12306 (match_operand:SI 2 "call_insn_operand" "")]
12307 UNSPEC_TLS_LD_BASE)
12308 (const:SI (unspec:SI
12309 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12311 (clobber (match_scratch:SI 4 "=d"))
12312 (clobber (match_scratch:SI 5 "=c"))
12313 (clobber (reg:CC FLAGS_REG))]
12317 [(parallel [(set (match_dup 0)
12318 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12320 (clobber (match_dup 4))
12321 (clobber (match_dup 5))
12322 (clobber (reg:CC FLAGS_REG))])])
12324 ;; Segment register for the thread base ptr load
12325 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12327 ;; Load and add the thread base pointer from %gs:0.
12328 (define_insn "*load_tp_<mode>"
12329 [(set (match_operand:P 0 "register_operand" "=r")
12330 (unspec:P [(const_int 0)] UNSPEC_TP))]
12332 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12333 [(set_attr "type" "imov")
12334 (set_attr "modrm" "0")
12335 (set_attr "length" "7")
12336 (set_attr "memory" "load")
12337 (set_attr "imm_disp" "false")])
12339 (define_insn "*add_tp_<mode>"
12340 [(set (match_operand:P 0 "register_operand" "=r")
12341 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12342 (match_operand:P 1 "register_operand" "0")))
12343 (clobber (reg:CC FLAGS_REG))]
12345 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12346 [(set_attr "type" "alu")
12347 (set_attr "modrm" "0")
12348 (set_attr "length" "7")
12349 (set_attr "memory" "load")
12350 (set_attr "imm_disp" "false")])
12352 ;; GNU2 TLS patterns can be split.
12354 (define_expand "tls_dynamic_gnu2_32"
12355 [(set (match_dup 3)
12356 (plus:SI (match_operand:SI 2 "register_operand" "")
12358 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12361 [(set (match_operand:SI 0 "register_operand" "")
12362 (unspec:SI [(match_dup 1) (match_dup 3)
12363 (match_dup 2) (reg:SI SP_REG)]
12365 (clobber (reg:CC FLAGS_REG))])]
12366 "!TARGET_64BIT && TARGET_GNU2_TLS"
12368 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12369 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12372 (define_insn "*tls_dynamic_lea_32"
12373 [(set (match_operand:SI 0 "register_operand" "=r")
12374 (plus:SI (match_operand:SI 1 "register_operand" "b")
12376 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12377 UNSPEC_TLSDESC))))]
12378 "!TARGET_64BIT && TARGET_GNU2_TLS"
12379 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12380 [(set_attr "type" "lea")
12381 (set_attr "mode" "SI")
12382 (set_attr "length" "6")
12383 (set_attr "length_address" "4")])
12385 (define_insn "*tls_dynamic_call_32"
12386 [(set (match_operand:SI 0 "register_operand" "=a")
12387 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12388 (match_operand:SI 2 "register_operand" "0")
12389 ;; we have to make sure %ebx still points to the GOT
12390 (match_operand:SI 3 "register_operand" "b")
12393 (clobber (reg:CC FLAGS_REG))]
12394 "!TARGET_64BIT && TARGET_GNU2_TLS"
12395 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12396 [(set_attr "type" "call")
12397 (set_attr "length" "2")
12398 (set_attr "length_address" "0")])
12400 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12401 [(set (match_operand:SI 0 "register_operand" "=&a")
12403 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12404 (match_operand:SI 4 "" "")
12405 (match_operand:SI 2 "register_operand" "b")
12408 (const:SI (unspec:SI
12409 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12411 (clobber (reg:CC FLAGS_REG))]
12412 "!TARGET_64BIT && TARGET_GNU2_TLS"
12415 [(set (match_dup 0) (match_dup 5))]
12417 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12418 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12421 (define_expand "tls_dynamic_gnu2_64"
12422 [(set (match_dup 2)
12423 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12426 [(set (match_operand:DI 0 "register_operand" "")
12427 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12429 (clobber (reg:CC FLAGS_REG))])]
12430 "TARGET_64BIT && TARGET_GNU2_TLS"
12432 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12433 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12436 (define_insn "*tls_dynamic_lea_64"
12437 [(set (match_operand:DI 0 "register_operand" "=r")
12438 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
12440 "TARGET_64BIT && TARGET_GNU2_TLS"
12441 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12442 [(set_attr "type" "lea")
12443 (set_attr "mode" "DI")
12444 (set_attr "length" "7")
12445 (set_attr "length_address" "4")])
12447 (define_insn "*tls_dynamic_call_64"
12448 [(set (match_operand:DI 0 "register_operand" "=a")
12449 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
12450 (match_operand:DI 2 "register_operand" "0")
12453 (clobber (reg:CC FLAGS_REG))]
12454 "TARGET_64BIT && TARGET_GNU2_TLS"
12455 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12456 [(set_attr "type" "call")
12457 (set_attr "length" "2")
12458 (set_attr "length_address" "0")])
12460 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12461 [(set (match_operand:DI 0 "register_operand" "=&a")
12463 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12464 (match_operand:DI 3 "" "")
12467 (const:DI (unspec:DI
12468 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12470 (clobber (reg:CC FLAGS_REG))]
12471 "TARGET_64BIT && TARGET_GNU2_TLS"
12474 [(set (match_dup 0) (match_dup 4))]
12476 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12477 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12480 ;; These patterns match the binary 387 instructions for addM3, subM3,
12481 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12482 ;; SFmode. The first is the normal insn, the second the same insn but
12483 ;; with one operand a conversion, and the third the same insn but with
12484 ;; the other operand a conversion. The conversion may be SFmode or
12485 ;; SImode if the target mode DFmode, but only SImode if the target mode
12488 ;; Gcc is slightly more smart about handling normal two address instructions
12489 ;; so use special patterns for add and mull.
12491 (define_insn "*fop_<mode>_comm_mixed_avx"
12492 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12493 (match_operator:MODEF 3 "binary_fp_operator"
12494 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12495 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12496 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12497 && COMMUTATIVE_ARITH_P (operands[3])
12498 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12499 "* return output_387_binary_op (insn, operands);"
12500 [(set (attr "type")
12501 (if_then_else (eq_attr "alternative" "1")
12502 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12503 (const_string "ssemul")
12504 (const_string "sseadd"))
12505 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12506 (const_string "fmul")
12507 (const_string "fop"))))
12508 (set_attr "prefix" "orig,maybe_vex")
12509 (set_attr "mode" "<MODE>")])
12511 (define_insn "*fop_<mode>_comm_mixed"
12512 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
12513 (match_operator:MODEF 3 "binary_fp_operator"
12514 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
12515 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
12516 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12517 && COMMUTATIVE_ARITH_P (operands[3])
12518 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12519 "* return output_387_binary_op (insn, operands);"
12520 [(set (attr "type")
12521 (if_then_else (eq_attr "alternative" "1")
12522 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12523 (const_string "ssemul")
12524 (const_string "sseadd"))
12525 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12526 (const_string "fmul")
12527 (const_string "fop"))))
12528 (set_attr "mode" "<MODE>")])
12530 (define_insn "*fop_<mode>_comm_avx"
12531 [(set (match_operand:MODEF 0 "register_operand" "=x")
12532 (match_operator:MODEF 3 "binary_fp_operator"
12533 [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
12534 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12535 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12536 && COMMUTATIVE_ARITH_P (operands[3])
12537 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12538 "* return output_387_binary_op (insn, operands);"
12539 [(set (attr "type")
12540 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12541 (const_string "ssemul")
12542 (const_string "sseadd")))
12543 (set_attr "prefix" "vex")
12544 (set_attr "mode" "<MODE>")])
12546 (define_insn "*fop_<mode>_comm_sse"
12547 [(set (match_operand:MODEF 0 "register_operand" "=x")
12548 (match_operator:MODEF 3 "binary_fp_operator"
12549 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12550 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12551 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12552 && COMMUTATIVE_ARITH_P (operands[3])
12553 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12554 "* return output_387_binary_op (insn, operands);"
12555 [(set (attr "type")
12556 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12557 (const_string "ssemul")
12558 (const_string "sseadd")))
12559 (set_attr "mode" "<MODE>")])
12561 (define_insn "*fop_<mode>_comm_i387"
12562 [(set (match_operand:MODEF 0 "register_operand" "=f")
12563 (match_operator:MODEF 3 "binary_fp_operator"
12564 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12565 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12566 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12567 && COMMUTATIVE_ARITH_P (operands[3])
12568 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12569 "* return output_387_binary_op (insn, operands);"
12570 [(set (attr "type")
12571 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12572 (const_string "fmul")
12573 (const_string "fop")))
12574 (set_attr "mode" "<MODE>")])
12576 (define_insn "*fop_<mode>_1_mixed_avx"
12577 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12578 (match_operator:MODEF 3 "binary_fp_operator"
12579 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
12580 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12581 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12582 && !COMMUTATIVE_ARITH_P (operands[3])
12583 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12584 "* return output_387_binary_op (insn, operands);"
12585 [(set (attr "type")
12586 (cond [(and (eq_attr "alternative" "2")
12587 (match_operand:MODEF 3 "mult_operator" ""))
12588 (const_string "ssemul")
12589 (and (eq_attr "alternative" "2")
12590 (match_operand:MODEF 3 "div_operator" ""))
12591 (const_string "ssediv")
12592 (eq_attr "alternative" "2")
12593 (const_string "sseadd")
12594 (match_operand:MODEF 3 "mult_operator" "")
12595 (const_string "fmul")
12596 (match_operand:MODEF 3 "div_operator" "")
12597 (const_string "fdiv")
12599 (const_string "fop")))
12600 (set_attr "prefix" "orig,orig,maybe_vex")
12601 (set_attr "mode" "<MODE>")])
12603 (define_insn "*fop_<mode>_1_mixed"
12604 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
12605 (match_operator:MODEF 3 "binary_fp_operator"
12606 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
12607 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
12608 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12609 && !COMMUTATIVE_ARITH_P (operands[3])
12610 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12611 "* return output_387_binary_op (insn, operands);"
12612 [(set (attr "type")
12613 (cond [(and (eq_attr "alternative" "2")
12614 (match_operand:MODEF 3 "mult_operator" ""))
12615 (const_string "ssemul")
12616 (and (eq_attr "alternative" "2")
12617 (match_operand:MODEF 3 "div_operator" ""))
12618 (const_string "ssediv")
12619 (eq_attr "alternative" "2")
12620 (const_string "sseadd")
12621 (match_operand:MODEF 3 "mult_operator" "")
12622 (const_string "fmul")
12623 (match_operand:MODEF 3 "div_operator" "")
12624 (const_string "fdiv")
12626 (const_string "fop")))
12627 (set_attr "mode" "<MODE>")])
12629 (define_insn "*rcpsf2_sse"
12630 [(set (match_operand:SF 0 "register_operand" "=x")
12631 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12634 "%vrcpss\t{%1, %d0|%d0, %1}"
12635 [(set_attr "type" "sse")
12636 (set_attr "atom_sse_attr" "rcp")
12637 (set_attr "prefix" "maybe_vex")
12638 (set_attr "mode" "SF")])
12640 (define_insn "*fop_<mode>_1_avx"
12641 [(set (match_operand:MODEF 0 "register_operand" "=x")
12642 (match_operator:MODEF 3 "binary_fp_operator"
12643 [(match_operand:MODEF 1 "register_operand" "x")
12644 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12645 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12646 && !COMMUTATIVE_ARITH_P (operands[3])"
12647 "* return output_387_binary_op (insn, operands);"
12648 [(set (attr "type")
12649 (cond [(match_operand:MODEF 3 "mult_operator" "")
12650 (const_string "ssemul")
12651 (match_operand:MODEF 3 "div_operator" "")
12652 (const_string "ssediv")
12654 (const_string "sseadd")))
12655 (set_attr "prefix" "vex")
12656 (set_attr "mode" "<MODE>")])
12658 (define_insn "*fop_<mode>_1_sse"
12659 [(set (match_operand:MODEF 0 "register_operand" "=x")
12660 (match_operator:MODEF 3 "binary_fp_operator"
12661 [(match_operand:MODEF 1 "register_operand" "0")
12662 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
12663 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12664 && !COMMUTATIVE_ARITH_P (operands[3])"
12665 "* return output_387_binary_op (insn, operands);"
12666 [(set (attr "type")
12667 (cond [(match_operand:MODEF 3 "mult_operator" "")
12668 (const_string "ssemul")
12669 (match_operand:MODEF 3 "div_operator" "")
12670 (const_string "ssediv")
12672 (const_string "sseadd")))
12673 (set_attr "mode" "<MODE>")])
12675 ;; This pattern is not fully shadowed by the pattern above.
12676 (define_insn "*fop_<mode>_1_i387"
12677 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12678 (match_operator:MODEF 3 "binary_fp_operator"
12679 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12680 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12681 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12682 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12683 && !COMMUTATIVE_ARITH_P (operands[3])
12684 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12685 "* return output_387_binary_op (insn, operands);"
12686 [(set (attr "type")
12687 (cond [(match_operand:MODEF 3 "mult_operator" "")
12688 (const_string "fmul")
12689 (match_operand:MODEF 3 "div_operator" "")
12690 (const_string "fdiv")
12692 (const_string "fop")))
12693 (set_attr "mode" "<MODE>")])
12695 ;; ??? Add SSE splitters for these!
12696 (define_insn "*fop_<MODEF:mode>_2_i387"
12697 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12698 (match_operator:MODEF 3 "binary_fp_operator"
12700 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12701 (match_operand:MODEF 2 "register_operand" "0,0")]))]
12702 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12703 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12704 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12705 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12706 [(set (attr "type")
12707 (cond [(match_operand:MODEF 3 "mult_operator" "")
12708 (const_string "fmul")
12709 (match_operand:MODEF 3 "div_operator" "")
12710 (const_string "fdiv")
12712 (const_string "fop")))
12713 (set_attr "fp_int_src" "true")
12714 (set_attr "mode" "<X87MODEI12:MODE>")])
12716 (define_insn "*fop_<MODEF:mode>_3_i387"
12717 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12718 (match_operator:MODEF 3 "binary_fp_operator"
12719 [(match_operand:MODEF 1 "register_operand" "0,0")
12721 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12722 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
12723 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12724 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12725 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12726 [(set (attr "type")
12727 (cond [(match_operand:MODEF 3 "mult_operator" "")
12728 (const_string "fmul")
12729 (match_operand:MODEF 3 "div_operator" "")
12730 (const_string "fdiv")
12732 (const_string "fop")))
12733 (set_attr "fp_int_src" "true")
12734 (set_attr "mode" "<MODE>")])
12736 (define_insn "*fop_df_4_i387"
12737 [(set (match_operand:DF 0 "register_operand" "=f,f")
12738 (match_operator:DF 3 "binary_fp_operator"
12740 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12741 (match_operand:DF 2 "register_operand" "0,f")]))]
12742 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12743 && !(TARGET_SSE2 && TARGET_SSE_MATH)
12744 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12745 "* return output_387_binary_op (insn, operands);"
12746 [(set (attr "type")
12747 (cond [(match_operand:DF 3 "mult_operator" "")
12748 (const_string "fmul")
12749 (match_operand:DF 3 "div_operator" "")
12750 (const_string "fdiv")
12752 (const_string "fop")))
12753 (set_attr "mode" "SF")])
12755 (define_insn "*fop_df_5_i387"
12756 [(set (match_operand:DF 0 "register_operand" "=f,f")
12757 (match_operator:DF 3 "binary_fp_operator"
12758 [(match_operand:DF 1 "register_operand" "0,f")
12760 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12761 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12762 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12763 "* return output_387_binary_op (insn, operands);"
12764 [(set (attr "type")
12765 (cond [(match_operand:DF 3 "mult_operator" "")
12766 (const_string "fmul")
12767 (match_operand:DF 3 "div_operator" "")
12768 (const_string "fdiv")
12770 (const_string "fop")))
12771 (set_attr "mode" "SF")])
12773 (define_insn "*fop_df_6_i387"
12774 [(set (match_operand:DF 0 "register_operand" "=f,f")
12775 (match_operator:DF 3 "binary_fp_operator"
12777 (match_operand:SF 1 "register_operand" "0,f"))
12779 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12780 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12781 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12782 "* return output_387_binary_op (insn, operands);"
12783 [(set (attr "type")
12784 (cond [(match_operand:DF 3 "mult_operator" "")
12785 (const_string "fmul")
12786 (match_operand:DF 3 "div_operator" "")
12787 (const_string "fdiv")
12789 (const_string "fop")))
12790 (set_attr "mode" "SF")])
12792 (define_insn "*fop_xf_comm_i387"
12793 [(set (match_operand:XF 0 "register_operand" "=f")
12794 (match_operator:XF 3 "binary_fp_operator"
12795 [(match_operand:XF 1 "register_operand" "%0")
12796 (match_operand:XF 2 "register_operand" "f")]))]
12798 && COMMUTATIVE_ARITH_P (operands[3])"
12799 "* return output_387_binary_op (insn, operands);"
12800 [(set (attr "type")
12801 (if_then_else (match_operand:XF 3 "mult_operator" "")
12802 (const_string "fmul")
12803 (const_string "fop")))
12804 (set_attr "mode" "XF")])
12806 (define_insn "*fop_xf_1_i387"
12807 [(set (match_operand:XF 0 "register_operand" "=f,f")
12808 (match_operator:XF 3 "binary_fp_operator"
12809 [(match_operand:XF 1 "register_operand" "0,f")
12810 (match_operand:XF 2 "register_operand" "f,0")]))]
12812 && !COMMUTATIVE_ARITH_P (operands[3])"
12813 "* return output_387_binary_op (insn, operands);"
12814 [(set (attr "type")
12815 (cond [(match_operand:XF 3 "mult_operator" "")
12816 (const_string "fmul")
12817 (match_operand:XF 3 "div_operator" "")
12818 (const_string "fdiv")
12820 (const_string "fop")))
12821 (set_attr "mode" "XF")])
12823 (define_insn "*fop_xf_2_i387"
12824 [(set (match_operand:XF 0 "register_operand" "=f,f")
12825 (match_operator:XF 3 "binary_fp_operator"
12827 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
12828 (match_operand:XF 2 "register_operand" "0,0")]))]
12829 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12830 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12831 [(set (attr "type")
12832 (cond [(match_operand:XF 3 "mult_operator" "")
12833 (const_string "fmul")
12834 (match_operand:XF 3 "div_operator" "")
12835 (const_string "fdiv")
12837 (const_string "fop")))
12838 (set_attr "fp_int_src" "true")
12839 (set_attr "mode" "<MODE>")])
12841 (define_insn "*fop_xf_3_i387"
12842 [(set (match_operand:XF 0 "register_operand" "=f,f")
12843 (match_operator:XF 3 "binary_fp_operator"
12844 [(match_operand:XF 1 "register_operand" "0,0")
12846 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
12847 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12848 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12849 [(set (attr "type")
12850 (cond [(match_operand:XF 3 "mult_operator" "")
12851 (const_string "fmul")
12852 (match_operand:XF 3 "div_operator" "")
12853 (const_string "fdiv")
12855 (const_string "fop")))
12856 (set_attr "fp_int_src" "true")
12857 (set_attr "mode" "<MODE>")])
12859 (define_insn "*fop_xf_4_i387"
12860 [(set (match_operand:XF 0 "register_operand" "=f,f")
12861 (match_operator:XF 3 "binary_fp_operator"
12863 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
12864 (match_operand:XF 2 "register_operand" "0,f")]))]
12866 "* return output_387_binary_op (insn, operands);"
12867 [(set (attr "type")
12868 (cond [(match_operand:XF 3 "mult_operator" "")
12869 (const_string "fmul")
12870 (match_operand:XF 3 "div_operator" "")
12871 (const_string "fdiv")
12873 (const_string "fop")))
12874 (set_attr "mode" "<MODE>")])
12876 (define_insn "*fop_xf_5_i387"
12877 [(set (match_operand:XF 0 "register_operand" "=f,f")
12878 (match_operator:XF 3 "binary_fp_operator"
12879 [(match_operand:XF 1 "register_operand" "0,f")
12881 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12883 "* return output_387_binary_op (insn, operands);"
12884 [(set (attr "type")
12885 (cond [(match_operand:XF 3 "mult_operator" "")
12886 (const_string "fmul")
12887 (match_operand:XF 3 "div_operator" "")
12888 (const_string "fdiv")
12890 (const_string "fop")))
12891 (set_attr "mode" "<MODE>")])
12893 (define_insn "*fop_xf_6_i387"
12894 [(set (match_operand:XF 0 "register_operand" "=f,f")
12895 (match_operator:XF 3 "binary_fp_operator"
12897 (match_operand:MODEF 1 "register_operand" "0,f"))
12899 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12901 "* return output_387_binary_op (insn, operands);"
12902 [(set (attr "type")
12903 (cond [(match_operand:XF 3 "mult_operator" "")
12904 (const_string "fmul")
12905 (match_operand:XF 3 "div_operator" "")
12906 (const_string "fdiv")
12908 (const_string "fop")))
12909 (set_attr "mode" "<MODE>")])
12912 [(set (match_operand 0 "register_operand" "")
12913 (match_operator 3 "binary_fp_operator"
12914 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
12915 (match_operand 2 "register_operand" "")]))]
12917 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12918 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
12921 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
12922 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12923 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12924 gen_rtx_fmt_ee (GET_CODE (operands[3]),
12925 GET_MODE (operands[3]),
12928 ix86_free_from_memory (GET_MODE (operands[1]));
12933 [(set (match_operand 0 "register_operand" "")
12934 (match_operator 3 "binary_fp_operator"
12935 [(match_operand 1 "register_operand" "")
12936 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
12938 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12939 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
12942 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
12943 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12944 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12945 gen_rtx_fmt_ee (GET_CODE (operands[3]),
12946 GET_MODE (operands[3]),
12949 ix86_free_from_memory (GET_MODE (operands[2]));
12953 ;; FPU special functions.
12955 ;; This pattern implements a no-op XFmode truncation for
12956 ;; all fancy i386 XFmode math functions.
12958 (define_insn "truncxf<mode>2_i387_noop_unspec"
12959 [(set (match_operand:MODEF 0 "register_operand" "=f")
12960 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
12961 UNSPEC_TRUNC_NOOP))]
12962 "TARGET_USE_FANCY_MATH_387"
12963 "* return output_387_reg_move (insn, operands);"
12964 [(set_attr "type" "fmov")
12965 (set_attr "mode" "<MODE>")])
12967 (define_insn "sqrtxf2"
12968 [(set (match_operand:XF 0 "register_operand" "=f")
12969 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
12970 "TARGET_USE_FANCY_MATH_387"
12972 [(set_attr "type" "fpspc")
12973 (set_attr "mode" "XF")
12974 (set_attr "athlon_decode" "direct")
12975 (set_attr "amdfam10_decode" "direct")
12976 (set_attr "bdver1_decode" "direct")])
12978 (define_insn "sqrt_extend<mode>xf2_i387"
12979 [(set (match_operand:XF 0 "register_operand" "=f")
12982 (match_operand:MODEF 1 "register_operand" "0"))))]
12983 "TARGET_USE_FANCY_MATH_387"
12985 [(set_attr "type" "fpspc")
12986 (set_attr "mode" "XF")
12987 (set_attr "athlon_decode" "direct")
12988 (set_attr "amdfam10_decode" "direct")
12989 (set_attr "bdver1_decode" "direct")])
12991 (define_insn "*rsqrtsf2_sse"
12992 [(set (match_operand:SF 0 "register_operand" "=x")
12993 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12996 "%vrsqrtss\t{%1, %d0|%d0, %1}"
12997 [(set_attr "type" "sse")
12998 (set_attr "atom_sse_attr" "rcp")
12999 (set_attr "prefix" "maybe_vex")
13000 (set_attr "mode" "SF")])
13002 (define_expand "rsqrtsf2"
13003 [(set (match_operand:SF 0 "register_operand" "")
13004 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13008 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13012 (define_insn "*sqrt<mode>2_sse"
13013 [(set (match_operand:MODEF 0 "register_operand" "=x")
13015 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13016 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13017 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
13018 [(set_attr "type" "sse")
13019 (set_attr "atom_sse_attr" "sqrt")
13020 (set_attr "prefix" "maybe_vex")
13021 (set_attr "mode" "<MODE>")
13022 (set_attr "athlon_decode" "*")
13023 (set_attr "amdfam10_decode" "*")
13024 (set_attr "bdver1_decode" "*")])
13026 (define_expand "sqrt<mode>2"
13027 [(set (match_operand:MODEF 0 "register_operand" "")
13029 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13030 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13031 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13033 if (<MODE>mode == SFmode
13034 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
13035 && flag_finite_math_only && !flag_trapping_math
13036 && flag_unsafe_math_optimizations)
13038 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13042 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13044 rtx op0 = gen_reg_rtx (XFmode);
13045 rtx op1 = force_reg (<MODE>mode, operands[1]);
13047 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13048 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13053 (define_insn "fpremxf4_i387"
13054 [(set (match_operand:XF 0 "register_operand" "=f")
13055 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13056 (match_operand:XF 3 "register_operand" "1")]
13058 (set (match_operand:XF 1 "register_operand" "=u")
13059 (unspec:XF [(match_dup 2) (match_dup 3)]
13061 (set (reg:CCFP FPSR_REG)
13062 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13064 "TARGET_USE_FANCY_MATH_387"
13066 [(set_attr "type" "fpspc")
13067 (set_attr "mode" "XF")])
13069 (define_expand "fmodxf3"
13070 [(use (match_operand:XF 0 "register_operand" ""))
13071 (use (match_operand:XF 1 "general_operand" ""))
13072 (use (match_operand:XF 2 "general_operand" ""))]
13073 "TARGET_USE_FANCY_MATH_387"
13075 rtx label = gen_label_rtx ();
13077 rtx op1 = gen_reg_rtx (XFmode);
13078 rtx op2 = gen_reg_rtx (XFmode);
13080 emit_move_insn (op2, operands[2]);
13081 emit_move_insn (op1, operands[1]);
13083 emit_label (label);
13084 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13085 ix86_emit_fp_unordered_jump (label);
13086 LABEL_NUSES (label) = 1;
13088 emit_move_insn (operands[0], op1);
13092 (define_expand "fmod<mode>3"
13093 [(use (match_operand:MODEF 0 "register_operand" ""))
13094 (use (match_operand:MODEF 1 "general_operand" ""))
13095 (use (match_operand:MODEF 2 "general_operand" ""))]
13096 "TARGET_USE_FANCY_MATH_387"
13098 rtx (*gen_truncxf) (rtx, rtx);
13100 rtx label = gen_label_rtx ();
13102 rtx op1 = gen_reg_rtx (XFmode);
13103 rtx op2 = gen_reg_rtx (XFmode);
13105 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13106 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13108 emit_label (label);
13109 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13110 ix86_emit_fp_unordered_jump (label);
13111 LABEL_NUSES (label) = 1;
13113 /* Truncate the result properly for strict SSE math. */
13114 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13115 && !TARGET_MIX_SSE_I387)
13116 gen_truncxf = gen_truncxf<mode>2;
13118 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13120 emit_insn (gen_truncxf (operands[0], op1));
13124 (define_insn "fprem1xf4_i387"
13125 [(set (match_operand:XF 0 "register_operand" "=f")
13126 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13127 (match_operand:XF 3 "register_operand" "1")]
13129 (set (match_operand:XF 1 "register_operand" "=u")
13130 (unspec:XF [(match_dup 2) (match_dup 3)]
13132 (set (reg:CCFP FPSR_REG)
13133 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13135 "TARGET_USE_FANCY_MATH_387"
13137 [(set_attr "type" "fpspc")
13138 (set_attr "mode" "XF")])
13140 (define_expand "remainderxf3"
13141 [(use (match_operand:XF 0 "register_operand" ""))
13142 (use (match_operand:XF 1 "general_operand" ""))
13143 (use (match_operand:XF 2 "general_operand" ""))]
13144 "TARGET_USE_FANCY_MATH_387"
13146 rtx label = gen_label_rtx ();
13148 rtx op1 = gen_reg_rtx (XFmode);
13149 rtx op2 = gen_reg_rtx (XFmode);
13151 emit_move_insn (op2, operands[2]);
13152 emit_move_insn (op1, operands[1]);
13154 emit_label (label);
13155 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13156 ix86_emit_fp_unordered_jump (label);
13157 LABEL_NUSES (label) = 1;
13159 emit_move_insn (operands[0], op1);
13163 (define_expand "remainder<mode>3"
13164 [(use (match_operand:MODEF 0 "register_operand" ""))
13165 (use (match_operand:MODEF 1 "general_operand" ""))
13166 (use (match_operand:MODEF 2 "general_operand" ""))]
13167 "TARGET_USE_FANCY_MATH_387"
13169 rtx (*gen_truncxf) (rtx, rtx);
13171 rtx label = gen_label_rtx ();
13173 rtx op1 = gen_reg_rtx (XFmode);
13174 rtx op2 = gen_reg_rtx (XFmode);
13176 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13177 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13179 emit_label (label);
13181 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13182 ix86_emit_fp_unordered_jump (label);
13183 LABEL_NUSES (label) = 1;
13185 /* Truncate the result properly for strict SSE math. */
13186 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13187 && !TARGET_MIX_SSE_I387)
13188 gen_truncxf = gen_truncxf<mode>2;
13190 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13192 emit_insn (gen_truncxf (operands[0], op1));
13196 (define_insn "*sinxf2_i387"
13197 [(set (match_operand:XF 0 "register_operand" "=f")
13198 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13199 "TARGET_USE_FANCY_MATH_387
13200 && flag_unsafe_math_optimizations"
13202 [(set_attr "type" "fpspc")
13203 (set_attr "mode" "XF")])
13205 (define_insn "*sin_extend<mode>xf2_i387"
13206 [(set (match_operand:XF 0 "register_operand" "=f")
13207 (unspec:XF [(float_extend:XF
13208 (match_operand:MODEF 1 "register_operand" "0"))]
13210 "TARGET_USE_FANCY_MATH_387
13211 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13212 || TARGET_MIX_SSE_I387)
13213 && flag_unsafe_math_optimizations"
13215 [(set_attr "type" "fpspc")
13216 (set_attr "mode" "XF")])
13218 (define_insn "*cosxf2_i387"
13219 [(set (match_operand:XF 0 "register_operand" "=f")
13220 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13221 "TARGET_USE_FANCY_MATH_387
13222 && flag_unsafe_math_optimizations"
13224 [(set_attr "type" "fpspc")
13225 (set_attr "mode" "XF")])
13227 (define_insn "*cos_extend<mode>xf2_i387"
13228 [(set (match_operand:XF 0 "register_operand" "=f")
13229 (unspec:XF [(float_extend:XF
13230 (match_operand:MODEF 1 "register_operand" "0"))]
13232 "TARGET_USE_FANCY_MATH_387
13233 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13234 || TARGET_MIX_SSE_I387)
13235 && flag_unsafe_math_optimizations"
13237 [(set_attr "type" "fpspc")
13238 (set_attr "mode" "XF")])
13240 ;; When sincos pattern is defined, sin and cos builtin functions will be
13241 ;; expanded to sincos pattern with one of its outputs left unused.
13242 ;; CSE pass will figure out if two sincos patterns can be combined,
13243 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13244 ;; depending on the unused output.
13246 (define_insn "sincosxf3"
13247 [(set (match_operand:XF 0 "register_operand" "=f")
13248 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13249 UNSPEC_SINCOS_COS))
13250 (set (match_operand:XF 1 "register_operand" "=u")
13251 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13252 "TARGET_USE_FANCY_MATH_387
13253 && flag_unsafe_math_optimizations"
13255 [(set_attr "type" "fpspc")
13256 (set_attr "mode" "XF")])
13259 [(set (match_operand:XF 0 "register_operand" "")
13260 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13261 UNSPEC_SINCOS_COS))
13262 (set (match_operand:XF 1 "register_operand" "")
13263 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13264 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13265 && !(reload_completed || reload_in_progress)"
13266 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13269 [(set (match_operand:XF 0 "register_operand" "")
13270 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13271 UNSPEC_SINCOS_COS))
13272 (set (match_operand:XF 1 "register_operand" "")
13273 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13274 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13275 && !(reload_completed || reload_in_progress)"
13276 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13278 (define_insn "sincos_extend<mode>xf3_i387"
13279 [(set (match_operand:XF 0 "register_operand" "=f")
13280 (unspec:XF [(float_extend:XF
13281 (match_operand:MODEF 2 "register_operand" "0"))]
13282 UNSPEC_SINCOS_COS))
13283 (set (match_operand:XF 1 "register_operand" "=u")
13284 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13285 "TARGET_USE_FANCY_MATH_387
13286 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13287 || TARGET_MIX_SSE_I387)
13288 && flag_unsafe_math_optimizations"
13290 [(set_attr "type" "fpspc")
13291 (set_attr "mode" "XF")])
13294 [(set (match_operand:XF 0 "register_operand" "")
13295 (unspec:XF [(float_extend:XF
13296 (match_operand:MODEF 2 "register_operand" ""))]
13297 UNSPEC_SINCOS_COS))
13298 (set (match_operand:XF 1 "register_operand" "")
13299 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13300 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13301 && !(reload_completed || reload_in_progress)"
13302 [(set (match_dup 1)
13303 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13306 [(set (match_operand:XF 0 "register_operand" "")
13307 (unspec:XF [(float_extend:XF
13308 (match_operand:MODEF 2 "register_operand" ""))]
13309 UNSPEC_SINCOS_COS))
13310 (set (match_operand:XF 1 "register_operand" "")
13311 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13312 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13313 && !(reload_completed || reload_in_progress)"
13314 [(set (match_dup 0)
13315 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13317 (define_expand "sincos<mode>3"
13318 [(use (match_operand:MODEF 0 "register_operand" ""))
13319 (use (match_operand:MODEF 1 "register_operand" ""))
13320 (use (match_operand:MODEF 2 "register_operand" ""))]
13321 "TARGET_USE_FANCY_MATH_387
13322 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13323 || TARGET_MIX_SSE_I387)
13324 && flag_unsafe_math_optimizations"
13326 rtx op0 = gen_reg_rtx (XFmode);
13327 rtx op1 = gen_reg_rtx (XFmode);
13329 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13330 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13331 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13335 (define_insn "fptanxf4_i387"
13336 [(set (match_operand:XF 0 "register_operand" "=f")
13337 (match_operand:XF 3 "const_double_operand" "F"))
13338 (set (match_operand:XF 1 "register_operand" "=u")
13339 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13341 "TARGET_USE_FANCY_MATH_387
13342 && flag_unsafe_math_optimizations
13343 && standard_80387_constant_p (operands[3]) == 2"
13345 [(set_attr "type" "fpspc")
13346 (set_attr "mode" "XF")])
13348 (define_insn "fptan_extend<mode>xf4_i387"
13349 [(set (match_operand:MODEF 0 "register_operand" "=f")
13350 (match_operand:MODEF 3 "const_double_operand" "F"))
13351 (set (match_operand:XF 1 "register_operand" "=u")
13352 (unspec:XF [(float_extend:XF
13353 (match_operand:MODEF 2 "register_operand" "0"))]
13355 "TARGET_USE_FANCY_MATH_387
13356 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13357 || TARGET_MIX_SSE_I387)
13358 && flag_unsafe_math_optimizations
13359 && standard_80387_constant_p (operands[3]) == 2"
13361 [(set_attr "type" "fpspc")
13362 (set_attr "mode" "XF")])
13364 (define_expand "tanxf2"
13365 [(use (match_operand:XF 0 "register_operand" ""))
13366 (use (match_operand:XF 1 "register_operand" ""))]
13367 "TARGET_USE_FANCY_MATH_387
13368 && flag_unsafe_math_optimizations"
13370 rtx one = gen_reg_rtx (XFmode);
13371 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13373 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13377 (define_expand "tan<mode>2"
13378 [(use (match_operand:MODEF 0 "register_operand" ""))
13379 (use (match_operand:MODEF 1 "register_operand" ""))]
13380 "TARGET_USE_FANCY_MATH_387
13381 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13382 || TARGET_MIX_SSE_I387)
13383 && flag_unsafe_math_optimizations"
13385 rtx op0 = gen_reg_rtx (XFmode);
13387 rtx one = gen_reg_rtx (<MODE>mode);
13388 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13390 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13391 operands[1], op2));
13392 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13396 (define_insn "*fpatanxf3_i387"
13397 [(set (match_operand:XF 0 "register_operand" "=f")
13398 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13399 (match_operand:XF 2 "register_operand" "u")]
13401 (clobber (match_scratch:XF 3 "=2"))]
13402 "TARGET_USE_FANCY_MATH_387
13403 && flag_unsafe_math_optimizations"
13405 [(set_attr "type" "fpspc")
13406 (set_attr "mode" "XF")])
13408 (define_insn "fpatan_extend<mode>xf3_i387"
13409 [(set (match_operand:XF 0 "register_operand" "=f")
13410 (unspec:XF [(float_extend:XF
13411 (match_operand:MODEF 1 "register_operand" "0"))
13413 (match_operand:MODEF 2 "register_operand" "u"))]
13415 (clobber (match_scratch:XF 3 "=2"))]
13416 "TARGET_USE_FANCY_MATH_387
13417 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13418 || TARGET_MIX_SSE_I387)
13419 && flag_unsafe_math_optimizations"
13421 [(set_attr "type" "fpspc")
13422 (set_attr "mode" "XF")])
13424 (define_expand "atan2xf3"
13425 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13426 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13427 (match_operand:XF 1 "register_operand" "")]
13429 (clobber (match_scratch:XF 3 ""))])]
13430 "TARGET_USE_FANCY_MATH_387
13431 && flag_unsafe_math_optimizations")
13433 (define_expand "atan2<mode>3"
13434 [(use (match_operand:MODEF 0 "register_operand" ""))
13435 (use (match_operand:MODEF 1 "register_operand" ""))
13436 (use (match_operand:MODEF 2 "register_operand" ""))]
13437 "TARGET_USE_FANCY_MATH_387
13438 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13439 || TARGET_MIX_SSE_I387)
13440 && flag_unsafe_math_optimizations"
13442 rtx op0 = gen_reg_rtx (XFmode);
13444 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13445 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13449 (define_expand "atanxf2"
13450 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13451 (unspec:XF [(match_dup 2)
13452 (match_operand:XF 1 "register_operand" "")]
13454 (clobber (match_scratch:XF 3 ""))])]
13455 "TARGET_USE_FANCY_MATH_387
13456 && flag_unsafe_math_optimizations"
13458 operands[2] = gen_reg_rtx (XFmode);
13459 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13462 (define_expand "atan<mode>2"
13463 [(use (match_operand:MODEF 0 "register_operand" ""))
13464 (use (match_operand:MODEF 1 "register_operand" ""))]
13465 "TARGET_USE_FANCY_MATH_387
13466 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13467 || TARGET_MIX_SSE_I387)
13468 && flag_unsafe_math_optimizations"
13470 rtx op0 = gen_reg_rtx (XFmode);
13472 rtx op2 = gen_reg_rtx (<MODE>mode);
13473 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13475 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13476 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13480 (define_expand "asinxf2"
13481 [(set (match_dup 2)
13482 (mult:XF (match_operand:XF 1 "register_operand" "")
13484 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13485 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13486 (parallel [(set (match_operand:XF 0 "register_operand" "")
13487 (unspec:XF [(match_dup 5) (match_dup 1)]
13489 (clobber (match_scratch:XF 6 ""))])]
13490 "TARGET_USE_FANCY_MATH_387
13491 && flag_unsafe_math_optimizations"
13495 if (optimize_insn_for_size_p ())
13498 for (i = 2; i < 6; i++)
13499 operands[i] = gen_reg_rtx (XFmode);
13501 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13504 (define_expand "asin<mode>2"
13505 [(use (match_operand:MODEF 0 "register_operand" ""))
13506 (use (match_operand:MODEF 1 "general_operand" ""))]
13507 "TARGET_USE_FANCY_MATH_387
13508 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13509 || TARGET_MIX_SSE_I387)
13510 && flag_unsafe_math_optimizations"
13512 rtx op0 = gen_reg_rtx (XFmode);
13513 rtx op1 = gen_reg_rtx (XFmode);
13515 if (optimize_insn_for_size_p ())
13518 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13519 emit_insn (gen_asinxf2 (op0, op1));
13520 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13524 (define_expand "acosxf2"
13525 [(set (match_dup 2)
13526 (mult:XF (match_operand:XF 1 "register_operand" "")
13528 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13529 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13530 (parallel [(set (match_operand:XF 0 "register_operand" "")
13531 (unspec:XF [(match_dup 1) (match_dup 5)]
13533 (clobber (match_scratch:XF 6 ""))])]
13534 "TARGET_USE_FANCY_MATH_387
13535 && flag_unsafe_math_optimizations"
13539 if (optimize_insn_for_size_p ())
13542 for (i = 2; i < 6; i++)
13543 operands[i] = gen_reg_rtx (XFmode);
13545 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13548 (define_expand "acos<mode>2"
13549 [(use (match_operand:MODEF 0 "register_operand" ""))
13550 (use (match_operand:MODEF 1 "general_operand" ""))]
13551 "TARGET_USE_FANCY_MATH_387
13552 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13553 || TARGET_MIX_SSE_I387)
13554 && flag_unsafe_math_optimizations"
13556 rtx op0 = gen_reg_rtx (XFmode);
13557 rtx op1 = gen_reg_rtx (XFmode);
13559 if (optimize_insn_for_size_p ())
13562 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13563 emit_insn (gen_acosxf2 (op0, op1));
13564 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13568 (define_insn "fyl2xxf3_i387"
13569 [(set (match_operand:XF 0 "register_operand" "=f")
13570 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13571 (match_operand:XF 2 "register_operand" "u")]
13573 (clobber (match_scratch:XF 3 "=2"))]
13574 "TARGET_USE_FANCY_MATH_387
13575 && flag_unsafe_math_optimizations"
13577 [(set_attr "type" "fpspc")
13578 (set_attr "mode" "XF")])
13580 (define_insn "fyl2x_extend<mode>xf3_i387"
13581 [(set (match_operand:XF 0 "register_operand" "=f")
13582 (unspec:XF [(float_extend:XF
13583 (match_operand:MODEF 1 "register_operand" "0"))
13584 (match_operand:XF 2 "register_operand" "u")]
13586 (clobber (match_scratch:XF 3 "=2"))]
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"
13592 [(set_attr "type" "fpspc")
13593 (set_attr "mode" "XF")])
13595 (define_expand "logxf2"
13596 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13597 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13598 (match_dup 2)] UNSPEC_FYL2X))
13599 (clobber (match_scratch:XF 3 ""))])]
13600 "TARGET_USE_FANCY_MATH_387
13601 && flag_unsafe_math_optimizations"
13603 operands[2] = gen_reg_rtx (XFmode);
13604 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13607 (define_expand "log<mode>2"
13608 [(use (match_operand:MODEF 0 "register_operand" ""))
13609 (use (match_operand:MODEF 1 "register_operand" ""))]
13610 "TARGET_USE_FANCY_MATH_387
13611 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13612 || TARGET_MIX_SSE_I387)
13613 && flag_unsafe_math_optimizations"
13615 rtx op0 = gen_reg_rtx (XFmode);
13617 rtx op2 = gen_reg_rtx (XFmode);
13618 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13620 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13621 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13625 (define_expand "log10xf2"
13626 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13627 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13628 (match_dup 2)] UNSPEC_FYL2X))
13629 (clobber (match_scratch:XF 3 ""))])]
13630 "TARGET_USE_FANCY_MATH_387
13631 && flag_unsafe_math_optimizations"
13633 operands[2] = gen_reg_rtx (XFmode);
13634 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13637 (define_expand "log10<mode>2"
13638 [(use (match_operand:MODEF 0 "register_operand" ""))
13639 (use (match_operand:MODEF 1 "register_operand" ""))]
13640 "TARGET_USE_FANCY_MATH_387
13641 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13642 || TARGET_MIX_SSE_I387)
13643 && flag_unsafe_math_optimizations"
13645 rtx op0 = gen_reg_rtx (XFmode);
13647 rtx op2 = gen_reg_rtx (XFmode);
13648 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13650 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13651 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13655 (define_expand "log2xf2"
13656 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13657 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13658 (match_dup 2)] UNSPEC_FYL2X))
13659 (clobber (match_scratch:XF 3 ""))])]
13660 "TARGET_USE_FANCY_MATH_387
13661 && flag_unsafe_math_optimizations"
13663 operands[2] = gen_reg_rtx (XFmode);
13664 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13667 (define_expand "log2<mode>2"
13668 [(use (match_operand:MODEF 0 "register_operand" ""))
13669 (use (match_operand:MODEF 1 "register_operand" ""))]
13670 "TARGET_USE_FANCY_MATH_387
13671 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13672 || TARGET_MIX_SSE_I387)
13673 && flag_unsafe_math_optimizations"
13675 rtx op0 = gen_reg_rtx (XFmode);
13677 rtx op2 = gen_reg_rtx (XFmode);
13678 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13680 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13681 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13685 (define_insn "fyl2xp1xf3_i387"
13686 [(set (match_operand:XF 0 "register_operand" "=f")
13687 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13688 (match_operand:XF 2 "register_operand" "u")]
13690 (clobber (match_scratch:XF 3 "=2"))]
13691 "TARGET_USE_FANCY_MATH_387
13692 && flag_unsafe_math_optimizations"
13694 [(set_attr "type" "fpspc")
13695 (set_attr "mode" "XF")])
13697 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13698 [(set (match_operand:XF 0 "register_operand" "=f")
13699 (unspec:XF [(float_extend:XF
13700 (match_operand:MODEF 1 "register_operand" "0"))
13701 (match_operand:XF 2 "register_operand" "u")]
13703 (clobber (match_scratch:XF 3 "=2"))]
13704 "TARGET_USE_FANCY_MATH_387
13705 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13706 || TARGET_MIX_SSE_I387)
13707 && flag_unsafe_math_optimizations"
13709 [(set_attr "type" "fpspc")
13710 (set_attr "mode" "XF")])
13712 (define_expand "log1pxf2"
13713 [(use (match_operand:XF 0 "register_operand" ""))
13714 (use (match_operand:XF 1 "register_operand" ""))]
13715 "TARGET_USE_FANCY_MATH_387
13716 && flag_unsafe_math_optimizations"
13718 if (optimize_insn_for_size_p ())
13721 ix86_emit_i387_log1p (operands[0], operands[1]);
13725 (define_expand "log1p<mode>2"
13726 [(use (match_operand:MODEF 0 "register_operand" ""))
13727 (use (match_operand:MODEF 1 "register_operand" ""))]
13728 "TARGET_USE_FANCY_MATH_387
13729 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13730 || TARGET_MIX_SSE_I387)
13731 && flag_unsafe_math_optimizations"
13735 if (optimize_insn_for_size_p ())
13738 op0 = gen_reg_rtx (XFmode);
13740 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13742 ix86_emit_i387_log1p (op0, operands[1]);
13743 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13747 (define_insn "fxtractxf3_i387"
13748 [(set (match_operand:XF 0 "register_operand" "=f")
13749 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13750 UNSPEC_XTRACT_FRACT))
13751 (set (match_operand:XF 1 "register_operand" "=u")
13752 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13753 "TARGET_USE_FANCY_MATH_387
13754 && flag_unsafe_math_optimizations"
13756 [(set_attr "type" "fpspc")
13757 (set_attr "mode" "XF")])
13759 (define_insn "fxtract_extend<mode>xf3_i387"
13760 [(set (match_operand:XF 0 "register_operand" "=f")
13761 (unspec:XF [(float_extend:XF
13762 (match_operand:MODEF 2 "register_operand" "0"))]
13763 UNSPEC_XTRACT_FRACT))
13764 (set (match_operand:XF 1 "register_operand" "=u")
13765 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13766 "TARGET_USE_FANCY_MATH_387
13767 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13768 || TARGET_MIX_SSE_I387)
13769 && flag_unsafe_math_optimizations"
13771 [(set_attr "type" "fpspc")
13772 (set_attr "mode" "XF")])
13774 (define_expand "logbxf2"
13775 [(parallel [(set (match_dup 2)
13776 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
13777 UNSPEC_XTRACT_FRACT))
13778 (set (match_operand:XF 0 "register_operand" "")
13779 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13780 "TARGET_USE_FANCY_MATH_387
13781 && flag_unsafe_math_optimizations"
13782 "operands[2] = gen_reg_rtx (XFmode);")
13784 (define_expand "logb<mode>2"
13785 [(use (match_operand:MODEF 0 "register_operand" ""))
13786 (use (match_operand:MODEF 1 "register_operand" ""))]
13787 "TARGET_USE_FANCY_MATH_387
13788 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13789 || TARGET_MIX_SSE_I387)
13790 && flag_unsafe_math_optimizations"
13792 rtx op0 = gen_reg_rtx (XFmode);
13793 rtx op1 = gen_reg_rtx (XFmode);
13795 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13796 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13800 (define_expand "ilogbxf2"
13801 [(use (match_operand:SI 0 "register_operand" ""))
13802 (use (match_operand:XF 1 "register_operand" ""))]
13803 "TARGET_USE_FANCY_MATH_387
13804 && flag_unsafe_math_optimizations"
13808 if (optimize_insn_for_size_p ())
13811 op0 = gen_reg_rtx (XFmode);
13812 op1 = gen_reg_rtx (XFmode);
13814 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13815 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13819 (define_expand "ilogb<mode>2"
13820 [(use (match_operand:SI 0 "register_operand" ""))
13821 (use (match_operand:MODEF 1 "register_operand" ""))]
13822 "TARGET_USE_FANCY_MATH_387
13823 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13824 || TARGET_MIX_SSE_I387)
13825 && flag_unsafe_math_optimizations"
13829 if (optimize_insn_for_size_p ())
13832 op0 = gen_reg_rtx (XFmode);
13833 op1 = gen_reg_rtx (XFmode);
13835 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13836 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13840 (define_insn "*f2xm1xf2_i387"
13841 [(set (match_operand:XF 0 "register_operand" "=f")
13842 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13844 "TARGET_USE_FANCY_MATH_387
13845 && flag_unsafe_math_optimizations"
13847 [(set_attr "type" "fpspc")
13848 (set_attr "mode" "XF")])
13850 (define_insn "*fscalexf4_i387"
13851 [(set (match_operand:XF 0 "register_operand" "=f")
13852 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13853 (match_operand:XF 3 "register_operand" "1")]
13854 UNSPEC_FSCALE_FRACT))
13855 (set (match_operand:XF 1 "register_operand" "=u")
13856 (unspec:XF [(match_dup 2) (match_dup 3)]
13857 UNSPEC_FSCALE_EXP))]
13858 "TARGET_USE_FANCY_MATH_387
13859 && flag_unsafe_math_optimizations"
13861 [(set_attr "type" "fpspc")
13862 (set_attr "mode" "XF")])
13864 (define_expand "expNcorexf3"
13865 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
13866 (match_operand:XF 2 "register_operand" "")))
13867 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13868 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13869 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13870 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
13871 (parallel [(set (match_operand:XF 0 "register_operand" "")
13872 (unspec:XF [(match_dup 8) (match_dup 4)]
13873 UNSPEC_FSCALE_FRACT))
13875 (unspec:XF [(match_dup 8) (match_dup 4)]
13876 UNSPEC_FSCALE_EXP))])]
13877 "TARGET_USE_FANCY_MATH_387
13878 && flag_unsafe_math_optimizations"
13882 if (optimize_insn_for_size_p ())
13885 for (i = 3; i < 10; i++)
13886 operands[i] = gen_reg_rtx (XFmode);
13888 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
13891 (define_expand "expxf2"
13892 [(use (match_operand:XF 0 "register_operand" ""))
13893 (use (match_operand:XF 1 "register_operand" ""))]
13894 "TARGET_USE_FANCY_MATH_387
13895 && flag_unsafe_math_optimizations"
13899 if (optimize_insn_for_size_p ())
13902 op2 = gen_reg_rtx (XFmode);
13903 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
13905 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13909 (define_expand "exp<mode>2"
13910 [(use (match_operand:MODEF 0 "register_operand" ""))
13911 (use (match_operand:MODEF 1 "general_operand" ""))]
13912 "TARGET_USE_FANCY_MATH_387
13913 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13914 || TARGET_MIX_SSE_I387)
13915 && flag_unsafe_math_optimizations"
13919 if (optimize_insn_for_size_p ())
13922 op0 = gen_reg_rtx (XFmode);
13923 op1 = gen_reg_rtx (XFmode);
13925 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13926 emit_insn (gen_expxf2 (op0, op1));
13927 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13931 (define_expand "exp10xf2"
13932 [(use (match_operand:XF 0 "register_operand" ""))
13933 (use (match_operand:XF 1 "register_operand" ""))]
13934 "TARGET_USE_FANCY_MATH_387
13935 && flag_unsafe_math_optimizations"
13939 if (optimize_insn_for_size_p ())
13942 op2 = gen_reg_rtx (XFmode);
13943 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
13945 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13949 (define_expand "exp10<mode>2"
13950 [(use (match_operand:MODEF 0 "register_operand" ""))
13951 (use (match_operand:MODEF 1 "general_operand" ""))]
13952 "TARGET_USE_FANCY_MATH_387
13953 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13954 || TARGET_MIX_SSE_I387)
13955 && flag_unsafe_math_optimizations"
13959 if (optimize_insn_for_size_p ())
13962 op0 = gen_reg_rtx (XFmode);
13963 op1 = gen_reg_rtx (XFmode);
13965 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13966 emit_insn (gen_exp10xf2 (op0, op1));
13967 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13971 (define_expand "exp2xf2"
13972 [(use (match_operand:XF 0 "register_operand" ""))
13973 (use (match_operand:XF 1 "register_operand" ""))]
13974 "TARGET_USE_FANCY_MATH_387
13975 && flag_unsafe_math_optimizations"
13979 if (optimize_insn_for_size_p ())
13982 op2 = gen_reg_rtx (XFmode);
13983 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13985 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13989 (define_expand "exp2<mode>2"
13990 [(use (match_operand:MODEF 0 "register_operand" ""))
13991 (use (match_operand:MODEF 1 "general_operand" ""))]
13992 "TARGET_USE_FANCY_MATH_387
13993 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13994 || TARGET_MIX_SSE_I387)
13995 && flag_unsafe_math_optimizations"
13999 if (optimize_insn_for_size_p ())
14002 op0 = gen_reg_rtx (XFmode);
14003 op1 = gen_reg_rtx (XFmode);
14005 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14006 emit_insn (gen_exp2xf2 (op0, op1));
14007 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14011 (define_expand "expm1xf2"
14012 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14014 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14015 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14016 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14017 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14018 (parallel [(set (match_dup 7)
14019 (unspec:XF [(match_dup 6) (match_dup 4)]
14020 UNSPEC_FSCALE_FRACT))
14022 (unspec:XF [(match_dup 6) (match_dup 4)]
14023 UNSPEC_FSCALE_EXP))])
14024 (parallel [(set (match_dup 10)
14025 (unspec:XF [(match_dup 9) (match_dup 8)]
14026 UNSPEC_FSCALE_FRACT))
14027 (set (match_dup 11)
14028 (unspec:XF [(match_dup 9) (match_dup 8)]
14029 UNSPEC_FSCALE_EXP))])
14030 (set (match_dup 12) (minus:XF (match_dup 10)
14031 (float_extend:XF (match_dup 13))))
14032 (set (match_operand:XF 0 "register_operand" "")
14033 (plus:XF (match_dup 12) (match_dup 7)))]
14034 "TARGET_USE_FANCY_MATH_387
14035 && flag_unsafe_math_optimizations"
14039 if (optimize_insn_for_size_p ())
14042 for (i = 2; i < 13; i++)
14043 operands[i] = gen_reg_rtx (XFmode);
14046 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14048 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14051 (define_expand "expm1<mode>2"
14052 [(use (match_operand:MODEF 0 "register_operand" ""))
14053 (use (match_operand:MODEF 1 "general_operand" ""))]
14054 "TARGET_USE_FANCY_MATH_387
14055 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14056 || TARGET_MIX_SSE_I387)
14057 && flag_unsafe_math_optimizations"
14061 if (optimize_insn_for_size_p ())
14064 op0 = gen_reg_rtx (XFmode);
14065 op1 = gen_reg_rtx (XFmode);
14067 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14068 emit_insn (gen_expm1xf2 (op0, op1));
14069 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14073 (define_expand "ldexpxf3"
14074 [(set (match_dup 3)
14075 (float:XF (match_operand:SI 2 "register_operand" "")))
14076 (parallel [(set (match_operand:XF 0 " register_operand" "")
14077 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14079 UNSPEC_FSCALE_FRACT))
14081 (unspec:XF [(match_dup 1) (match_dup 3)]
14082 UNSPEC_FSCALE_EXP))])]
14083 "TARGET_USE_FANCY_MATH_387
14084 && flag_unsafe_math_optimizations"
14086 if (optimize_insn_for_size_p ())
14089 operands[3] = gen_reg_rtx (XFmode);
14090 operands[4] = gen_reg_rtx (XFmode);
14093 (define_expand "ldexp<mode>3"
14094 [(use (match_operand:MODEF 0 "register_operand" ""))
14095 (use (match_operand:MODEF 1 "general_operand" ""))
14096 (use (match_operand:SI 2 "register_operand" ""))]
14097 "TARGET_USE_FANCY_MATH_387
14098 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14099 || TARGET_MIX_SSE_I387)
14100 && flag_unsafe_math_optimizations"
14104 if (optimize_insn_for_size_p ())
14107 op0 = gen_reg_rtx (XFmode);
14108 op1 = gen_reg_rtx (XFmode);
14110 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14111 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14112 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14116 (define_expand "scalbxf3"
14117 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14118 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14119 (match_operand:XF 2 "register_operand" "")]
14120 UNSPEC_FSCALE_FRACT))
14122 (unspec:XF [(match_dup 1) (match_dup 2)]
14123 UNSPEC_FSCALE_EXP))])]
14124 "TARGET_USE_FANCY_MATH_387
14125 && flag_unsafe_math_optimizations"
14127 if (optimize_insn_for_size_p ())
14130 operands[3] = gen_reg_rtx (XFmode);
14133 (define_expand "scalb<mode>3"
14134 [(use (match_operand:MODEF 0 "register_operand" ""))
14135 (use (match_operand:MODEF 1 "general_operand" ""))
14136 (use (match_operand:MODEF 2 "general_operand" ""))]
14137 "TARGET_USE_FANCY_MATH_387
14138 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14139 || TARGET_MIX_SSE_I387)
14140 && flag_unsafe_math_optimizations"
14144 if (optimize_insn_for_size_p ())
14147 op0 = gen_reg_rtx (XFmode);
14148 op1 = gen_reg_rtx (XFmode);
14149 op2 = gen_reg_rtx (XFmode);
14151 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14152 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14153 emit_insn (gen_scalbxf3 (op0, op1, op2));
14154 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14158 (define_expand "significandxf2"
14159 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14160 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14161 UNSPEC_XTRACT_FRACT))
14163 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14164 "TARGET_USE_FANCY_MATH_387
14165 && flag_unsafe_math_optimizations"
14166 "operands[2] = gen_reg_rtx (XFmode);")
14168 (define_expand "significand<mode>2"
14169 [(use (match_operand:MODEF 0 "register_operand" ""))
14170 (use (match_operand:MODEF 1 "register_operand" ""))]
14171 "TARGET_USE_FANCY_MATH_387
14172 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14173 || TARGET_MIX_SSE_I387)
14174 && flag_unsafe_math_optimizations"
14176 rtx op0 = gen_reg_rtx (XFmode);
14177 rtx op1 = gen_reg_rtx (XFmode);
14179 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14180 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14185 (define_insn "sse4_1_round<mode>2"
14186 [(set (match_operand:MODEF 0 "register_operand" "=x")
14187 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14188 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14191 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14192 [(set_attr "type" "ssecvt")
14193 (set_attr "prefix_extra" "1")
14194 (set_attr "prefix" "maybe_vex")
14195 (set_attr "mode" "<MODE>")])
14197 (define_insn "rintxf2"
14198 [(set (match_operand:XF 0 "register_operand" "=f")
14199 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14201 "TARGET_USE_FANCY_MATH_387
14202 && flag_unsafe_math_optimizations"
14204 [(set_attr "type" "fpspc")
14205 (set_attr "mode" "XF")])
14207 (define_expand "rint<mode>2"
14208 [(use (match_operand:MODEF 0 "register_operand" ""))
14209 (use (match_operand:MODEF 1 "register_operand" ""))]
14210 "(TARGET_USE_FANCY_MATH_387
14211 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14212 || TARGET_MIX_SSE_I387)
14213 && flag_unsafe_math_optimizations)
14214 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14215 && !flag_trapping_math)"
14217 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14218 && !flag_trapping_math)
14220 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14223 emit_insn (gen_sse4_1_round<mode>2
14224 (operands[0], operands[1], GEN_INT (0x04)));
14226 ix86_expand_rint (operand0, operand1);
14230 rtx op0 = gen_reg_rtx (XFmode);
14231 rtx op1 = gen_reg_rtx (XFmode);
14233 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14234 emit_insn (gen_rintxf2 (op0, op1));
14236 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14241 (define_expand "round<mode>2"
14242 [(match_operand:MODEF 0 "register_operand" "")
14243 (match_operand:MODEF 1 "nonimmediate_operand" "")]
14244 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14245 && !flag_trapping_math && !flag_rounding_math"
14247 if (optimize_insn_for_size_p ())
14249 if (TARGET_64BIT || (<MODE>mode != DFmode))
14250 ix86_expand_round (operand0, operand1);
14252 ix86_expand_rounddf_32 (operand0, operand1);
14256 (define_insn_and_split "*fistdi2_1"
14257 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14258 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14260 "TARGET_USE_FANCY_MATH_387
14261 && can_create_pseudo_p ()"
14266 if (memory_operand (operands[0], VOIDmode))
14267 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14270 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14271 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14276 [(set_attr "type" "fpspc")
14277 (set_attr "mode" "DI")])
14279 (define_insn "fistdi2"
14280 [(set (match_operand:DI 0 "memory_operand" "=m")
14281 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14283 (clobber (match_scratch:XF 2 "=&1f"))]
14284 "TARGET_USE_FANCY_MATH_387"
14285 "* return output_fix_trunc (insn, operands, 0);"
14286 [(set_attr "type" "fpspc")
14287 (set_attr "mode" "DI")])
14289 (define_insn "fistdi2_with_temp"
14290 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14291 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14293 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14294 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14295 "TARGET_USE_FANCY_MATH_387"
14297 [(set_attr "type" "fpspc")
14298 (set_attr "mode" "DI")])
14301 [(set (match_operand:DI 0 "register_operand" "")
14302 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14304 (clobber (match_operand:DI 2 "memory_operand" ""))
14305 (clobber (match_scratch 3 ""))]
14307 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14308 (clobber (match_dup 3))])
14309 (set (match_dup 0) (match_dup 2))])
14312 [(set (match_operand:DI 0 "memory_operand" "")
14313 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14315 (clobber (match_operand:DI 2 "memory_operand" ""))
14316 (clobber (match_scratch 3 ""))]
14318 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14319 (clobber (match_dup 3))])])
14321 (define_insn_and_split "*fist<mode>2_1"
14322 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14323 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14325 "TARGET_USE_FANCY_MATH_387
14326 && can_create_pseudo_p ()"
14331 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14332 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14336 [(set_attr "type" "fpspc")
14337 (set_attr "mode" "<MODE>")])
14339 (define_insn "fist<mode>2"
14340 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14341 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14343 "TARGET_USE_FANCY_MATH_387"
14344 "* return output_fix_trunc (insn, operands, 0);"
14345 [(set_attr "type" "fpspc")
14346 (set_attr "mode" "<MODE>")])
14348 (define_insn "fist<mode>2_with_temp"
14349 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
14350 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14352 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
14353 "TARGET_USE_FANCY_MATH_387"
14355 [(set_attr "type" "fpspc")
14356 (set_attr "mode" "<MODE>")])
14359 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14360 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14362 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14364 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
14365 (set (match_dup 0) (match_dup 2))])
14368 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14369 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14371 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
14373 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))])
14375 (define_expand "lrintxf<mode>2"
14376 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14377 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14379 "TARGET_USE_FANCY_MATH_387")
14381 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
14382 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14383 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
14384 UNSPEC_FIX_NOTRUNC))]
14385 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14386 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)")
14388 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
14389 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
14390 (match_operand:MODEF 1 "register_operand" "")]
14391 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14392 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
14393 && !flag_trapping_math && !flag_rounding_math"
14395 if (optimize_insn_for_size_p ())
14397 ix86_expand_lround (operand0, operand1);
14401 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14402 (define_insn_and_split "frndintxf2_floor"
14403 [(set (match_operand:XF 0 "register_operand" "")
14404 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14405 UNSPEC_FRNDINT_FLOOR))
14406 (clobber (reg:CC FLAGS_REG))]
14407 "TARGET_USE_FANCY_MATH_387
14408 && flag_unsafe_math_optimizations
14409 && can_create_pseudo_p ()"
14414 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14416 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14417 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14419 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14420 operands[2], operands[3]));
14423 [(set_attr "type" "frndint")
14424 (set_attr "i387_cw" "floor")
14425 (set_attr "mode" "XF")])
14427 (define_insn "frndintxf2_floor_i387"
14428 [(set (match_operand:XF 0 "register_operand" "=f")
14429 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14430 UNSPEC_FRNDINT_FLOOR))
14431 (use (match_operand:HI 2 "memory_operand" "m"))
14432 (use (match_operand:HI 3 "memory_operand" "m"))]
14433 "TARGET_USE_FANCY_MATH_387
14434 && flag_unsafe_math_optimizations"
14435 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14436 [(set_attr "type" "frndint")
14437 (set_attr "i387_cw" "floor")
14438 (set_attr "mode" "XF")])
14440 (define_expand "floorxf2"
14441 [(use (match_operand:XF 0 "register_operand" ""))
14442 (use (match_operand:XF 1 "register_operand" ""))]
14443 "TARGET_USE_FANCY_MATH_387
14444 && flag_unsafe_math_optimizations"
14446 if (optimize_insn_for_size_p ())
14448 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14452 (define_expand "floor<mode>2"
14453 [(use (match_operand:MODEF 0 "register_operand" ""))
14454 (use (match_operand:MODEF 1 "register_operand" ""))]
14455 "(TARGET_USE_FANCY_MATH_387
14456 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14457 || TARGET_MIX_SSE_I387)
14458 && flag_unsafe_math_optimizations)
14459 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14460 && !flag_trapping_math)"
14462 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14463 && !flag_trapping_math
14464 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14466 if (!TARGET_ROUND && optimize_insn_for_size_p ())
14469 emit_insn (gen_sse4_1_round<mode>2
14470 (operands[0], operands[1], GEN_INT (0x01)));
14471 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14472 ix86_expand_floorceil (operand0, operand1, true);
14474 ix86_expand_floorceildf_32 (operand0, operand1, true);
14480 if (optimize_insn_for_size_p ())
14483 op0 = gen_reg_rtx (XFmode);
14484 op1 = gen_reg_rtx (XFmode);
14485 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14486 emit_insn (gen_frndintxf2_floor (op0, op1));
14488 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14493 (define_insn_and_split "*fist<mode>2_floor_1"
14494 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14495 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14496 UNSPEC_FIST_FLOOR))
14497 (clobber (reg:CC FLAGS_REG))]
14498 "TARGET_USE_FANCY_MATH_387
14499 && flag_unsafe_math_optimizations
14500 && can_create_pseudo_p ()"
14505 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14507 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14508 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14509 if (memory_operand (operands[0], VOIDmode))
14510 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14511 operands[2], operands[3]));
14514 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14515 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14516 operands[2], operands[3],
14521 [(set_attr "type" "fistp")
14522 (set_attr "i387_cw" "floor")
14523 (set_attr "mode" "<MODE>")])
14525 (define_insn "fistdi2_floor"
14526 [(set (match_operand:DI 0 "memory_operand" "=m")
14527 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14528 UNSPEC_FIST_FLOOR))
14529 (use (match_operand:HI 2 "memory_operand" "m"))
14530 (use (match_operand:HI 3 "memory_operand" "m"))
14531 (clobber (match_scratch:XF 4 "=&1f"))]
14532 "TARGET_USE_FANCY_MATH_387
14533 && flag_unsafe_math_optimizations"
14534 "* return output_fix_trunc (insn, operands, 0);"
14535 [(set_attr "type" "fistp")
14536 (set_attr "i387_cw" "floor")
14537 (set_attr "mode" "DI")])
14539 (define_insn "fistdi2_floor_with_temp"
14540 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14541 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14542 UNSPEC_FIST_FLOOR))
14543 (use (match_operand:HI 2 "memory_operand" "m,m"))
14544 (use (match_operand:HI 3 "memory_operand" "m,m"))
14545 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14546 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14547 "TARGET_USE_FANCY_MATH_387
14548 && flag_unsafe_math_optimizations"
14550 [(set_attr "type" "fistp")
14551 (set_attr "i387_cw" "floor")
14552 (set_attr "mode" "DI")])
14555 [(set (match_operand:DI 0 "register_operand" "")
14556 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14557 UNSPEC_FIST_FLOOR))
14558 (use (match_operand:HI 2 "memory_operand" ""))
14559 (use (match_operand:HI 3 "memory_operand" ""))
14560 (clobber (match_operand:DI 4 "memory_operand" ""))
14561 (clobber (match_scratch 5 ""))]
14563 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14564 (use (match_dup 2))
14565 (use (match_dup 3))
14566 (clobber (match_dup 5))])
14567 (set (match_dup 0) (match_dup 4))])
14570 [(set (match_operand:DI 0 "memory_operand" "")
14571 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14572 UNSPEC_FIST_FLOOR))
14573 (use (match_operand:HI 2 "memory_operand" ""))
14574 (use (match_operand:HI 3 "memory_operand" ""))
14575 (clobber (match_operand:DI 4 "memory_operand" ""))
14576 (clobber (match_scratch 5 ""))]
14578 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14579 (use (match_dup 2))
14580 (use (match_dup 3))
14581 (clobber (match_dup 5))])])
14583 (define_insn "fist<mode>2_floor"
14584 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14585 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14586 UNSPEC_FIST_FLOOR))
14587 (use (match_operand:HI 2 "memory_operand" "m"))
14588 (use (match_operand:HI 3 "memory_operand" "m"))]
14589 "TARGET_USE_FANCY_MATH_387
14590 && flag_unsafe_math_optimizations"
14591 "* return output_fix_trunc (insn, operands, 0);"
14592 [(set_attr "type" "fistp")
14593 (set_attr "i387_cw" "floor")
14594 (set_attr "mode" "<MODE>")])
14596 (define_insn "fist<mode>2_floor_with_temp"
14597 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14598 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14599 UNSPEC_FIST_FLOOR))
14600 (use (match_operand:HI 2 "memory_operand" "m,m"))
14601 (use (match_operand:HI 3 "memory_operand" "m,m"))
14602 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14603 "TARGET_USE_FANCY_MATH_387
14604 && flag_unsafe_math_optimizations"
14606 [(set_attr "type" "fistp")
14607 (set_attr "i387_cw" "floor")
14608 (set_attr "mode" "<MODE>")])
14611 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14612 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14613 UNSPEC_FIST_FLOOR))
14614 (use (match_operand:HI 2 "memory_operand" ""))
14615 (use (match_operand:HI 3 "memory_operand" ""))
14616 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14618 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14619 UNSPEC_FIST_FLOOR))
14620 (use (match_dup 2))
14621 (use (match_dup 3))])
14622 (set (match_dup 0) (match_dup 4))])
14625 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14626 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14627 UNSPEC_FIST_FLOOR))
14628 (use (match_operand:HI 2 "memory_operand" ""))
14629 (use (match_operand:HI 3 "memory_operand" ""))
14630 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14632 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14633 UNSPEC_FIST_FLOOR))
14634 (use (match_dup 2))
14635 (use (match_dup 3))])])
14637 (define_expand "lfloorxf<mode>2"
14638 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14639 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14640 UNSPEC_FIST_FLOOR))
14641 (clobber (reg:CC FLAGS_REG))])]
14642 "TARGET_USE_FANCY_MATH_387
14643 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14644 && flag_unsafe_math_optimizations")
14646 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
14647 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14648 (match_operand:MODEF 1 "register_operand" "")]
14649 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14650 && !flag_trapping_math"
14652 if (TARGET_64BIT && optimize_insn_for_size_p ())
14654 ix86_expand_lfloorceil (operand0, operand1, true);
14658 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14659 (define_insn_and_split "frndintxf2_ceil"
14660 [(set (match_operand:XF 0 "register_operand" "")
14661 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14662 UNSPEC_FRNDINT_CEIL))
14663 (clobber (reg:CC FLAGS_REG))]
14664 "TARGET_USE_FANCY_MATH_387
14665 && flag_unsafe_math_optimizations
14666 && can_create_pseudo_p ()"
14671 ix86_optimize_mode_switching[I387_CEIL] = 1;
14673 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14674 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14676 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
14677 operands[2], operands[3]));
14680 [(set_attr "type" "frndint")
14681 (set_attr "i387_cw" "ceil")
14682 (set_attr "mode" "XF")])
14684 (define_insn "frndintxf2_ceil_i387"
14685 [(set (match_operand:XF 0 "register_operand" "=f")
14686 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14687 UNSPEC_FRNDINT_CEIL))
14688 (use (match_operand:HI 2 "memory_operand" "m"))
14689 (use (match_operand:HI 3 "memory_operand" "m"))]
14690 "TARGET_USE_FANCY_MATH_387
14691 && flag_unsafe_math_optimizations"
14692 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14693 [(set_attr "type" "frndint")
14694 (set_attr "i387_cw" "ceil")
14695 (set_attr "mode" "XF")])
14697 (define_expand "ceilxf2"
14698 [(use (match_operand:XF 0 "register_operand" ""))
14699 (use (match_operand:XF 1 "register_operand" ""))]
14700 "TARGET_USE_FANCY_MATH_387
14701 && flag_unsafe_math_optimizations"
14703 if (optimize_insn_for_size_p ())
14705 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
14709 (define_expand "ceil<mode>2"
14710 [(use (match_operand:MODEF 0 "register_operand" ""))
14711 (use (match_operand:MODEF 1 "register_operand" ""))]
14712 "(TARGET_USE_FANCY_MATH_387
14713 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14714 || TARGET_MIX_SSE_I387)
14715 && flag_unsafe_math_optimizations)
14716 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14717 && !flag_trapping_math)"
14719 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14720 && !flag_trapping_math
14721 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14724 emit_insn (gen_sse4_1_round<mode>2
14725 (operands[0], operands[1], GEN_INT (0x02)));
14726 else if (optimize_insn_for_size_p ())
14728 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14729 ix86_expand_floorceil (operand0, operand1, false);
14731 ix86_expand_floorceildf_32 (operand0, operand1, false);
14737 if (optimize_insn_for_size_p ())
14740 op0 = gen_reg_rtx (XFmode);
14741 op1 = gen_reg_rtx (XFmode);
14742 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14743 emit_insn (gen_frndintxf2_ceil (op0, op1));
14745 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14750 (define_insn_and_split "*fist<mode>2_ceil_1"
14751 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14752 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14754 (clobber (reg:CC FLAGS_REG))]
14755 "TARGET_USE_FANCY_MATH_387
14756 && flag_unsafe_math_optimizations
14757 && can_create_pseudo_p ()"
14762 ix86_optimize_mode_switching[I387_CEIL] = 1;
14764 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14765 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
14766 if (memory_operand (operands[0], VOIDmode))
14767 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
14768 operands[2], operands[3]));
14771 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14772 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
14773 operands[2], operands[3],
14778 [(set_attr "type" "fistp")
14779 (set_attr "i387_cw" "ceil")
14780 (set_attr "mode" "<MODE>")])
14782 (define_insn "fistdi2_ceil"
14783 [(set (match_operand:DI 0 "memory_operand" "=m")
14784 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14786 (use (match_operand:HI 2 "memory_operand" "m"))
14787 (use (match_operand:HI 3 "memory_operand" "m"))
14788 (clobber (match_scratch:XF 4 "=&1f"))]
14789 "TARGET_USE_FANCY_MATH_387
14790 && flag_unsafe_math_optimizations"
14791 "* return output_fix_trunc (insn, operands, 0);"
14792 [(set_attr "type" "fistp")
14793 (set_attr "i387_cw" "ceil")
14794 (set_attr "mode" "DI")])
14796 (define_insn "fistdi2_ceil_with_temp"
14797 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14798 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14800 (use (match_operand:HI 2 "memory_operand" "m,m"))
14801 (use (match_operand:HI 3 "memory_operand" "m,m"))
14802 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14803 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14804 "TARGET_USE_FANCY_MATH_387
14805 && flag_unsafe_math_optimizations"
14807 [(set_attr "type" "fistp")
14808 (set_attr "i387_cw" "ceil")
14809 (set_attr "mode" "DI")])
14812 [(set (match_operand:DI 0 "register_operand" "")
14813 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14815 (use (match_operand:HI 2 "memory_operand" ""))
14816 (use (match_operand:HI 3 "memory_operand" ""))
14817 (clobber (match_operand:DI 4 "memory_operand" ""))
14818 (clobber (match_scratch 5 ""))]
14820 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14821 (use (match_dup 2))
14822 (use (match_dup 3))
14823 (clobber (match_dup 5))])
14824 (set (match_dup 0) (match_dup 4))])
14827 [(set (match_operand:DI 0 "memory_operand" "")
14828 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14830 (use (match_operand:HI 2 "memory_operand" ""))
14831 (use (match_operand:HI 3 "memory_operand" ""))
14832 (clobber (match_operand:DI 4 "memory_operand" ""))
14833 (clobber (match_scratch 5 ""))]
14835 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
14836 (use (match_dup 2))
14837 (use (match_dup 3))
14838 (clobber (match_dup 5))])])
14840 (define_insn "fist<mode>2_ceil"
14841 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
14842 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
14844 (use (match_operand:HI 2 "memory_operand" "m"))
14845 (use (match_operand:HI 3 "memory_operand" "m"))]
14846 "TARGET_USE_FANCY_MATH_387
14847 && flag_unsafe_math_optimizations"
14848 "* return output_fix_trunc (insn, operands, 0);"
14849 [(set_attr "type" "fistp")
14850 (set_attr "i387_cw" "ceil")
14851 (set_attr "mode" "<MODE>")])
14853 (define_insn "fist<mode>2_ceil_with_temp"
14854 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
14855 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
14857 (use (match_operand:HI 2 "memory_operand" "m,m"))
14858 (use (match_operand:HI 3 "memory_operand" "m,m"))
14859 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
14860 "TARGET_USE_FANCY_MATH_387
14861 && flag_unsafe_math_optimizations"
14863 [(set_attr "type" "fistp")
14864 (set_attr "i387_cw" "ceil")
14865 (set_attr "mode" "<MODE>")])
14868 [(set (match_operand:X87MODEI12 0 "register_operand" "")
14869 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14871 (use (match_operand:HI 2 "memory_operand" ""))
14872 (use (match_operand:HI 3 "memory_operand" ""))
14873 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14875 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
14877 (use (match_dup 2))
14878 (use (match_dup 3))])
14879 (set (match_dup 0) (match_dup 4))])
14882 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
14883 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
14885 (use (match_operand:HI 2 "memory_operand" ""))
14886 (use (match_operand:HI 3 "memory_operand" ""))
14887 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
14889 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
14891 (use (match_dup 2))
14892 (use (match_dup 3))])])
14894 (define_expand "lceilxf<mode>2"
14895 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
14896 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
14898 (clobber (reg:CC FLAGS_REG))])]
14899 "TARGET_USE_FANCY_MATH_387
14900 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14901 && flag_unsafe_math_optimizations")
14903 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
14904 [(match_operand:SWI48 0 "nonimmediate_operand" "")
14905 (match_operand:MODEF 1 "register_operand" "")]
14906 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14907 && !flag_trapping_math"
14909 ix86_expand_lfloorceil (operand0, operand1, false);
14913 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14914 (define_insn_and_split "frndintxf2_trunc"
14915 [(set (match_operand:XF 0 "register_operand" "")
14916 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14917 UNSPEC_FRNDINT_TRUNC))
14918 (clobber (reg:CC FLAGS_REG))]
14919 "TARGET_USE_FANCY_MATH_387
14920 && flag_unsafe_math_optimizations
14921 && can_create_pseudo_p ()"
14926 ix86_optimize_mode_switching[I387_TRUNC] = 1;
14928 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14929 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
14931 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
14932 operands[2], operands[3]));
14935 [(set_attr "type" "frndint")
14936 (set_attr "i387_cw" "trunc")
14937 (set_attr "mode" "XF")])
14939 (define_insn "frndintxf2_trunc_i387"
14940 [(set (match_operand:XF 0 "register_operand" "=f")
14941 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14942 UNSPEC_FRNDINT_TRUNC))
14943 (use (match_operand:HI 2 "memory_operand" "m"))
14944 (use (match_operand:HI 3 "memory_operand" "m"))]
14945 "TARGET_USE_FANCY_MATH_387
14946 && flag_unsafe_math_optimizations"
14947 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14948 [(set_attr "type" "frndint")
14949 (set_attr "i387_cw" "trunc")
14950 (set_attr "mode" "XF")])
14952 (define_expand "btruncxf2"
14953 [(use (match_operand:XF 0 "register_operand" ""))
14954 (use (match_operand:XF 1 "register_operand" ""))]
14955 "TARGET_USE_FANCY_MATH_387
14956 && flag_unsafe_math_optimizations"
14958 if (optimize_insn_for_size_p ())
14960 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
14964 (define_expand "btrunc<mode>2"
14965 [(use (match_operand:MODEF 0 "register_operand" ""))
14966 (use (match_operand:MODEF 1 "register_operand" ""))]
14967 "(TARGET_USE_FANCY_MATH_387
14968 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14969 || TARGET_MIX_SSE_I387)
14970 && flag_unsafe_math_optimizations)
14971 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14972 && !flag_trapping_math)"
14974 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14975 && !flag_trapping_math
14976 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
14979 emit_insn (gen_sse4_1_round<mode>2
14980 (operands[0], operands[1], GEN_INT (0x03)));
14981 else if (optimize_insn_for_size_p ())
14983 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14984 ix86_expand_trunc (operand0, operand1);
14986 ix86_expand_truncdf_32 (operand0, operand1);
14992 if (optimize_insn_for_size_p ())
14995 op0 = gen_reg_rtx (XFmode);
14996 op1 = gen_reg_rtx (XFmode);
14997 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14998 emit_insn (gen_frndintxf2_trunc (op0, op1));
15000 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15005 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15006 (define_insn_and_split "frndintxf2_mask_pm"
15007 [(set (match_operand:XF 0 "register_operand" "")
15008 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15009 UNSPEC_FRNDINT_MASK_PM))
15010 (clobber (reg:CC FLAGS_REG))]
15011 "TARGET_USE_FANCY_MATH_387
15012 && flag_unsafe_math_optimizations
15013 && can_create_pseudo_p ()"
15018 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15020 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15021 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15023 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15024 operands[2], operands[3]));
15027 [(set_attr "type" "frndint")
15028 (set_attr "i387_cw" "mask_pm")
15029 (set_attr "mode" "XF")])
15031 (define_insn "frndintxf2_mask_pm_i387"
15032 [(set (match_operand:XF 0 "register_operand" "=f")
15033 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15034 UNSPEC_FRNDINT_MASK_PM))
15035 (use (match_operand:HI 2 "memory_operand" "m"))
15036 (use (match_operand:HI 3 "memory_operand" "m"))]
15037 "TARGET_USE_FANCY_MATH_387
15038 && flag_unsafe_math_optimizations"
15039 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15040 [(set_attr "type" "frndint")
15041 (set_attr "i387_cw" "mask_pm")
15042 (set_attr "mode" "XF")])
15044 (define_expand "nearbyintxf2"
15045 [(use (match_operand:XF 0 "register_operand" ""))
15046 (use (match_operand:XF 1 "register_operand" ""))]
15047 "TARGET_USE_FANCY_MATH_387
15048 && flag_unsafe_math_optimizations"
15050 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15054 (define_expand "nearbyint<mode>2"
15055 [(use (match_operand:MODEF 0 "register_operand" ""))
15056 (use (match_operand:MODEF 1 "register_operand" ""))]
15057 "TARGET_USE_FANCY_MATH_387
15058 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15059 || TARGET_MIX_SSE_I387)
15060 && flag_unsafe_math_optimizations"
15062 rtx op0 = gen_reg_rtx (XFmode);
15063 rtx op1 = gen_reg_rtx (XFmode);
15065 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15066 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15068 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15072 (define_insn "fxam<mode>2_i387"
15073 [(set (match_operand:HI 0 "register_operand" "=a")
15075 [(match_operand:X87MODEF 1 "register_operand" "f")]
15077 "TARGET_USE_FANCY_MATH_387"
15078 "fxam\n\tfnstsw\t%0"
15079 [(set_attr "type" "multi")
15080 (set_attr "length" "4")
15081 (set_attr "unit" "i387")
15082 (set_attr "mode" "<MODE>")])
15084 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15085 [(set (match_operand:HI 0 "register_operand" "")
15087 [(match_operand:MODEF 1 "memory_operand" "")]
15089 "TARGET_USE_FANCY_MATH_387
15090 && can_create_pseudo_p ()"
15093 [(set (match_dup 2)(match_dup 1))
15095 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15097 operands[2] = gen_reg_rtx (<MODE>mode);
15099 MEM_VOLATILE_P (operands[1]) = 1;
15101 [(set_attr "type" "multi")
15102 (set_attr "unit" "i387")
15103 (set_attr "mode" "<MODE>")])
15105 (define_expand "isinfxf2"
15106 [(use (match_operand:SI 0 "register_operand" ""))
15107 (use (match_operand:XF 1 "register_operand" ""))]
15108 "TARGET_USE_FANCY_MATH_387
15109 && TARGET_C99_FUNCTIONS"
15111 rtx mask = GEN_INT (0x45);
15112 rtx val = GEN_INT (0x05);
15116 rtx scratch = gen_reg_rtx (HImode);
15117 rtx res = gen_reg_rtx (QImode);
15119 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15121 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15122 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15123 cond = gen_rtx_fmt_ee (EQ, QImode,
15124 gen_rtx_REG (CCmode, FLAGS_REG),
15126 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15127 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15131 (define_expand "isinf<mode>2"
15132 [(use (match_operand:SI 0 "register_operand" ""))
15133 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15134 "TARGET_USE_FANCY_MATH_387
15135 && TARGET_C99_FUNCTIONS
15136 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15138 rtx mask = GEN_INT (0x45);
15139 rtx val = GEN_INT (0x05);
15143 rtx scratch = gen_reg_rtx (HImode);
15144 rtx res = gen_reg_rtx (QImode);
15146 /* Remove excess precision by forcing value through memory. */
15147 if (memory_operand (operands[1], VOIDmode))
15148 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15151 enum ix86_stack_slot slot = (virtuals_instantiated
15154 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15156 emit_move_insn (temp, operands[1]);
15157 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15160 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15161 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15162 cond = gen_rtx_fmt_ee (EQ, QImode,
15163 gen_rtx_REG (CCmode, FLAGS_REG),
15165 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15166 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15170 (define_expand "signbitxf2"
15171 [(use (match_operand:SI 0 "register_operand" ""))
15172 (use (match_operand:XF 1 "register_operand" ""))]
15173 "TARGET_USE_FANCY_MATH_387"
15175 rtx scratch = gen_reg_rtx (HImode);
15177 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15178 emit_insn (gen_andsi3 (operands[0],
15179 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15183 (define_insn "movmsk_df"
15184 [(set (match_operand:SI 0 "register_operand" "=r")
15186 [(match_operand:DF 1 "register_operand" "x")]
15188 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15189 "%vmovmskpd\t{%1, %0|%0, %1}"
15190 [(set_attr "type" "ssemov")
15191 (set_attr "prefix" "maybe_vex")
15192 (set_attr "mode" "DF")])
15194 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15195 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15196 (define_expand "signbitdf2"
15197 [(use (match_operand:SI 0 "register_operand" ""))
15198 (use (match_operand:DF 1 "register_operand" ""))]
15199 "TARGET_USE_FANCY_MATH_387
15200 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15202 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15204 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15205 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15209 rtx scratch = gen_reg_rtx (HImode);
15211 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15212 emit_insn (gen_andsi3 (operands[0],
15213 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15218 (define_expand "signbitsf2"
15219 [(use (match_operand:SI 0 "register_operand" ""))
15220 (use (match_operand:SF 1 "register_operand" ""))]
15221 "TARGET_USE_FANCY_MATH_387
15222 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15224 rtx scratch = gen_reg_rtx (HImode);
15226 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15227 emit_insn (gen_andsi3 (operands[0],
15228 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15232 ;; Block operation instructions
15235 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15238 [(set_attr "length" "1")
15239 (set_attr "length_immediate" "0")
15240 (set_attr "modrm" "0")])
15242 (define_expand "movmem<mode>"
15243 [(use (match_operand:BLK 0 "memory_operand" ""))
15244 (use (match_operand:BLK 1 "memory_operand" ""))
15245 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15246 (use (match_operand:SWI48 3 "const_int_operand" ""))
15247 (use (match_operand:SI 4 "const_int_operand" ""))
15248 (use (match_operand:SI 5 "const_int_operand" ""))]
15251 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15252 operands[4], operands[5]))
15258 ;; Most CPUs don't like single string operations
15259 ;; Handle this case here to simplify previous expander.
15261 (define_expand "strmov"
15262 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15263 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15264 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15265 (clobber (reg:CC FLAGS_REG))])
15266 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15267 (clobber (reg:CC FLAGS_REG))])]
15270 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15272 /* If .md ever supports :P for Pmode, these can be directly
15273 in the pattern above. */
15274 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15275 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15277 /* Can't use this if the user has appropriated esi or edi. */
15278 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15279 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15281 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15282 operands[2], operands[3],
15283 operands[5], operands[6]));
15287 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15290 (define_expand "strmov_singleop"
15291 [(parallel [(set (match_operand 1 "memory_operand" "")
15292 (match_operand 3 "memory_operand" ""))
15293 (set (match_operand 0 "register_operand" "")
15294 (match_operand 4 "" ""))
15295 (set (match_operand 2 "register_operand" "")
15296 (match_operand 5 "" ""))])]
15298 "ix86_current_function_needs_cld = 1;")
15300 (define_insn "*strmovdi_rex_1"
15301 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15302 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15303 (set (match_operand:DI 0 "register_operand" "=D")
15304 (plus:DI (match_dup 2)
15306 (set (match_operand:DI 1 "register_operand" "=S")
15307 (plus:DI (match_dup 3)
15311 [(set_attr "type" "str")
15312 (set_attr "memory" "both")
15313 (set_attr "mode" "DI")])
15315 (define_insn "*strmovsi_1"
15316 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15317 (mem:SI (match_operand:P 3 "register_operand" "1")))
15318 (set (match_operand:P 0 "register_operand" "=D")
15319 (plus:P (match_dup 2)
15321 (set (match_operand:P 1 "register_operand" "=S")
15322 (plus:P (match_dup 3)
15326 [(set_attr "type" "str")
15327 (set_attr "memory" "both")
15328 (set_attr "mode" "SI")])
15330 (define_insn "*strmovhi_1"
15331 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15332 (mem:HI (match_operand:P 3 "register_operand" "1")))
15333 (set (match_operand:P 0 "register_operand" "=D")
15334 (plus:P (match_dup 2)
15336 (set (match_operand:P 1 "register_operand" "=S")
15337 (plus:P (match_dup 3)
15341 [(set_attr "type" "str")
15342 (set_attr "memory" "both")
15343 (set_attr "mode" "HI")])
15345 (define_insn "*strmovqi_1"
15346 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15347 (mem:QI (match_operand:P 3 "register_operand" "1")))
15348 (set (match_operand:P 0 "register_operand" "=D")
15349 (plus:P (match_dup 2)
15351 (set (match_operand:P 1 "register_operand" "=S")
15352 (plus:P (match_dup 3)
15356 [(set_attr "type" "str")
15357 (set_attr "memory" "both")
15358 (set (attr "prefix_rex")
15360 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15362 (const_string "*")))
15363 (set_attr "mode" "QI")])
15365 (define_expand "rep_mov"
15366 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15367 (set (match_operand 0 "register_operand" "")
15368 (match_operand 5 "" ""))
15369 (set (match_operand 2 "register_operand" "")
15370 (match_operand 6 "" ""))
15371 (set (match_operand 1 "memory_operand" "")
15372 (match_operand 3 "memory_operand" ""))
15373 (use (match_dup 4))])]
15375 "ix86_current_function_needs_cld = 1;")
15377 (define_insn "*rep_movdi_rex64"
15378 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15379 (set (match_operand:DI 0 "register_operand" "=D")
15380 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15382 (match_operand:DI 3 "register_operand" "0")))
15383 (set (match_operand:DI 1 "register_operand" "=S")
15384 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15385 (match_operand:DI 4 "register_operand" "1")))
15386 (set (mem:BLK (match_dup 3))
15387 (mem:BLK (match_dup 4)))
15388 (use (match_dup 5))]
15391 [(set_attr "type" "str")
15392 (set_attr "prefix_rep" "1")
15393 (set_attr "memory" "both")
15394 (set_attr "mode" "DI")])
15396 (define_insn "*rep_movsi"
15397 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15398 (set (match_operand:P 0 "register_operand" "=D")
15399 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15401 (match_operand:P 3 "register_operand" "0")))
15402 (set (match_operand:P 1 "register_operand" "=S")
15403 (plus:P (ashift:P (match_dup 5) (const_int 2))
15404 (match_operand:P 4 "register_operand" "1")))
15405 (set (mem:BLK (match_dup 3))
15406 (mem:BLK (match_dup 4)))
15407 (use (match_dup 5))]
15409 "rep{%;} movs{l|d}"
15410 [(set_attr "type" "str")
15411 (set_attr "prefix_rep" "1")
15412 (set_attr "memory" "both")
15413 (set_attr "mode" "SI")])
15415 (define_insn "*rep_movqi"
15416 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15417 (set (match_operand:P 0 "register_operand" "=D")
15418 (plus:P (match_operand:P 3 "register_operand" "0")
15419 (match_operand:P 5 "register_operand" "2")))
15420 (set (match_operand:P 1 "register_operand" "=S")
15421 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15422 (set (mem:BLK (match_dup 3))
15423 (mem:BLK (match_dup 4)))
15424 (use (match_dup 5))]
15427 [(set_attr "type" "str")
15428 (set_attr "prefix_rep" "1")
15429 (set_attr "memory" "both")
15430 (set_attr "mode" "QI")])
15432 (define_expand "setmem<mode>"
15433 [(use (match_operand:BLK 0 "memory_operand" ""))
15434 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15435 (use (match_operand 2 "const_int_operand" ""))
15436 (use (match_operand 3 "const_int_operand" ""))
15437 (use (match_operand:SI 4 "const_int_operand" ""))
15438 (use (match_operand:SI 5 "const_int_operand" ""))]
15441 if (ix86_expand_setmem (operands[0], operands[1],
15442 operands[2], operands[3],
15443 operands[4], operands[5]))
15449 ;; Most CPUs don't like single string operations
15450 ;; Handle this case here to simplify previous expander.
15452 (define_expand "strset"
15453 [(set (match_operand 1 "memory_operand" "")
15454 (match_operand 2 "register_operand" ""))
15455 (parallel [(set (match_operand 0 "register_operand" "")
15457 (clobber (reg:CC FLAGS_REG))])]
15460 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15461 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15463 /* If .md ever supports :P for Pmode, this can be directly
15464 in the pattern above. */
15465 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15466 GEN_INT (GET_MODE_SIZE (GET_MODE
15468 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15470 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15476 (define_expand "strset_singleop"
15477 [(parallel [(set (match_operand 1 "memory_operand" "")
15478 (match_operand 2 "register_operand" ""))
15479 (set (match_operand 0 "register_operand" "")
15480 (match_operand 3 "" ""))])]
15482 "ix86_current_function_needs_cld = 1;")
15484 (define_insn "*strsetdi_rex_1"
15485 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15486 (match_operand:DI 2 "register_operand" "a"))
15487 (set (match_operand:DI 0 "register_operand" "=D")
15488 (plus:DI (match_dup 1)
15492 [(set_attr "type" "str")
15493 (set_attr "memory" "store")
15494 (set_attr "mode" "DI")])
15496 (define_insn "*strsetsi_1"
15497 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15498 (match_operand:SI 2 "register_operand" "a"))
15499 (set (match_operand:P 0 "register_operand" "=D")
15500 (plus:P (match_dup 1)
15504 [(set_attr "type" "str")
15505 (set_attr "memory" "store")
15506 (set_attr "mode" "SI")])
15508 (define_insn "*strsethi_1"
15509 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15510 (match_operand:HI 2 "register_operand" "a"))
15511 (set (match_operand:P 0 "register_operand" "=D")
15512 (plus:P (match_dup 1)
15516 [(set_attr "type" "str")
15517 (set_attr "memory" "store")
15518 (set_attr "mode" "HI")])
15520 (define_insn "*strsetqi_1"
15521 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15522 (match_operand:QI 2 "register_operand" "a"))
15523 (set (match_operand:P 0 "register_operand" "=D")
15524 (plus:P (match_dup 1)
15528 [(set_attr "type" "str")
15529 (set_attr "memory" "store")
15530 (set (attr "prefix_rex")
15532 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15534 (const_string "*")))
15535 (set_attr "mode" "QI")])
15537 (define_expand "rep_stos"
15538 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15539 (set (match_operand 0 "register_operand" "")
15540 (match_operand 4 "" ""))
15541 (set (match_operand 2 "memory_operand" "") (const_int 0))
15542 (use (match_operand 3 "register_operand" ""))
15543 (use (match_dup 1))])]
15545 "ix86_current_function_needs_cld = 1;")
15547 (define_insn "*rep_stosdi_rex64"
15548 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15549 (set (match_operand:DI 0 "register_operand" "=D")
15550 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15552 (match_operand:DI 3 "register_operand" "0")))
15553 (set (mem:BLK (match_dup 3))
15555 (use (match_operand:DI 2 "register_operand" "a"))
15556 (use (match_dup 4))]
15559 [(set_attr "type" "str")
15560 (set_attr "prefix_rep" "1")
15561 (set_attr "memory" "store")
15562 (set_attr "mode" "DI")])
15564 (define_insn "*rep_stossi"
15565 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15566 (set (match_operand:P 0 "register_operand" "=D")
15567 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15569 (match_operand:P 3 "register_operand" "0")))
15570 (set (mem:BLK (match_dup 3))
15572 (use (match_operand:SI 2 "register_operand" "a"))
15573 (use (match_dup 4))]
15575 "rep{%;} stos{l|d}"
15576 [(set_attr "type" "str")
15577 (set_attr "prefix_rep" "1")
15578 (set_attr "memory" "store")
15579 (set_attr "mode" "SI")])
15581 (define_insn "*rep_stosqi"
15582 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15583 (set (match_operand:P 0 "register_operand" "=D")
15584 (plus:P (match_operand:P 3 "register_operand" "0")
15585 (match_operand:P 4 "register_operand" "1")))
15586 (set (mem:BLK (match_dup 3))
15588 (use (match_operand:QI 2 "register_operand" "a"))
15589 (use (match_dup 4))]
15592 [(set_attr "type" "str")
15593 (set_attr "prefix_rep" "1")
15594 (set_attr "memory" "store")
15595 (set (attr "prefix_rex")
15597 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15599 (const_string "*")))
15600 (set_attr "mode" "QI")])
15602 (define_expand "cmpstrnsi"
15603 [(set (match_operand:SI 0 "register_operand" "")
15604 (compare:SI (match_operand:BLK 1 "general_operand" "")
15605 (match_operand:BLK 2 "general_operand" "")))
15606 (use (match_operand 3 "general_operand" ""))
15607 (use (match_operand 4 "immediate_operand" ""))]
15610 rtx addr1, addr2, out, outlow, count, countreg, align;
15612 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15615 /* Can't use this if the user has appropriated esi or edi. */
15616 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
15621 out = gen_reg_rtx (SImode);
15623 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
15624 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
15625 if (addr1 != XEXP (operands[1], 0))
15626 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15627 if (addr2 != XEXP (operands[2], 0))
15628 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15630 count = operands[3];
15631 countreg = ix86_zero_extend_to_Pmode (count);
15633 /* %%% Iff we are testing strict equality, we can use known alignment
15634 to good advantage. This may be possible with combine, particularly
15635 once cc0 is dead. */
15636 align = operands[4];
15638 if (CONST_INT_P (count))
15640 if (INTVAL (count) == 0)
15642 emit_move_insn (operands[0], const0_rtx);
15645 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15646 operands[1], operands[2]));
15650 rtx (*gen_cmp) (rtx, rtx);
15652 gen_cmp = (TARGET_64BIT
15653 ? gen_cmpdi_1 : gen_cmpsi_1);
15655 emit_insn (gen_cmp (countreg, countreg));
15656 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15657 operands[1], operands[2]));
15660 outlow = gen_lowpart (QImode, out);
15661 emit_insn (gen_cmpintqi (outlow));
15662 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15664 if (operands[0] != out)
15665 emit_move_insn (operands[0], out);
15670 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15672 (define_expand "cmpintqi"
15673 [(set (match_dup 1)
15674 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15676 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15677 (parallel [(set (match_operand:QI 0 "register_operand" "")
15678 (minus:QI (match_dup 1)
15680 (clobber (reg:CC FLAGS_REG))])]
15683 operands[1] = gen_reg_rtx (QImode);
15684 operands[2] = gen_reg_rtx (QImode);
15687 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15688 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
15690 (define_expand "cmpstrnqi_nz_1"
15691 [(parallel [(set (reg:CC FLAGS_REG)
15692 (compare:CC (match_operand 4 "memory_operand" "")
15693 (match_operand 5 "memory_operand" "")))
15694 (use (match_operand 2 "register_operand" ""))
15695 (use (match_operand:SI 3 "immediate_operand" ""))
15696 (clobber (match_operand 0 "register_operand" ""))
15697 (clobber (match_operand 1 "register_operand" ""))
15698 (clobber (match_dup 2))])]
15700 "ix86_current_function_needs_cld = 1;")
15702 (define_insn "*cmpstrnqi_nz_1"
15703 [(set (reg:CC FLAGS_REG)
15704 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15705 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
15706 (use (match_operand:P 6 "register_operand" "2"))
15707 (use (match_operand:SI 3 "immediate_operand" "i"))
15708 (clobber (match_operand:P 0 "register_operand" "=S"))
15709 (clobber (match_operand:P 1 "register_operand" "=D"))
15710 (clobber (match_operand:P 2 "register_operand" "=c"))]
15713 [(set_attr "type" "str")
15714 (set_attr "mode" "QI")
15715 (set (attr "prefix_rex")
15717 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15719 (const_string "*")))
15720 (set_attr "prefix_rep" "1")])
15722 ;; The same, but the count is not known to not be zero.
15724 (define_expand "cmpstrnqi_1"
15725 [(parallel [(set (reg:CC FLAGS_REG)
15726 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
15728 (compare:CC (match_operand 4 "memory_operand" "")
15729 (match_operand 5 "memory_operand" ""))
15731 (use (match_operand:SI 3 "immediate_operand" ""))
15732 (use (reg:CC FLAGS_REG))
15733 (clobber (match_operand 0 "register_operand" ""))
15734 (clobber (match_operand 1 "register_operand" ""))
15735 (clobber (match_dup 2))])]
15737 "ix86_current_function_needs_cld = 1;")
15739 (define_insn "*cmpstrnqi_1"
15740 [(set (reg:CC FLAGS_REG)
15741 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
15743 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15744 (mem:BLK (match_operand:P 5 "register_operand" "1")))
15746 (use (match_operand:SI 3 "immediate_operand" "i"))
15747 (use (reg:CC FLAGS_REG))
15748 (clobber (match_operand:P 0 "register_operand" "=S"))
15749 (clobber (match_operand:P 1 "register_operand" "=D"))
15750 (clobber (match_operand:P 2 "register_operand" "=c"))]
15753 [(set_attr "type" "str")
15754 (set_attr "mode" "QI")
15755 (set (attr "prefix_rex")
15757 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15759 (const_string "*")))
15760 (set_attr "prefix_rep" "1")])
15762 (define_expand "strlen<mode>"
15763 [(set (match_operand:SWI48x 0 "register_operand" "")
15764 (unspec:SWI48x [(match_operand:BLK 1 "general_operand" "")
15765 (match_operand:QI 2 "immediate_operand" "")
15766 (match_operand 3 "immediate_operand" "")]
15770 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15776 (define_expand "strlenqi_1"
15777 [(parallel [(set (match_operand 0 "register_operand" "")
15778 (match_operand 2 "" ""))
15779 (clobber (match_operand 1 "register_operand" ""))
15780 (clobber (reg:CC FLAGS_REG))])]
15782 "ix86_current_function_needs_cld = 1;")
15784 (define_insn "*strlenqi_1"
15785 [(set (match_operand:P 0 "register_operand" "=&c")
15786 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
15787 (match_operand:QI 2 "register_operand" "a")
15788 (match_operand:P 3 "immediate_operand" "i")
15789 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
15790 (clobber (match_operand:P 1 "register_operand" "=D"))
15791 (clobber (reg:CC FLAGS_REG))]
15794 [(set_attr "type" "str")
15795 (set_attr "mode" "QI")
15796 (set (attr "prefix_rex")
15798 (ne (symbol_ref "<P:MODE>mode == DImode") (const_int 0))
15800 (const_string "*")))
15801 (set_attr "prefix_rep" "1")])
15803 ;; Peephole optimizations to clean up after cmpstrn*. This should be
15804 ;; handled in combine, but it is not currently up to the task.
15805 ;; When used for their truth value, the cmpstrn* expanders generate
15814 ;; The intermediate three instructions are unnecessary.
15816 ;; This one handles cmpstrn*_nz_1...
15819 (set (reg:CC FLAGS_REG)
15820 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15821 (mem:BLK (match_operand 5 "register_operand" ""))))
15822 (use (match_operand 6 "register_operand" ""))
15823 (use (match_operand:SI 3 "immediate_operand" ""))
15824 (clobber (match_operand 0 "register_operand" ""))
15825 (clobber (match_operand 1 "register_operand" ""))
15826 (clobber (match_operand 2 "register_operand" ""))])
15827 (set (match_operand:QI 7 "register_operand" "")
15828 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15829 (set (match_operand:QI 8 "register_operand" "")
15830 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15831 (set (reg FLAGS_REG)
15832 (compare (match_dup 7) (match_dup 8)))
15834 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15836 (set (reg:CC FLAGS_REG)
15837 (compare:CC (mem:BLK (match_dup 4))
15838 (mem:BLK (match_dup 5))))
15839 (use (match_dup 6))
15840 (use (match_dup 3))
15841 (clobber (match_dup 0))
15842 (clobber (match_dup 1))
15843 (clobber (match_dup 2))])])
15845 ;; ...and this one handles cmpstrn*_1.
15848 (set (reg:CC FLAGS_REG)
15849 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
15851 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
15852 (mem:BLK (match_operand 5 "register_operand" "")))
15854 (use (match_operand:SI 3 "immediate_operand" ""))
15855 (use (reg:CC FLAGS_REG))
15856 (clobber (match_operand 0 "register_operand" ""))
15857 (clobber (match_operand 1 "register_operand" ""))
15858 (clobber (match_operand 2 "register_operand" ""))])
15859 (set (match_operand:QI 7 "register_operand" "")
15860 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15861 (set (match_operand:QI 8 "register_operand" "")
15862 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15863 (set (reg FLAGS_REG)
15864 (compare (match_dup 7) (match_dup 8)))
15866 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15868 (set (reg:CC FLAGS_REG)
15869 (if_then_else:CC (ne (match_dup 6)
15871 (compare:CC (mem:BLK (match_dup 4))
15872 (mem:BLK (match_dup 5)))
15874 (use (match_dup 3))
15875 (use (reg:CC FLAGS_REG))
15876 (clobber (match_dup 0))
15877 (clobber (match_dup 1))
15878 (clobber (match_dup 2))])])
15880 ;; Conditional move instructions.
15882 (define_expand "mov<mode>cc"
15883 [(set (match_operand:SWIM 0 "register_operand" "")
15884 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
15885 (match_operand:SWIM 2 "general_operand" "")
15886 (match_operand:SWIM 3 "general_operand" "")))]
15888 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
15890 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
15891 ;; the register first winds up with `sbbl $0,reg', which is also weird.
15892 ;; So just document what we're doing explicitly.
15894 (define_expand "x86_mov<mode>cc_0_m1"
15896 [(set (match_operand:SWI48 0 "register_operand" "")
15897 (if_then_else:SWI48
15898 (match_operator:SWI48 2 "ix86_carry_flag_operator"
15899 [(match_operand 1 "flags_reg_operand" "")
15903 (clobber (reg:CC FLAGS_REG))])])
15905 (define_insn "*x86_mov<mode>cc_0_m1"
15906 [(set (match_operand:SWI48 0 "register_operand" "=r")
15907 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15908 [(reg FLAGS_REG) (const_int 0)])
15911 (clobber (reg:CC FLAGS_REG))]
15913 "sbb{<imodesuffix>}\t%0, %0"
15914 ; Since we don't have the proper number of operands for an alu insn,
15915 ; fill in all the blanks.
15916 [(set_attr "type" "alu")
15917 (set_attr "use_carry" "1")
15918 (set_attr "pent_pair" "pu")
15919 (set_attr "memory" "none")
15920 (set_attr "imm_disp" "false")
15921 (set_attr "mode" "<MODE>")
15922 (set_attr "length_immediate" "0")])
15924 (define_insn "*x86_mov<mode>cc_0_m1_se"
15925 [(set (match_operand:SWI48 0 "register_operand" "=r")
15926 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15927 [(reg FLAGS_REG) (const_int 0)])
15930 (clobber (reg:CC FLAGS_REG))]
15932 "sbb{<imodesuffix>}\t%0, %0"
15933 [(set_attr "type" "alu")
15934 (set_attr "use_carry" "1")
15935 (set_attr "pent_pair" "pu")
15936 (set_attr "memory" "none")
15937 (set_attr "imm_disp" "false")
15938 (set_attr "mode" "<MODE>")
15939 (set_attr "length_immediate" "0")])
15941 (define_insn "*x86_mov<mode>cc_0_m1_neg"
15942 [(set (match_operand:SWI48 0 "register_operand" "=r")
15943 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15944 [(reg FLAGS_REG) (const_int 0)])))]
15946 "sbb{<imodesuffix>}\t%0, %0"
15947 [(set_attr "type" "alu")
15948 (set_attr "use_carry" "1")
15949 (set_attr "pent_pair" "pu")
15950 (set_attr "memory" "none")
15951 (set_attr "imm_disp" "false")
15952 (set_attr "mode" "<MODE>")
15953 (set_attr "length_immediate" "0")])
15955 (define_insn "*mov<mode>cc_noc"
15956 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
15957 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
15958 [(reg FLAGS_REG) (const_int 0)])
15959 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
15960 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
15961 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
15963 cmov%O2%C1\t{%2, %0|%0, %2}
15964 cmov%O2%c1\t{%3, %0|%0, %3}"
15965 [(set_attr "type" "icmov")
15966 (set_attr "mode" "<MODE>")])
15968 (define_insn_and_split "*movqicc_noc"
15969 [(set (match_operand:QI 0 "register_operand" "=r,r")
15970 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
15971 [(match_operand 4 "flags_reg_operand" "")
15973 (match_operand:QI 2 "register_operand" "r,0")
15974 (match_operand:QI 3 "register_operand" "0,r")))]
15975 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
15977 "&& reload_completed"
15978 [(set (match_dup 0)
15979 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
15982 "operands[0] = gen_lowpart (SImode, operands[0]);
15983 operands[2] = gen_lowpart (SImode, operands[2]);
15984 operands[3] = gen_lowpart (SImode, operands[3]);"
15985 [(set_attr "type" "icmov")
15986 (set_attr "mode" "SI")])
15988 (define_expand "mov<mode>cc"
15989 [(set (match_operand:X87MODEF 0 "register_operand" "")
15990 (if_then_else:X87MODEF
15991 (match_operand 1 "ix86_fp_comparison_operator" "")
15992 (match_operand:X87MODEF 2 "register_operand" "")
15993 (match_operand:X87MODEF 3 "register_operand" "")))]
15994 "(TARGET_80387 && TARGET_CMOVE)
15995 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15996 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
15998 (define_insn "*movxfcc_1"
15999 [(set (match_operand:XF 0 "register_operand" "=f,f")
16000 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16001 [(reg FLAGS_REG) (const_int 0)])
16002 (match_operand:XF 2 "register_operand" "f,0")
16003 (match_operand:XF 3 "register_operand" "0,f")))]
16004 "TARGET_80387 && TARGET_CMOVE"
16006 fcmov%F1\t{%2, %0|%0, %2}
16007 fcmov%f1\t{%3, %0|%0, %3}"
16008 [(set_attr "type" "fcmov")
16009 (set_attr "mode" "XF")])
16011 (define_insn "*movdfcc_1_rex64"
16012 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16013 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16014 [(reg FLAGS_REG) (const_int 0)])
16015 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16016 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16017 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16018 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16020 fcmov%F1\t{%2, %0|%0, %2}
16021 fcmov%f1\t{%3, %0|%0, %3}
16022 cmov%O2%C1\t{%2, %0|%0, %2}
16023 cmov%O2%c1\t{%3, %0|%0, %3}"
16024 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16025 (set_attr "mode" "DF,DF,DI,DI")])
16027 (define_insn "*movdfcc_1"
16028 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16029 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16030 [(reg FLAGS_REG) (const_int 0)])
16031 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16032 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16033 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16034 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16036 fcmov%F1\t{%2, %0|%0, %2}
16037 fcmov%f1\t{%3, %0|%0, %3}
16040 [(set_attr "type" "fcmov,fcmov,multi,multi")
16041 (set_attr "mode" "DF,DF,DI,DI")])
16044 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16045 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16046 [(match_operand 4 "flags_reg_operand" "")
16048 (match_operand:DF 2 "nonimmediate_operand" "")
16049 (match_operand:DF 3 "nonimmediate_operand" "")))]
16050 "!TARGET_64BIT && reload_completed"
16051 [(set (match_dup 2)
16052 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16056 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16060 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16061 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16064 (define_insn "*movsfcc_1_387"
16065 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16066 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16067 [(reg FLAGS_REG) (const_int 0)])
16068 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16069 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16070 "TARGET_80387 && TARGET_CMOVE
16071 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16073 fcmov%F1\t{%2, %0|%0, %2}
16074 fcmov%f1\t{%3, %0|%0, %3}
16075 cmov%O2%C1\t{%2, %0|%0, %2}
16076 cmov%O2%c1\t{%3, %0|%0, %3}"
16077 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16078 (set_attr "mode" "SF,SF,SI,SI")])
16080 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16081 ;; the scalar versions to have only XMM registers as operands.
16083 ;; XOP conditional move
16084 (define_insn "*xop_pcmov_<mode>"
16085 [(set (match_operand:MODEF 0 "register_operand" "=x")
16086 (if_then_else:MODEF
16087 (match_operand:MODEF 1 "register_operand" "x")
16088 (match_operand:MODEF 2 "register_operand" "x")
16089 (match_operand:MODEF 3 "register_operand" "x")))]
16091 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16092 [(set_attr "type" "sse4arg")])
16094 ;; These versions of the min/max patterns are intentionally ignorant of
16095 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16096 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16097 ;; are undefined in this condition, we're certain this is correct.
16099 (define_insn "*avx_<code><mode>3"
16100 [(set (match_operand:MODEF 0 "register_operand" "=x")
16102 (match_operand:MODEF 1 "nonimmediate_operand" "%x")
16103 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16104 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16105 "v<maxmin_float>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16106 [(set_attr "type" "sseadd")
16107 (set_attr "prefix" "vex")
16108 (set_attr "mode" "<MODE>")])
16110 (define_insn "<code><mode>3"
16111 [(set (match_operand:MODEF 0 "register_operand" "=x")
16113 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
16114 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
16115 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16116 "<maxmin_float>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
16117 [(set_attr "type" "sseadd")
16118 (set_attr "mode" "<MODE>")])
16120 ;; These versions of the min/max patterns implement exactly the operations
16121 ;; min = (op1 < op2 ? op1 : op2)
16122 ;; max = (!(op1 < op2) ? op1 : op2)
16123 ;; Their operands are not commutative, and thus they may be used in the
16124 ;; presence of -0.0 and NaN.
16126 (define_insn "*avx_ieee_smin<mode>3"
16127 [(set (match_operand:MODEF 0 "register_operand" "=x")
16129 [(match_operand:MODEF 1 "register_operand" "x")
16130 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16132 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16133 "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16134 [(set_attr "type" "sseadd")
16135 (set_attr "prefix" "vex")
16136 (set_attr "mode" "<MODE>")])
16138 (define_insn "*ieee_smin<mode>3"
16139 [(set (match_operand:MODEF 0 "register_operand" "=x")
16141 [(match_operand:MODEF 1 "register_operand" "0")
16142 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16144 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16145 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
16146 [(set_attr "type" "sseadd")
16147 (set_attr "mode" "<MODE>")])
16149 (define_insn "*avx_ieee_smax<mode>3"
16150 [(set (match_operand:MODEF 0 "register_operand" "=x")
16152 [(match_operand:MODEF 1 "register_operand" "0")
16153 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16155 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16156 "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
16157 [(set_attr "type" "sseadd")
16158 (set_attr "prefix" "vex")
16159 (set_attr "mode" "<MODE>")])
16161 (define_insn "*ieee_smax<mode>3"
16162 [(set (match_operand:MODEF 0 "register_operand" "=x")
16164 [(match_operand:MODEF 1 "register_operand" "0")
16165 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
16167 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16168 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
16169 [(set_attr "type" "sseadd")
16170 (set_attr "mode" "<MODE>")])
16172 ;; Make two stack loads independent:
16174 ;; fld %st(0) -> fld bb
16175 ;; fmul bb fmul %st(1), %st
16177 ;; Actually we only match the last two instructions for simplicity.
16179 [(set (match_operand 0 "fp_register_operand" "")
16180 (match_operand 1 "fp_register_operand" ""))
16182 (match_operator 2 "binary_fp_operator"
16184 (match_operand 3 "memory_operand" "")]))]
16185 "REGNO (operands[0]) != REGNO (operands[1])"
16186 [(set (match_dup 0) (match_dup 3))
16187 (set (match_dup 0) (match_dup 4))]
16189 ;; The % modifier is not operational anymore in peephole2's, so we have to
16190 ;; swap the operands manually in the case of addition and multiplication.
16191 "if (COMMUTATIVE_ARITH_P (operands[2]))
16192 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16193 GET_MODE (operands[2]),
16194 operands[0], operands[1]);
16196 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16197 GET_MODE (operands[2]),
16198 operands[1], operands[0]);")
16200 ;; Conditional addition patterns
16201 (define_expand "add<mode>cc"
16202 [(match_operand:SWI 0 "register_operand" "")
16203 (match_operand 1 "ordered_comparison_operator" "")
16204 (match_operand:SWI 2 "register_operand" "")
16205 (match_operand:SWI 3 "const_int_operand" "")]
16207 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16209 ;; Misc patterns (?)
16211 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16212 ;; Otherwise there will be nothing to keep
16214 ;; [(set (reg ebp) (reg esp))]
16215 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16216 ;; (clobber (eflags)]
16217 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16219 ;; in proper program order.
16221 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16222 [(set (match_operand:P 0 "register_operand" "=r,r")
16223 (plus:P (match_operand:P 1 "register_operand" "0,r")
16224 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16225 (clobber (reg:CC FLAGS_REG))
16226 (clobber (mem:BLK (scratch)))]
16229 switch (get_attr_type (insn))
16232 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16235 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16236 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16237 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16239 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16242 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16243 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16246 [(set (attr "type")
16247 (cond [(and (eq_attr "alternative" "0")
16248 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
16249 (const_string "alu")
16250 (match_operand:<MODE> 2 "const0_operand" "")
16251 (const_string "imov")
16253 (const_string "lea")))
16254 (set (attr "length_immediate")
16255 (cond [(eq_attr "type" "imov")
16257 (and (eq_attr "type" "alu")
16258 (match_operand 2 "const128_operand" ""))
16261 (const_string "*")))
16262 (set_attr "mode" "<MODE>")])
16264 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16265 [(set (match_operand:P 0 "register_operand" "=r")
16266 (minus:P (match_operand:P 1 "register_operand" "0")
16267 (match_operand:P 2 "register_operand" "r")))
16268 (clobber (reg:CC FLAGS_REG))
16269 (clobber (mem:BLK (scratch)))]
16271 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16272 [(set_attr "type" "alu")
16273 (set_attr "mode" "<MODE>")])
16275 (define_insn "allocate_stack_worker_probe_<mode>"
16276 [(set (match_operand:P 0 "register_operand" "=a")
16277 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16278 UNSPECV_STACK_PROBE))
16279 (clobber (reg:CC FLAGS_REG))]
16280 "ix86_target_stack_probe ()"
16281 "call\t___chkstk_ms"
16282 [(set_attr "type" "multi")
16283 (set_attr "length" "5")])
16285 (define_expand "allocate_stack"
16286 [(match_operand 0 "register_operand" "")
16287 (match_operand 1 "general_operand" "")]
16288 "ix86_target_stack_probe ()"
16292 #ifndef CHECK_STACK_LIMIT
16293 #define CHECK_STACK_LIMIT 0
16296 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16297 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16299 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16300 stack_pointer_rtx, 0, OPTAB_DIRECT);
16301 if (x != stack_pointer_rtx)
16302 emit_move_insn (stack_pointer_rtx, x);
16306 x = copy_to_mode_reg (Pmode, operands[1]);
16308 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16310 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16311 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16312 stack_pointer_rtx, 0, OPTAB_DIRECT);
16313 if (x != stack_pointer_rtx)
16314 emit_move_insn (stack_pointer_rtx, x);
16317 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16321 ;; Use IOR for stack probes, this is shorter.
16322 (define_expand "probe_stack"
16323 [(match_operand 0 "memory_operand" "")]
16326 rtx (*gen_ior3) (rtx, rtx, rtx);
16328 gen_ior3 = (GET_MODE (operands[0]) == DImode
16329 ? gen_iordi3 : gen_iorsi3);
16331 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16335 (define_insn "adjust_stack_and_probe<mode>"
16336 [(set (match_operand:P 0 "register_operand" "=r")
16337 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16338 UNSPECV_PROBE_STACK_RANGE))
16339 (set (reg:P SP_REG)
16340 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16341 (clobber (reg:CC FLAGS_REG))
16342 (clobber (mem:BLK (scratch)))]
16344 "* return output_adjust_stack_and_probe (operands[0]);"
16345 [(set_attr "type" "multi")])
16347 (define_insn "probe_stack_range<mode>"
16348 [(set (match_operand:P 0 "register_operand" "=r")
16349 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16350 (match_operand:P 2 "const_int_operand" "n")]
16351 UNSPECV_PROBE_STACK_RANGE))
16352 (clobber (reg:CC FLAGS_REG))]
16354 "* return output_probe_stack_range (operands[0], operands[2]);"
16355 [(set_attr "type" "multi")])
16357 (define_expand "builtin_setjmp_receiver"
16358 [(label_ref (match_operand 0 "" ""))]
16359 "!TARGET_64BIT && flag_pic"
16365 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16366 rtx label_rtx = gen_label_rtx ();
16367 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16368 xops[0] = xops[1] = picreg;
16369 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16370 ix86_expand_binary_operator (MINUS, SImode, xops);
16374 emit_insn (gen_set_got (pic_offset_table_rtx));
16378 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16381 [(set (match_operand 0 "register_operand" "")
16382 (match_operator 3 "promotable_binary_operator"
16383 [(match_operand 1 "register_operand" "")
16384 (match_operand 2 "aligned_operand" "")]))
16385 (clobber (reg:CC FLAGS_REG))]
16386 "! TARGET_PARTIAL_REG_STALL && reload_completed
16387 && ((GET_MODE (operands[0]) == HImode
16388 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16389 /* ??? next two lines just !satisfies_constraint_K (...) */
16390 || !CONST_INT_P (operands[2])
16391 || satisfies_constraint_K (operands[2])))
16392 || (GET_MODE (operands[0]) == QImode
16393 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16394 [(parallel [(set (match_dup 0)
16395 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16396 (clobber (reg:CC FLAGS_REG))])]
16397 "operands[0] = gen_lowpart (SImode, operands[0]);
16398 operands[1] = gen_lowpart (SImode, operands[1]);
16399 if (GET_CODE (operands[3]) != ASHIFT)
16400 operands[2] = gen_lowpart (SImode, operands[2]);
16401 PUT_MODE (operands[3], SImode);")
16403 ; Promote the QImode tests, as i386 has encoding of the AND
16404 ; instruction with 32-bit sign-extended immediate and thus the
16405 ; instruction size is unchanged, except in the %eax case for
16406 ; which it is increased by one byte, hence the ! optimize_size.
16408 [(set (match_operand 0 "flags_reg_operand" "")
16409 (match_operator 2 "compare_operator"
16410 [(and (match_operand 3 "aligned_operand" "")
16411 (match_operand 4 "const_int_operand" ""))
16413 (set (match_operand 1 "register_operand" "")
16414 (and (match_dup 3) (match_dup 4)))]
16415 "! TARGET_PARTIAL_REG_STALL && reload_completed
16416 && optimize_insn_for_speed_p ()
16417 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16418 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16419 /* Ensure that the operand will remain sign-extended immediate. */
16420 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16421 [(parallel [(set (match_dup 0)
16422 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16425 (and:SI (match_dup 3) (match_dup 4)))])]
16428 = gen_int_mode (INTVAL (operands[4])
16429 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16430 operands[1] = gen_lowpart (SImode, operands[1]);
16431 operands[3] = gen_lowpart (SImode, operands[3]);
16434 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16435 ; the TEST instruction with 32-bit sign-extended immediate and thus
16436 ; the instruction size would at least double, which is not what we
16437 ; want even with ! optimize_size.
16439 [(set (match_operand 0 "flags_reg_operand" "")
16440 (match_operator 1 "compare_operator"
16441 [(and (match_operand:HI 2 "aligned_operand" "")
16442 (match_operand:HI 3 "const_int_operand" ""))
16444 "! TARGET_PARTIAL_REG_STALL && reload_completed
16445 && ! TARGET_FAST_PREFIX
16446 && optimize_insn_for_speed_p ()
16447 /* Ensure that the operand will remain sign-extended immediate. */
16448 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16449 [(set (match_dup 0)
16450 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16454 = gen_int_mode (INTVAL (operands[3])
16455 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16456 operands[2] = gen_lowpart (SImode, operands[2]);
16460 [(set (match_operand 0 "register_operand" "")
16461 (neg (match_operand 1 "register_operand" "")))
16462 (clobber (reg:CC FLAGS_REG))]
16463 "! TARGET_PARTIAL_REG_STALL && reload_completed
16464 && (GET_MODE (operands[0]) == HImode
16465 || (GET_MODE (operands[0]) == QImode
16466 && (TARGET_PROMOTE_QImode
16467 || optimize_insn_for_size_p ())))"
16468 [(parallel [(set (match_dup 0)
16469 (neg:SI (match_dup 1)))
16470 (clobber (reg:CC FLAGS_REG))])]
16471 "operands[0] = gen_lowpart (SImode, operands[0]);
16472 operands[1] = gen_lowpart (SImode, operands[1]);")
16475 [(set (match_operand 0 "register_operand" "")
16476 (not (match_operand 1 "register_operand" "")))]
16477 "! TARGET_PARTIAL_REG_STALL && reload_completed
16478 && (GET_MODE (operands[0]) == HImode
16479 || (GET_MODE (operands[0]) == QImode
16480 && (TARGET_PROMOTE_QImode
16481 || optimize_insn_for_size_p ())))"
16482 [(set (match_dup 0)
16483 (not:SI (match_dup 1)))]
16484 "operands[0] = gen_lowpart (SImode, operands[0]);
16485 operands[1] = gen_lowpart (SImode, operands[1]);")
16488 [(set (match_operand 0 "register_operand" "")
16489 (if_then_else (match_operator 1 "ordered_comparison_operator"
16490 [(reg FLAGS_REG) (const_int 0)])
16491 (match_operand 2 "register_operand" "")
16492 (match_operand 3 "register_operand" "")))]
16493 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16494 && (GET_MODE (operands[0]) == HImode
16495 || (GET_MODE (operands[0]) == QImode
16496 && (TARGET_PROMOTE_QImode
16497 || optimize_insn_for_size_p ())))"
16498 [(set (match_dup 0)
16499 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16500 "operands[0] = gen_lowpart (SImode, operands[0]);
16501 operands[2] = gen_lowpart (SImode, operands[2]);
16502 operands[3] = gen_lowpart (SImode, operands[3]);")
16504 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16505 ;; transform a complex memory operation into two memory to register operations.
16507 ;; Don't push memory operands
16509 [(set (match_operand:SWI 0 "push_operand" "")
16510 (match_operand:SWI 1 "memory_operand" ""))
16511 (match_scratch:SWI 2 "<r>")]
16512 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16513 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16514 [(set (match_dup 2) (match_dup 1))
16515 (set (match_dup 0) (match_dup 2))])
16517 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16520 [(set (match_operand:SF 0 "push_operand" "")
16521 (match_operand:SF 1 "memory_operand" ""))
16522 (match_scratch:SF 2 "r")]
16523 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
16524 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16525 [(set (match_dup 2) (match_dup 1))
16526 (set (match_dup 0) (match_dup 2))])
16528 ;; Don't move an immediate directly to memory when the instruction
16531 [(match_scratch:SWI124 1 "<r>")
16532 (set (match_operand:SWI124 0 "memory_operand" "")
16534 "optimize_insn_for_speed_p ()
16535 && !TARGET_USE_MOV0
16536 && TARGET_SPLIT_LONG_MOVES
16537 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16538 && peep2_regno_dead_p (0, FLAGS_REG)"
16539 [(parallel [(set (match_dup 2) (const_int 0))
16540 (clobber (reg:CC FLAGS_REG))])
16541 (set (match_dup 0) (match_dup 1))]
16542 "operands[2] = gen_lowpart (SImode, operands[1]);")
16545 [(match_scratch:SWI124 2 "<r>")
16546 (set (match_operand:SWI124 0 "memory_operand" "")
16547 (match_operand:SWI124 1 "immediate_operand" ""))]
16548 "optimize_insn_for_speed_p ()
16549 && TARGET_SPLIT_LONG_MOVES
16550 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16551 [(set (match_dup 2) (match_dup 1))
16552 (set (match_dup 0) (match_dup 2))])
16554 ;; Don't compare memory with zero, load and use a test instead.
16556 [(set (match_operand 0 "flags_reg_operand" "")
16557 (match_operator 1 "compare_operator"
16558 [(match_operand:SI 2 "memory_operand" "")
16560 (match_scratch:SI 3 "r")]
16561 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16562 [(set (match_dup 3) (match_dup 2))
16563 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16565 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16566 ;; Don't split NOTs with a displacement operand, because resulting XOR
16567 ;; will not be pairable anyway.
16569 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16570 ;; represented using a modRM byte. The XOR replacement is long decoded,
16571 ;; so this split helps here as well.
16573 ;; Note: Can't do this as a regular split because we can't get proper
16574 ;; lifetime information then.
16577 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16578 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16579 "optimize_insn_for_speed_p ()
16580 && ((TARGET_NOT_UNPAIRABLE
16581 && (!MEM_P (operands[0])
16582 || !memory_displacement_operand (operands[0], <MODE>mode)))
16583 || (TARGET_NOT_VECTORMODE
16584 && long_memory_operand (operands[0], <MODE>mode)))
16585 && peep2_regno_dead_p (0, FLAGS_REG)"
16586 [(parallel [(set (match_dup 0)
16587 (xor:SWI124 (match_dup 1) (const_int -1)))
16588 (clobber (reg:CC FLAGS_REG))])])
16590 ;; Non pairable "test imm, reg" instructions can be translated to
16591 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16592 ;; byte opcode instead of two, have a short form for byte operands),
16593 ;; so do it for other CPUs as well. Given that the value was dead,
16594 ;; this should not create any new dependencies. Pass on the sub-word
16595 ;; versions if we're concerned about partial register stalls.
16598 [(set (match_operand 0 "flags_reg_operand" "")
16599 (match_operator 1 "compare_operator"
16600 [(and:SI (match_operand:SI 2 "register_operand" "")
16601 (match_operand:SI 3 "immediate_operand" ""))
16603 "ix86_match_ccmode (insn, CCNOmode)
16604 && (true_regnum (operands[2]) != AX_REG
16605 || satisfies_constraint_K (operands[3]))
16606 && peep2_reg_dead_p (1, operands[2])"
16608 [(set (match_dup 0)
16609 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16612 (and:SI (match_dup 2) (match_dup 3)))])])
16614 ;; We don't need to handle HImode case, because it will be promoted to SImode
16615 ;; on ! TARGET_PARTIAL_REG_STALL
16618 [(set (match_operand 0 "flags_reg_operand" "")
16619 (match_operator 1 "compare_operator"
16620 [(and:QI (match_operand:QI 2 "register_operand" "")
16621 (match_operand:QI 3 "immediate_operand" ""))
16623 "! TARGET_PARTIAL_REG_STALL
16624 && ix86_match_ccmode (insn, CCNOmode)
16625 && true_regnum (operands[2]) != AX_REG
16626 && peep2_reg_dead_p (1, operands[2])"
16628 [(set (match_dup 0)
16629 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16632 (and:QI (match_dup 2) (match_dup 3)))])])
16635 [(set (match_operand 0 "flags_reg_operand" "")
16636 (match_operator 1 "compare_operator"
16639 (match_operand 2 "ext_register_operand" "")
16642 (match_operand 3 "const_int_operand" ""))
16644 "! TARGET_PARTIAL_REG_STALL
16645 && ix86_match_ccmode (insn, CCNOmode)
16646 && true_regnum (operands[2]) != AX_REG
16647 && peep2_reg_dead_p (1, operands[2])"
16648 [(parallel [(set (match_dup 0)
16657 (set (zero_extract:SI (match_dup 2)
16665 (match_dup 3)))])])
16667 ;; Don't do logical operations with memory inputs.
16669 [(match_scratch:SI 2 "r")
16670 (parallel [(set (match_operand:SI 0 "register_operand" "")
16671 (match_operator:SI 3 "arith_or_logical_operator"
16673 (match_operand:SI 1 "memory_operand" "")]))
16674 (clobber (reg:CC FLAGS_REG))])]
16675 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16676 [(set (match_dup 2) (match_dup 1))
16677 (parallel [(set (match_dup 0)
16678 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16679 (clobber (reg:CC FLAGS_REG))])])
16682 [(match_scratch:SI 2 "r")
16683 (parallel [(set (match_operand:SI 0 "register_operand" "")
16684 (match_operator:SI 3 "arith_or_logical_operator"
16685 [(match_operand:SI 1 "memory_operand" "")
16687 (clobber (reg:CC FLAGS_REG))])]
16688 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
16689 [(set (match_dup 2) (match_dup 1))
16690 (parallel [(set (match_dup 0)
16691 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16692 (clobber (reg:CC FLAGS_REG))])])
16694 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
16695 ;; refers to the destination of the load!
16698 [(set (match_operand:SI 0 "register_operand" "")
16699 (match_operand:SI 1 "register_operand" ""))
16700 (parallel [(set (match_dup 0)
16701 (match_operator:SI 3 "commutative_operator"
16703 (match_operand:SI 2 "memory_operand" "")]))
16704 (clobber (reg:CC FLAGS_REG))])]
16705 "REGNO (operands[0]) != REGNO (operands[1])
16706 && GENERAL_REGNO_P (REGNO (operands[0]))
16707 && GENERAL_REGNO_P (REGNO (operands[1]))"
16708 [(set (match_dup 0) (match_dup 4))
16709 (parallel [(set (match_dup 0)
16710 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16711 (clobber (reg:CC FLAGS_REG))])]
16712 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
16715 [(set (match_operand 0 "register_operand" "")
16716 (match_operand 1 "register_operand" ""))
16718 (match_operator 3 "commutative_operator"
16720 (match_operand 2 "memory_operand" "")]))]
16721 "REGNO (operands[0]) != REGNO (operands[1])
16722 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
16723 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
16724 [(set (match_dup 0) (match_dup 2))
16726 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
16728 ; Don't do logical operations with memory outputs
16730 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16731 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
16732 ; the same decoder scheduling characteristics as the original.
16735 [(match_scratch:SI 2 "r")
16736 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16737 (match_operator:SI 3 "arith_or_logical_operator"
16739 (match_operand:SI 1 "nonmemory_operand" "")]))
16740 (clobber (reg:CC FLAGS_REG))])]
16741 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16742 /* Do not split stack checking probes. */
16743 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16744 [(set (match_dup 2) (match_dup 0))
16745 (parallel [(set (match_dup 2)
16746 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16747 (clobber (reg:CC FLAGS_REG))])
16748 (set (match_dup 0) (match_dup 2))])
16751 [(match_scratch:SI 2 "r")
16752 (parallel [(set (match_operand:SI 0 "memory_operand" "")
16753 (match_operator:SI 3 "arith_or_logical_operator"
16754 [(match_operand:SI 1 "nonmemory_operand" "")
16756 (clobber (reg:CC FLAGS_REG))])]
16757 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
16758 /* Do not split stack checking probes. */
16759 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16760 [(set (match_dup 2) (match_dup 0))
16761 (parallel [(set (match_dup 2)
16762 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16763 (clobber (reg:CC FLAGS_REG))])
16764 (set (match_dup 0) (match_dup 2))])
16766 ;; Attempt to always use XOR for zeroing registers.
16768 [(set (match_operand 0 "register_operand" "")
16769 (match_operand 1 "const0_operand" ""))]
16770 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
16771 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16772 && GENERAL_REG_P (operands[0])
16773 && peep2_regno_dead_p (0, FLAGS_REG)"
16774 [(parallel [(set (match_dup 0) (const_int 0))
16775 (clobber (reg:CC FLAGS_REG))])]
16776 "operands[0] = gen_lowpart (word_mode, operands[0]);")
16779 [(set (strict_low_part (match_operand 0 "register_operand" ""))
16781 "(GET_MODE (operands[0]) == QImode
16782 || GET_MODE (operands[0]) == HImode)
16783 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16784 && peep2_regno_dead_p (0, FLAGS_REG)"
16785 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
16786 (clobber (reg:CC FLAGS_REG))])])
16788 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
16790 [(set (match_operand:SWI248 0 "register_operand" "")
16792 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
16793 && peep2_regno_dead_p (0, FLAGS_REG)"
16794 [(parallel [(set (match_dup 0) (const_int -1))
16795 (clobber (reg:CC FLAGS_REG))])]
16797 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
16798 operands[0] = gen_lowpart (SImode, operands[0]);
16801 ;; Attempt to convert simple lea to add/shift.
16802 ;; These can be created by move expanders.
16805 [(set (match_operand:SWI48 0 "register_operand" "")
16806 (plus:SWI48 (match_dup 0)
16807 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
16808 "peep2_regno_dead_p (0, FLAGS_REG)"
16809 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
16810 (clobber (reg:CC FLAGS_REG))])])
16813 [(set (match_operand:SI 0 "register_operand" "")
16814 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
16815 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
16817 && peep2_regno_dead_p (0, FLAGS_REG)
16818 && REGNO (operands[0]) == REGNO (operands[1])"
16819 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
16820 (clobber (reg:CC FLAGS_REG))])]
16821 "operands[2] = gen_lowpart (SImode, operands[2]);")
16824 [(set (match_operand:SWI48 0 "register_operand" "")
16825 (mult:SWI48 (match_dup 0)
16826 (match_operand:SWI48 1 "const_int_operand" "")))]
16827 "exact_log2 (INTVAL (operands[1])) >= 0
16828 && peep2_regno_dead_p (0, FLAGS_REG)"
16829 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
16830 (clobber (reg:CC FLAGS_REG))])]
16831 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
16834 [(set (match_operand:SI 0 "register_operand" "")
16835 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
16836 (match_operand:DI 2 "const_int_operand" "")) 0))]
16838 && exact_log2 (INTVAL (operands[2])) >= 0
16839 && REGNO (operands[0]) == REGNO (operands[1])
16840 && peep2_regno_dead_p (0, FLAGS_REG)"
16841 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
16842 (clobber (reg:CC FLAGS_REG))])]
16843 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
16845 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
16846 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
16847 ;; On many CPUs it is also faster, since special hardware to avoid esp
16848 ;; dependencies is present.
16850 ;; While some of these conversions may be done using splitters, we use
16851 ;; peepholes in order to allow combine_stack_adjustments pass to see
16852 ;; nonobfuscated RTL.
16854 ;; Convert prologue esp subtractions to push.
16855 ;; We need register to push. In order to keep verify_flow_info happy we have
16857 ;; - use scratch and clobber it in order to avoid dependencies
16858 ;; - use already live register
16859 ;; We can't use the second way right now, since there is no reliable way how to
16860 ;; verify that given register is live. First choice will also most likely in
16861 ;; fewer dependencies. On the place of esp adjustments it is very likely that
16862 ;; call clobbered registers are dead. We may want to use base pointer as an
16863 ;; alternative when no register is available later.
16866 [(match_scratch:P 1 "r")
16867 (parallel [(set (reg:P SP_REG)
16868 (plus:P (reg:P SP_REG)
16869 (match_operand:P 0 "const_int_operand" "")))
16870 (clobber (reg:CC FLAGS_REG))
16871 (clobber (mem:BLK (scratch)))])]
16872 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16873 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
16874 [(clobber (match_dup 1))
16875 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16876 (clobber (mem:BLK (scratch)))])])
16879 [(match_scratch:P 1 "r")
16880 (parallel [(set (reg:P SP_REG)
16881 (plus:P (reg:P SP_REG)
16882 (match_operand:P 0 "const_int_operand" "")))
16883 (clobber (reg:CC FLAGS_REG))
16884 (clobber (mem:BLK (scratch)))])]
16885 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16886 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
16887 [(clobber (match_dup 1))
16888 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16889 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16890 (clobber (mem:BLK (scratch)))])])
16892 ;; Convert esp subtractions to push.
16894 [(match_scratch:P 1 "r")
16895 (parallel [(set (reg:P SP_REG)
16896 (plus:P (reg:P SP_REG)
16897 (match_operand:P 0 "const_int_operand" "")))
16898 (clobber (reg:CC FLAGS_REG))])]
16899 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16900 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
16901 [(clobber (match_dup 1))
16902 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
16905 [(match_scratch:P 1 "r")
16906 (parallel [(set (reg:P SP_REG)
16907 (plus:P (reg:P SP_REG)
16908 (match_operand:P 0 "const_int_operand" "")))
16909 (clobber (reg:CC FLAGS_REG))])]
16910 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16911 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
16912 [(clobber (match_dup 1))
16913 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16914 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
16916 ;; Convert epilogue deallocator to pop.
16918 [(match_scratch:P 1 "r")
16919 (parallel [(set (reg:P SP_REG)
16920 (plus:P (reg:P SP_REG)
16921 (match_operand:P 0 "const_int_operand" "")))
16922 (clobber (reg:CC FLAGS_REG))
16923 (clobber (mem:BLK (scratch)))])]
16924 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
16925 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
16926 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
16927 (clobber (mem:BLK (scratch)))])])
16929 ;; Two pops case is tricky, since pop causes dependency
16930 ;; on destination register. We use two registers if available.
16932 [(match_scratch:P 1 "r")
16933 (match_scratch:P 2 "r")
16934 (parallel [(set (reg:P SP_REG)
16935 (plus:P (reg:P SP_REG)
16936 (match_operand:P 0 "const_int_operand" "")))
16937 (clobber (reg:CC FLAGS_REG))
16938 (clobber (mem:BLK (scratch)))])]
16939 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
16940 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
16941 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
16942 (clobber (mem:BLK (scratch)))])
16943 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
16946 [(match_scratch:P 1 "r")
16947 (parallel [(set (reg:P SP_REG)
16948 (plus:P (reg:P SP_REG)
16949 (match_operand:P 0 "const_int_operand" "")))
16950 (clobber (reg:CC FLAGS_REG))
16951 (clobber (mem:BLK (scratch)))])]
16952 "optimize_insn_for_size_p ()
16953 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
16954 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
16955 (clobber (mem:BLK (scratch)))])
16956 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
16958 ;; Convert esp additions to pop.
16960 [(match_scratch:P 1 "r")
16961 (parallel [(set (reg:P SP_REG)
16962 (plus:P (reg:P SP_REG)
16963 (match_operand:P 0 "const_int_operand" "")))
16964 (clobber (reg:CC FLAGS_REG))])]
16965 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
16966 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
16968 ;; Two pops case is tricky, since pop causes dependency
16969 ;; on destination register. We use two registers if available.
16971 [(match_scratch:P 1 "r")
16972 (match_scratch:P 2 "r")
16973 (parallel [(set (reg:P SP_REG)
16974 (plus:P (reg:P SP_REG)
16975 (match_operand:P 0 "const_int_operand" "")))
16976 (clobber (reg:CC FLAGS_REG))])]
16977 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
16978 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
16979 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
16982 [(match_scratch:P 1 "r")
16983 (parallel [(set (reg:P SP_REG)
16984 (plus:P (reg:P SP_REG)
16985 (match_operand:P 0 "const_int_operand" "")))
16986 (clobber (reg:CC FLAGS_REG))])]
16987 "optimize_insn_for_size_p ()
16988 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
16989 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
16990 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
16992 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
16993 ;; required and register dies. Similarly for 128 to -128.
16995 [(set (match_operand 0 "flags_reg_operand" "")
16996 (match_operator 1 "compare_operator"
16997 [(match_operand 2 "register_operand" "")
16998 (match_operand 3 "const_int_operand" "")]))]
16999 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17000 && incdec_operand (operands[3], GET_MODE (operands[3])))
17001 || (!TARGET_FUSE_CMP_AND_BRANCH
17002 && INTVAL (operands[3]) == 128))
17003 && ix86_match_ccmode (insn, CCGCmode)
17004 && peep2_reg_dead_p (1, operands[2])"
17005 [(parallel [(set (match_dup 0)
17006 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17007 (clobber (match_dup 2))])])
17009 ;; Convert imul by three, five and nine into lea
17012 [(set (match_operand:SWI48 0 "register_operand" "")
17013 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17014 (match_operand:SWI48 2 "const_int_operand" "")))
17015 (clobber (reg:CC FLAGS_REG))])]
17016 "INTVAL (operands[2]) == 3
17017 || INTVAL (operands[2]) == 5
17018 || INTVAL (operands[2]) == 9"
17019 [(set (match_dup 0)
17020 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17022 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17026 [(set (match_operand:SWI48 0 "register_operand" "")
17027 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17028 (match_operand:SWI48 2 "const_int_operand" "")))
17029 (clobber (reg:CC FLAGS_REG))])]
17030 "optimize_insn_for_speed_p ()
17031 && (INTVAL (operands[2]) == 3
17032 || INTVAL (operands[2]) == 5
17033 || INTVAL (operands[2]) == 9)"
17034 [(set (match_dup 0) (match_dup 1))
17036 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17038 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17040 ;; imul $32bit_imm, mem, reg is vector decoded, while
17041 ;; imul $32bit_imm, reg, reg is direct decoded.
17043 [(match_scratch:SWI48 3 "r")
17044 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17045 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17046 (match_operand:SWI48 2 "immediate_operand" "")))
17047 (clobber (reg:CC FLAGS_REG))])]
17048 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17049 && !satisfies_constraint_K (operands[2])"
17050 [(set (match_dup 3) (match_dup 1))
17051 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17052 (clobber (reg:CC FLAGS_REG))])])
17055 [(match_scratch:SI 3 "r")
17056 (parallel [(set (match_operand:DI 0 "register_operand" "")
17058 (mult:SI (match_operand:SI 1 "memory_operand" "")
17059 (match_operand:SI 2 "immediate_operand" ""))))
17060 (clobber (reg:CC FLAGS_REG))])]
17062 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17063 && !satisfies_constraint_K (operands[2])"
17064 [(set (match_dup 3) (match_dup 1))
17065 (parallel [(set (match_dup 0)
17066 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17067 (clobber (reg:CC FLAGS_REG))])])
17069 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17070 ;; Convert it into imul reg, reg
17071 ;; It would be better to force assembler to encode instruction using long
17072 ;; immediate, but there is apparently no way to do so.
17074 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17076 (match_operand:SWI248 1 "nonimmediate_operand" "")
17077 (match_operand:SWI248 2 "const_int_operand" "")))
17078 (clobber (reg:CC FLAGS_REG))])
17079 (match_scratch:SWI248 3 "r")]
17080 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17081 && satisfies_constraint_K (operands[2])"
17082 [(set (match_dup 3) (match_dup 2))
17083 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17084 (clobber (reg:CC FLAGS_REG))])]
17086 if (!rtx_equal_p (operands[0], operands[1]))
17087 emit_move_insn (operands[0], operands[1]);
17090 ;; After splitting up read-modify operations, array accesses with memory
17091 ;; operands might end up in form:
17093 ;; movl 4(%esp), %edx
17095 ;; instead of pre-splitting:
17097 ;; addl 4(%esp), %eax
17099 ;; movl 4(%esp), %edx
17100 ;; leal (%edx,%eax,4), %eax
17103 [(match_scratch:P 5 "r")
17104 (parallel [(set (match_operand 0 "register_operand" "")
17105 (ashift (match_operand 1 "register_operand" "")
17106 (match_operand 2 "const_int_operand" "")))
17107 (clobber (reg:CC FLAGS_REG))])
17108 (parallel [(set (match_operand 3 "register_operand" "")
17109 (plus (match_dup 0)
17110 (match_operand 4 "x86_64_general_operand" "")))
17111 (clobber (reg:CC FLAGS_REG))])]
17112 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
17113 /* Validate MODE for lea. */
17114 && ((!TARGET_PARTIAL_REG_STALL
17115 && (GET_MODE (operands[0]) == QImode
17116 || GET_MODE (operands[0]) == HImode))
17117 || GET_MODE (operands[0]) == SImode
17118 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17119 && (rtx_equal_p (operands[0], operands[3])
17120 || peep2_reg_dead_p (2, operands[0]))
17121 /* We reorder load and the shift. */
17122 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17123 [(set (match_dup 5) (match_dup 4))
17124 (set (match_dup 0) (match_dup 1))]
17126 enum machine_mode mode = GET_MODE (operands[1]) == DImode ? DImode : SImode;
17127 int scale = 1 << INTVAL (operands[2]);
17128 rtx index = gen_lowpart (Pmode, operands[1]);
17129 rtx base = gen_lowpart (Pmode, operands[5]);
17130 rtx dest = gen_lowpart (mode, operands[3]);
17132 operands[1] = gen_rtx_PLUS (Pmode, base,
17133 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17134 operands[5] = base;
17137 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17138 operands[5] = gen_rtx_SUBREG (mode, operands[5], 0);
17140 operands[0] = dest;
17143 ;; Call-value patterns last so that the wildcard operand does not
17144 ;; disrupt insn-recog's switch tables.
17146 (define_insn "*call_value_pop_0"
17147 [(set (match_operand 0 "" "")
17148 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17149 (match_operand:SI 2 "" "")))
17150 (set (reg:SI SP_REG)
17151 (plus:SI (reg:SI SP_REG)
17152 (match_operand:SI 3 "immediate_operand" "")))]
17155 if (SIBLING_CALL_P (insn))
17158 return "call\t%P1";
17160 [(set_attr "type" "callv")])
17162 (define_insn "*call_value_pop_1"
17163 [(set (match_operand 0 "" "")
17164 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17165 (match_operand:SI 2 "" "")))
17166 (set (reg:SI SP_REG)
17167 (plus:SI (reg:SI SP_REG)
17168 (match_operand:SI 3 "immediate_operand" "i")))]
17169 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17171 if (constant_call_address_operand (operands[1], Pmode))
17172 return "call\t%P1";
17173 return "call\t%A1";
17175 [(set_attr "type" "callv")])
17177 (define_insn "*sibcall_value_pop_1"
17178 [(set (match_operand 0 "" "")
17179 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17180 (match_operand:SI 2 "" "")))
17181 (set (reg:SI SP_REG)
17182 (plus:SI (reg:SI SP_REG)
17183 (match_operand:SI 3 "immediate_operand" "i,i")))]
17184 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17188 [(set_attr "type" "callv")])
17190 (define_insn "*call_value_0"
17191 [(set (match_operand 0 "" "")
17192 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
17193 (match_operand:SI 2 "" "")))]
17196 if (SIBLING_CALL_P (insn))
17199 return "call\t%P1";
17201 [(set_attr "type" "callv")])
17203 (define_insn "*call_value_0_rex64"
17204 [(set (match_operand 0 "" "")
17205 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17206 (match_operand:DI 2 "const_int_operand" "")))]
17209 if (SIBLING_CALL_P (insn))
17212 return "call\t%P1";
17214 [(set_attr "type" "callv")])
17216 (define_insn "*call_value_0_rex64_ms_sysv"
17217 [(set (match_operand 0 "" "")
17218 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
17219 (match_operand:DI 2 "const_int_operand" "")))
17220 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17221 (clobber (reg:TI XMM6_REG))
17222 (clobber (reg:TI XMM7_REG))
17223 (clobber (reg:TI XMM8_REG))
17224 (clobber (reg:TI XMM9_REG))
17225 (clobber (reg:TI XMM10_REG))
17226 (clobber (reg:TI XMM11_REG))
17227 (clobber (reg:TI XMM12_REG))
17228 (clobber (reg:TI XMM13_REG))
17229 (clobber (reg:TI XMM14_REG))
17230 (clobber (reg:TI XMM15_REG))
17231 (clobber (reg:DI SI_REG))
17232 (clobber (reg:DI DI_REG))]
17233 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17235 if (SIBLING_CALL_P (insn))
17238 return "call\t%P1";
17240 [(set_attr "type" "callv")])
17242 (define_insn "*call_value_1"
17243 [(set (match_operand 0 "" "")
17244 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
17245 (match_operand:SI 2 "" "")))]
17246 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
17248 if (constant_call_address_operand (operands[1], Pmode))
17249 return "call\t%P1";
17250 return "call\t%A1";
17252 [(set_attr "type" "callv")])
17254 (define_insn "*sibcall_value_1"
17255 [(set (match_operand 0 "" "")
17256 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
17257 (match_operand:SI 2 "" "")))]
17258 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
17262 [(set_attr "type" "callv")])
17264 (define_insn "*call_value_1_rex64"
17265 [(set (match_operand 0 "" "")
17266 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17267 (match_operand:DI 2 "" "")))]
17268 "TARGET_64BIT && !SIBLING_CALL_P (insn)
17269 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
17271 if (constant_call_address_operand (operands[1], Pmode))
17272 return "call\t%P1";
17273 return "call\t%A1";
17275 [(set_attr "type" "callv")])
17277 (define_insn "*call_value_1_rex64_ms_sysv"
17278 [(set (match_operand 0 "" "")
17279 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
17280 (match_operand:DI 2 "" "")))
17281 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
17282 (clobber (reg:TI XMM6_REG))
17283 (clobber (reg:TI XMM7_REG))
17284 (clobber (reg:TI XMM8_REG))
17285 (clobber (reg:TI XMM9_REG))
17286 (clobber (reg:TI XMM10_REG))
17287 (clobber (reg:TI XMM11_REG))
17288 (clobber (reg:TI XMM12_REG))
17289 (clobber (reg:TI XMM13_REG))
17290 (clobber (reg:TI XMM14_REG))
17291 (clobber (reg:TI XMM15_REG))
17292 (clobber (reg:DI SI_REG))
17293 (clobber (reg:DI DI_REG))]
17294 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17296 if (constant_call_address_operand (operands[1], Pmode))
17297 return "call\t%P1";
17298 return "call\t%A1";
17300 [(set_attr "type" "callv")])
17302 (define_insn "*call_value_1_rex64_large"
17303 [(set (match_operand 0 "" "")
17304 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
17305 (match_operand:DI 2 "" "")))]
17306 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
17308 [(set_attr "type" "callv")])
17310 (define_insn "*sibcall_value_1_rex64"
17311 [(set (match_operand 0 "" "")
17312 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
17313 (match_operand:DI 2 "" "")))]
17314 "TARGET_64BIT && SIBLING_CALL_P (insn)"
17318 [(set_attr "type" "callv")])
17320 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17321 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17322 ;; caught for use by garbage collectors and the like. Using an insn that
17323 ;; maps to SIGILL makes it more likely the program will rightfully die.
17324 ;; Keeping with tradition, "6" is in honor of #UD.
17325 (define_insn "trap"
17326 [(trap_if (const_int 1) (const_int 6))]
17328 { return ASM_SHORT "0x0b0f"; }
17329 [(set_attr "length" "2")])
17331 (define_expand "prefetch"
17332 [(prefetch (match_operand 0 "address_operand" "")
17333 (match_operand:SI 1 "const_int_operand" "")
17334 (match_operand:SI 2 "const_int_operand" ""))]
17335 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17337 int rw = INTVAL (operands[1]);
17338 int locality = INTVAL (operands[2]);
17340 gcc_assert (rw == 0 || rw == 1);
17341 gcc_assert (locality >= 0 && locality <= 3);
17342 gcc_assert (GET_MODE (operands[0]) == Pmode
17343 || GET_MODE (operands[0]) == VOIDmode);
17345 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17346 supported by SSE counterpart or the SSE prefetch is not available
17347 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17349 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17350 operands[2] = GEN_INT (3);
17352 operands[1] = const0_rtx;
17355 (define_insn "*prefetch_sse_<mode>"
17356 [(prefetch (match_operand:P 0 "address_operand" "p")
17358 (match_operand:SI 1 "const_int_operand" ""))]
17359 "TARGET_PREFETCH_SSE"
17361 static const char * const patterns[4] = {
17362 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17365 int locality = INTVAL (operands[1]);
17366 gcc_assert (locality >= 0 && locality <= 3);
17368 return patterns[locality];
17370 [(set_attr "type" "sse")
17371 (set_attr "atom_sse_attr" "prefetch")
17372 (set (attr "length_address")
17373 (symbol_ref "memory_address_length (operands[0])"))
17374 (set_attr "memory" "none")])
17376 (define_insn "*prefetch_3dnow_<mode>"
17377 [(prefetch (match_operand:P 0 "address_operand" "p")
17378 (match_operand:SI 1 "const_int_operand" "n")
17382 if (INTVAL (operands[1]) == 0)
17383 return "prefetch\t%a0";
17385 return "prefetchw\t%a0";
17387 [(set_attr "type" "mmx")
17388 (set (attr "length_address")
17389 (symbol_ref "memory_address_length (operands[0])"))
17390 (set_attr "memory" "none")])
17392 (define_expand "stack_protect_set"
17393 [(match_operand 0 "memory_operand" "")
17394 (match_operand 1 "memory_operand" "")]
17397 rtx (*insn)(rtx, rtx);
17399 #ifdef TARGET_THREAD_SSP_OFFSET
17400 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17401 insn = (TARGET_64BIT
17402 ? gen_stack_tls_protect_set_di
17403 : gen_stack_tls_protect_set_si);
17405 insn = (TARGET_64BIT
17406 ? gen_stack_protect_set_di
17407 : gen_stack_protect_set_si);
17410 emit_insn (insn (operands[0], operands[1]));
17414 (define_insn "stack_protect_set_<mode>"
17415 [(set (match_operand:P 0 "memory_operand" "=m")
17416 (unspec:P [(match_operand:P 1 "memory_operand" "m")] UNSPEC_SP_SET))
17417 (set (match_scratch:P 2 "=&r") (const_int 0))
17418 (clobber (reg:CC FLAGS_REG))]
17420 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17421 [(set_attr "type" "multi")])
17423 (define_insn "stack_tls_protect_set_<mode>"
17424 [(set (match_operand:P 0 "memory_operand" "=m")
17425 (unspec:P [(match_operand:P 1 "const_int_operand" "i")]
17426 UNSPEC_SP_TLS_SET))
17427 (set (match_scratch:P 2 "=&r") (const_int 0))
17428 (clobber (reg:CC FLAGS_REG))]
17430 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17431 [(set_attr "type" "multi")])
17433 (define_expand "stack_protect_test"
17434 [(match_operand 0 "memory_operand" "")
17435 (match_operand 1 "memory_operand" "")
17436 (match_operand 2 "" "")]
17439 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17441 rtx (*insn)(rtx, rtx, rtx);
17443 #ifdef TARGET_THREAD_SSP_OFFSET
17444 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17445 insn = (TARGET_64BIT
17446 ? gen_stack_tls_protect_test_di
17447 : gen_stack_tls_protect_test_si);
17449 insn = (TARGET_64BIT
17450 ? gen_stack_protect_test_di
17451 : gen_stack_protect_test_si);
17454 emit_insn (insn (flags, operands[0], operands[1]));
17456 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17457 flags, const0_rtx, operands[2]));
17461 (define_insn "stack_protect_test_<mode>"
17462 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17463 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17464 (match_operand:P 2 "memory_operand" "m")]
17466 (clobber (match_scratch:P 3 "=&r"))]
17468 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17469 [(set_attr "type" "multi")])
17471 (define_insn "stack_tls_protect_test_<mode>"
17472 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17473 (unspec:CCZ [(match_operand:P 1 "memory_operand" "m")
17474 (match_operand:P 2 "const_int_operand" "i")]
17475 UNSPEC_SP_TLS_TEST))
17476 (clobber (match_scratch:P 3 "=r"))]
17478 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17479 [(set_attr "type" "multi")])
17481 (define_insn "sse4_2_crc32<mode>"
17482 [(set (match_operand:SI 0 "register_operand" "=r")
17484 [(match_operand:SI 1 "register_operand" "0")
17485 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17487 "TARGET_SSE4_2 || TARGET_CRC32"
17488 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17489 [(set_attr "type" "sselog1")
17490 (set_attr "prefix_rep" "1")
17491 (set_attr "prefix_extra" "1")
17492 (set (attr "prefix_data16")
17493 (if_then_else (match_operand:HI 2 "" "")
17495 (const_string "*")))
17496 (set (attr "prefix_rex")
17497 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17499 (const_string "*")))
17500 (set_attr "mode" "SI")])
17502 (define_insn "sse4_2_crc32di"
17503 [(set (match_operand:DI 0 "register_operand" "=r")
17505 [(match_operand:DI 1 "register_operand" "0")
17506 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17508 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17509 "crc32{q}\t{%2, %0|%0, %2}"
17510 [(set_attr "type" "sselog1")
17511 (set_attr "prefix_rep" "1")
17512 (set_attr "prefix_extra" "1")
17513 (set_attr "mode" "DI")])
17515 (define_expand "rdpmc"
17516 [(match_operand:DI 0 "register_operand" "")
17517 (match_operand:SI 1 "register_operand" "")]
17520 rtx reg = gen_reg_rtx (DImode);
17523 /* Force operand 1 into ECX. */
17524 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17525 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17526 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17531 rtvec vec = rtvec_alloc (2);
17532 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17533 rtx upper = gen_reg_rtx (DImode);
17534 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17535 gen_rtvec (1, const0_rtx),
17537 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17538 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17540 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17541 NULL, 1, OPTAB_DIRECT);
17542 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17546 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17547 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17551 (define_insn "*rdpmc"
17552 [(set (match_operand:DI 0 "register_operand" "=A")
17553 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17557 [(set_attr "type" "other")
17558 (set_attr "length" "2")])
17560 (define_insn "*rdpmc_rex64"
17561 [(set (match_operand:DI 0 "register_operand" "=a")
17562 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17564 (set (match_operand:DI 1 "register_operand" "=d")
17565 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17568 [(set_attr "type" "other")
17569 (set_attr "length" "2")])
17571 (define_expand "rdtsc"
17572 [(set (match_operand:DI 0 "register_operand" "")
17573 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17578 rtvec vec = rtvec_alloc (2);
17579 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17580 rtx upper = gen_reg_rtx (DImode);
17581 rtx lower = gen_reg_rtx (DImode);
17582 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17583 gen_rtvec (1, const0_rtx),
17585 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17586 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17588 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17589 NULL, 1, OPTAB_DIRECT);
17590 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17592 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17597 (define_insn "*rdtsc"
17598 [(set (match_operand:DI 0 "register_operand" "=A")
17599 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17602 [(set_attr "type" "other")
17603 (set_attr "length" "2")])
17605 (define_insn "*rdtsc_rex64"
17606 [(set (match_operand:DI 0 "register_operand" "=a")
17607 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17608 (set (match_operand:DI 1 "register_operand" "=d")
17609 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17612 [(set_attr "type" "other")
17613 (set_attr "length" "2")])
17615 (define_expand "rdtscp"
17616 [(match_operand:DI 0 "register_operand" "")
17617 (match_operand:SI 1 "memory_operand" "")]
17620 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17621 gen_rtvec (1, const0_rtx),
17623 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17624 gen_rtvec (1, const0_rtx),
17626 rtx reg = gen_reg_rtx (DImode);
17627 rtx tmp = gen_reg_rtx (SImode);
17631 rtvec vec = rtvec_alloc (3);
17632 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17633 rtx upper = gen_reg_rtx (DImode);
17634 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17635 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17636 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17638 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17639 NULL, 1, OPTAB_DIRECT);
17640 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17645 rtvec vec = rtvec_alloc (2);
17646 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17647 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17648 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17651 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17652 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17656 (define_insn "*rdtscp"
17657 [(set (match_operand:DI 0 "register_operand" "=A")
17658 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17659 (set (match_operand:SI 1 "register_operand" "=c")
17660 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17663 [(set_attr "type" "other")
17664 (set_attr "length" "3")])
17666 (define_insn "*rdtscp_rex64"
17667 [(set (match_operand:DI 0 "register_operand" "=a")
17668 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17669 (set (match_operand:DI 1 "register_operand" "=d")
17670 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17671 (set (match_operand:SI 2 "register_operand" "=c")
17672 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17675 [(set_attr "type" "other")
17676 (set_attr "length" "3")])
17678 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17680 ;; LWP instructions
17682 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17684 (define_expand "lwp_llwpcb"
17685 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17686 UNSPECV_LLWP_INTRINSIC)]
17689 (define_insn "*lwp_llwpcb<mode>1"
17690 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17691 UNSPECV_LLWP_INTRINSIC)]
17694 [(set_attr "type" "lwp")
17695 (set_attr "mode" "<MODE>")
17696 (set_attr "length" "5")])
17698 (define_expand "lwp_slwpcb"
17699 [(set (match_operand 0 "register_operand" "=r")
17700 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17704 emit_insn (gen_lwp_slwpcbdi (operands[0]));
17706 emit_insn (gen_lwp_slwpcbsi (operands[0]));
17710 (define_insn "lwp_slwpcb<mode>"
17711 [(set (match_operand:P 0 "register_operand" "=r")
17712 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17715 [(set_attr "type" "lwp")
17716 (set_attr "mode" "<MODE>")
17717 (set_attr "length" "5")])
17719 (define_expand "lwp_lwpval<mode>3"
17720 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
17721 (match_operand:SI 2 "nonimmediate_operand" "rm")
17722 (match_operand:SI 3 "const_int_operand" "i")]
17723 UNSPECV_LWPVAL_INTRINSIC)]
17725 "/* Avoid unused variable warning. */
17728 (define_insn "*lwp_lwpval<mode>3_1"
17729 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
17730 (match_operand:SI 1 "nonimmediate_operand" "rm")
17731 (match_operand:SI 2 "const_int_operand" "i")]
17732 UNSPECV_LWPVAL_INTRINSIC)]
17734 "lwpval\t{%2, %1, %0|%0, %1, %2}"
17735 [(set_attr "type" "lwp")
17736 (set_attr "mode" "<MODE>")
17737 (set (attr "length")
17738 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17740 (define_expand "lwp_lwpins<mode>3"
17741 [(set (reg:CCC FLAGS_REG)
17742 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
17743 (match_operand:SI 2 "nonimmediate_operand" "rm")
17744 (match_operand:SI 3 "const_int_operand" "i")]
17745 UNSPECV_LWPINS_INTRINSIC))
17746 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
17747 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
17750 (define_insn "*lwp_lwpins<mode>3_1"
17751 [(set (reg:CCC FLAGS_REG)
17752 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
17753 (match_operand:SI 1 "nonimmediate_operand" "rm")
17754 (match_operand:SI 2 "const_int_operand" "i")]
17755 UNSPECV_LWPINS_INTRINSIC))]
17757 "lwpins\t{%2, %1, %0|%0, %1, %2}"
17758 [(set_attr "type" "lwp")
17759 (set_attr "mode" "<MODE>")
17760 (set (attr "length")
17761 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17763 (define_insn "rdfsbase<mode>"
17764 [(set (match_operand:SWI48 0 "register_operand" "=r")
17765 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
17766 "TARGET_64BIT && TARGET_FSGSBASE"
17768 [(set_attr "type" "other")
17769 (set_attr "prefix_extra" "2")])
17771 (define_insn "rdgsbase<mode>"
17772 [(set (match_operand:SWI48 0 "register_operand" "=r")
17773 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
17774 "TARGET_64BIT && TARGET_FSGSBASE"
17776 [(set_attr "type" "other")
17777 (set_attr "prefix_extra" "2")])
17779 (define_insn "wrfsbase<mode>"
17780 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17782 "TARGET_64BIT && TARGET_FSGSBASE"
17784 [(set_attr "type" "other")
17785 (set_attr "prefix_extra" "2")])
17787 (define_insn "wrgsbase<mode>"
17788 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17790 "TARGET_64BIT && TARGET_FSGSBASE"
17792 [(set_attr "type" "other")
17793 (set_attr "prefix_extra" "2")])
17795 (define_expand "rdrand<mode>"
17796 [(set (match_operand:SWI248 0 "register_operand" "=r")
17797 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))]
17800 rtx retry_label, insn, ccc;
17802 retry_label = gen_label_rtx ();
17804 emit_label (retry_label);
17806 /* Generate rdrand. */
17807 emit_insn (gen_rdrand<mode>_1 (operands[0]));
17809 /* Retry if the carry flag isn't valid. */
17810 ccc = gen_rtx_REG (CCCmode, FLAGS_REG);
17811 ccc = gen_rtx_EQ (VOIDmode, ccc, const0_rtx);
17812 ccc = gen_rtx_IF_THEN_ELSE (VOIDmode, ccc, pc_rtx,
17813 gen_rtx_LABEL_REF (VOIDmode, retry_label));
17814 insn = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, ccc));
17815 JUMP_LABEL (insn) = retry_label;
17820 (define_insn "rdrand<mode>_1"
17821 [(set (match_operand:SWI248 0 "register_operand" "=r")
17822 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))]
17825 [(set_attr "type" "other")
17826 (set_attr "prefix_extra" "1")])
17830 (include "sync.md")