1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2013 Free Software Foundation, Inc.
3 ;; Mostly by William Schelter.
4 ;; x86_64 support added by Jan Hubicka
6 ;; This file is part of GCC.
8 ;; GCC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; GCC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING3. If not see
20 ;; <http://www.gnu.org/licenses/>. */
22 ;; The original PO technology requires these to be ordered by speed,
23 ;; so that assigner will pick the fastest.
25 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
27 ;; The special asm out single letter directives following a '%' are:
28 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
29 ;; C -- print opcode suffix for set/cmov insn.
30 ;; c -- like C, but print reversed condition
31 ;; F,f -- likewise, but for floating-point.
32 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
34 ;; R -- print the prefix for register names.
35 ;; z -- print the opcode suffix for the size of the current operand.
36 ;; Z -- likewise, with special suffixes for x87 instructions.
37 ;; * -- print a star (in certain assembler syntax)
38 ;; A -- print an absolute memory reference.
39 ;; E -- print address with DImode register names if TARGET_64BIT.
40 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
41 ;; s -- print a shift double count, followed by the assemblers argument
43 ;; b -- print the QImode name of the register for the indicated operand.
44 ;; %b0 would print %al if operands[0] is reg 0.
45 ;; w -- likewise, print the HImode name of the register.
46 ;; k -- likewise, print the SImode name of the register.
47 ;; q -- likewise, print the DImode name of the register.
48 ;; x -- likewise, print the V4SFmode name of the register.
49 ;; t -- likewise, print the V8SFmode name of the register.
50 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
51 ;; y -- print "st(0)" instead of "st" as a register.
52 ;; d -- print duplicated register operand for AVX instruction.
53 ;; D -- print condition for SSE cmp instruction.
54 ;; P -- if PIC, print an @PLT suffix.
55 ;; p -- print raw symbol name.
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 ;; K -- print HLE lock prefix
60 ;; Y -- print condition for XOP pcom* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
63 ;; ~ -- print "i" if TARGET_AVX2, "f" otherwise.
64 ;; @ -- print a segment register of thread base pointer load
65 ;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
67 (define_c_enum "unspec" [
68 ;; Relocation specifiers
79 UNSPEC_MACHOPIC_OFFSET
87 UNSPEC_MEMORY_BLOCKAGE
97 ;; Other random patterns
106 UNSPEC_LD_MPIC ; load_macho_picbase
108 UNSPEC_DIV_ALREADY_SPLIT
109 UNSPEC_MS_TO_SYSV_CALL
115 ;; For SSE/MMX support:
123 ;; Generic math support
125 UNSPEC_IEEE_MIN ; not commutative
126 UNSPEC_IEEE_MAX ; not commutative
128 ;; x87 Floating point
144 UNSPEC_FRNDINT_MASK_PM
148 ;; x87 Double output FP
183 (define_c_enum "unspecv" [
186 UNSPECV_PROBE_STACK_RANGE
189 UNSPECV_SPLIT_STACK_RETURN
195 UNSPECV_LLWP_INTRINSIC
196 UNSPECV_SLWP_INTRINSIC
197 UNSPECV_LWPVAL_INTRINSIC
198 UNSPECV_LWPINS_INTRINSIC
214 ;; For RDRAND support
217 ;; For RDSEED support
227 ;; Constants to represent rounding modes in the ROUND instruction
236 ;; Constants to represent pcomtrue/pcomfalse variants
246 ;; Constants used in the XOP pperm instruction
248 [(PPERM_SRC 0x00) /* copy source */
249 (PPERM_INVERT 0x20) /* invert source */
250 (PPERM_REVERSE 0x40) /* bit reverse source */
251 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
252 (PPERM_ZERO 0x80) /* all 0's */
253 (PPERM_ONES 0xa0) /* all 1's */
254 (PPERM_SIGN 0xc0) /* propagate sign bit */
255 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
256 (PPERM_SRC1 0x00) /* use first source byte */
257 (PPERM_SRC2 0x10) /* use second source byte */
260 ;; Registers by name.
315 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
318 ;; In C guard expressions, put expressions which may be compile-time
319 ;; constants first. This allows for better optimization. For
320 ;; example, write "TARGET_64BIT && reload_completed", not
321 ;; "reload_completed && TARGET_64BIT".
325 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
326 atom,slm,generic64,amdfam10,bdver1,bdver2,bdver3,btver1,btver2"
327 (const (symbol_ref "ix86_schedule")))
329 ;; A basic instruction type. Refinements due to arguments to be
330 ;; provided in other attributes.
333 alu,alu1,negnot,imov,imovx,lea,
334 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,
335 imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
336 push,pop,call,callv,leave,
338 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
339 fxch,fistp,fisttp,frndint,
340 sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
341 ssemul,sseimul,ssediv,sselog,sselog1,
342 sseishft,sseishft1,ssecmp,ssecomi,
343 ssecvt,ssecvt1,sseicvt,sseins,
344 sseshuf,sseshuf1,ssemuladd,sse4arg,
346 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
347 (const_string "other"))
349 ;; Main data type used by the insn
351 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
352 (const_string "unknown"))
354 ;; The CPU unit operations uses.
355 (define_attr "unit" "integer,i387,sse,mmx,unknown"
356 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
357 fxch,fistp,fisttp,frndint")
358 (const_string "i387")
359 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
360 ssemul,sseimul,ssediv,sselog,sselog1,
361 sseishft,sseishft1,ssecmp,ssecomi,
362 ssecvt,ssecvt1,sseicvt,sseins,
363 sseshuf,sseshuf1,ssemuladd,sse4arg")
365 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
367 (eq_attr "type" "other")
368 (const_string "unknown")]
369 (const_string "integer")))
371 ;; The (bounding maximum) length of an instruction immediate.
372 (define_attr "length_immediate" ""
373 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
376 (eq_attr "unit" "i387,sse,mmx")
378 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
379 rotate,rotatex,rotate1,imul,icmp,push,pop")
380 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
381 (eq_attr "type" "imov,test")
382 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
383 (eq_attr "type" "call")
384 (if_then_else (match_operand 0 "constant_call_address_operand")
387 (eq_attr "type" "callv")
388 (if_then_else (match_operand 1 "constant_call_address_operand")
391 ;; We don't know the size before shorten_branches. Expect
392 ;; the instruction to fit for better scheduling.
393 (eq_attr "type" "ibr")
396 (symbol_ref "/* Update immediate_length and other attributes! */
397 gcc_unreachable (),1")))
399 ;; The (bounding maximum) length of an instruction address.
400 (define_attr "length_address" ""
401 (cond [(eq_attr "type" "str,other,multi,fxch")
403 (and (eq_attr "type" "call")
404 (match_operand 0 "constant_call_address_operand"))
406 (and (eq_attr "type" "callv")
407 (match_operand 1 "constant_call_address_operand"))
410 (symbol_ref "ix86_attr_length_address_default (insn)")))
412 ;; Set when length prefix is used.
413 (define_attr "prefix_data16" ""
414 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
416 (eq_attr "mode" "HI")
418 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
423 ;; Set when string REP prefix is used.
424 (define_attr "prefix_rep" ""
425 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
427 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
432 ;; Set when 0f opcode prefix is used.
433 (define_attr "prefix_0f" ""
435 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
436 (eq_attr "unit" "sse,mmx"))
440 ;; Set when REX opcode prefix is used.
441 (define_attr "prefix_rex" ""
442 (cond [(not (match_test "TARGET_64BIT"))
444 (and (eq_attr "mode" "DI")
445 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
446 (eq_attr "unit" "!mmx")))
448 (and (eq_attr "mode" "QI")
449 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
451 (match_test "x86_extended_reg_mentioned_p (insn)")
453 (and (eq_attr "type" "imovx")
454 (match_operand:QI 1 "ext_QIreg_operand"))
459 ;; There are also additional prefixes in 3DNOW, SSSE3.
460 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
461 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
462 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
463 (define_attr "prefix_extra" ""
464 (cond [(eq_attr "type" "ssemuladd,sse4arg")
466 (eq_attr "type" "sseiadd1,ssecvt1")
471 ;; Prefix used: original, VEX or maybe VEX.
472 (define_attr "prefix" "orig,vex,maybe_vex"
473 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
475 (const_string "orig")))
477 ;; VEX W bit is used.
478 (define_attr "prefix_vex_w" "" (const_int 0))
480 ;; The length of VEX prefix
481 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
482 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
483 ;; still prefix_0f 1, with prefix_extra 1.
484 (define_attr "length_vex" ""
485 (if_then_else (and (eq_attr "prefix_0f" "1")
486 (eq_attr "prefix_extra" "0"))
487 (if_then_else (eq_attr "prefix_vex_w" "1")
488 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
489 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
490 (if_then_else (eq_attr "prefix_vex_w" "1")
491 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
492 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
494 ;; Set when modrm byte is used.
495 (define_attr "modrm" ""
496 (cond [(eq_attr "type" "str,leave")
498 (eq_attr "unit" "i387")
500 (and (eq_attr "type" "incdec")
501 (and (not (match_test "TARGET_64BIT"))
502 (ior (match_operand:SI 1 "register_operand")
503 (match_operand:HI 1 "register_operand"))))
505 (and (eq_attr "type" "push")
506 (not (match_operand 1 "memory_operand")))
508 (and (eq_attr "type" "pop")
509 (not (match_operand 0 "memory_operand")))
511 (and (eq_attr "type" "imov")
512 (and (not (eq_attr "mode" "DI"))
513 (ior (and (match_operand 0 "register_operand")
514 (match_operand 1 "immediate_operand"))
515 (ior (and (match_operand 0 "ax_reg_operand")
516 (match_operand 1 "memory_displacement_only_operand"))
517 (and (match_operand 0 "memory_displacement_only_operand")
518 (match_operand 1 "ax_reg_operand"))))))
520 (and (eq_attr "type" "call")
521 (match_operand 0 "constant_call_address_operand"))
523 (and (eq_attr "type" "callv")
524 (match_operand 1 "constant_call_address_operand"))
526 (and (eq_attr "type" "alu,alu1,icmp,test")
527 (match_operand 0 "ax_reg_operand"))
528 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
532 ;; The (bounding maximum) length of an instruction in bytes.
533 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
534 ;; Later we may want to split them and compute proper length as for
536 (define_attr "length" ""
537 (cond [(eq_attr "type" "other,multi,fistp,frndint")
539 (eq_attr "type" "fcmp")
541 (eq_attr "unit" "i387")
543 (plus (attr "prefix_data16")
544 (attr "length_address")))
545 (ior (eq_attr "prefix" "vex")
546 (and (eq_attr "prefix" "maybe_vex")
547 (match_test "TARGET_AVX")))
548 (plus (attr "length_vex")
549 (plus (attr "length_immediate")
551 (attr "length_address"))))]
552 (plus (plus (attr "modrm")
553 (plus (attr "prefix_0f")
554 (plus (attr "prefix_rex")
555 (plus (attr "prefix_extra")
557 (plus (attr "prefix_rep")
558 (plus (attr "prefix_data16")
559 (plus (attr "length_immediate")
560 (attr "length_address")))))))
562 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
563 ;; `store' if there is a simple memory reference therein, or `unknown'
564 ;; if the instruction is complex.
566 (define_attr "memory" "none,load,store,both,unknown"
567 (cond [(eq_attr "type" "other,multi,str,lwp")
568 (const_string "unknown")
569 (eq_attr "type" "lea,fcmov,fpspc")
570 (const_string "none")
571 (eq_attr "type" "fistp,leave")
572 (const_string "both")
573 (eq_attr "type" "frndint")
574 (const_string "load")
575 (eq_attr "type" "push")
576 (if_then_else (match_operand 1 "memory_operand")
577 (const_string "both")
578 (const_string "store"))
579 (eq_attr "type" "pop")
580 (if_then_else (match_operand 0 "memory_operand")
581 (const_string "both")
582 (const_string "load"))
583 (eq_attr "type" "setcc")
584 (if_then_else (match_operand 0 "memory_operand")
585 (const_string "store")
586 (const_string "none"))
587 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
588 (if_then_else (ior (match_operand 0 "memory_operand")
589 (match_operand 1 "memory_operand"))
590 (const_string "load")
591 (const_string "none"))
592 (eq_attr "type" "ibr")
593 (if_then_else (match_operand 0 "memory_operand")
594 (const_string "load")
595 (const_string "none"))
596 (eq_attr "type" "call")
597 (if_then_else (match_operand 0 "constant_call_address_operand")
598 (const_string "none")
599 (const_string "load"))
600 (eq_attr "type" "callv")
601 (if_then_else (match_operand 1 "constant_call_address_operand")
602 (const_string "none")
603 (const_string "load"))
604 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1,sseshuf1")
605 (match_operand 1 "memory_operand"))
606 (const_string "both")
607 (and (match_operand 0 "memory_operand")
608 (match_operand 1 "memory_operand"))
609 (const_string "both")
610 (match_operand 0 "memory_operand")
611 (const_string "store")
612 (match_operand 1 "memory_operand")
613 (const_string "load")
615 "!alu1,negnot,ishift1,
616 imov,imovx,icmp,test,bitmanip,
618 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
619 sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
620 mmx,mmxmov,mmxcmp,mmxcvt")
621 (match_operand 2 "memory_operand"))
622 (const_string "load")
623 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
624 (match_operand 3 "memory_operand"))
625 (const_string "load")
627 (const_string "none")))
629 ;; Indicates if an instruction has both an immediate and a displacement.
631 (define_attr "imm_disp" "false,true,unknown"
632 (cond [(eq_attr "type" "other,multi")
633 (const_string "unknown")
634 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
635 (and (match_operand 0 "memory_displacement_operand")
636 (match_operand 1 "immediate_operand")))
637 (const_string "true")
638 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
639 (and (match_operand 0 "memory_displacement_operand")
640 (match_operand 2 "immediate_operand")))
641 (const_string "true")
643 (const_string "false")))
645 ;; Indicates if an FP operation has an integer source.
647 (define_attr "fp_int_src" "false,true"
648 (const_string "false"))
650 ;; Defines rounding mode of an FP operation.
652 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
653 (const_string "any"))
655 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
656 (define_attr "use_carry" "0,1" (const_string "0"))
658 ;; Define attribute to indicate unaligned ssemov insns
659 (define_attr "movu" "0,1" (const_string "0"))
661 ;; Used to control the "enabled" attribute on a per-instruction basis.
662 (define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
663 sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
664 avx2,noavx2,bmi2,fma4,fma"
665 (const_string "base"))
667 (define_attr "enabled" ""
668 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
669 (eq_attr "isa" "x64_sse4")
670 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
671 (eq_attr "isa" "x64_sse4_noavx")
672 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
673 (eq_attr "isa" "x64_avx")
674 (symbol_ref "TARGET_64BIT && TARGET_AVX")
675 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
676 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
677 (eq_attr "isa" "sse2_noavx")
678 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
679 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
680 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
681 (eq_attr "isa" "sse4_noavx")
682 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
683 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
684 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
685 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
686 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
687 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
688 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
689 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
693 ;; Describe a user's asm statement.
694 (define_asm_attributes
695 [(set_attr "length" "128")
696 (set_attr "type" "multi")])
698 (define_code_iterator plusminus [plus minus])
700 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
702 ;; Base name for define_insn
703 (define_code_attr plusminus_insn
704 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
705 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
707 ;; Base name for insn mnemonic.
708 (define_code_attr plusminus_mnemonic
709 [(plus "add") (ss_plus "adds") (us_plus "addus")
710 (minus "sub") (ss_minus "subs") (us_minus "subus")])
711 (define_code_attr plusminus_carry_mnemonic
712 [(plus "adc") (minus "sbb")])
714 ;; Mark commutative operators as such in constraints.
715 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
716 (minus "") (ss_minus "") (us_minus "")])
718 ;; Mapping of max and min
719 (define_code_iterator maxmin [smax smin umax umin])
721 ;; Mapping of signed max and min
722 (define_code_iterator smaxmin [smax smin])
724 ;; Mapping of unsigned max and min
725 (define_code_iterator umaxmin [umax umin])
727 ;; Base name for integer and FP insn mnemonic
728 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
729 (umax "maxu") (umin "minu")])
730 (define_code_attr maxmin_float [(smax "max") (smin "min")])
732 ;; Mapping of logic operators
733 (define_code_iterator any_logic [and ior xor])
734 (define_code_iterator any_or [ior xor])
736 ;; Base name for insn mnemonic.
737 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
739 ;; Mapping of logic-shift operators
740 (define_code_iterator any_lshift [ashift lshiftrt])
742 ;; Mapping of shift-right operators
743 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
745 ;; Mapping of all shift operators
746 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
748 ;; Base name for define_insn
749 (define_code_attr shift_insn
750 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
752 ;; Base name for insn mnemonic.
753 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
754 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
756 ;; Mapping of rotate operators
757 (define_code_iterator any_rotate [rotate rotatert])
759 ;; Base name for define_insn
760 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
762 ;; Base name for insn mnemonic.
763 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
765 ;; Mapping of abs neg operators
766 (define_code_iterator absneg [abs neg])
768 ;; Base name for x87 insn mnemonic.
769 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
771 ;; Used in signed and unsigned widening multiplications.
772 (define_code_iterator any_extend [sign_extend zero_extend])
774 ;; Prefix for insn menmonic.
775 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
777 ;; Prefix for define_insn
778 (define_code_attr u [(sign_extend "") (zero_extend "u")])
779 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
780 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
782 ;; All integer modes.
783 (define_mode_iterator SWI1248x [QI HI SI DI])
785 ;; All integer modes without QImode.
786 (define_mode_iterator SWI248x [HI SI DI])
788 ;; All integer modes without QImode and HImode.
789 (define_mode_iterator SWI48x [SI DI])
791 ;; All integer modes without SImode and DImode.
792 (define_mode_iterator SWI12 [QI HI])
794 ;; All integer modes without DImode.
795 (define_mode_iterator SWI124 [QI HI SI])
797 ;; All integer modes without QImode and DImode.
798 (define_mode_iterator SWI24 [HI SI])
800 ;; Single word integer modes.
801 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
803 ;; Single word integer modes without QImode.
804 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
806 ;; Single word integer modes without QImode and HImode.
807 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
809 ;; All math-dependant single and double word integer modes.
810 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
811 (HI "TARGET_HIMODE_MATH")
812 SI DI (TI "TARGET_64BIT")])
814 ;; Math-dependant single word integer modes.
815 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
816 (HI "TARGET_HIMODE_MATH")
817 SI (DI "TARGET_64BIT")])
819 ;; Math-dependant integer modes without DImode.
820 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
821 (HI "TARGET_HIMODE_MATH")
824 ;; Math-dependant single word integer modes without QImode.
825 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
826 SI (DI "TARGET_64BIT")])
828 ;; Double word integer modes.
829 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
830 (TI "TARGET_64BIT")])
832 ;; Double word integer modes as mode attribute.
833 (define_mode_attr DWI [(SI "DI") (DI "TI")])
834 (define_mode_attr dwi [(SI "di") (DI "ti")])
836 ;; Half mode for double word integer modes.
837 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
838 (DI "TARGET_64BIT")])
840 ;; Instruction suffix for integer modes.
841 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
843 ;; Pointer size prefix for integer modes (Intel asm dialect)
844 (define_mode_attr iptrsize [(QI "BYTE")
849 ;; Register class for integer modes.
850 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
852 ;; Immediate operand constraint for integer modes.
853 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
855 ;; General operand constraint for word modes.
856 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
858 ;; Immediate operand constraint for double integer modes.
859 (define_mode_attr di [(SI "nF") (DI "e")])
861 ;; Immediate operand constraint for shifts.
862 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
864 ;; General operand predicate for integer modes.
865 (define_mode_attr general_operand
866 [(QI "general_operand")
867 (HI "general_operand")
868 (SI "x86_64_general_operand")
869 (DI "x86_64_general_operand")
870 (TI "x86_64_general_operand")])
872 ;; General sign/zero extend operand predicate for integer modes.
873 (define_mode_attr general_szext_operand
874 [(QI "general_operand")
875 (HI "general_operand")
876 (SI "x86_64_szext_general_operand")
877 (DI "x86_64_szext_general_operand")])
879 ;; Immediate operand predicate for integer modes.
880 (define_mode_attr immediate_operand
881 [(QI "immediate_operand")
882 (HI "immediate_operand")
883 (SI "x86_64_immediate_operand")
884 (DI "x86_64_immediate_operand")])
886 ;; Nonmemory operand predicate for integer modes.
887 (define_mode_attr nonmemory_operand
888 [(QI "nonmemory_operand")
889 (HI "nonmemory_operand")
890 (SI "x86_64_nonmemory_operand")
891 (DI "x86_64_nonmemory_operand")])
893 ;; Operand predicate for shifts.
894 (define_mode_attr shift_operand
895 [(QI "nonimmediate_operand")
896 (HI "nonimmediate_operand")
897 (SI "nonimmediate_operand")
898 (DI "shiftdi_operand")
899 (TI "register_operand")])
901 ;; Operand predicate for shift argument.
902 (define_mode_attr shift_immediate_operand
903 [(QI "const_1_to_31_operand")
904 (HI "const_1_to_31_operand")
905 (SI "const_1_to_31_operand")
906 (DI "const_1_to_63_operand")])
908 ;; Input operand predicate for arithmetic left shifts.
909 (define_mode_attr ashl_input_operand
910 [(QI "nonimmediate_operand")
911 (HI "nonimmediate_operand")
912 (SI "nonimmediate_operand")
913 (DI "ashldi_input_operand")
914 (TI "reg_or_pm1_operand")])
916 ;; SSE and x87 SFmode and DFmode floating point modes
917 (define_mode_iterator MODEF [SF DF])
919 ;; All x87 floating point modes
920 (define_mode_iterator X87MODEF [SF DF XF])
922 ;; SSE instruction suffix for various modes
923 (define_mode_attr ssemodesuffix
925 (V8SF "ps") (V4DF "pd")
926 (V4SF "ps") (V2DF "pd")
927 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
928 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
930 ;; SSE vector suffix for floating point modes
931 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
933 ;; SSE vector mode corresponding to a scalar mode
934 (define_mode_attr ssevecmode
935 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
936 (define_mode_attr ssevecmodelower
937 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
939 ;; Instruction suffix for REX 64bit operators.
940 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
942 ;; This mode iterator allows :P to be used for patterns that operate on
943 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
944 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
946 ;; This mode iterator allows :W to be used for patterns that operate on
947 ;; word_mode sized quantities.
948 (define_mode_iterator W
949 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
951 ;; This mode iterator allows :PTR to be used for patterns that operate on
952 ;; ptr_mode sized quantities.
953 (define_mode_iterator PTR
954 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
956 ;; Scheduling descriptions
958 (include "pentium.md")
961 (include "athlon.md")
962 (include "bdver1.md")
963 (include "bdver3.md")
964 (include "btver2.md")
971 ;; Operand and operator predicates and constraints
973 (include "predicates.md")
974 (include "constraints.md")
977 ;; Compare and branch/compare and store instructions.
979 (define_expand "cbranch<mode>4"
980 [(set (reg:CC FLAGS_REG)
981 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
982 (match_operand:SDWIM 2 "<general_operand>")))
983 (set (pc) (if_then_else
984 (match_operator 0 "ordered_comparison_operator"
985 [(reg:CC FLAGS_REG) (const_int 0)])
986 (label_ref (match_operand 3))
990 if (MEM_P (operands[1]) && MEM_P (operands[2]))
991 operands[1] = force_reg (<MODE>mode, operands[1]);
992 ix86_expand_branch (GET_CODE (operands[0]),
993 operands[1], operands[2], operands[3]);
997 (define_expand "cstore<mode>4"
998 [(set (reg:CC FLAGS_REG)
999 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1000 (match_operand:SWIM 3 "<general_operand>")))
1001 (set (match_operand:QI 0 "register_operand")
1002 (match_operator 1 "ordered_comparison_operator"
1003 [(reg:CC FLAGS_REG) (const_int 0)]))]
1006 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1007 operands[2] = force_reg (<MODE>mode, operands[2]);
1008 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1009 operands[2], operands[3]);
1013 (define_expand "cmp<mode>_1"
1014 [(set (reg:CC FLAGS_REG)
1015 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1016 (match_operand:SWI48 1 "<general_operand>")))])
1018 (define_insn "*cmp<mode>_ccno_1"
1019 [(set (reg FLAGS_REG)
1020 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1021 (match_operand:SWI 1 "const0_operand")))]
1022 "ix86_match_ccmode (insn, CCNOmode)"
1024 test{<imodesuffix>}\t%0, %0
1025 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1026 [(set_attr "type" "test,icmp")
1027 (set_attr "length_immediate" "0,1")
1028 (set_attr "mode" "<MODE>")])
1030 (define_insn "*cmp<mode>_1"
1031 [(set (reg FLAGS_REG)
1032 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1033 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1034 "ix86_match_ccmode (insn, CCmode)"
1035 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1036 [(set_attr "type" "icmp")
1037 (set_attr "mode" "<MODE>")])
1039 (define_insn "*cmp<mode>_minus_1"
1040 [(set (reg FLAGS_REG)
1042 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1043 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1045 "ix86_match_ccmode (insn, CCGOCmode)"
1046 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1047 [(set_attr "type" "icmp")
1048 (set_attr "mode" "<MODE>")])
1050 (define_insn "*cmpqi_ext_1"
1051 [(set (reg FLAGS_REG)
1053 (match_operand:QI 0 "nonimmediate_x64nomem_operand" "Q,m")
1056 (match_operand 1 "ext_register_operand" "Q,Q")
1058 (const_int 8)) 0)))]
1059 "ix86_match_ccmode (insn, CCmode)"
1060 "cmp{b}\t{%h1, %0|%0, %h1}"
1061 [(set_attr "isa" "*,nox64")
1062 (set_attr "type" "icmp")
1063 (set_attr "mode" "QI")])
1065 (define_insn "*cmpqi_ext_2"
1066 [(set (reg FLAGS_REG)
1070 (match_operand 0 "ext_register_operand" "Q")
1073 (match_operand:QI 1 "const0_operand")))]
1074 "ix86_match_ccmode (insn, CCNOmode)"
1076 [(set_attr "type" "test")
1077 (set_attr "length_immediate" "0")
1078 (set_attr "mode" "QI")])
1080 (define_expand "cmpqi_ext_3"
1081 [(set (reg:CC FLAGS_REG)
1085 (match_operand 0 "ext_register_operand")
1088 (match_operand:QI 1 "const_int_operand")))])
1090 (define_insn "*cmpqi_ext_3"
1091 [(set (reg FLAGS_REG)
1095 (match_operand 0 "ext_register_operand" "Q,Q")
1098 (match_operand:QI 1 "general_x64nomem_operand" "Qn,m")))]
1099 "ix86_match_ccmode (insn, CCmode)"
1100 "cmp{b}\t{%1, %h0|%h0, %1}"
1101 [(set_attr "isa" "*,nox64")
1102 (set_attr "type" "icmp")
1103 (set_attr "modrm" "1")
1104 (set_attr "mode" "QI")])
1106 (define_insn "*cmpqi_ext_4"
1107 [(set (reg FLAGS_REG)
1111 (match_operand 0 "ext_register_operand" "Q")
1116 (match_operand 1 "ext_register_operand" "Q")
1118 (const_int 8)) 0)))]
1119 "ix86_match_ccmode (insn, CCmode)"
1120 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1121 [(set_attr "type" "icmp")
1122 (set_attr "mode" "QI")])
1124 ;; These implement float point compares.
1125 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1126 ;; which would allow mix and match FP modes on the compares. Which is what
1127 ;; the old patterns did, but with many more of them.
1129 (define_expand "cbranchxf4"
1130 [(set (reg:CC FLAGS_REG)
1131 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1132 (match_operand:XF 2 "nonmemory_operand")))
1133 (set (pc) (if_then_else
1134 (match_operator 0 "ix86_fp_comparison_operator"
1137 (label_ref (match_operand 3))
1141 ix86_expand_branch (GET_CODE (operands[0]),
1142 operands[1], operands[2], operands[3]);
1146 (define_expand "cstorexf4"
1147 [(set (reg:CC FLAGS_REG)
1148 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1149 (match_operand:XF 3 "nonmemory_operand")))
1150 (set (match_operand:QI 0 "register_operand")
1151 (match_operator 1 "ix86_fp_comparison_operator"
1156 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1157 operands[2], operands[3]);
1161 (define_expand "cbranch<mode>4"
1162 [(set (reg:CC FLAGS_REG)
1163 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1164 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1165 (set (pc) (if_then_else
1166 (match_operator 0 "ix86_fp_comparison_operator"
1169 (label_ref (match_operand 3))
1171 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1173 ix86_expand_branch (GET_CODE (operands[0]),
1174 operands[1], operands[2], operands[3]);
1178 (define_expand "cstore<mode>4"
1179 [(set (reg:CC FLAGS_REG)
1180 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1181 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1182 (set (match_operand:QI 0 "register_operand")
1183 (match_operator 1 "ix86_fp_comparison_operator"
1186 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1188 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1189 operands[2], operands[3]);
1193 (define_expand "cbranchcc4"
1194 [(set (pc) (if_then_else
1195 (match_operator 0 "comparison_operator"
1196 [(match_operand 1 "flags_reg_operand")
1197 (match_operand 2 "const0_operand")])
1198 (label_ref (match_operand 3))
1202 ix86_expand_branch (GET_CODE (operands[0]),
1203 operands[1], operands[2], operands[3]);
1207 (define_expand "cstorecc4"
1208 [(set (match_operand:QI 0 "register_operand")
1209 (match_operator 1 "comparison_operator"
1210 [(match_operand 2 "flags_reg_operand")
1211 (match_operand 3 "const0_operand")]))]
1214 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1215 operands[2], operands[3]);
1220 ;; FP compares, step 1:
1221 ;; Set the FP condition codes.
1223 ;; CCFPmode compare with exceptions
1224 ;; CCFPUmode compare with no exceptions
1226 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1227 ;; used to manage the reg stack popping would not be preserved.
1229 (define_insn "*cmp<mode>_0_i387"
1230 [(set (match_operand:HI 0 "register_operand" "=a")
1233 (match_operand:X87MODEF 1 "register_operand" "f")
1234 (match_operand:X87MODEF 2 "const0_operand"))]
1237 "* return output_fp_compare (insn, operands, false, false);"
1238 [(set_attr "type" "multi")
1239 (set_attr "unit" "i387")
1240 (set_attr "mode" "<MODE>")])
1242 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1243 [(set (reg:CCFP FLAGS_REG)
1245 (match_operand:X87MODEF 1 "register_operand" "f")
1246 (match_operand:X87MODEF 2 "const0_operand")))
1247 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1248 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1250 "&& reload_completed"
1253 [(compare:CCFP (match_dup 1)(match_dup 2))]
1255 (set (reg:CC FLAGS_REG)
1256 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1258 [(set_attr "type" "multi")
1259 (set_attr "unit" "i387")
1260 (set_attr "mode" "<MODE>")])
1262 (define_insn "*cmpxf_i387"
1263 [(set (match_operand:HI 0 "register_operand" "=a")
1266 (match_operand:XF 1 "register_operand" "f")
1267 (match_operand:XF 2 "register_operand" "f"))]
1270 "* return output_fp_compare (insn, operands, false, false);"
1271 [(set_attr "type" "multi")
1272 (set_attr "unit" "i387")
1273 (set_attr "mode" "XF")])
1275 (define_insn_and_split "*cmpxf_cc_i387"
1276 [(set (reg:CCFP FLAGS_REG)
1278 (match_operand:XF 1 "register_operand" "f")
1279 (match_operand:XF 2 "register_operand" "f")))
1280 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1281 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1283 "&& reload_completed"
1286 [(compare:CCFP (match_dup 1)(match_dup 2))]
1288 (set (reg:CC FLAGS_REG)
1289 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1291 [(set_attr "type" "multi")
1292 (set_attr "unit" "i387")
1293 (set_attr "mode" "XF")])
1295 (define_insn "*cmp<mode>_i387"
1296 [(set (match_operand:HI 0 "register_operand" "=a")
1299 (match_operand:MODEF 1 "register_operand" "f")
1300 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1303 "* return output_fp_compare (insn, operands, false, false);"
1304 [(set_attr "type" "multi")
1305 (set_attr "unit" "i387")
1306 (set_attr "mode" "<MODE>")])
1308 (define_insn_and_split "*cmp<mode>_cc_i387"
1309 [(set (reg:CCFP FLAGS_REG)
1311 (match_operand:MODEF 1 "register_operand" "f")
1312 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1313 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1314 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1316 "&& reload_completed"
1319 [(compare:CCFP (match_dup 1)(match_dup 2))]
1321 (set (reg:CC FLAGS_REG)
1322 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1324 [(set_attr "type" "multi")
1325 (set_attr "unit" "i387")
1326 (set_attr "mode" "<MODE>")])
1328 (define_insn "*cmpu<mode>_i387"
1329 [(set (match_operand:HI 0 "register_operand" "=a")
1332 (match_operand:X87MODEF 1 "register_operand" "f")
1333 (match_operand:X87MODEF 2 "register_operand" "f"))]
1336 "* return output_fp_compare (insn, operands, false, true);"
1337 [(set_attr "type" "multi")
1338 (set_attr "unit" "i387")
1339 (set_attr "mode" "<MODE>")])
1341 (define_insn_and_split "*cmpu<mode>_cc_i387"
1342 [(set (reg:CCFPU FLAGS_REG)
1344 (match_operand:X87MODEF 1 "register_operand" "f")
1345 (match_operand:X87MODEF 2 "register_operand" "f")))
1346 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1347 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1349 "&& reload_completed"
1352 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1354 (set (reg:CC FLAGS_REG)
1355 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1357 [(set_attr "type" "multi")
1358 (set_attr "unit" "i387")
1359 (set_attr "mode" "<MODE>")])
1361 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1362 [(set (match_operand:HI 0 "register_operand" "=a")
1365 (match_operand:X87MODEF 1 "register_operand" "f")
1366 (match_operator:X87MODEF 3 "float_operator"
1367 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1370 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1371 || optimize_function_for_size_p (cfun))"
1372 "* return output_fp_compare (insn, operands, false, false);"
1373 [(set_attr "type" "multi")
1374 (set_attr "unit" "i387")
1375 (set_attr "fp_int_src" "true")
1376 (set_attr "mode" "<SWI24:MODE>")])
1378 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1379 [(set (reg:CCFP FLAGS_REG)
1381 (match_operand:X87MODEF 1 "register_operand" "f")
1382 (match_operator:X87MODEF 3 "float_operator"
1383 [(match_operand:SWI24 2 "memory_operand" "m")])))
1384 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1385 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1386 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1387 || optimize_function_for_size_p (cfun))"
1389 "&& reload_completed"
1394 (match_op_dup 3 [(match_dup 2)]))]
1396 (set (reg:CC FLAGS_REG)
1397 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1399 [(set_attr "type" "multi")
1400 (set_attr "unit" "i387")
1401 (set_attr "fp_int_src" "true")
1402 (set_attr "mode" "<SWI24:MODE>")])
1404 ;; FP compares, step 2
1405 ;; Move the fpsw to ax.
1407 (define_insn "x86_fnstsw_1"
1408 [(set (match_operand:HI 0 "register_operand" "=a")
1409 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1412 [(set (attr "length")
1413 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1414 (set_attr "mode" "SI")
1415 (set_attr "unit" "i387")])
1417 ;; FP compares, step 3
1418 ;; Get ax into flags, general case.
1420 (define_insn "x86_sahf_1"
1421 [(set (reg:CC FLAGS_REG)
1422 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1426 #ifndef HAVE_AS_IX86_SAHF
1428 return ASM_BYTE "0x9e";
1433 [(set_attr "length" "1")
1434 (set_attr "athlon_decode" "vector")
1435 (set_attr "amdfam10_decode" "direct")
1436 (set_attr "bdver1_decode" "direct")
1437 (set_attr "mode" "SI")])
1439 ;; Pentium Pro can do steps 1 through 3 in one go.
1440 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1441 ;; (these i387 instructions set flags directly)
1443 (define_mode_iterator FPCMP [CCFP CCFPU])
1444 (define_mode_attr unord [(CCFP "") (CCFPU "u")])
1446 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_mixed"
1447 [(set (reg:FPCMP FLAGS_REG)
1449 (match_operand:MODEF 0 "register_operand" "f,x")
1450 (match_operand:MODEF 1 "nonimmediate_operand" "f,xm")))]
1451 "TARGET_MIX_SSE_I387
1452 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1453 "* return output_fp_compare (insn, operands, true,
1454 <FPCMP:MODE>mode == CCFPUmode);"
1455 [(set_attr "type" "fcmp,ssecomi")
1456 (set_attr "prefix" "orig,maybe_vex")
1457 (set_attr "mode" "<MODEF:MODE>")
1458 (set (attr "prefix_rep")
1459 (if_then_else (eq_attr "type" "ssecomi")
1461 (const_string "*")))
1462 (set (attr "prefix_data16")
1463 (cond [(eq_attr "type" "fcmp")
1465 (eq_attr "mode" "DF")
1468 (const_string "0")))
1469 (set_attr "athlon_decode" "vector")
1470 (set_attr "amdfam10_decode" "direct")
1471 (set_attr "bdver1_decode" "double")])
1473 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_sse"
1474 [(set (reg:FPCMP FLAGS_REG)
1476 (match_operand:MODEF 0 "register_operand" "x")
1477 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
1479 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1480 "* return output_fp_compare (insn, operands, true,
1481 <FPCMP:MODE>mode == CCFPUmode);"
1482 [(set_attr "type" "ssecomi")
1483 (set_attr "prefix" "maybe_vex")
1484 (set_attr "mode" "<MODEF:MODE>")
1485 (set_attr "prefix_rep" "0")
1486 (set (attr "prefix_data16")
1487 (if_then_else (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 "*cmpi<FPCMP:unord><X87MODEF:mode>_i387"
1495 [(set (reg:FPCMP FLAGS_REG)
1497 (match_operand:X87MODEF 0 "register_operand" "f")
1498 (match_operand:X87MODEF 1 "register_operand" "f")))]
1499 "TARGET_80387 && TARGET_CMOVE
1500 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
1501 "* return output_fp_compare (insn, operands, true,
1502 <FPCMP:MODE>mode == CCFPUmode);"
1503 [(set_attr "type" "fcmp")
1504 (set_attr "mode" "<X87MODEF:MODE>")
1505 (set_attr "athlon_decode" "vector")
1506 (set_attr "amdfam10_decode" "direct")
1507 (set_attr "bdver1_decode" "double")])
1509 ;; Push/pop instructions.
1511 (define_insn "*push<mode>2"
1512 [(set (match_operand:DWI 0 "push_operand" "=<")
1513 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1516 [(set_attr "type" "multi")
1517 (set_attr "mode" "<MODE>")])
1520 [(set (match_operand:TI 0 "push_operand")
1521 (match_operand:TI 1 "general_operand"))]
1522 "TARGET_64BIT && reload_completed
1523 && !SSE_REG_P (operands[1])"
1525 "ix86_split_long_move (operands); DONE;")
1527 (define_insn "*pushdi2_rex64"
1528 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1529 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1534 [(set_attr "type" "push,multi")
1535 (set_attr "mode" "DI")])
1537 ;; Convert impossible pushes of immediate to existing instructions.
1538 ;; First try to get scratch register and go through it. In case this
1539 ;; fails, push sign extended lower part first and then overwrite
1540 ;; upper part by 32bit move.
1542 [(match_scratch:DI 2 "r")
1543 (set (match_operand:DI 0 "push_operand")
1544 (match_operand:DI 1 "immediate_operand"))]
1545 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1546 && !x86_64_immediate_operand (operands[1], DImode)"
1547 [(set (match_dup 2) (match_dup 1))
1548 (set (match_dup 0) (match_dup 2))])
1550 ;; We need to define this as both peepholer and splitter for case
1551 ;; peephole2 pass is not run.
1552 ;; "&& 1" is needed to keep it from matching the previous pattern.
1554 [(set (match_operand:DI 0 "push_operand")
1555 (match_operand:DI 1 "immediate_operand"))]
1556 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1557 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1558 [(set (match_dup 0) (match_dup 1))
1559 (set (match_dup 2) (match_dup 3))]
1561 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1563 operands[1] = gen_lowpart (DImode, operands[2]);
1564 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1569 [(set (match_operand:DI 0 "push_operand")
1570 (match_operand:DI 1 "immediate_operand"))]
1571 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1572 ? epilogue_completed : reload_completed)
1573 && !symbolic_operand (operands[1], DImode)
1574 && !x86_64_immediate_operand (operands[1], DImode)"
1575 [(set (match_dup 0) (match_dup 1))
1576 (set (match_dup 2) (match_dup 3))]
1578 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1580 operands[1] = gen_lowpart (DImode, operands[2]);
1581 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1586 [(set (match_operand:DI 0 "push_operand")
1587 (match_operand:DI 1 "general_operand"))]
1588 "!TARGET_64BIT && reload_completed
1589 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1591 "ix86_split_long_move (operands); DONE;")
1593 (define_insn "*pushsi2"
1594 [(set (match_operand:SI 0 "push_operand" "=<")
1595 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1598 [(set_attr "type" "push")
1599 (set_attr "mode" "SI")])
1601 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1602 ;; "push a byte/word". But actually we use pushl, which has the effect
1603 ;; of rounding the amount pushed up to a word.
1605 ;; For TARGET_64BIT we always round up to 8 bytes.
1606 (define_insn "*push<mode>2_rex64"
1607 [(set (match_operand:SWI124 0 "push_operand" "=X")
1608 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1611 [(set_attr "type" "push")
1612 (set_attr "mode" "DI")])
1614 (define_insn "*push<mode>2"
1615 [(set (match_operand:SWI12 0 "push_operand" "=X")
1616 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1619 [(set_attr "type" "push")
1620 (set_attr "mode" "SI")])
1622 (define_insn "*push<mode>2_prologue"
1623 [(set (match_operand:W 0 "push_operand" "=<")
1624 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1625 (clobber (mem:BLK (scratch)))]
1627 "push{<imodesuffix>}\t%1"
1628 [(set_attr "type" "push")
1629 (set_attr "mode" "<MODE>")])
1631 (define_insn "*pop<mode>1"
1632 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1633 (match_operand:W 1 "pop_operand" ">"))]
1635 "pop{<imodesuffix>}\t%0"
1636 [(set_attr "type" "pop")
1637 (set_attr "mode" "<MODE>")])
1639 (define_insn "*pop<mode>1_epilogue"
1640 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1641 (match_operand:W 1 "pop_operand" ">"))
1642 (clobber (mem:BLK (scratch)))]
1644 "pop{<imodesuffix>}\t%0"
1645 [(set_attr "type" "pop")
1646 (set_attr "mode" "<MODE>")])
1648 ;; Move instructions.
1650 ;; Reload patterns to support multi-word load/store
1651 ;; with non-offsetable address.
1652 (define_expand "reload_noff_store"
1653 [(parallel [(match_operand 0 "memory_operand" "=m")
1654 (match_operand 1 "register_operand" "r")
1655 (match_operand:DI 2 "register_operand" "=&r")])]
1658 rtx mem = operands[0];
1659 rtx addr = XEXP (mem, 0);
1661 emit_move_insn (operands[2], addr);
1662 mem = replace_equiv_address_nv (mem, operands[2]);
1664 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
1668 (define_expand "reload_noff_load"
1669 [(parallel [(match_operand 0 "register_operand" "=r")
1670 (match_operand 1 "memory_operand" "m")
1671 (match_operand:DI 2 "register_operand" "=r")])]
1674 rtx mem = operands[1];
1675 rtx addr = XEXP (mem, 0);
1677 emit_move_insn (operands[2], addr);
1678 mem = replace_equiv_address_nv (mem, operands[2]);
1680 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
1684 (define_expand "movoi"
1685 [(set (match_operand:OI 0 "nonimmediate_operand")
1686 (match_operand:OI 1 "general_operand"))]
1688 "ix86_expand_move (OImode, operands); DONE;")
1690 (define_expand "movti"
1691 [(set (match_operand:TI 0 "nonimmediate_operand")
1692 (match_operand:TI 1 "nonimmediate_operand"))]
1693 "TARGET_64BIT || TARGET_SSE"
1696 ix86_expand_move (TImode, operands);
1697 else if (push_operand (operands[0], TImode))
1698 ix86_expand_push (TImode, operands[1]);
1700 ix86_expand_vector_move (TImode, operands);
1704 ;; This expands to what emit_move_complex would generate if we didn't
1705 ;; have a movti pattern. Having this avoids problems with reload on
1706 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1707 ;; to have around all the time.
1708 (define_expand "movcdi"
1709 [(set (match_operand:CDI 0 "nonimmediate_operand")
1710 (match_operand:CDI 1 "general_operand"))]
1713 if (push_operand (operands[0], CDImode))
1714 emit_move_complex_push (CDImode, operands[0], operands[1]);
1716 emit_move_complex_parts (operands[0], operands[1]);
1720 (define_expand "mov<mode>"
1721 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1722 (match_operand:SWI1248x 1 "general_operand"))]
1724 "ix86_expand_move (<MODE>mode, operands); DONE;")
1726 (define_insn "*mov<mode>_xor"
1727 [(set (match_operand:SWI48 0 "register_operand" "=r")
1728 (match_operand:SWI48 1 "const0_operand"))
1729 (clobber (reg:CC FLAGS_REG))]
1732 [(set_attr "type" "alu1")
1733 (set_attr "mode" "SI")
1734 (set_attr "length_immediate" "0")])
1736 (define_insn "*mov<mode>_or"
1737 [(set (match_operand:SWI48 0 "register_operand" "=r")
1738 (match_operand:SWI48 1 "const_int_operand"))
1739 (clobber (reg:CC FLAGS_REG))]
1741 && operands[1] == constm1_rtx"
1742 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1743 [(set_attr "type" "alu1")
1744 (set_attr "mode" "<MODE>")
1745 (set_attr "length_immediate" "1")])
1747 (define_insn "*movoi_internal_avx"
1748 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x ,m")
1749 (match_operand:OI 1 "vector_move_operand" "C ,xm,x"))]
1750 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1752 switch (get_attr_type (insn))
1755 return standard_sse_constant_opcode (insn, operands[1]);
1758 if (misaligned_operand (operands[0], OImode)
1759 || misaligned_operand (operands[1], OImode))
1761 if (get_attr_mode (insn) == MODE_V8SF)
1762 return "vmovups\t{%1, %0|%0, %1}";
1764 return "vmovdqu\t{%1, %0|%0, %1}";
1768 if (get_attr_mode (insn) == MODE_V8SF)
1769 return "vmovaps\t{%1, %0|%0, %1}";
1771 return "vmovdqa\t{%1, %0|%0, %1}";
1778 [(set_attr "type" "sselog1,ssemov,ssemov")
1779 (set_attr "prefix" "vex")
1781 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1782 (const_string "V8SF")
1783 (and (eq_attr "alternative" "2")
1784 (match_test "TARGET_SSE_TYPELESS_STORES"))
1785 (const_string "V8SF")
1787 (const_string "OI")))])
1789 (define_insn "*movti_internal"
1790 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,x,x ,m")
1791 (match_operand:TI 1 "general_operand" "riFo,re,C,xm,x"))]
1792 "(TARGET_64BIT || TARGET_SSE)
1793 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1795 switch (get_attr_type (insn))
1801 return standard_sse_constant_opcode (insn, operands[1]);
1804 /* TDmode values are passed as TImode on the stack. Moving them
1805 to stack may result in unaligned memory access. */
1806 if (misaligned_operand (operands[0], TImode)
1807 || misaligned_operand (operands[1], TImode))
1809 if (get_attr_mode (insn) == MODE_V4SF)
1810 return "%vmovups\t{%1, %0|%0, %1}";
1812 return "%vmovdqu\t{%1, %0|%0, %1}";
1816 if (get_attr_mode (insn) == MODE_V4SF)
1817 return "%vmovaps\t{%1, %0|%0, %1}";
1819 return "%vmovdqa\t{%1, %0|%0, %1}";
1826 [(set_attr "isa" "x64,x64,*,*,*")
1827 (set_attr "type" "multi,multi,sselog1,ssemov,ssemov")
1828 (set (attr "prefix")
1829 (if_then_else (eq_attr "type" "sselog1,ssemov")
1830 (const_string "maybe_vex")
1831 (const_string "orig")))
1833 (cond [(eq_attr "alternative" "0,1")
1835 (ior (not (match_test "TARGET_SSE2"))
1836 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
1837 (const_string "V4SF")
1838 (and (eq_attr "alternative" "4")
1839 (match_test "TARGET_SSE_TYPELESS_STORES"))
1840 (const_string "V4SF")
1841 (match_test "TARGET_AVX")
1843 (match_test "optimize_function_for_size_p (cfun)")
1844 (const_string "V4SF")
1846 (const_string "TI")))])
1849 [(set (match_operand:TI 0 "nonimmediate_operand")
1850 (match_operand:TI 1 "general_operand"))]
1852 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1854 "ix86_split_long_move (operands); DONE;")
1856 (define_insn "*movdi_internal"
1857 [(set (match_operand:DI 0 "nonimmediate_operand"
1858 "=r ,o ,r,r ,r,m ,*y,*y,?*y,?m,?r ,?*Ym,*x,*x,*x,m ,?r ,?r,?*Yi,?*Ym,?*Yi")
1859 (match_operand:DI 1 "general_operand"
1860 "riFo,riF,Z,rem,i,re,C ,*y,m ,*y,*Yn,r ,C ,*x,m ,*x,*Yj,*x,r ,*Yj ,*Yn"))]
1861 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1863 switch (get_attr_type (insn))
1869 return "pxor\t%0, %0";
1872 #ifndef HAVE_AS_IX86_INTERUNIT_MOVQ
1873 /* Handle broken assemblers that require movd instead of movq. */
1874 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1875 return "movd\t{%1, %0|%0, %1}";
1877 return "movq\t{%1, %0|%0, %1}";
1880 if (GENERAL_REG_P (operands[0]))
1881 return "%vpextrq\t{$0, %1, %0|%0, %1, 0}";
1883 return standard_sse_constant_opcode (insn, operands[1]);
1886 switch (get_attr_mode (insn))
1889 #ifndef HAVE_AS_IX86_INTERUNIT_MOVQ
1890 /* Handle broken assemblers that require movd instead of movq. */
1891 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1892 return "%vmovd\t{%1, %0|%0, %1}";
1894 return "%vmovq\t{%1, %0|%0, %1}";
1896 return "%vmovdqa\t{%1, %0|%0, %1}";
1899 gcc_assert (!TARGET_AVX);
1900 return "movlps\t{%1, %0|%0, %1}";
1902 return "%vmovaps\t{%1, %0|%0, %1}";
1909 if (SSE_REG_P (operands[0]))
1910 return "movq2dq\t{%1, %0|%0, %1}";
1912 return "movdq2q\t{%1, %0|%0, %1}";
1915 return "lea{q}\t{%E1, %0|%0, %E1}";
1918 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1919 if (get_attr_mode (insn) == MODE_SI)
1920 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1921 else if (which_alternative == 4)
1922 return "movabs{q}\t{%1, %0|%0, %1}";
1923 else if (ix86_use_lea_for_mov (insn, operands))
1924 return "lea{q}\t{%E1, %0|%0, %E1}";
1926 return "mov{q}\t{%1, %0|%0, %1}";
1933 (cond [(eq_attr "alternative" "0,1")
1934 (const_string "nox64")
1935 (eq_attr "alternative" "2,3,4,5,10,11,16,18")
1936 (const_string "x64")
1937 (eq_attr "alternative" "17")
1938 (const_string "x64_sse4")
1940 (const_string "*")))
1942 (cond [(eq_attr "alternative" "0,1")
1943 (const_string "multi")
1944 (eq_attr "alternative" "6")
1945 (const_string "mmx")
1946 (eq_attr "alternative" "7,8,9,10,11")
1947 (const_string "mmxmov")
1948 (eq_attr "alternative" "12,17")
1949 (const_string "sselog1")
1950 (eq_attr "alternative" "13,14,15,16,18")
1951 (const_string "ssemov")
1952 (eq_attr "alternative" "19,20")
1953 (const_string "ssecvt")
1954 (match_operand 1 "pic_32bit_operand")
1955 (const_string "lea")
1957 (const_string "imov")))
1960 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
1962 (const_string "*")))
1963 (set (attr "length_immediate")
1964 (cond [(and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
1966 (eq_attr "alternative" "17")
1969 (const_string "*")))
1970 (set (attr "prefix_rex")
1971 (if_then_else (eq_attr "alternative" "10,11,16,17,18")
1973 (const_string "*")))
1974 (set (attr "prefix_extra")
1975 (if_then_else (eq_attr "alternative" "17")
1977 (const_string "*")))
1978 (set (attr "prefix")
1979 (if_then_else (eq_attr "type" "sselog1,ssemov")
1980 (const_string "maybe_vex")
1981 (const_string "orig")))
1982 (set (attr "prefix_data16")
1983 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
1985 (const_string "*")))
1987 (cond [(eq_attr "alternative" "2")
1989 (eq_attr "alternative" "12,13")
1990 (cond [(ior (not (match_test "TARGET_SSE2"))
1991 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
1992 (const_string "V4SF")
1993 (match_test "TARGET_AVX")
1995 (match_test "optimize_function_for_size_p (cfun)")
1996 (const_string "V4SF")
1998 (const_string "TI"))
2000 (and (eq_attr "alternative" "14,15")
2001 (not (match_test "TARGET_SSE2")))
2002 (const_string "V2SF")
2003 (eq_attr "alternative" "17")
2006 (const_string "DI")))])
2009 [(set (match_operand:DI 0 "nonimmediate_operand")
2010 (match_operand:DI 1 "general_operand"))]
2011 "!TARGET_64BIT && reload_completed
2012 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2013 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2015 "ix86_split_long_move (operands); DONE;")
2017 (define_insn "*movsi_internal"
2018 [(set (match_operand:SI 0 "nonimmediate_operand"
2019 "=r,m ,*y,*y,?rm,?*y,*x,*x,*x,m ,?r ,?r,?*Yi")
2020 (match_operand:SI 1 "general_operand"
2021 "g ,re,C ,*y,*y ,rm ,C ,*x,m ,*x,*Yj,*x,r"))]
2022 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2024 switch (get_attr_type (insn))
2027 if (GENERAL_REG_P (operands[0]))
2028 return "%vpextrd\t{$0, %1, %0|%0, %1, 0}";
2030 return standard_sse_constant_opcode (insn, operands[1]);
2033 switch (get_attr_mode (insn))
2036 return "%vmovd\t{%1, %0|%0, %1}";
2038 return "%vmovdqa\t{%1, %0|%0, %1}";
2041 return "%vmovaps\t{%1, %0|%0, %1}";
2044 gcc_assert (!TARGET_AVX);
2045 return "movss\t{%1, %0|%0, %1}";
2052 return "pxor\t%0, %0";
2055 switch (get_attr_mode (insn))
2058 return "movq\t{%1, %0|%0, %1}";
2060 return "movd\t{%1, %0|%0, %1}";
2067 return "lea{l}\t{%E1, %0|%0, %E1}";
2070 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2071 if (ix86_use_lea_for_mov (insn, operands))
2072 return "lea{l}\t{%E1, %0|%0, %E1}";
2074 return "mov{l}\t{%1, %0|%0, %1}";
2081 (if_then_else (eq_attr "alternative" "11")
2082 (const_string "sse4")
2083 (const_string "*")))
2085 (cond [(eq_attr "alternative" "2")
2086 (const_string "mmx")
2087 (eq_attr "alternative" "3,4,5")
2088 (const_string "mmxmov")
2089 (eq_attr "alternative" "6,11")
2090 (const_string "sselog1")
2091 (eq_attr "alternative" "7,8,9,10,12")
2092 (const_string "ssemov")
2093 (match_operand 1 "pic_32bit_operand")
2094 (const_string "lea")
2096 (const_string "imov")))
2097 (set (attr "length_immediate")
2098 (if_then_else (eq_attr "alternative" "11")
2100 (const_string "*")))
2101 (set (attr "prefix_extra")
2102 (if_then_else (eq_attr "alternative" "11")
2104 (const_string "*")))
2105 (set (attr "prefix")
2106 (if_then_else (eq_attr "type" "sselog1,ssemov")
2107 (const_string "maybe_vex")
2108 (const_string "orig")))
2109 (set (attr "prefix_data16")
2110 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2112 (const_string "*")))
2114 (cond [(eq_attr "alternative" "2,3")
2116 (eq_attr "alternative" "6,7")
2117 (cond [(ior (not (match_test "TARGET_SSE2"))
2118 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2119 (const_string "V4SF")
2120 (match_test "TARGET_AVX")
2122 (match_test "optimize_function_for_size_p (cfun)")
2123 (const_string "V4SF")
2125 (const_string "TI"))
2127 (and (eq_attr "alternative" "8,9")
2128 (not (match_test "TARGET_SSE2")))
2130 (eq_attr "alternative" "11")
2133 (const_string "SI")))])
2135 (define_insn "*movhi_internal"
2136 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m")
2137 (match_operand:HI 1 "general_operand" "r ,rn,rm,rn"))]
2138 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2140 switch (get_attr_type (insn))
2143 /* movzwl is faster than movw on p2 due to partial word stalls,
2144 though not as fast as an aligned movl. */
2145 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2147 if (get_attr_mode (insn) == MODE_SI)
2148 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2150 return "mov{w}\t{%1, %0|%0, %1}";
2154 (cond [(match_test "optimize_function_for_size_p (cfun)")
2155 (const_string "imov")
2156 (and (eq_attr "alternative" "0")
2157 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2158 (not (match_test "TARGET_HIMODE_MATH"))))
2159 (const_string "imov")
2160 (and (eq_attr "alternative" "1,2")
2161 (match_operand:HI 1 "aligned_operand"))
2162 (const_string "imov")
2163 (and (match_test "TARGET_MOVX")
2164 (eq_attr "alternative" "0,2"))
2165 (const_string "imovx")
2167 (const_string "imov")))
2169 (cond [(eq_attr "type" "imovx")
2171 (and (eq_attr "alternative" "1,2")
2172 (match_operand:HI 1 "aligned_operand"))
2174 (and (eq_attr "alternative" "0")
2175 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2176 (not (match_test "TARGET_HIMODE_MATH"))))
2179 (const_string "HI")))])
2181 ;; Situation is quite tricky about when to choose full sized (SImode) move
2182 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2183 ;; partial register dependency machines (such as AMD Athlon), where QImode
2184 ;; moves issue extra dependency and for partial register stalls machines
2185 ;; that don't use QImode patterns (and QImode move cause stall on the next
2188 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2189 ;; register stall machines with, where we use QImode instructions, since
2190 ;; partial register stall can be caused there. Then we use movzx.
2191 (define_insn "*movqi_internal"
2192 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2193 (match_operand:QI 1 "general_operand" "q ,qn,qm,q,rn,qm,qn"))]
2194 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2196 switch (get_attr_type (insn))
2199 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2200 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2202 if (get_attr_mode (insn) == MODE_SI)
2203 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2205 return "mov{b}\t{%1, %0|%0, %1}";
2209 (cond [(and (eq_attr "alternative" "5")
2210 (not (match_operand:QI 1 "aligned_operand")))
2211 (const_string "imovx")
2212 (match_test "optimize_function_for_size_p (cfun)")
2213 (const_string "imov")
2214 (and (eq_attr "alternative" "3")
2215 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2216 (not (match_test "TARGET_QIMODE_MATH"))))
2217 (const_string "imov")
2218 (eq_attr "alternative" "3,5")
2219 (const_string "imovx")
2220 (and (match_test "TARGET_MOVX")
2221 (eq_attr "alternative" "2"))
2222 (const_string "imovx")
2224 (const_string "imov")))
2226 (cond [(eq_attr "alternative" "3,4,5")
2228 (eq_attr "alternative" "6")
2230 (eq_attr "type" "imovx")
2232 (and (eq_attr "type" "imov")
2233 (and (eq_attr "alternative" "0,1")
2234 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2235 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2236 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2238 ;; Avoid partial register stalls when not using QImode arithmetic
2239 (and (eq_attr "type" "imov")
2240 (and (eq_attr "alternative" "0,1")
2241 (and (match_test "TARGET_PARTIAL_REG_STALL")
2242 (not (match_test "TARGET_QIMODE_MATH")))))
2245 (const_string "QI")))])
2247 ;; Stores and loads of ax to arbitrary constant address.
2248 ;; We fake an second form of instruction to force reload to load address
2249 ;; into register when rax is not available
2250 (define_insn "*movabs<mode>_1"
2251 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2252 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2253 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2255 movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1}
2256 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2257 [(set_attr "type" "imov")
2258 (set_attr "modrm" "0,*")
2259 (set_attr "length_address" "8,0")
2260 (set_attr "length_immediate" "0,*")
2261 (set_attr "memory" "store")
2262 (set_attr "mode" "<MODE>")])
2264 (define_insn "*movabs<mode>_2"
2265 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2266 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2267 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2269 movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]}
2270 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2271 [(set_attr "type" "imov")
2272 (set_attr "modrm" "0,*")
2273 (set_attr "length_address" "8,0")
2274 (set_attr "length_immediate" "0")
2275 (set_attr "memory" "load")
2276 (set_attr "mode" "<MODE>")])
2278 (define_insn "swap<mode>"
2279 [(set (match_operand:SWI48 0 "register_operand" "+r")
2280 (match_operand:SWI48 1 "register_operand" "+r"))
2284 "xchg{<imodesuffix>}\t%1, %0"
2285 [(set_attr "type" "imov")
2286 (set_attr "mode" "<MODE>")
2287 (set_attr "pent_pair" "np")
2288 (set_attr "athlon_decode" "vector")
2289 (set_attr "amdfam10_decode" "double")
2290 (set_attr "bdver1_decode" "double")])
2292 (define_insn "*swap<mode>_1"
2293 [(set (match_operand:SWI12 0 "register_operand" "+r")
2294 (match_operand:SWI12 1 "register_operand" "+r"))
2297 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2299 [(set_attr "type" "imov")
2300 (set_attr "mode" "SI")
2301 (set_attr "pent_pair" "np")
2302 (set_attr "athlon_decode" "vector")
2303 (set_attr "amdfam10_decode" "double")
2304 (set_attr "bdver1_decode" "double")])
2306 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2307 ;; is disabled for AMDFAM10
2308 (define_insn "*swap<mode>_2"
2309 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2310 (match_operand:SWI12 1 "register_operand" "+<r>"))
2313 "TARGET_PARTIAL_REG_STALL"
2314 "xchg{<imodesuffix>}\t%1, %0"
2315 [(set_attr "type" "imov")
2316 (set_attr "mode" "<MODE>")
2317 (set_attr "pent_pair" "np")
2318 (set_attr "athlon_decode" "vector")])
2320 (define_expand "movstrict<mode>"
2321 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2322 (match_operand:SWI12 1 "general_operand"))]
2325 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2327 if (GET_CODE (operands[0]) == SUBREG
2328 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2330 /* Don't generate memory->memory moves, go through a register */
2331 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2332 operands[1] = force_reg (<MODE>mode, operands[1]);
2335 (define_insn "*movstrict<mode>_1"
2336 [(set (strict_low_part
2337 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2338 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2339 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2340 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2341 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2342 [(set_attr "type" "imov")
2343 (set_attr "mode" "<MODE>")])
2345 (define_insn "*movstrict<mode>_xor"
2346 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2347 (match_operand:SWI12 1 "const0_operand"))
2348 (clobber (reg:CC FLAGS_REG))]
2350 "xor{<imodesuffix>}\t%0, %0"
2351 [(set_attr "type" "alu1")
2352 (set_attr "mode" "<MODE>")
2353 (set_attr "length_immediate" "0")])
2355 (define_insn "*mov<mode>_extv_1"
2356 [(set (match_operand:SWI24 0 "register_operand" "=R")
2357 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2361 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2362 [(set_attr "type" "imovx")
2363 (set_attr "mode" "SI")])
2365 (define_insn "*movqi_extv_1"
2366 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2367 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2372 switch (get_attr_type (insn))
2375 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2377 return "mov{b}\t{%h1, %0|%0, %h1}";
2380 [(set_attr "isa" "*,*,nox64")
2382 (if_then_else (and (match_operand:QI 0 "register_operand")
2383 (ior (not (match_operand:QI 0 "QIreg_operand"))
2384 (match_test "TARGET_MOVX")))
2385 (const_string "imovx")
2386 (const_string "imov")))
2388 (if_then_else (eq_attr "type" "imovx")
2390 (const_string "QI")))])
2392 (define_insn "*mov<mode>_extzv_1"
2393 [(set (match_operand:SWI48 0 "register_operand" "=R")
2394 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2398 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2399 [(set_attr "type" "imovx")
2400 (set_attr "mode" "SI")])
2402 (define_insn "*movqi_extzv_2"
2403 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2405 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2410 switch (get_attr_type (insn))
2413 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2415 return "mov{b}\t{%h1, %0|%0, %h1}";
2418 [(set_attr "isa" "*,*,nox64")
2420 (if_then_else (and (match_operand:QI 0 "register_operand")
2421 (ior (not (match_operand:QI 0 "QIreg_operand"))
2422 (match_test "TARGET_MOVX")))
2423 (const_string "imovx")
2424 (const_string "imov")))
2426 (if_then_else (eq_attr "type" "imovx")
2428 (const_string "QI")))])
2430 (define_insn "mov<mode>_insv_1"
2431 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "+Q,Q")
2434 (match_operand:SWI48 1 "general_x64nomem_operand" "Qn,m"))]
2437 if (CONST_INT_P (operands[1]))
2438 operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2439 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2441 [(set_attr "isa" "*,nox64")
2442 (set_attr "type" "imov")
2443 (set_attr "mode" "QI")])
2445 (define_insn "*movqi_insv_2"
2446 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2449 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2452 "mov{b}\t{%h1, %h0|%h0, %h1}"
2453 [(set_attr "type" "imov")
2454 (set_attr "mode" "QI")])
2456 ;; Floating point push instructions.
2458 (define_insn "*pushtf"
2459 [(set (match_operand:TF 0 "push_operand" "=<,<")
2460 (match_operand:TF 1 "general_no_elim_operand" "x,*roF"))]
2461 "TARGET_64BIT || TARGET_SSE"
2463 /* This insn should be already split before reg-stack. */
2466 [(set_attr "isa" "*,x64")
2467 (set_attr "type" "multi")
2468 (set_attr "unit" "sse,*")
2469 (set_attr "mode" "TF,DI")])
2471 ;; %%% Kill this when call knows how to work this out.
2473 [(set (match_operand:TF 0 "push_operand")
2474 (match_operand:TF 1 "sse_reg_operand"))]
2475 "TARGET_SSE && reload_completed"
2476 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2477 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2479 (define_insn "*pushxf"
2480 [(set (match_operand:XF 0 "push_operand" "=<,<")
2481 (match_operand:XF 1 "general_no_elim_operand" "f,Yx*roF"))]
2484 /* This insn should be already split before reg-stack. */
2487 [(set_attr "type" "multi")
2488 (set_attr "unit" "i387,*")
2490 (cond [(eq_attr "alternative" "1")
2491 (if_then_else (match_test "TARGET_64BIT")
2493 (const_string "SI"))
2495 (const_string "XF")))])
2497 ;; %%% Kill this when call knows how to work this out.
2499 [(set (match_operand:XF 0 "push_operand")
2500 (match_operand:XF 1 "fp_register_operand"))]
2502 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2503 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2504 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2506 (define_insn "*pushdf"
2507 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2508 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*roF,rmF,x"))]
2511 /* This insn should be already split before reg-stack. */
2514 [(set_attr "isa" "*,nox64,x64,sse2")
2515 (set_attr "type" "multi")
2516 (set_attr "unit" "i387,*,*,sse")
2517 (set_attr "mode" "DF,SI,DI,DF")])
2519 ;; %%% Kill this when call knows how to work this out.
2521 [(set (match_operand:DF 0 "push_operand")
2522 (match_operand:DF 1 "any_fp_register_operand"))]
2524 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2525 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2527 (define_insn "*pushsf_rex64"
2528 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2529 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2532 /* Anything else should be already split before reg-stack. */
2533 gcc_assert (which_alternative == 1);
2534 return "push{q}\t%q1";
2536 [(set_attr "type" "multi,push,multi")
2537 (set_attr "unit" "i387,*,*")
2538 (set_attr "mode" "SF,DI,SF")])
2540 (define_insn "*pushsf"
2541 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2542 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
2545 /* Anything else should be already split before reg-stack. */
2546 gcc_assert (which_alternative == 1);
2547 return "push{l}\t%1";
2549 [(set_attr "type" "multi,push,multi")
2550 (set_attr "unit" "i387,*,*")
2551 (set_attr "mode" "SF,SI,SF")])
2553 ;; %%% Kill this when call knows how to work this out.
2555 [(set (match_operand:SF 0 "push_operand")
2556 (match_operand:SF 1 "any_fp_register_operand"))]
2558 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2559 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2560 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2563 [(set (match_operand:SF 0 "push_operand")
2564 (match_operand:SF 1 "memory_operand"))]
2566 && (operands[2] = find_constant_src (insn))"
2567 [(set (match_dup 0) (match_dup 2))])
2570 [(set (match_operand 0 "push_operand")
2571 (match_operand 1 "general_operand"))]
2573 && (GET_MODE (operands[0]) == TFmode
2574 || GET_MODE (operands[0]) == XFmode
2575 || GET_MODE (operands[0]) == DFmode)
2576 && !ANY_FP_REG_P (operands[1])"
2578 "ix86_split_long_move (operands); DONE;")
2580 ;; Floating point move instructions.
2582 (define_expand "movtf"
2583 [(set (match_operand:TF 0 "nonimmediate_operand")
2584 (match_operand:TF 1 "nonimmediate_operand"))]
2585 "TARGET_64BIT || TARGET_SSE"
2586 "ix86_expand_move (TFmode, operands); DONE;")
2588 (define_expand "mov<mode>"
2589 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2590 (match_operand:X87MODEF 1 "general_operand"))]
2592 "ix86_expand_move (<MODE>mode, operands); DONE;")
2594 (define_insn "*movtf_internal"
2595 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
2596 (match_operand:TF 1 "general_operand" "C ,xm,x,*roF,*rC"))]
2597 "(TARGET_64BIT || TARGET_SSE)
2598 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2599 && (!can_create_pseudo_p ()
2600 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2601 || GET_CODE (operands[1]) != CONST_DOUBLE
2602 || (optimize_function_for_size_p (cfun)
2603 && standard_sse_constant_p (operands[1])
2604 && !memory_operand (operands[0], TFmode))
2605 || (!TARGET_MEMORY_MISMATCH_STALL
2606 && memory_operand (operands[0], TFmode)))"
2608 switch (get_attr_type (insn))
2611 return standard_sse_constant_opcode (insn, operands[1]);
2614 /* Handle misaligned load/store since we
2615 don't have movmisaligntf pattern. */
2616 if (misaligned_operand (operands[0], TFmode)
2617 || misaligned_operand (operands[1], TFmode))
2619 if (get_attr_mode (insn) == MODE_V4SF)
2620 return "%vmovups\t{%1, %0|%0, %1}";
2622 return "%vmovdqu\t{%1, %0|%0, %1}";
2626 if (get_attr_mode (insn) == MODE_V4SF)
2627 return "%vmovaps\t{%1, %0|%0, %1}";
2629 return "%vmovdqa\t{%1, %0|%0, %1}";
2639 [(set_attr "isa" "*,*,*,x64,x64")
2640 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
2641 (set (attr "prefix")
2642 (if_then_else (eq_attr "type" "sselog1,ssemov")
2643 (const_string "maybe_vex")
2644 (const_string "orig")))
2646 (cond [(eq_attr "alternative" "3,4")
2648 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2649 (const_string "V4SF")
2650 (and (eq_attr "alternative" "2")
2651 (match_test "TARGET_SSE_TYPELESS_STORES"))
2652 (const_string "V4SF")
2653 (match_test "TARGET_AVX")
2655 (ior (not (match_test "TARGET_SSE2"))
2656 (match_test "optimize_function_for_size_p (cfun)"))
2657 (const_string "V4SF")
2659 (const_string "TI")))])
2661 ;; Possible store forwarding (partial memory) stall in alternatives 4 and 5.
2662 (define_insn "*movxf_internal"
2663 [(set (match_operand:XF 0 "nonimmediate_operand"
2664 "=f,m,f,?Yx*r ,!o ,!o")
2665 (match_operand:XF 1 "general_operand"
2666 "fm,f,G,Yx*roF,Yx*rF,Yx*rC"))]
2667 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2668 && (!can_create_pseudo_p ()
2669 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2670 || GET_CODE (operands[1]) != CONST_DOUBLE
2671 || (optimize_function_for_size_p (cfun)
2672 && standard_80387_constant_p (operands[1]) > 0
2673 && !memory_operand (operands[0], XFmode))
2674 || (!TARGET_MEMORY_MISMATCH_STALL
2675 && memory_operand (operands[0], XFmode)))"
2677 switch (get_attr_type (insn))
2680 if (which_alternative == 2)
2681 return standard_80387_constant_opcode (operands[1]);
2682 return output_387_reg_move (insn, operands);
2691 [(set_attr "isa" "*,*,*,*,nox64,x64")
2692 (set_attr "type" "fmov,fmov,fmov,multi,multi,multi")
2694 (cond [(eq_attr "alternative" "3,4,5")
2695 (if_then_else (match_test "TARGET_64BIT")
2697 (const_string "SI"))
2699 (const_string "XF")))])
2701 ;; Possible store forwarding (partial memory) stall in alternative 4.
2702 (define_insn "*movdf_internal"
2703 [(set (match_operand:DF 0 "nonimmediate_operand"
2704 "=Yf*f,m ,Yf*f,?Yd*r ,!o ,?r,?m,?r,?r,x,x,x,m,*x,*x,*x,m ,r ,Yi")
2705 (match_operand:DF 1 "general_operand"
2706 "Yf*fm,Yf*f,G ,Yd*roF,Yd*rF,rm,rC,C ,F ,C,x,m,x,C ,*x,m ,*x,Yj,r"))]
2707 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2708 && (!can_create_pseudo_p ()
2709 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2710 || GET_CODE (operands[1]) != CONST_DOUBLE
2711 || (optimize_function_for_size_p (cfun)
2712 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2713 && standard_80387_constant_p (operands[1]) > 0)
2714 || (TARGET_SSE2 && TARGET_SSE_MATH
2715 && standard_sse_constant_p (operands[1])))
2716 && !memory_operand (operands[0], DFmode))
2717 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
2718 && memory_operand (operands[0], DFmode)))"
2720 switch (get_attr_type (insn))
2723 if (which_alternative == 2)
2724 return standard_80387_constant_opcode (operands[1]);
2725 return output_387_reg_move (insn, operands);
2731 if (get_attr_mode (insn) == MODE_SI)
2732 return "mov{l}\t{%1, %k0|%k0, %1}";
2733 else if (which_alternative == 8)
2734 return "movabs{q}\t{%1, %0|%0, %1}";
2736 return "mov{q}\t{%1, %0|%0, %1}";
2739 return standard_sse_constant_opcode (insn, operands[1]);
2742 switch (get_attr_mode (insn))
2745 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2746 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2747 return "%vmovsd\t{%1, %0|%0, %1}";
2750 return "%vmovaps\t{%1, %0|%0, %1}";
2752 return "%vmovapd\t{%1, %0|%0, %1}";
2755 gcc_assert (!TARGET_AVX);
2756 return "movlps\t{%1, %0|%0, %1}";
2758 gcc_assert (!TARGET_AVX);
2759 return "movlpd\t{%1, %0|%0, %1}";
2762 #ifndef HAVE_AS_IX86_INTERUNIT_MOVQ
2763 /* Handle broken assemblers that require movd instead of movq. */
2764 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2765 return "%vmovd\t{%1, %0|%0, %1}";
2767 return "%vmovq\t{%1, %0|%0, %1}";
2778 (cond [(eq_attr "alternative" "3,4")
2779 (const_string "nox64")
2780 (eq_attr "alternative" "5,6,7,8,17,18")
2781 (const_string "x64")
2782 (eq_attr "alternative" "9,10,11,12")
2783 (const_string "sse2")
2785 (const_string "*")))
2787 (cond [(eq_attr "alternative" "0,1,2")
2788 (const_string "fmov")
2789 (eq_attr "alternative" "3,4")
2790 (const_string "multi")
2791 (eq_attr "alternative" "5,6,7,8")
2792 (const_string "imov")
2793 (eq_attr "alternative" "9,13")
2794 (const_string "sselog1")
2796 (const_string "ssemov")))
2798 (if_then_else (eq_attr "alternative" "8")
2800 (const_string "*")))
2801 (set (attr "length_immediate")
2802 (if_then_else (eq_attr "alternative" "8")
2804 (const_string "*")))
2805 (set (attr "prefix")
2806 (if_then_else (eq_attr "type" "sselog1,ssemov")
2807 (const_string "maybe_vex")
2808 (const_string "orig")))
2809 (set (attr "prefix_data16")
2811 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2812 (eq_attr "mode" "V1DF"))
2814 (const_string "*")))
2816 (cond [(eq_attr "alternative" "3,4,7")
2818 (eq_attr "alternative" "5,6,8,17,18")
2821 /* xorps is one byte shorter for non-AVX targets. */
2822 (eq_attr "alternative" "9,13")
2823 (cond [(not (match_test "TARGET_SSE2"))
2824 (const_string "V4SF")
2825 (match_test "TARGET_AVX")
2826 (const_string "V2DF")
2827 (match_test "optimize_function_for_size_p (cfun)")
2828 (const_string "V4SF")
2829 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
2832 (const_string "V2DF"))
2834 /* For architectures resolving dependencies on
2835 whole SSE registers use movapd to break dependency
2836 chains, otherwise use short move to avoid extra work. */
2838 /* movaps is one byte shorter for non-AVX targets. */
2839 (eq_attr "alternative" "10,14")
2840 (cond [(ior (not (match_test "TARGET_SSE2"))
2841 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2842 (const_string "V4SF")
2843 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2844 (const_string "V2DF")
2845 (match_test "TARGET_AVX")
2847 (match_test "optimize_function_for_size_p (cfun)")
2848 (const_string "V4SF")
2850 (const_string "DF"))
2852 /* For architectures resolving dependencies on register
2853 parts we may avoid extra work to zero out upper part
2855 (eq_attr "alternative" "11,15")
2856 (cond [(not (match_test "TARGET_SSE2"))
2857 (const_string "V2SF")
2858 (match_test "TARGET_AVX")
2860 (match_test "TARGET_SSE_SPLIT_REGS")
2861 (const_string "V1DF")
2863 (const_string "DF"))
2865 (and (eq_attr "alternative" "12,16")
2866 (not (match_test "TARGET_SSE2")))
2867 (const_string "V2SF")
2869 (const_string "DF")))])
2871 (define_insn "*movsf_internal"
2872 [(set (match_operand:SF 0 "nonimmediate_operand"
2873 "=Yf*f,m ,Yf*f,?r ,?m,x,x,x,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym")
2874 (match_operand:SF 1 "general_operand"
2875 "Yf*fm,Yf*f,G ,rmF,rF,C,x,m,x,Yj,r ,*y ,m ,*y,*Yn,r"))]
2876 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2877 && (!can_create_pseudo_p ()
2878 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2879 || GET_CODE (operands[1]) != CONST_DOUBLE
2880 || (optimize_function_for_size_p (cfun)
2881 && ((!TARGET_SSE_MATH
2882 && standard_80387_constant_p (operands[1]) > 0)
2884 && standard_sse_constant_p (operands[1]))))
2885 || memory_operand (operands[0], SFmode))"
2887 switch (get_attr_type (insn))
2890 if (which_alternative == 2)
2891 return standard_80387_constant_opcode (operands[1]);
2892 return output_387_reg_move (insn, operands);
2895 return "mov{l}\t{%1, %0|%0, %1}";
2898 return standard_sse_constant_opcode (insn, operands[1]);
2901 switch (get_attr_mode (insn))
2904 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2905 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
2906 return "%vmovss\t{%1, %0|%0, %1}";
2909 return "%vmovaps\t{%1, %0|%0, %1}";
2912 return "%vmovd\t{%1, %0|%0, %1}";
2919 switch (get_attr_mode (insn))
2922 return "movq\t{%1, %0|%0, %1}";
2924 return "movd\t{%1, %0|%0, %1}";
2935 (cond [(eq_attr "alternative" "0,1,2")
2936 (const_string "fmov")
2937 (eq_attr "alternative" "3,4")
2938 (const_string "imov")
2939 (eq_attr "alternative" "5")
2940 (const_string "sselog1")
2941 (eq_attr "alternative" "11,12,13,14,15")
2942 (const_string "mmxmov")
2944 (const_string "ssemov")))
2945 (set (attr "prefix")
2946 (if_then_else (eq_attr "type" "sselog1,ssemov")
2947 (const_string "maybe_vex")
2948 (const_string "orig")))
2949 (set (attr "prefix_data16")
2950 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2952 (const_string "*")))
2954 (cond [(eq_attr "alternative" "3,4,9,10,14,15")
2956 (eq_attr "alternative" "11")
2958 (eq_attr "alternative" "5")
2959 (cond [(not (match_test "TARGET_SSE2"))
2960 (const_string "V4SF")
2961 (match_test "TARGET_AVX")
2962 (const_string "V4SF")
2963 (match_test "optimize_function_for_size_p (cfun)")
2964 (const_string "V4SF")
2965 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
2968 (const_string "V4SF"))
2970 /* For architectures resolving dependencies on
2971 whole SSE registers use APS move to break dependency
2972 chains, otherwise use short move to avoid extra work.
2974 Do the same for architectures resolving dependencies on
2975 the parts. While in DF mode it is better to always handle
2976 just register parts, the SF mode is different due to lack
2977 of instructions to load just part of the register. It is
2978 better to maintain the whole registers in single format
2979 to avoid problems on using packed logical operations. */
2980 (and (eq_attr "alternative" "6")
2981 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2982 (match_test "TARGET_SSE_SPLIT_REGS")))
2983 (const_string "V4SF")
2985 (const_string "SF")))])
2988 [(set (match_operand 0 "any_fp_register_operand")
2989 (match_operand 1 "memory_operand"))]
2991 && (GET_MODE (operands[0]) == TFmode
2992 || GET_MODE (operands[0]) == XFmode
2993 || GET_MODE (operands[0]) == DFmode
2994 || GET_MODE (operands[0]) == SFmode)
2995 && (operands[2] = find_constant_src (insn))"
2996 [(set (match_dup 0) (match_dup 2))]
2998 rtx c = operands[2];
2999 int r = REGNO (operands[0]);
3001 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3002 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3007 [(set (match_operand 0 "any_fp_register_operand")
3008 (float_extend (match_operand 1 "memory_operand")))]
3010 && (GET_MODE (operands[0]) == TFmode
3011 || GET_MODE (operands[0]) == XFmode
3012 || GET_MODE (operands[0]) == DFmode)
3013 && (operands[2] = find_constant_src (insn))"
3014 [(set (match_dup 0) (match_dup 2))]
3016 rtx c = operands[2];
3017 int r = REGNO (operands[0]);
3019 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3020 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3024 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3026 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3027 (match_operand:X87MODEF 1 "immediate_operand"))]
3029 && (standard_80387_constant_p (operands[1]) == 8
3030 || standard_80387_constant_p (operands[1]) == 9)"
3031 [(set (match_dup 0)(match_dup 1))
3033 (neg:X87MODEF (match_dup 0)))]
3037 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3038 if (real_isnegzero (&r))
3039 operands[1] = CONST0_RTX (<MODE>mode);
3041 operands[1] = CONST1_RTX (<MODE>mode);
3045 [(set (match_operand 0 "nonimmediate_operand")
3046 (match_operand 1 "general_operand"))]
3048 && (GET_MODE (operands[0]) == TFmode
3049 || GET_MODE (operands[0]) == XFmode
3050 || GET_MODE (operands[0]) == DFmode)
3051 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3053 "ix86_split_long_move (operands); DONE;")
3055 (define_insn "swapxf"
3056 [(set (match_operand:XF 0 "register_operand" "+f")
3057 (match_operand:XF 1 "register_operand" "+f"))
3062 if (STACK_TOP_P (operands[0]))
3067 [(set_attr "type" "fxch")
3068 (set_attr "mode" "XF")])
3070 (define_insn "*swap<mode>"
3071 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3072 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3075 "TARGET_80387 || reload_completed"
3077 if (STACK_TOP_P (operands[0]))
3082 [(set_attr "type" "fxch")
3083 (set_attr "mode" "<MODE>")])
3085 ;; Zero extension instructions
3087 (define_expand "zero_extendsidi2"
3088 [(set (match_operand:DI 0 "nonimmediate_operand")
3089 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3091 (define_insn "*zero_extendsidi2"
3092 [(set (match_operand:DI 0 "nonimmediate_operand"
3093 "=r,?r,?o,r ,o,?*Ym,?!*y,?r ,?r,?*Yi,?*x")
3095 (match_operand:SI 1 "x86_64_zext_operand"
3096 "0 ,rm,r ,rmWz,0,r ,m ,*Yj,*x,r ,m")))]
3099 switch (get_attr_type (insn))
3102 if (ix86_use_lea_for_mov (insn, operands))
3103 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3105 return "mov{l}\t{%1, %k0|%k0, %1}";
3111 return "movd\t{%1, %0|%0, %1}";
3114 return "%vpextrd\t{$0, %1, %k0|%k0, %1, 0}";
3117 if (GENERAL_REG_P (operands[0]))
3118 return "%vmovd\t{%1, %k0|%k0, %1}";
3120 return "%vmovd\t{%1, %0|%0, %1}";
3127 (cond [(eq_attr "alternative" "0,1,2")
3128 (const_string "nox64")
3129 (eq_attr "alternative" "3,7")
3130 (const_string "x64")
3131 (eq_attr "alternative" "8")
3132 (const_string "x64_sse4")
3133 (eq_attr "alternative" "10")
3134 (const_string "sse2")
3136 (const_string "*")))
3138 (cond [(eq_attr "alternative" "0,1,2,4")
3139 (const_string "multi")
3140 (eq_attr "alternative" "5,6")
3141 (const_string "mmxmov")
3142 (eq_attr "alternative" "7,9,10")
3143 (const_string "ssemov")
3144 (eq_attr "alternative" "8")
3145 (const_string "sselog1")
3147 (const_string "imovx")))
3148 (set (attr "prefix_extra")
3149 (if_then_else (eq_attr "alternative" "8")
3151 (const_string "*")))
3152 (set (attr "length_immediate")
3153 (if_then_else (eq_attr "alternative" "8")
3155 (const_string "*")))
3156 (set (attr "prefix")
3157 (if_then_else (eq_attr "type" "ssemov,sselog1")
3158 (const_string "maybe_vex")
3159 (const_string "orig")))
3160 (set (attr "prefix_0f")
3161 (if_then_else (eq_attr "type" "imovx")
3163 (const_string "*")))
3165 (cond [(eq_attr "alternative" "5,6")
3167 (eq_attr "alternative" "7,8,9")
3170 (const_string "SI")))])
3173 [(set (match_operand:DI 0 "memory_operand")
3174 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3176 [(set (match_dup 4) (const_int 0))]
3177 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3180 [(set (match_operand:DI 0 "register_operand")
3181 (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3182 "!TARGET_64BIT && reload_completed
3183 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3184 && true_regnum (operands[0]) == true_regnum (operands[1])"
3185 [(set (match_dup 4) (const_int 0))]
3186 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3189 [(set (match_operand:DI 0 "nonimmediate_operand")
3190 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3191 "!TARGET_64BIT && reload_completed
3192 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3193 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3194 [(set (match_dup 3) (match_dup 1))
3195 (set (match_dup 4) (const_int 0))]
3196 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3198 (define_insn "zero_extend<mode>di2"
3199 [(set (match_operand:DI 0 "register_operand" "=r")
3201 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3203 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3204 [(set_attr "type" "imovx")
3205 (set_attr "mode" "SI")])
3207 (define_expand "zero_extend<mode>si2"
3208 [(set (match_operand:SI 0 "register_operand")
3209 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3212 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3214 operands[1] = force_reg (<MODE>mode, operands[1]);
3215 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3220 (define_insn_and_split "zero_extend<mode>si2_and"
3221 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3223 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3224 (clobber (reg:CC FLAGS_REG))]
3225 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3227 "&& reload_completed"
3228 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3229 (clobber (reg:CC FLAGS_REG))])]
3231 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3233 ix86_expand_clear (operands[0]);
3235 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3236 emit_insn (gen_movstrict<mode>
3237 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3241 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3243 [(set_attr "type" "alu1")
3244 (set_attr "mode" "SI")])
3246 (define_insn "*zero_extend<mode>si2"
3247 [(set (match_operand:SI 0 "register_operand" "=r")
3249 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3250 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3251 "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3252 [(set_attr "type" "imovx")
3253 (set_attr "mode" "SI")])
3255 (define_expand "zero_extendqihi2"
3256 [(set (match_operand:HI 0 "register_operand")
3257 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3260 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3262 operands[1] = force_reg (QImode, operands[1]);
3263 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3268 (define_insn_and_split "zero_extendqihi2_and"
3269 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3270 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3271 (clobber (reg:CC FLAGS_REG))]
3272 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3274 "&& reload_completed"
3275 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3276 (clobber (reg:CC FLAGS_REG))])]
3278 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3280 ix86_expand_clear (operands[0]);
3282 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3283 emit_insn (gen_movstrictqi
3284 (gen_lowpart (QImode, operands[0]), operands[1]));
3288 operands[0] = gen_lowpart (SImode, operands[0]);
3290 [(set_attr "type" "alu1")
3291 (set_attr "mode" "SI")])
3293 ; zero extend to SImode to avoid partial register stalls
3294 (define_insn "*zero_extendqihi2"
3295 [(set (match_operand:HI 0 "register_operand" "=r")
3296 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3297 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3298 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3299 [(set_attr "type" "imovx")
3300 (set_attr "mode" "SI")])
3302 ;; Sign extension instructions
3304 (define_expand "extendsidi2"
3305 [(set (match_operand:DI 0 "register_operand")
3306 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3311 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3316 (define_insn "*extendsidi2_rex64"
3317 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3318 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3322 movs{lq|x}\t{%1, %0|%0, %1}"
3323 [(set_attr "type" "imovx")
3324 (set_attr "mode" "DI")
3325 (set_attr "prefix_0f" "0")
3326 (set_attr "modrm" "0,1")])
3328 (define_insn "extendsidi2_1"
3329 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3330 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3331 (clobber (reg:CC FLAGS_REG))
3332 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3336 ;; Split the memory case. If the source register doesn't die, it will stay
3337 ;; this way, if it does die, following peephole2s take care of it.
3339 [(set (match_operand:DI 0 "memory_operand")
3340 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3341 (clobber (reg:CC FLAGS_REG))
3342 (clobber (match_operand:SI 2 "register_operand"))]
3346 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3348 emit_move_insn (operands[3], operands[1]);
3350 /* Generate a cltd if possible and doing so it profitable. */
3351 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3352 && true_regnum (operands[1]) == AX_REG
3353 && true_regnum (operands[2]) == DX_REG)
3355 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3359 emit_move_insn (operands[2], operands[1]);
3360 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3362 emit_move_insn (operands[4], operands[2]);
3366 ;; Peepholes for the case where the source register does die, after
3367 ;; being split with the above splitter.
3369 [(set (match_operand:SI 0 "memory_operand")
3370 (match_operand:SI 1 "register_operand"))
3371 (set (match_operand:SI 2 "register_operand") (match_dup 1))
3372 (parallel [(set (match_dup 2)
3373 (ashiftrt:SI (match_dup 2) (const_int 31)))
3374 (clobber (reg:CC FLAGS_REG))])
3375 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3376 "REGNO (operands[1]) != REGNO (operands[2])
3377 && peep2_reg_dead_p (2, operands[1])
3378 && peep2_reg_dead_p (4, operands[2])
3379 && !reg_mentioned_p (operands[2], operands[3])"
3380 [(set (match_dup 0) (match_dup 1))
3381 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3382 (clobber (reg:CC FLAGS_REG))])
3383 (set (match_dup 3) (match_dup 1))])
3386 [(set (match_operand:SI 0 "memory_operand")
3387 (match_operand:SI 1 "register_operand"))
3388 (parallel [(set (match_operand:SI 2 "register_operand")
3389 (ashiftrt:SI (match_dup 1) (const_int 31)))
3390 (clobber (reg:CC FLAGS_REG))])
3391 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3392 "/* cltd is shorter than sarl $31, %eax */
3393 !optimize_function_for_size_p (cfun)
3394 && true_regnum (operands[1]) == AX_REG
3395 && true_regnum (operands[2]) == DX_REG
3396 && peep2_reg_dead_p (2, operands[1])
3397 && peep2_reg_dead_p (3, operands[2])
3398 && !reg_mentioned_p (operands[2], operands[3])"
3399 [(set (match_dup 0) (match_dup 1))
3400 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3401 (clobber (reg:CC FLAGS_REG))])
3402 (set (match_dup 3) (match_dup 1))])
3404 ;; Extend to register case. Optimize case where source and destination
3405 ;; registers match and cases where we can use cltd.
3407 [(set (match_operand:DI 0 "register_operand")
3408 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3409 (clobber (reg:CC FLAGS_REG))
3410 (clobber (match_scratch:SI 2))]
3414 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3416 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3417 emit_move_insn (operands[3], operands[1]);
3419 /* Generate a cltd if possible and doing so it profitable. */
3420 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3421 && true_regnum (operands[3]) == AX_REG
3422 && true_regnum (operands[4]) == DX_REG)
3424 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3428 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3429 emit_move_insn (operands[4], operands[1]);
3431 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3435 (define_insn "extend<mode>di2"
3436 [(set (match_operand:DI 0 "register_operand" "=r")
3438 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3440 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3441 [(set_attr "type" "imovx")
3442 (set_attr "mode" "DI")])
3444 (define_insn "extendhisi2"
3445 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3446 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3449 switch (get_attr_prefix_0f (insn))
3452 return "{cwtl|cwde}";
3454 return "movs{wl|x}\t{%1, %0|%0, %1}";
3457 [(set_attr "type" "imovx")
3458 (set_attr "mode" "SI")
3459 (set (attr "prefix_0f")
3460 ;; movsx is short decodable while cwtl is vector decoded.
3461 (if_then_else (and (eq_attr "cpu" "!k6")
3462 (eq_attr "alternative" "0"))
3464 (const_string "1")))
3466 (if_then_else (eq_attr "prefix_0f" "0")
3468 (const_string "1")))])
3470 (define_insn "*extendhisi2_zext"
3471 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3474 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3477 switch (get_attr_prefix_0f (insn))
3480 return "{cwtl|cwde}";
3482 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3485 [(set_attr "type" "imovx")
3486 (set_attr "mode" "SI")
3487 (set (attr "prefix_0f")
3488 ;; movsx is short decodable while cwtl is vector decoded.
3489 (if_then_else (and (eq_attr "cpu" "!k6")
3490 (eq_attr "alternative" "0"))
3492 (const_string "1")))
3494 (if_then_else (eq_attr "prefix_0f" "0")
3496 (const_string "1")))])
3498 (define_insn "extendqisi2"
3499 [(set (match_operand:SI 0 "register_operand" "=r")
3500 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3502 "movs{bl|x}\t{%1, %0|%0, %1}"
3503 [(set_attr "type" "imovx")
3504 (set_attr "mode" "SI")])
3506 (define_insn "*extendqisi2_zext"
3507 [(set (match_operand:DI 0 "register_operand" "=r")
3509 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3511 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3512 [(set_attr "type" "imovx")
3513 (set_attr "mode" "SI")])
3515 (define_insn "extendqihi2"
3516 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3517 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3520 switch (get_attr_prefix_0f (insn))
3523 return "{cbtw|cbw}";
3525 return "movs{bw|x}\t{%1, %0|%0, %1}";
3528 [(set_attr "type" "imovx")
3529 (set_attr "mode" "HI")
3530 (set (attr "prefix_0f")
3531 ;; movsx is short decodable while cwtl is vector decoded.
3532 (if_then_else (and (eq_attr "cpu" "!k6")
3533 (eq_attr "alternative" "0"))
3535 (const_string "1")))
3537 (if_then_else (eq_attr "prefix_0f" "0")
3539 (const_string "1")))])
3541 ;; Conversions between float and double.
3543 ;; These are all no-ops in the model used for the 80387.
3544 ;; So just emit moves.
3546 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3548 [(set (match_operand:DF 0 "push_operand")
3549 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3551 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3552 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3555 [(set (match_operand:XF 0 "push_operand")
3556 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3558 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3559 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3560 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3562 (define_expand "extendsfdf2"
3563 [(set (match_operand:DF 0 "nonimmediate_operand")
3564 (float_extend:DF (match_operand:SF 1 "general_operand")))]
3565 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3567 /* ??? Needed for compress_float_constant since all fp constants
3568 are TARGET_LEGITIMATE_CONSTANT_P. */
3569 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3571 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3572 && standard_80387_constant_p (operands[1]) > 0)
3574 operands[1] = simplify_const_unary_operation
3575 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3576 emit_move_insn_1 (operands[0], operands[1]);
3579 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3583 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3585 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3587 We do the conversion post reload to avoid producing of 128bit spills
3588 that might lead to ICE on 32bit target. The sequence unlikely combine
3591 [(set (match_operand:DF 0 "register_operand")
3593 (match_operand:SF 1 "nonimmediate_operand")))]
3594 "TARGET_USE_VECTOR_FP_CONVERTS
3595 && optimize_insn_for_speed_p ()
3596 && reload_completed && SSE_REG_P (operands[0])"
3601 (parallel [(const_int 0) (const_int 1)]))))]
3603 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3604 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3605 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3606 Try to avoid move when unpacking can be done in source. */
3607 if (REG_P (operands[1]))
3609 /* If it is unsafe to overwrite upper half of source, we need
3610 to move to destination and unpack there. */
3611 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3612 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3613 && true_regnum (operands[0]) != true_regnum (operands[1]))
3615 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3616 emit_move_insn (tmp, operands[1]);
3619 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3620 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3624 emit_insn (gen_vec_setv4sf_0 (operands[3],
3625 CONST0_RTX (V4SFmode), operands[1]));
3628 ;; It's more profitable to split and then extend in the same register.
3630 [(set (match_operand:DF 0 "register_operand")
3632 (match_operand:SF 1 "memory_operand")))]
3633 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
3634 && optimize_insn_for_speed_p ()
3635 && SSE_REG_P (operands[0])"
3636 [(set (match_dup 2) (match_dup 1))
3637 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
3638 "operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));")
3640 (define_insn "*extendsfdf2_mixed"
3641 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3643 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3644 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3646 switch (which_alternative)
3650 return output_387_reg_move (insn, operands);
3653 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3659 [(set_attr "type" "fmov,fmov,ssecvt")
3660 (set_attr "prefix" "orig,orig,maybe_vex")
3661 (set_attr "mode" "SF,XF,DF")])
3663 (define_insn "*extendsfdf2_sse"
3664 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3665 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3666 "TARGET_SSE2 && TARGET_SSE_MATH"
3667 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3668 [(set_attr "type" "ssecvt")
3669 (set_attr "prefix" "maybe_vex")
3670 (set_attr "mode" "DF")])
3672 (define_insn "*extendsfdf2_i387"
3673 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3674 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3676 "* return output_387_reg_move (insn, operands);"
3677 [(set_attr "type" "fmov")
3678 (set_attr "mode" "SF,XF")])
3680 (define_expand "extend<mode>xf2"
3681 [(set (match_operand:XF 0 "nonimmediate_operand")
3682 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
3685 /* ??? Needed for compress_float_constant since all fp constants
3686 are TARGET_LEGITIMATE_CONSTANT_P. */
3687 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3689 if (standard_80387_constant_p (operands[1]) > 0)
3691 operands[1] = simplify_const_unary_operation
3692 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3693 emit_move_insn_1 (operands[0], operands[1]);
3696 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3700 (define_insn "*extend<mode>xf2_i387"
3701 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3703 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3705 "* return output_387_reg_move (insn, operands);"
3706 [(set_attr "type" "fmov")
3707 (set_attr "mode" "<MODE>,XF")])
3709 ;; %%% This seems bad bad news.
3710 ;; This cannot output into an f-reg because there is no way to be sure
3711 ;; of truncating in that case. Otherwise this is just like a simple move
3712 ;; insn. So we pretend we can output to a reg in order to get better
3713 ;; register preferencing, but we really use a stack slot.
3715 ;; Conversion from DFmode to SFmode.
3717 (define_expand "truncdfsf2"
3718 [(set (match_operand:SF 0 "nonimmediate_operand")
3720 (match_operand:DF 1 "nonimmediate_operand")))]
3721 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3723 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3725 else if (flag_unsafe_math_optimizations)
3729 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3730 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3735 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
3737 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3739 We do the conversion post reload to avoid producing of 128bit spills
3740 that might lead to ICE on 32bit target. The sequence unlikely combine
3743 [(set (match_operand:SF 0 "register_operand")
3745 (match_operand:DF 1 "nonimmediate_operand")))]
3746 "TARGET_USE_VECTOR_FP_CONVERTS
3747 && optimize_insn_for_speed_p ()
3748 && reload_completed && SSE_REG_P (operands[0])"
3751 (float_truncate:V2SF
3755 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3756 operands[3] = CONST0_RTX (V2SFmode);
3757 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
3758 /* Use movsd for loading from memory, unpcklpd for registers.
3759 Try to avoid move when unpacking can be done in source, or SSE3
3760 movddup is available. */
3761 if (REG_P (operands[1]))
3764 && true_regnum (operands[0]) != true_regnum (operands[1])
3765 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3766 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
3768 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
3769 emit_move_insn (tmp, operands[1]);
3772 else if (!TARGET_SSE3)
3773 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3774 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
3777 emit_insn (gen_sse2_loadlpd (operands[4],
3778 CONST0_RTX (V2DFmode), operands[1]));
3781 ;; It's more profitable to split and then extend in the same register.
3783 [(set (match_operand:SF 0 "register_operand")
3785 (match_operand:DF 1 "memory_operand")))]
3786 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
3787 && optimize_insn_for_speed_p ()
3788 && SSE_REG_P (operands[0])"
3789 [(set (match_dup 2) (match_dup 1))
3790 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
3791 "operands[2] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
3793 (define_expand "truncdfsf2_with_temp"
3794 [(parallel [(set (match_operand:SF 0)
3795 (float_truncate:SF (match_operand:DF 1)))
3796 (clobber (match_operand:SF 2))])])
3798 (define_insn "*truncdfsf_fast_mixed"
3799 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
3801 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
3802 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3804 switch (which_alternative)
3807 return output_387_reg_move (insn, operands);
3809 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
3814 [(set_attr "type" "fmov,ssecvt")
3815 (set_attr "prefix" "orig,maybe_vex")
3816 (set_attr "mode" "SF")])
3818 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3819 ;; because nothing we do here is unsafe.
3820 (define_insn "*truncdfsf_fast_sse"
3821 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
3823 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
3824 "TARGET_SSE2 && TARGET_SSE_MATH"
3825 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
3826 [(set_attr "type" "ssecvt")
3827 (set_attr "prefix" "maybe_vex")
3828 (set_attr "mode" "SF")])
3830 (define_insn "*truncdfsf_fast_i387"
3831 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
3833 (match_operand:DF 1 "nonimmediate_operand" "f")))]
3834 "TARGET_80387 && flag_unsafe_math_optimizations"
3835 "* return output_387_reg_move (insn, operands);"
3836 [(set_attr "type" "fmov")
3837 (set_attr "mode" "SF")])
3839 (define_insn "*truncdfsf_mixed"
3840 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
3842 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
3843 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
3844 "TARGET_MIX_SSE_I387"
3846 switch (which_alternative)
3849 return output_387_reg_move (insn, operands);
3851 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
3857 [(set_attr "isa" "*,sse2,*,*,*")
3858 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
3859 (set_attr "unit" "*,*,i387,i387,i387")
3860 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
3861 (set_attr "mode" "SF")])
3863 (define_insn "*truncdfsf_i387"
3864 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
3866 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
3867 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
3870 switch (which_alternative)
3873 return output_387_reg_move (insn, operands);
3879 [(set_attr "type" "fmov,multi,multi,multi")
3880 (set_attr "unit" "*,i387,i387,i387")
3881 (set_attr "mode" "SF")])
3883 (define_insn "*truncdfsf2_i387_1"
3884 [(set (match_operand:SF 0 "memory_operand" "=m")
3886 (match_operand:DF 1 "register_operand" "f")))]
3888 && !(TARGET_SSE2 && TARGET_SSE_MATH)
3889 && !TARGET_MIX_SSE_I387"
3890 "* return output_387_reg_move (insn, operands);"
3891 [(set_attr "type" "fmov")
3892 (set_attr "mode" "SF")])
3895 [(set (match_operand:SF 0 "register_operand")
3897 (match_operand:DF 1 "fp_register_operand")))
3898 (clobber (match_operand 2))]
3900 [(set (match_dup 2) (match_dup 1))
3901 (set (match_dup 0) (match_dup 2))]
3902 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
3904 ;; Conversion from XFmode to {SF,DF}mode
3906 (define_expand "truncxf<mode>2"
3907 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
3908 (float_truncate:MODEF
3909 (match_operand:XF 1 "register_operand")))
3910 (clobber (match_dup 2))])]
3913 if (flag_unsafe_math_optimizations)
3915 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
3916 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
3917 if (reg != operands[0])
3918 emit_move_insn (operands[0], reg);
3922 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
3925 (define_insn "*truncxfsf2_mixed"
3926 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
3928 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
3929 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
3932 gcc_assert (!which_alternative);
3933 return output_387_reg_move (insn, operands);
3935 [(set_attr "type" "fmov,multi,multi,multi")
3936 (set_attr "unit" "*,i387,i387,i387")
3937 (set_attr "mode" "SF")])
3939 (define_insn "*truncxfdf2_mixed"
3940 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
3942 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
3943 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
3946 gcc_assert (!which_alternative);
3947 return output_387_reg_move (insn, operands);
3949 [(set_attr "isa" "*,*,sse2,*")
3950 (set_attr "type" "fmov,multi,multi,multi")
3951 (set_attr "unit" "*,i387,i387,i387")
3952 (set_attr "mode" "DF")])
3954 (define_insn "truncxf<mode>2_i387_noop"
3955 [(set (match_operand:MODEF 0 "register_operand" "=f")
3956 (float_truncate:MODEF
3957 (match_operand:XF 1 "register_operand" "f")))]
3958 "TARGET_80387 && flag_unsafe_math_optimizations"
3959 "* return output_387_reg_move (insn, operands);"
3960 [(set_attr "type" "fmov")
3961 (set_attr "mode" "<MODE>")])
3963 (define_insn "*truncxf<mode>2_i387"
3964 [(set (match_operand:MODEF 0 "memory_operand" "=m")
3965 (float_truncate:MODEF
3966 (match_operand:XF 1 "register_operand" "f")))]
3968 "* return output_387_reg_move (insn, operands);"
3969 [(set_attr "type" "fmov")
3970 (set_attr "mode" "<MODE>")])
3973 [(set (match_operand:MODEF 0 "register_operand")
3974 (float_truncate:MODEF
3975 (match_operand:XF 1 "register_operand")))
3976 (clobber (match_operand:MODEF 2 "memory_operand"))]
3977 "TARGET_80387 && reload_completed"
3978 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
3979 (set (match_dup 0) (match_dup 2))])
3982 [(set (match_operand:MODEF 0 "memory_operand")
3983 (float_truncate:MODEF
3984 (match_operand:XF 1 "register_operand")))
3985 (clobber (match_operand:MODEF 2 "memory_operand"))]
3987 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
3989 ;; Signed conversion to DImode.
3991 (define_expand "fix_truncxfdi2"
3992 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
3993 (fix:DI (match_operand:XF 1 "register_operand")))
3994 (clobber (reg:CC FLAGS_REG))])]
3999 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4004 (define_expand "fix_trunc<mode>di2"
4005 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4006 (fix:DI (match_operand:MODEF 1 "register_operand")))
4007 (clobber (reg:CC FLAGS_REG))])]
4008 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4011 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4013 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4016 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4018 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4019 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4020 if (out != operands[0])
4021 emit_move_insn (operands[0], out);
4026 ;; Signed conversion to SImode.
4028 (define_expand "fix_truncxfsi2"
4029 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4030 (fix:SI (match_operand:XF 1 "register_operand")))
4031 (clobber (reg:CC FLAGS_REG))])]
4036 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4041 (define_expand "fix_trunc<mode>si2"
4042 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4043 (fix:SI (match_operand:MODEF 1 "register_operand")))
4044 (clobber (reg:CC FLAGS_REG))])]
4045 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4048 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4050 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4053 if (SSE_FLOAT_MODE_P (<MODE>mode))
4055 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4056 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4057 if (out != operands[0])
4058 emit_move_insn (operands[0], out);
4063 ;; Signed conversion to HImode.
4065 (define_expand "fix_trunc<mode>hi2"
4066 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4067 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4068 (clobber (reg:CC FLAGS_REG))])]
4070 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4074 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4079 ;; Unsigned conversion to SImode.
4081 (define_expand "fixuns_trunc<mode>si2"
4083 [(set (match_operand:SI 0 "register_operand")
4085 (match_operand:MODEF 1 "nonimmediate_operand")))
4087 (clobber (match_scratch:<ssevecmode> 3))
4088 (clobber (match_scratch:<ssevecmode> 4))])]
4089 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4091 enum machine_mode mode = <MODE>mode;
4092 enum machine_mode vecmode = <ssevecmode>mode;
4093 REAL_VALUE_TYPE TWO31r;
4096 if (optimize_insn_for_size_p ())
4099 real_ldexp (&TWO31r, &dconst1, 31);
4100 two31 = const_double_from_real_value (TWO31r, mode);
4101 two31 = ix86_build_const_vector (vecmode, true, two31);
4102 operands[2] = force_reg (vecmode, two31);
4105 (define_insn_and_split "*fixuns_trunc<mode>_1"
4106 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4108 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4109 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4110 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4111 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4112 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4113 && optimize_function_for_speed_p (cfun)"
4115 "&& reload_completed"
4118 ix86_split_convert_uns_si_sse (operands);
4122 ;; Unsigned conversion to HImode.
4123 ;; Without these patterns, we'll try the unsigned SI conversion which
4124 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4126 (define_expand "fixuns_trunc<mode>hi2"
4128 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4129 (set (match_operand:HI 0 "nonimmediate_operand")
4130 (subreg:HI (match_dup 2) 0))]
4131 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4132 "operands[2] = gen_reg_rtx (SImode);")
4134 ;; When SSE is available, it is always faster to use it!
4135 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4136 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4137 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4138 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4139 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4140 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4141 [(set_attr "type" "sseicvt")
4142 (set_attr "prefix" "maybe_vex")
4143 (set (attr "prefix_rex")
4145 (match_test "<SWI48:MODE>mode == DImode")
4147 (const_string "*")))
4148 (set_attr "mode" "<MODEF:MODE>")
4149 (set_attr "athlon_decode" "double,vector")
4150 (set_attr "amdfam10_decode" "double,double")
4151 (set_attr "bdver1_decode" "double,double")])
4153 ;; Avoid vector decoded forms of the instruction.
4155 [(match_scratch:MODEF 2 "x")
4156 (set (match_operand:SWI48 0 "register_operand")
4157 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4158 "TARGET_AVOID_VECTOR_DECODE
4159 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4160 && optimize_insn_for_speed_p ()"
4161 [(set (match_dup 2) (match_dup 1))
4162 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4164 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4165 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4166 (fix:SWI248x (match_operand 1 "register_operand")))]
4167 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4169 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4170 && (TARGET_64BIT || <MODE>mode != DImode))
4172 && can_create_pseudo_p ()"
4177 if (memory_operand (operands[0], VOIDmode))
4178 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4181 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4182 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4188 [(set_attr "type" "fisttp")
4189 (set_attr "mode" "<MODE>")])
4191 (define_insn "fix_trunc<mode>_i387_fisttp"
4192 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4193 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4194 (clobber (match_scratch:XF 2 "=&1f"))]
4195 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4197 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4198 && (TARGET_64BIT || <MODE>mode != DImode))
4199 && TARGET_SSE_MATH)"
4200 "* return output_fix_trunc (insn, operands, true);"
4201 [(set_attr "type" "fisttp")
4202 (set_attr "mode" "<MODE>")])
4204 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4205 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4206 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4207 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4208 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4209 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4211 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4212 && (TARGET_64BIT || <MODE>mode != DImode))
4213 && TARGET_SSE_MATH)"
4215 [(set_attr "type" "fisttp")
4216 (set_attr "mode" "<MODE>")])
4219 [(set (match_operand:SWI248x 0 "register_operand")
4220 (fix:SWI248x (match_operand 1 "register_operand")))
4221 (clobber (match_operand:SWI248x 2 "memory_operand"))
4222 (clobber (match_scratch 3))]
4224 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4225 (clobber (match_dup 3))])
4226 (set (match_dup 0) (match_dup 2))])
4229 [(set (match_operand:SWI248x 0 "memory_operand")
4230 (fix:SWI248x (match_operand 1 "register_operand")))
4231 (clobber (match_operand:SWI248x 2 "memory_operand"))
4232 (clobber (match_scratch 3))]
4234 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4235 (clobber (match_dup 3))])])
4237 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4238 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4239 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4240 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4241 ;; function in i386.c.
4242 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4243 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4244 (fix:SWI248x (match_operand 1 "register_operand")))
4245 (clobber (reg:CC FLAGS_REG))]
4246 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4248 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4249 && (TARGET_64BIT || <MODE>mode != DImode))
4250 && can_create_pseudo_p ()"
4255 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4257 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4258 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4259 if (memory_operand (operands[0], VOIDmode))
4260 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4261 operands[2], operands[3]));
4264 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4265 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4266 operands[2], operands[3],
4271 [(set_attr "type" "fistp")
4272 (set_attr "i387_cw" "trunc")
4273 (set_attr "mode" "<MODE>")])
4275 (define_insn "fix_truncdi_i387"
4276 [(set (match_operand:DI 0 "memory_operand" "=m")
4277 (fix:DI (match_operand 1 "register_operand" "f")))
4278 (use (match_operand:HI 2 "memory_operand" "m"))
4279 (use (match_operand:HI 3 "memory_operand" "m"))
4280 (clobber (match_scratch:XF 4 "=&1f"))]
4281 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4283 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4284 "* return output_fix_trunc (insn, operands, false);"
4285 [(set_attr "type" "fistp")
4286 (set_attr "i387_cw" "trunc")
4287 (set_attr "mode" "DI")])
4289 (define_insn "fix_truncdi_i387_with_temp"
4290 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4291 (fix:DI (match_operand 1 "register_operand" "f,f")))
4292 (use (match_operand:HI 2 "memory_operand" "m,m"))
4293 (use (match_operand:HI 3 "memory_operand" "m,m"))
4294 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4295 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4296 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4298 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4300 [(set_attr "type" "fistp")
4301 (set_attr "i387_cw" "trunc")
4302 (set_attr "mode" "DI")])
4305 [(set (match_operand:DI 0 "register_operand")
4306 (fix:DI (match_operand 1 "register_operand")))
4307 (use (match_operand:HI 2 "memory_operand"))
4308 (use (match_operand:HI 3 "memory_operand"))
4309 (clobber (match_operand:DI 4 "memory_operand"))
4310 (clobber (match_scratch 5))]
4312 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4315 (clobber (match_dup 5))])
4316 (set (match_dup 0) (match_dup 4))])
4319 [(set (match_operand:DI 0 "memory_operand")
4320 (fix:DI (match_operand 1 "register_operand")))
4321 (use (match_operand:HI 2 "memory_operand"))
4322 (use (match_operand:HI 3 "memory_operand"))
4323 (clobber (match_operand:DI 4 "memory_operand"))
4324 (clobber (match_scratch 5))]
4326 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4329 (clobber (match_dup 5))])])
4331 (define_insn "fix_trunc<mode>_i387"
4332 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4333 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4334 (use (match_operand:HI 2 "memory_operand" "m"))
4335 (use (match_operand:HI 3 "memory_operand" "m"))]
4336 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4338 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4339 "* return output_fix_trunc (insn, operands, false);"
4340 [(set_attr "type" "fistp")
4341 (set_attr "i387_cw" "trunc")
4342 (set_attr "mode" "<MODE>")])
4344 (define_insn "fix_trunc<mode>_i387_with_temp"
4345 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4346 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4347 (use (match_operand:HI 2 "memory_operand" "m,m"))
4348 (use (match_operand:HI 3 "memory_operand" "m,m"))
4349 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4350 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4352 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4354 [(set_attr "type" "fistp")
4355 (set_attr "i387_cw" "trunc")
4356 (set_attr "mode" "<MODE>")])
4359 [(set (match_operand:SWI24 0 "register_operand")
4360 (fix:SWI24 (match_operand 1 "register_operand")))
4361 (use (match_operand:HI 2 "memory_operand"))
4362 (use (match_operand:HI 3 "memory_operand"))
4363 (clobber (match_operand:SWI24 4 "memory_operand"))]
4365 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4367 (use (match_dup 3))])
4368 (set (match_dup 0) (match_dup 4))])
4371 [(set (match_operand:SWI24 0 "memory_operand")
4372 (fix:SWI24 (match_operand 1 "register_operand")))
4373 (use (match_operand:HI 2 "memory_operand"))
4374 (use (match_operand:HI 3 "memory_operand"))
4375 (clobber (match_operand:SWI24 4 "memory_operand"))]
4377 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4379 (use (match_dup 3))])])
4381 (define_insn "x86_fnstcw_1"
4382 [(set (match_operand:HI 0 "memory_operand" "=m")
4383 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4386 [(set (attr "length")
4387 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4388 (set_attr "mode" "HI")
4389 (set_attr "unit" "i387")
4390 (set_attr "bdver1_decode" "vector")])
4392 (define_insn "x86_fldcw_1"
4393 [(set (reg:HI FPCR_REG)
4394 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4397 [(set (attr "length")
4398 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4399 (set_attr "mode" "HI")
4400 (set_attr "unit" "i387")
4401 (set_attr "athlon_decode" "vector")
4402 (set_attr "amdfam10_decode" "vector")
4403 (set_attr "bdver1_decode" "vector")])
4405 ;; Conversion between fixed point and floating point.
4407 ;; Even though we only accept memory inputs, the backend _really_
4408 ;; wants to be able to do this between registers.
4410 (define_expand "floathi<mode>2"
4411 [(set (match_operand:X87MODEF 0 "register_operand")
4412 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand")))]
4414 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4415 || TARGET_MIX_SSE_I387)")
4417 ;; Pre-reload splitter to add memory clobber to the pattern.
4418 (define_insn_and_split "*floathi<mode>2_1"
4419 [(set (match_operand:X87MODEF 0 "register_operand")
4420 (float:X87MODEF (match_operand:HI 1 "register_operand")))]
4422 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4423 || TARGET_MIX_SSE_I387)
4424 && can_create_pseudo_p ()"
4427 [(parallel [(set (match_dup 0)
4428 (float:X87MODEF (match_dup 1)))
4429 (clobber (match_dup 2))])]
4430 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4432 (define_insn "*floathi<mode>2_i387_with_temp"
4433 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4434 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4435 (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4437 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4438 || TARGET_MIX_SSE_I387)"
4440 [(set_attr "type" "fmov,multi")
4441 (set_attr "mode" "<MODE>")
4442 (set_attr "unit" "*,i387")
4443 (set_attr "fp_int_src" "true")])
4445 (define_insn "*floathi<mode>2_i387"
4446 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4447 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4449 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4450 || TARGET_MIX_SSE_I387)"
4452 [(set_attr "type" "fmov")
4453 (set_attr "mode" "<MODE>")
4454 (set_attr "fp_int_src" "true")])
4457 [(set (match_operand:X87MODEF 0 "register_operand")
4458 (float:X87MODEF (match_operand:HI 1 "register_operand")))
4459 (clobber (match_operand:HI 2 "memory_operand"))]
4461 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4462 || TARGET_MIX_SSE_I387)
4463 && reload_completed"
4464 [(set (match_dup 2) (match_dup 1))
4465 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4468 [(set (match_operand:X87MODEF 0 "register_operand")
4469 (float:X87MODEF (match_operand:HI 1 "memory_operand")))
4470 (clobber (match_operand:HI 2 "memory_operand"))]
4472 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4473 || TARGET_MIX_SSE_I387)
4474 && reload_completed"
4475 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4477 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4478 [(set (match_operand:X87MODEF 0 "register_operand")
4480 (match_operand:SWI48x 1 "nonimmediate_operand")))]
4482 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4483 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4485 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4486 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4487 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4489 rtx reg = gen_reg_rtx (XFmode);
4490 rtx (*insn)(rtx, rtx);
4492 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4494 if (<X87MODEF:MODE>mode == SFmode)
4495 insn = gen_truncxfsf2;
4496 else if (<X87MODEF:MODE>mode == DFmode)
4497 insn = gen_truncxfdf2;
4501 emit_insn (insn (operands[0], reg));
4506 ;; Pre-reload splitter to add memory clobber to the pattern.
4507 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4508 [(set (match_operand:X87MODEF 0 "register_operand")
4509 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))]
4511 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4512 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4513 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4514 || TARGET_MIX_SSE_I387))
4515 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4516 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4517 && ((<SWI48x:MODE>mode == SImode
4518 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4519 && optimize_function_for_speed_p (cfun)
4520 && flag_trapping_math)
4521 || !(TARGET_INTER_UNIT_CONVERSIONS
4522 || optimize_function_for_size_p (cfun)))))
4523 && can_create_pseudo_p ()"
4526 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4527 (clobber (match_dup 2))])]
4529 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4531 /* Avoid store forwarding (partial memory) stall penalty
4532 by passing DImode value through XMM registers. */
4533 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4534 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4535 && optimize_function_for_speed_p (cfun))
4537 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4544 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4545 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4547 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4548 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4549 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4550 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4552 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4553 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4554 (set_attr "unit" "*,i387,*,*,*")
4555 (set_attr "athlon_decode" "*,*,double,direct,double")
4556 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4557 (set_attr "bdver1_decode" "*,*,double,direct,double")
4558 (set_attr "fp_int_src" "true")])
4560 (define_insn "*floatsi<mode>2_vector_mixed"
4561 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4562 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4563 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4564 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4568 [(set_attr "type" "fmov,sseicvt")
4569 (set_attr "mode" "<MODE>,<ssevecmode>")
4570 (set_attr "unit" "i387,*")
4571 (set_attr "athlon_decode" "*,direct")
4572 (set_attr "amdfam10_decode" "*,double")
4573 (set_attr "bdver1_decode" "*,direct")
4574 (set_attr "fp_int_src" "true")])
4576 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_with_temp"
4577 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4579 (match_operand:SWI48 1 "nonimmediate_operand" "m,?r,r,m")))
4580 (clobber (match_operand:SWI48 2 "memory_operand" "=X,m,m,X"))]
4581 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4583 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4584 (set_attr "mode" "<MODEF:MODE>")
4585 (set_attr "unit" "*,i387,*,*")
4586 (set_attr "athlon_decode" "*,*,double,direct")
4587 (set_attr "amdfam10_decode" "*,*,vector,double")
4588 (set_attr "bdver1_decode" "*,*,double,direct")
4589 (set_attr "fp_int_src" "true")])
4592 [(set (match_operand:MODEF 0 "register_operand")
4593 (float:MODEF (match_operand:SWI48 1 "register_operand")))
4594 (clobber (match_operand:SWI48 2 "memory_operand"))]
4595 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4596 && TARGET_INTER_UNIT_CONVERSIONS
4598 && (SSE_REG_P (operands[0])
4599 || (GET_CODE (operands[0]) == SUBREG
4600 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4601 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4604 [(set (match_operand:MODEF 0 "register_operand")
4605 (float:MODEF (match_operand:SWI48 1 "register_operand")))
4606 (clobber (match_operand:SWI48 2 "memory_operand"))]
4607 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4608 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4610 && (SSE_REG_P (operands[0])
4611 || (GET_CODE (operands[0]) == SUBREG
4612 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4613 [(set (match_dup 2) (match_dup 1))
4614 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4616 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_interunit"
4617 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4619 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
4620 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4621 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4624 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
4625 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4626 [(set_attr "type" "fmov,sseicvt,sseicvt")
4627 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4628 (set_attr "mode" "<MODEF:MODE>")
4629 (set (attr "prefix_rex")
4631 (and (eq_attr "prefix" "maybe_vex")
4632 (match_test "<SWI48:MODE>mode == DImode"))
4634 (const_string "*")))
4635 (set_attr "unit" "i387,*,*")
4636 (set_attr "athlon_decode" "*,double,direct")
4637 (set_attr "amdfam10_decode" "*,vector,double")
4638 (set_attr "bdver1_decode" "*,double,direct")
4639 (set_attr "fp_int_src" "true")])
4641 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_nointerunit"
4642 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4644 (match_operand:SWI48 1 "memory_operand" "m,m")))]
4645 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4646 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4649 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4650 [(set_attr "type" "fmov,sseicvt")
4651 (set_attr "prefix" "orig,maybe_vex")
4652 (set_attr "mode" "<MODEF:MODE>")
4653 (set (attr "prefix_rex")
4655 (and (eq_attr "prefix" "maybe_vex")
4656 (match_test "<SWI48:MODE>mode == DImode"))
4658 (const_string "*")))
4659 (set_attr "athlon_decode" "*,direct")
4660 (set_attr "amdfam10_decode" "*,double")
4661 (set_attr "bdver1_decode" "*,direct")
4662 (set_attr "fp_int_src" "true")])
4664 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4665 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4667 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4668 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4669 "TARGET_SSE2 && TARGET_SSE_MATH
4670 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4672 [(set_attr "type" "sseicvt")
4673 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4674 (set_attr "athlon_decode" "double,direct,double")
4675 (set_attr "amdfam10_decode" "vector,double,double")
4676 (set_attr "bdver1_decode" "double,direct,double")
4677 (set_attr "fp_int_src" "true")])
4679 (define_insn "*floatsi<mode>2_vector_sse"
4680 [(set (match_operand:MODEF 0 "register_operand" "=x")
4681 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4682 "TARGET_SSE2 && TARGET_SSE_MATH
4683 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4685 [(set_attr "type" "sseicvt")
4686 (set_attr "mode" "<MODE>")
4687 (set_attr "athlon_decode" "direct")
4688 (set_attr "amdfam10_decode" "double")
4689 (set_attr "bdver1_decode" "direct")
4690 (set_attr "fp_int_src" "true")])
4693 [(set (match_operand:MODEF 0 "register_operand")
4694 (float:MODEF (match_operand:SI 1 "register_operand")))
4695 (clobber (match_operand:SI 2 "memory_operand"))]
4696 "TARGET_SSE2 && TARGET_SSE_MATH
4697 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4699 && (SSE_REG_P (operands[0])
4700 || (GET_CODE (operands[0]) == SUBREG
4701 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4704 rtx op1 = operands[1];
4706 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4708 if (GET_CODE (op1) == SUBREG)
4709 op1 = SUBREG_REG (op1);
4711 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES_TO_VEC)
4713 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4714 emit_insn (gen_sse2_loadld (operands[4],
4715 CONST0_RTX (V4SImode), operands[1]));
4717 /* We can ignore possible trapping value in the
4718 high part of SSE register for non-trapping math. */
4719 else if (SSE_REG_P (op1) && !flag_trapping_math)
4720 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4723 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4724 emit_move_insn (operands[2], operands[1]);
4725 emit_insn (gen_sse2_loadld (operands[4],
4726 CONST0_RTX (V4SImode), operands[2]));
4728 if (<ssevecmode>mode == V4SFmode)
4729 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4731 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4736 [(set (match_operand:MODEF 0 "register_operand")
4737 (float:MODEF (match_operand:SI 1 "memory_operand")))
4738 (clobber (match_operand:SI 2 "memory_operand"))]
4739 "TARGET_SSE2 && TARGET_SSE_MATH
4740 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4742 && (SSE_REG_P (operands[0])
4743 || (GET_CODE (operands[0]) == SUBREG
4744 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4747 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4749 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4751 emit_insn (gen_sse2_loadld (operands[4],
4752 CONST0_RTX (V4SImode), operands[1]));
4753 if (<ssevecmode>mode == V4SFmode)
4754 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4756 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4761 [(set (match_operand:MODEF 0 "register_operand")
4762 (float:MODEF (match_operand:SI 1 "register_operand")))]
4763 "TARGET_SSE2 && TARGET_SSE_MATH
4764 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4766 && (SSE_REG_P (operands[0])
4767 || (GET_CODE (operands[0]) == SUBREG
4768 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4771 rtx op1 = operands[1];
4773 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4775 if (GET_CODE (op1) == SUBREG)
4776 op1 = SUBREG_REG (op1);
4778 if (GENERAL_REG_P (op1))
4780 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4781 if (TARGET_INTER_UNIT_MOVES_TO_VEC)
4782 emit_insn (gen_sse2_loadld (operands[4],
4783 CONST0_RTX (V4SImode), operands[1]));
4786 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
4788 emit_insn (gen_sse2_loadld (operands[4],
4789 CONST0_RTX (V4SImode), operands[5]));
4790 ix86_free_from_memory (GET_MODE (operands[1]));
4793 /* We can ignore possible trapping value in the
4794 high part of SSE register for non-trapping math. */
4795 else if (SSE_REG_P (op1) && !flag_trapping_math)
4796 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4799 if (<ssevecmode>mode == V4SFmode)
4800 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4802 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4807 [(set (match_operand:MODEF 0 "register_operand")
4808 (float:MODEF (match_operand:SI 1 "memory_operand")))]
4809 "TARGET_SSE2 && TARGET_SSE_MATH
4810 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4812 && (SSE_REG_P (operands[0])
4813 || (GET_CODE (operands[0]) == SUBREG
4814 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4817 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4819 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4821 emit_insn (gen_sse2_loadld (operands[4],
4822 CONST0_RTX (V4SImode), operands[1]));
4823 if (<ssevecmode>mode == V4SFmode)
4824 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4826 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4830 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_with_temp"
4831 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
4833 (match_operand:SWI48 1 "nonimmediate_operand" "r,m")))
4834 (clobber (match_operand:SWI48 2 "memory_operand" "=m,X"))]
4835 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
4837 [(set_attr "type" "sseicvt")
4838 (set_attr "mode" "<MODEF:MODE>")
4839 (set_attr "athlon_decode" "double,direct")
4840 (set_attr "amdfam10_decode" "vector,double")
4841 (set_attr "bdver1_decode" "double,direct")
4842 (set_attr "btver2_decode" "double,double")
4843 (set_attr "fp_int_src" "true")])
4845 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_interunit"
4846 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
4848 (match_operand:SWI48 1 "nonimmediate_operand" "r,m")))]
4849 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
4850 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4851 "%vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4852 [(set_attr "type" "sseicvt")
4853 (set_attr "prefix" "maybe_vex")
4854 (set_attr "mode" "<MODEF:MODE>")
4855 (set (attr "prefix_rex")
4857 (and (eq_attr "prefix" "maybe_vex")
4858 (match_test "<SWI48:MODE>mode == DImode"))
4860 (const_string "*")))
4861 (set_attr "athlon_decode" "double,direct")
4862 (set_attr "amdfam10_decode" "vector,double")
4863 (set_attr "bdver1_decode" "double,direct")
4864 (set_attr "btver2_decode" "double,double")
4865 (set_attr "fp_int_src" "true")])
4868 [(set (match_operand:MODEF 0 "register_operand")
4869 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))
4870 (clobber (match_operand:SWI48 2 "memory_operand"))]
4871 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
4872 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4874 && (SSE_REG_P (operands[0])
4875 || (GET_CODE (operands[0]) == SUBREG
4876 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4877 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4879 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_nointerunit"
4880 [(set (match_operand:MODEF 0 "register_operand" "=x")
4882 (match_operand:SWI48 1 "memory_operand" "m")))]
4883 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
4884 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4885 "%vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4886 [(set_attr "type" "sseicvt")
4887 (set_attr "prefix" "maybe_vex")
4888 (set_attr "mode" "<MODEF:MODE>")
4889 (set (attr "prefix_rex")
4891 (and (eq_attr "prefix" "maybe_vex")
4892 (match_test "<SWI48:MODE>mode == DImode"))
4894 (const_string "*")))
4895 (set_attr "athlon_decode" "direct")
4896 (set_attr "amdfam10_decode" "double")
4897 (set_attr "bdver1_decode" "direct")
4898 (set_attr "fp_int_src" "true")])
4901 [(set (match_operand:MODEF 0 "register_operand")
4902 (float:MODEF (match_operand:SWI48 1 "register_operand")))
4903 (clobber (match_operand:SWI48 2 "memory_operand"))]
4904 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
4905 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4907 && (SSE_REG_P (operands[0])
4908 || (GET_CODE (operands[0]) == SUBREG
4909 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4910 [(set (match_dup 2) (match_dup 1))
4911 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4914 [(set (match_operand:MODEF 0 "register_operand")
4915 (float:MODEF (match_operand:SWI48 1 "memory_operand")))
4916 (clobber (match_operand:SWI48 2 "memory_operand"))]
4917 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
4919 && (SSE_REG_P (operands[0])
4920 || (GET_CODE (operands[0]) == SUBREG
4921 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4922 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4924 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
4925 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4927 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
4928 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
4930 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
4934 [(set_attr "type" "fmov,multi")
4935 (set_attr "mode" "<X87MODEF:MODE>")
4936 (set_attr "unit" "*,i387")
4937 (set_attr "fp_int_src" "true")])
4939 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
4940 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4942 (match_operand:SWI48x 1 "memory_operand" "m")))]
4944 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
4946 [(set_attr "type" "fmov")
4947 (set_attr "mode" "<X87MODEF:MODE>")
4948 (set_attr "fp_int_src" "true")])
4951 [(set (match_operand:X87MODEF 0 "fp_register_operand")
4952 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))
4953 (clobber (match_operand:SWI48x 2 "memory_operand"))]
4955 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4956 && reload_completed"
4957 [(set (match_dup 2) (match_dup 1))
4958 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4961 [(set (match_operand:X87MODEF 0 "fp_register_operand")
4962 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand")))
4963 (clobber (match_operand:SWI48x 2 "memory_operand"))]
4965 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4966 && reload_completed"
4967 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4969 ;; Avoid store forwarding (partial memory) stall penalty
4970 ;; by passing DImode value through XMM registers. */
4972 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
4973 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4975 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
4976 (clobber (match_scratch:V4SI 3 "=X,x"))
4977 (clobber (match_scratch:V4SI 4 "=X,x"))
4978 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
4979 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4980 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4981 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
4983 [(set_attr "type" "multi")
4984 (set_attr "mode" "<X87MODEF:MODE>")
4985 (set_attr "unit" "i387")
4986 (set_attr "fp_int_src" "true")])
4989 [(set (match_operand:X87MODEF 0 "fp_register_operand")
4990 (float:X87MODEF (match_operand:DI 1 "register_operand")))
4991 (clobber (match_scratch:V4SI 3))
4992 (clobber (match_scratch:V4SI 4))
4993 (clobber (match_operand:DI 2 "memory_operand"))]
4994 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4995 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4996 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
4997 && reload_completed"
4998 [(set (match_dup 2) (match_dup 3))
4999 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5001 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5002 Assemble the 64-bit DImode value in an xmm register. */
5003 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5004 gen_rtx_SUBREG (SImode, operands[1], 0)));
5005 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5006 gen_rtx_SUBREG (SImode, operands[1], 4)));
5007 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5010 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5014 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5015 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5016 (clobber (match_scratch:V4SI 3))
5017 (clobber (match_scratch:V4SI 4))
5018 (clobber (match_operand:DI 2 "memory_operand"))]
5019 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5020 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5021 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5022 && reload_completed"
5023 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5025 ;; Avoid store forwarding (partial memory) stall penalty by extending
5026 ;; SImode value to DImode through XMM register instead of pushing two
5027 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES_TO_VEC
5028 ;; targets benefit from this optimization. Also note that fild
5029 ;; loads from memory only.
5031 (define_insn "*floatunssi<mode>2_1"
5032 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5033 (unsigned_float:X87MODEF
5034 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5035 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5036 (clobber (match_scratch:SI 3 "=X,x"))]
5038 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5041 [(set_attr "type" "multi")
5042 (set_attr "mode" "<MODE>")])
5045 [(set (match_operand:X87MODEF 0 "register_operand")
5046 (unsigned_float:X87MODEF
5047 (match_operand:SI 1 "register_operand")))
5048 (clobber (match_operand:DI 2 "memory_operand"))
5049 (clobber (match_scratch:SI 3))]
5051 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5053 && reload_completed"
5054 [(set (match_dup 2) (match_dup 1))
5056 (float:X87MODEF (match_dup 2)))]
5057 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5060 [(set (match_operand:X87MODEF 0 "register_operand")
5061 (unsigned_float:X87MODEF
5062 (match_operand:SI 1 "memory_operand")))
5063 (clobber (match_operand:DI 2 "memory_operand"))
5064 (clobber (match_scratch:SI 3))]
5066 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5068 && reload_completed"
5069 [(set (match_dup 2) (match_dup 3))
5071 (float:X87MODEF (match_dup 2)))]
5073 emit_move_insn (operands[3], operands[1]);
5074 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5077 (define_expand "floatunssi<mode>2"
5079 [(set (match_operand:X87MODEF 0 "register_operand")
5080 (unsigned_float:X87MODEF
5081 (match_operand:SI 1 "nonimmediate_operand")))
5082 (clobber (match_dup 2))
5083 (clobber (match_scratch:SI 3))])]
5085 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5087 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5089 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5091 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5095 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5098 (define_expand "floatunsdisf2"
5099 [(use (match_operand:SF 0 "register_operand"))
5100 (use (match_operand:DI 1 "nonimmediate_operand"))]
5101 "TARGET_64BIT && TARGET_SSE_MATH"
5102 "x86_emit_floatuns (operands); DONE;")
5104 (define_expand "floatunsdidf2"
5105 [(use (match_operand:DF 0 "register_operand"))
5106 (use (match_operand:DI 1 "nonimmediate_operand"))]
5107 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5108 && TARGET_SSE2 && TARGET_SSE_MATH"
5111 x86_emit_floatuns (operands);
5113 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5117 ;; Load effective address instructions
5119 (define_insn_and_split "*lea<mode>"
5120 [(set (match_operand:SWI48 0 "register_operand" "=r")
5121 (match_operand:SWI48 1 "lea_address_operand" "p"))]
5124 if (SImode_address_operand (operands[1], VOIDmode))
5126 gcc_assert (TARGET_64BIT);
5127 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5130 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5132 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5135 enum machine_mode mode = <MODE>mode;
5138 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5139 change operands[] array behind our back. */
5140 pat = PATTERN (curr_insn);
5142 operands[0] = SET_DEST (pat);
5143 operands[1] = SET_SRC (pat);
5145 /* Emit all operations in SImode for zero-extended addresses. Recall
5146 that x86_64 inheretly zero-extends SImode operations to DImode. */
5147 if (SImode_address_operand (operands[1], VOIDmode))
5150 ix86_split_lea_for_addr (curr_insn, operands, mode);
5153 [(set_attr "type" "lea")
5156 (match_operand 1 "SImode_address_operand")
5158 (const_string "<MODE>")))])
5162 (define_expand "add<mode>3"
5163 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5164 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5165 (match_operand:SDWIM 2 "<general_operand>")))]
5167 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5169 (define_insn_and_split "*add<dwi>3_doubleword"
5170 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5172 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5173 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5174 (clobber (reg:CC FLAGS_REG))]
5175 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5178 [(parallel [(set (reg:CC FLAGS_REG)
5179 (unspec:CC [(match_dup 1) (match_dup 2)]
5182 (plus:DWIH (match_dup 1) (match_dup 2)))])
5183 (parallel [(set (match_dup 3)
5187 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5189 (clobber (reg:CC FLAGS_REG))])]
5190 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5192 (define_insn "*add<mode>3_cc"
5193 [(set (reg:CC FLAGS_REG)
5195 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5196 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5198 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5199 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5200 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5201 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5202 [(set_attr "type" "alu")
5203 (set_attr "mode" "<MODE>")])
5205 (define_insn "addqi3_cc"
5206 [(set (reg:CC FLAGS_REG)
5208 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5209 (match_operand:QI 2 "general_operand" "qn,qm")]
5211 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5212 (plus:QI (match_dup 1) (match_dup 2)))]
5213 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5214 "add{b}\t{%2, %0|%0, %2}"
5215 [(set_attr "type" "alu")
5216 (set_attr "mode" "QI")])
5218 (define_insn "*add<mode>_1"
5219 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5221 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5222 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5223 (clobber (reg:CC FLAGS_REG))]
5224 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5226 switch (get_attr_type (insn))
5232 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5233 if (operands[2] == const1_rtx)
5234 return "inc{<imodesuffix>}\t%0";
5237 gcc_assert (operands[2] == constm1_rtx);
5238 return "dec{<imodesuffix>}\t%0";
5242 /* For most processors, ADD is faster than LEA. This alternative
5243 was added to use ADD as much as possible. */
5244 if (which_alternative == 2)
5247 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5250 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5251 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5252 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5254 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5258 (cond [(eq_attr "alternative" "3")
5259 (const_string "lea")
5260 (match_operand:SWI48 2 "incdec_operand")
5261 (const_string "incdec")
5263 (const_string "alu")))
5264 (set (attr "length_immediate")
5266 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5268 (const_string "*")))
5269 (set_attr "mode" "<MODE>")])
5271 ;; It may seem that nonimmediate operand is proper one for operand 1.
5272 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5273 ;; we take care in ix86_binary_operator_ok to not allow two memory
5274 ;; operands so proper swapping will be done in reload. This allow
5275 ;; patterns constructed from addsi_1 to match.
5277 (define_insn "addsi_1_zext"
5278 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5280 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5281 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5282 (clobber (reg:CC FLAGS_REG))]
5283 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5285 switch (get_attr_type (insn))
5291 if (operands[2] == const1_rtx)
5292 return "inc{l}\t%k0";
5295 gcc_assert (operands[2] == constm1_rtx);
5296 return "dec{l}\t%k0";
5300 /* For most processors, ADD is faster than LEA. This alternative
5301 was added to use ADD as much as possible. */
5302 if (which_alternative == 1)
5305 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5308 if (x86_maybe_negate_const_int (&operands[2], SImode))
5309 return "sub{l}\t{%2, %k0|%k0, %2}";
5311 return "add{l}\t{%2, %k0|%k0, %2}";
5315 (cond [(eq_attr "alternative" "2")
5316 (const_string "lea")
5317 (match_operand:SI 2 "incdec_operand")
5318 (const_string "incdec")
5320 (const_string "alu")))
5321 (set (attr "length_immediate")
5323 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5325 (const_string "*")))
5326 (set_attr "mode" "SI")])
5328 (define_insn "*addhi_1"
5329 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5330 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5331 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5332 (clobber (reg:CC FLAGS_REG))]
5333 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5335 switch (get_attr_type (insn))
5341 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5342 if (operands[2] == const1_rtx)
5343 return "inc{w}\t%0";
5346 gcc_assert (operands[2] == constm1_rtx);
5347 return "dec{w}\t%0";
5351 /* For most processors, ADD is faster than LEA. This alternative
5352 was added to use ADD as much as possible. */
5353 if (which_alternative == 2)
5356 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5359 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5360 if (x86_maybe_negate_const_int (&operands[2], HImode))
5361 return "sub{w}\t{%2, %0|%0, %2}";
5363 return "add{w}\t{%2, %0|%0, %2}";
5367 (cond [(eq_attr "alternative" "3")
5368 (const_string "lea")
5369 (match_operand:HI 2 "incdec_operand")
5370 (const_string "incdec")
5372 (const_string "alu")))
5373 (set (attr "length_immediate")
5375 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5377 (const_string "*")))
5378 (set_attr "mode" "HI,HI,HI,SI")])
5380 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5381 (define_insn "*addqi_1"
5382 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5383 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5384 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5385 (clobber (reg:CC FLAGS_REG))]
5386 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5388 bool widen = (which_alternative == 3 || which_alternative == 4);
5390 switch (get_attr_type (insn))
5396 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5397 if (operands[2] == const1_rtx)
5398 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5401 gcc_assert (operands[2] == constm1_rtx);
5402 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5406 /* For most processors, ADD is faster than LEA. These alternatives
5407 were added to use ADD as much as possible. */
5408 if (which_alternative == 2 || which_alternative == 4)
5411 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5414 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5415 if (x86_maybe_negate_const_int (&operands[2], QImode))
5418 return "sub{l}\t{%2, %k0|%k0, %2}";
5420 return "sub{b}\t{%2, %0|%0, %2}";
5423 return "add{l}\t{%k2, %k0|%k0, %k2}";
5425 return "add{b}\t{%2, %0|%0, %2}";
5429 (cond [(eq_attr "alternative" "5")
5430 (const_string "lea")
5431 (match_operand:QI 2 "incdec_operand")
5432 (const_string "incdec")
5434 (const_string "alu")))
5435 (set (attr "length_immediate")
5437 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5439 (const_string "*")))
5440 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5442 (define_insn "*addqi_1_slp"
5443 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5444 (plus:QI (match_dup 0)
5445 (match_operand:QI 1 "general_operand" "qn,qm")))
5446 (clobber (reg:CC FLAGS_REG))]
5447 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5448 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5450 switch (get_attr_type (insn))
5453 if (operands[1] == const1_rtx)
5454 return "inc{b}\t%0";
5457 gcc_assert (operands[1] == constm1_rtx);
5458 return "dec{b}\t%0";
5462 if (x86_maybe_negate_const_int (&operands[1], QImode))
5463 return "sub{b}\t{%1, %0|%0, %1}";
5465 return "add{b}\t{%1, %0|%0, %1}";
5469 (if_then_else (match_operand:QI 1 "incdec_operand")
5470 (const_string "incdec")
5471 (const_string "alu1")))
5472 (set (attr "memory")
5473 (if_then_else (match_operand 1 "memory_operand")
5474 (const_string "load")
5475 (const_string "none")))
5476 (set_attr "mode" "QI")])
5478 ;; Split non destructive adds if we cannot use lea.
5480 [(set (match_operand:SWI48 0 "register_operand")
5481 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5482 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5483 (clobber (reg:CC FLAGS_REG))]
5484 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5485 [(set (match_dup 0) (match_dup 1))
5486 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5487 (clobber (reg:CC FLAGS_REG))])])
5489 ;; Convert add to the lea pattern to avoid flags dependency.
5491 [(set (match_operand:SWI 0 "register_operand")
5492 (plus:SWI (match_operand:SWI 1 "register_operand")
5493 (match_operand:SWI 2 "<nonmemory_operand>")))
5494 (clobber (reg:CC FLAGS_REG))]
5495 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5498 enum machine_mode mode = <MODE>mode;
5501 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5504 operands[0] = gen_lowpart (mode, operands[0]);
5505 operands[1] = gen_lowpart (mode, operands[1]);
5506 operands[2] = gen_lowpart (mode, operands[2]);
5509 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5511 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5515 ;; Split non destructive adds if we cannot use lea.
5517 [(set (match_operand:DI 0 "register_operand")
5519 (plus:SI (match_operand:SI 1 "register_operand")
5520 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5521 (clobber (reg:CC FLAGS_REG))]
5523 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5524 [(set (match_dup 3) (match_dup 1))
5525 (parallel [(set (match_dup 0)
5526 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5527 (clobber (reg:CC FLAGS_REG))])]
5528 "operands[3] = gen_lowpart (SImode, operands[0]);")
5530 ;; Convert add to the lea pattern to avoid flags dependency.
5532 [(set (match_operand:DI 0 "register_operand")
5534 (plus:SI (match_operand:SI 1 "register_operand")
5535 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5536 (clobber (reg:CC FLAGS_REG))]
5537 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5539 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5541 (define_insn "*add<mode>_2"
5542 [(set (reg FLAGS_REG)
5545 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5546 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5548 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5549 (plus:SWI (match_dup 1) (match_dup 2)))]
5550 "ix86_match_ccmode (insn, CCGOCmode)
5551 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5553 switch (get_attr_type (insn))
5556 if (operands[2] == const1_rtx)
5557 return "inc{<imodesuffix>}\t%0";
5560 gcc_assert (operands[2] == constm1_rtx);
5561 return "dec{<imodesuffix>}\t%0";
5565 if (which_alternative == 2)
5568 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5571 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5572 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5573 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5575 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5579 (if_then_else (match_operand:SWI 2 "incdec_operand")
5580 (const_string "incdec")
5581 (const_string "alu")))
5582 (set (attr "length_immediate")
5584 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5586 (const_string "*")))
5587 (set_attr "mode" "<MODE>")])
5589 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5590 (define_insn "*addsi_2_zext"
5591 [(set (reg FLAGS_REG)
5593 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5594 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5596 (set (match_operand:DI 0 "register_operand" "=r,r")
5597 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5598 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5599 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5601 switch (get_attr_type (insn))
5604 if (operands[2] == const1_rtx)
5605 return "inc{l}\t%k0";
5608 gcc_assert (operands[2] == constm1_rtx);
5609 return "dec{l}\t%k0";
5613 if (which_alternative == 1)
5616 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5619 if (x86_maybe_negate_const_int (&operands[2], SImode))
5620 return "sub{l}\t{%2, %k0|%k0, %2}";
5622 return "add{l}\t{%2, %k0|%k0, %2}";
5626 (if_then_else (match_operand:SI 2 "incdec_operand")
5627 (const_string "incdec")
5628 (const_string "alu")))
5629 (set (attr "length_immediate")
5631 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5633 (const_string "*")))
5634 (set_attr "mode" "SI")])
5636 (define_insn "*add<mode>_3"
5637 [(set (reg FLAGS_REG)
5639 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5640 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5641 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5642 "ix86_match_ccmode (insn, CCZmode)
5643 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5645 switch (get_attr_type (insn))
5648 if (operands[2] == const1_rtx)
5649 return "inc{<imodesuffix>}\t%0";
5652 gcc_assert (operands[2] == constm1_rtx);
5653 return "dec{<imodesuffix>}\t%0";
5657 if (which_alternative == 1)
5660 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5663 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5664 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5665 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5667 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5671 (if_then_else (match_operand:SWI 2 "incdec_operand")
5672 (const_string "incdec")
5673 (const_string "alu")))
5674 (set (attr "length_immediate")
5676 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5678 (const_string "*")))
5679 (set_attr "mode" "<MODE>")])
5681 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5682 (define_insn "*addsi_3_zext"
5683 [(set (reg FLAGS_REG)
5685 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5686 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5687 (set (match_operand:DI 0 "register_operand" "=r,r")
5688 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5689 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5690 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5692 switch (get_attr_type (insn))
5695 if (operands[2] == const1_rtx)
5696 return "inc{l}\t%k0";
5699 gcc_assert (operands[2] == constm1_rtx);
5700 return "dec{l}\t%k0";
5704 if (which_alternative == 1)
5707 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5710 if (x86_maybe_negate_const_int (&operands[2], SImode))
5711 return "sub{l}\t{%2, %k0|%k0, %2}";
5713 return "add{l}\t{%2, %k0|%k0, %2}";
5717 (if_then_else (match_operand:SI 2 "incdec_operand")
5718 (const_string "incdec")
5719 (const_string "alu")))
5720 (set (attr "length_immediate")
5722 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5724 (const_string "*")))
5725 (set_attr "mode" "SI")])
5727 ; For comparisons against 1, -1 and 128, we may generate better code
5728 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5729 ; is matched then. We can't accept general immediate, because for
5730 ; case of overflows, the result is messed up.
5731 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5732 ; only for comparisons not depending on it.
5734 (define_insn "*adddi_4"
5735 [(set (reg FLAGS_REG)
5737 (match_operand:DI 1 "nonimmediate_operand" "0")
5738 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5739 (clobber (match_scratch:DI 0 "=rm"))]
5741 && ix86_match_ccmode (insn, CCGCmode)"
5743 switch (get_attr_type (insn))
5746 if (operands[2] == constm1_rtx)
5747 return "inc{q}\t%0";
5750 gcc_assert (operands[2] == const1_rtx);
5751 return "dec{q}\t%0";
5755 if (x86_maybe_negate_const_int (&operands[2], DImode))
5756 return "add{q}\t{%2, %0|%0, %2}";
5758 return "sub{q}\t{%2, %0|%0, %2}";
5762 (if_then_else (match_operand:DI 2 "incdec_operand")
5763 (const_string "incdec")
5764 (const_string "alu")))
5765 (set (attr "length_immediate")
5767 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5769 (const_string "*")))
5770 (set_attr "mode" "DI")])
5772 ; For comparisons against 1, -1 and 128, we may generate better code
5773 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5774 ; is matched then. We can't accept general immediate, because for
5775 ; case of overflows, the result is messed up.
5776 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5777 ; only for comparisons not depending on it.
5779 (define_insn "*add<mode>_4"
5780 [(set (reg FLAGS_REG)
5782 (match_operand:SWI124 1 "nonimmediate_operand" "0")
5783 (match_operand:SWI124 2 "const_int_operand" "n")))
5784 (clobber (match_scratch:SWI124 0 "=<r>m"))]
5785 "ix86_match_ccmode (insn, CCGCmode)"
5787 switch (get_attr_type (insn))
5790 if (operands[2] == constm1_rtx)
5791 return "inc{<imodesuffix>}\t%0";
5794 gcc_assert (operands[2] == const1_rtx);
5795 return "dec{<imodesuffix>}\t%0";
5799 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5800 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5802 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5806 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
5807 (const_string "incdec")
5808 (const_string "alu")))
5809 (set (attr "length_immediate")
5811 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5813 (const_string "*")))
5814 (set_attr "mode" "<MODE>")])
5816 (define_insn "*add<mode>_5"
5817 [(set (reg FLAGS_REG)
5820 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
5821 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5823 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5824 "ix86_match_ccmode (insn, CCGOCmode)
5825 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5827 switch (get_attr_type (insn))
5830 if (operands[2] == const1_rtx)
5831 return "inc{<imodesuffix>}\t%0";
5834 gcc_assert (operands[2] == constm1_rtx);
5835 return "dec{<imodesuffix>}\t%0";
5839 if (which_alternative == 1)
5842 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5845 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5846 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5847 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5849 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5853 (if_then_else (match_operand:SWI 2 "incdec_operand")
5854 (const_string "incdec")
5855 (const_string "alu")))
5856 (set (attr "length_immediate")
5858 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5860 (const_string "*")))
5861 (set_attr "mode" "<MODE>")])
5863 (define_insn "addqi_ext_1"
5864 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
5869 (match_operand 1 "ext_register_operand" "0,0")
5872 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m")))
5873 (clobber (reg:CC FLAGS_REG))]
5876 switch (get_attr_type (insn))
5879 if (operands[2] == const1_rtx)
5880 return "inc{b}\t%h0";
5883 gcc_assert (operands[2] == constm1_rtx);
5884 return "dec{b}\t%h0";
5888 return "add{b}\t{%2, %h0|%h0, %2}";
5891 [(set_attr "isa" "*,nox64")
5893 (if_then_else (match_operand:QI 2 "incdec_operand")
5894 (const_string "incdec")
5895 (const_string "alu")))
5896 (set_attr "modrm" "1")
5897 (set_attr "mode" "QI")])
5899 (define_insn "*addqi_ext_2"
5900 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
5905 (match_operand 1 "ext_register_operand" "%0")
5909 (match_operand 2 "ext_register_operand" "Q")
5912 (clobber (reg:CC FLAGS_REG))]
5914 "add{b}\t{%h2, %h0|%h0, %h2}"
5915 [(set_attr "type" "alu")
5916 (set_attr "mode" "QI")])
5918 ;; The lea patterns for modes less than 32 bits need to be matched by
5919 ;; several insns converted to real lea by splitters.
5921 (define_insn_and_split "*lea_general_1"
5922 [(set (match_operand 0 "register_operand" "=r")
5923 (plus (plus (match_operand 1 "index_register_operand" "l")
5924 (match_operand 2 "register_operand" "r"))
5925 (match_operand 3 "immediate_operand" "i")))]
5926 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5927 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5928 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5929 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5930 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5931 || GET_MODE (operands[3]) == VOIDmode)"
5933 "&& reload_completed"
5936 enum machine_mode mode = SImode;
5939 operands[0] = gen_lowpart (mode, operands[0]);
5940 operands[1] = gen_lowpart (mode, operands[1]);
5941 operands[2] = gen_lowpart (mode, operands[2]);
5942 operands[3] = gen_lowpart (mode, operands[3]);
5944 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
5947 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5950 [(set_attr "type" "lea")
5951 (set_attr "mode" "SI")])
5953 (define_insn_and_split "*lea_general_2"
5954 [(set (match_operand 0 "register_operand" "=r")
5955 (plus (mult (match_operand 1 "index_register_operand" "l")
5956 (match_operand 2 "const248_operand" "n"))
5957 (match_operand 3 "nonmemory_operand" "ri")))]
5958 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5959 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5960 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5961 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5962 || GET_MODE (operands[3]) == VOIDmode)"
5964 "&& reload_completed"
5967 enum machine_mode mode = SImode;
5970 operands[0] = gen_lowpart (mode, operands[0]);
5971 operands[1] = gen_lowpart (mode, operands[1]);
5972 operands[3] = gen_lowpart (mode, operands[3]);
5974 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
5977 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5980 [(set_attr "type" "lea")
5981 (set_attr "mode" "SI")])
5983 (define_insn_and_split "*lea_general_3"
5984 [(set (match_operand 0 "register_operand" "=r")
5985 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5986 (match_operand 2 "const248_operand" "n"))
5987 (match_operand 3 "register_operand" "r"))
5988 (match_operand 4 "immediate_operand" "i")))]
5989 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5990 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5991 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5992 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5994 "&& reload_completed"
5997 enum machine_mode mode = SImode;
6000 operands[0] = gen_lowpart (mode, operands[0]);
6001 operands[1] = gen_lowpart (mode, operands[1]);
6002 operands[3] = gen_lowpart (mode, operands[3]);
6003 operands[4] = gen_lowpart (mode, operands[4]);
6005 pat = gen_rtx_PLUS (mode,
6007 gen_rtx_MULT (mode, operands[1],
6012 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6015 [(set_attr "type" "lea")
6016 (set_attr "mode" "SI")])
6018 (define_insn_and_split "*lea_general_4"
6019 [(set (match_operand 0 "register_operand" "=r")
6021 (match_operand 1 "index_register_operand" "l")
6022 (match_operand 2 "const_int_operand" "n"))
6023 (match_operand 3 "const_int_operand" "n")))]
6024 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6025 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6026 || GET_MODE (operands[0]) == SImode
6027 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6028 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6029 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6030 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6031 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6033 "&& reload_completed"
6036 enum machine_mode mode = GET_MODE (operands[0]);
6039 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6042 operands[0] = gen_lowpart (mode, operands[0]);
6043 operands[1] = gen_lowpart (mode, operands[1]);
6046 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6048 pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6049 INTVAL (operands[3]));
6051 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6054 [(set_attr "type" "lea")
6056 (if_then_else (match_operand:DI 0)
6058 (const_string "SI")))])
6060 ;; Subtract instructions
6062 (define_expand "sub<mode>3"
6063 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6064 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6065 (match_operand:SDWIM 2 "<general_operand>")))]
6067 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6069 (define_insn_and_split "*sub<dwi>3_doubleword"
6070 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6072 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6073 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6074 (clobber (reg:CC FLAGS_REG))]
6075 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6078 [(parallel [(set (reg:CC FLAGS_REG)
6079 (compare:CC (match_dup 1) (match_dup 2)))
6081 (minus:DWIH (match_dup 1) (match_dup 2)))])
6082 (parallel [(set (match_dup 3)
6086 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6088 (clobber (reg:CC FLAGS_REG))])]
6089 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6091 (define_insn "*sub<mode>_1"
6092 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6094 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6095 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6096 (clobber (reg:CC FLAGS_REG))]
6097 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6098 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6099 [(set_attr "type" "alu")
6100 (set_attr "mode" "<MODE>")])
6102 (define_insn "*subsi_1_zext"
6103 [(set (match_operand:DI 0 "register_operand" "=r")
6105 (minus:SI (match_operand:SI 1 "register_operand" "0")
6106 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6107 (clobber (reg:CC FLAGS_REG))]
6108 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6109 "sub{l}\t{%2, %k0|%k0, %2}"
6110 [(set_attr "type" "alu")
6111 (set_attr "mode" "SI")])
6113 (define_insn "*subqi_1_slp"
6114 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6115 (minus:QI (match_dup 0)
6116 (match_operand:QI 1 "general_operand" "qn,qm")))
6117 (clobber (reg:CC FLAGS_REG))]
6118 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6119 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6120 "sub{b}\t{%1, %0|%0, %1}"
6121 [(set_attr "type" "alu1")
6122 (set_attr "mode" "QI")])
6124 (define_insn "*sub<mode>_2"
6125 [(set (reg FLAGS_REG)
6128 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6129 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6131 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6132 (minus:SWI (match_dup 1) (match_dup 2)))]
6133 "ix86_match_ccmode (insn, CCGOCmode)
6134 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6135 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6136 [(set_attr "type" "alu")
6137 (set_attr "mode" "<MODE>")])
6139 (define_insn "*subsi_2_zext"
6140 [(set (reg FLAGS_REG)
6142 (minus:SI (match_operand:SI 1 "register_operand" "0")
6143 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6145 (set (match_operand:DI 0 "register_operand" "=r")
6147 (minus:SI (match_dup 1)
6149 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6150 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6151 "sub{l}\t{%2, %k0|%k0, %2}"
6152 [(set_attr "type" "alu")
6153 (set_attr "mode" "SI")])
6155 (define_insn "*sub<mode>_3"
6156 [(set (reg FLAGS_REG)
6157 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6158 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6159 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6160 (minus:SWI (match_dup 1) (match_dup 2)))]
6161 "ix86_match_ccmode (insn, CCmode)
6162 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6163 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6164 [(set_attr "type" "alu")
6165 (set_attr "mode" "<MODE>")])
6167 (define_insn "*subsi_3_zext"
6168 [(set (reg FLAGS_REG)
6169 (compare (match_operand:SI 1 "register_operand" "0")
6170 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6171 (set (match_operand:DI 0 "register_operand" "=r")
6173 (minus:SI (match_dup 1)
6175 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6176 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6177 "sub{l}\t{%2, %1|%1, %2}"
6178 [(set_attr "type" "alu")
6179 (set_attr "mode" "SI")])
6181 ;; Add with carry and subtract with borrow
6183 (define_expand "<plusminus_insn><mode>3_carry"
6185 [(set (match_operand:SWI 0 "nonimmediate_operand")
6187 (match_operand:SWI 1 "nonimmediate_operand")
6188 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6189 [(match_operand 3 "flags_reg_operand")
6191 (match_operand:SWI 2 "<general_operand>"))))
6192 (clobber (reg:CC FLAGS_REG))])]
6193 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6195 (define_insn "*<plusminus_insn><mode>3_carry"
6196 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6198 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6200 (match_operator 3 "ix86_carry_flag_operator"
6201 [(reg FLAGS_REG) (const_int 0)])
6202 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6203 (clobber (reg:CC FLAGS_REG))]
6204 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6205 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6206 [(set_attr "type" "alu")
6207 (set_attr "use_carry" "1")
6208 (set_attr "pent_pair" "pu")
6209 (set_attr "mode" "<MODE>")])
6211 (define_insn "*addsi3_carry_zext"
6212 [(set (match_operand:DI 0 "register_operand" "=r")
6214 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6215 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6216 [(reg FLAGS_REG) (const_int 0)])
6217 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6218 (clobber (reg:CC FLAGS_REG))]
6219 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6220 "adc{l}\t{%2, %k0|%k0, %2}"
6221 [(set_attr "type" "alu")
6222 (set_attr "use_carry" "1")
6223 (set_attr "pent_pair" "pu")
6224 (set_attr "mode" "SI")])
6226 (define_insn "*subsi3_carry_zext"
6227 [(set (match_operand:DI 0 "register_operand" "=r")
6229 (minus:SI (match_operand:SI 1 "register_operand" "0")
6230 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6231 [(reg FLAGS_REG) (const_int 0)])
6232 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6233 (clobber (reg:CC FLAGS_REG))]
6234 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6235 "sbb{l}\t{%2, %k0|%k0, %2}"
6236 [(set_attr "type" "alu")
6237 (set_attr "pent_pair" "pu")
6238 (set_attr "mode" "SI")])
6242 (define_insn "adcx<mode>3"
6243 [(set (reg:CCC FLAGS_REG)
6246 (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6248 (match_operator 4 "ix86_carry_flag_operator"
6249 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6250 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6252 (set (match_operand:SWI48 0 "register_operand" "=r")
6253 (plus:SWI48 (match_dup 1)
6254 (plus:SWI48 (match_op_dup 4
6255 [(match_dup 3) (const_int 0)])
6257 "TARGET_ADX && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6258 "adcx\t{%2, %0|%0, %2}"
6259 [(set_attr "type" "alu")
6260 (set_attr "use_carry" "1")
6261 (set_attr "mode" "<MODE>")])
6263 ;; Overflow setting add and subtract instructions
6265 (define_insn "*add<mode>3_cconly_overflow"
6266 [(set (reg:CCC FLAGS_REG)
6269 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6270 (match_operand:SWI 2 "<general_operand>" "<g>"))
6272 (clobber (match_scratch:SWI 0 "=<r>"))]
6273 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6274 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6275 [(set_attr "type" "alu")
6276 (set_attr "mode" "<MODE>")])
6278 (define_insn "*sub<mode>3_cconly_overflow"
6279 [(set (reg:CCC FLAGS_REG)
6282 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6283 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6286 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6287 [(set_attr "type" "icmp")
6288 (set_attr "mode" "<MODE>")])
6290 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6291 [(set (reg:CCC FLAGS_REG)
6294 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6295 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6297 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6298 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6299 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6300 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6301 [(set_attr "type" "alu")
6302 (set_attr "mode" "<MODE>")])
6304 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6305 [(set (reg:CCC FLAGS_REG)
6308 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6309 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6311 (set (match_operand:DI 0 "register_operand" "=r")
6312 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6313 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6314 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6315 [(set_attr "type" "alu")
6316 (set_attr "mode" "SI")])
6318 ;; The patterns that match these are at the end of this file.
6320 (define_expand "<plusminus_insn>xf3"
6321 [(set (match_operand:XF 0 "register_operand")
6323 (match_operand:XF 1 "register_operand")
6324 (match_operand:XF 2 "register_operand")))]
6327 (define_expand "<plusminus_insn><mode>3"
6328 [(set (match_operand:MODEF 0 "register_operand")
6330 (match_operand:MODEF 1 "register_operand")
6331 (match_operand:MODEF 2 "nonimmediate_operand")))]
6332 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6333 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6335 ;; Multiply instructions
6337 (define_expand "mul<mode>3"
6338 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6340 (match_operand:SWIM248 1 "register_operand")
6341 (match_operand:SWIM248 2 "<general_operand>")))
6342 (clobber (reg:CC FLAGS_REG))])])
6344 (define_expand "mulqi3"
6345 [(parallel [(set (match_operand:QI 0 "register_operand")
6347 (match_operand:QI 1 "register_operand")
6348 (match_operand:QI 2 "nonimmediate_operand")))
6349 (clobber (reg:CC FLAGS_REG))])]
6350 "TARGET_QIMODE_MATH")
6353 ;; IMUL reg32/64, reg32/64, imm8 Direct
6354 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6355 ;; IMUL reg32/64, reg32/64, imm32 Direct
6356 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6357 ;; IMUL reg32/64, reg32/64 Direct
6358 ;; IMUL reg32/64, mem32/64 Direct
6360 ;; On BDVER1, all above IMULs use DirectPath
6362 (define_insn "*mul<mode>3_1"
6363 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6365 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6366 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6367 (clobber (reg:CC FLAGS_REG))]
6368 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6370 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6371 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6372 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6373 [(set_attr "type" "imul")
6374 (set_attr "prefix_0f" "0,0,1")
6375 (set (attr "athlon_decode")
6376 (cond [(eq_attr "cpu" "athlon")
6377 (const_string "vector")
6378 (eq_attr "alternative" "1")
6379 (const_string "vector")
6380 (and (eq_attr "alternative" "2")
6381 (match_operand 1 "memory_operand"))
6382 (const_string "vector")]
6383 (const_string "direct")))
6384 (set (attr "amdfam10_decode")
6385 (cond [(and (eq_attr "alternative" "0,1")
6386 (match_operand 1 "memory_operand"))
6387 (const_string "vector")]
6388 (const_string "direct")))
6389 (set_attr "bdver1_decode" "direct")
6390 (set_attr "mode" "<MODE>")])
6392 (define_insn "*mulsi3_1_zext"
6393 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6395 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6396 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6397 (clobber (reg:CC FLAGS_REG))]
6399 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6401 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6402 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6403 imul{l}\t{%2, %k0|%k0, %2}"
6404 [(set_attr "type" "imul")
6405 (set_attr "prefix_0f" "0,0,1")
6406 (set (attr "athlon_decode")
6407 (cond [(eq_attr "cpu" "athlon")
6408 (const_string "vector")
6409 (eq_attr "alternative" "1")
6410 (const_string "vector")
6411 (and (eq_attr "alternative" "2")
6412 (match_operand 1 "memory_operand"))
6413 (const_string "vector")]
6414 (const_string "direct")))
6415 (set (attr "amdfam10_decode")
6416 (cond [(and (eq_attr "alternative" "0,1")
6417 (match_operand 1 "memory_operand"))
6418 (const_string "vector")]
6419 (const_string "direct")))
6420 (set_attr "bdver1_decode" "direct")
6421 (set_attr "mode" "SI")])
6424 ;; IMUL reg16, reg16, imm8 VectorPath
6425 ;; IMUL reg16, mem16, imm8 VectorPath
6426 ;; IMUL reg16, reg16, imm16 VectorPath
6427 ;; IMUL reg16, mem16, imm16 VectorPath
6428 ;; IMUL reg16, reg16 Direct
6429 ;; IMUL reg16, mem16 Direct
6431 ;; On BDVER1, all HI MULs use DoublePath
6433 (define_insn "*mulhi3_1"
6434 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6435 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6436 (match_operand:HI 2 "general_operand" "K,n,mr")))
6437 (clobber (reg:CC FLAGS_REG))]
6439 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6441 imul{w}\t{%2, %1, %0|%0, %1, %2}
6442 imul{w}\t{%2, %1, %0|%0, %1, %2}
6443 imul{w}\t{%2, %0|%0, %2}"
6444 [(set_attr "type" "imul")
6445 (set_attr "prefix_0f" "0,0,1")
6446 (set (attr "athlon_decode")
6447 (cond [(eq_attr "cpu" "athlon")
6448 (const_string "vector")
6449 (eq_attr "alternative" "1,2")
6450 (const_string "vector")]
6451 (const_string "direct")))
6452 (set (attr "amdfam10_decode")
6453 (cond [(eq_attr "alternative" "0,1")
6454 (const_string "vector")]
6455 (const_string "direct")))
6456 (set_attr "bdver1_decode" "double")
6457 (set_attr "mode" "HI")])
6459 ;;On AMDFAM10 and BDVER1
6463 (define_insn "*mulqi3_1"
6464 [(set (match_operand:QI 0 "register_operand" "=a")
6465 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6466 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6467 (clobber (reg:CC FLAGS_REG))]
6469 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6471 [(set_attr "type" "imul")
6472 (set_attr "length_immediate" "0")
6473 (set (attr "athlon_decode")
6474 (if_then_else (eq_attr "cpu" "athlon")
6475 (const_string "vector")
6476 (const_string "direct")))
6477 (set_attr "amdfam10_decode" "direct")
6478 (set_attr "bdver1_decode" "direct")
6479 (set_attr "mode" "QI")])
6481 (define_expand "<u>mul<mode><dwi>3"
6482 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6485 (match_operand:DWIH 1 "nonimmediate_operand"))
6487 (match_operand:DWIH 2 "register_operand"))))
6488 (clobber (reg:CC FLAGS_REG))])])
6490 (define_expand "<u>mulqihi3"
6491 [(parallel [(set (match_operand:HI 0 "register_operand")
6494 (match_operand:QI 1 "nonimmediate_operand"))
6496 (match_operand:QI 2 "register_operand"))))
6497 (clobber (reg:CC FLAGS_REG))])]
6498 "TARGET_QIMODE_MATH")
6500 (define_insn "*bmi2_umulditi3_1"
6501 [(set (match_operand:DI 0 "register_operand" "=r")
6503 (match_operand:DI 2 "nonimmediate_operand" "%d")
6504 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6505 (set (match_operand:DI 1 "register_operand" "=r")
6508 (mult:TI (zero_extend:TI (match_dup 2))
6509 (zero_extend:TI (match_dup 3)))
6511 "TARGET_64BIT && TARGET_BMI2
6512 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6513 "mulx\t{%3, %0, %1|%1, %0, %3}"
6514 [(set_attr "type" "imulx")
6515 (set_attr "prefix" "vex")
6516 (set_attr "mode" "DI")])
6518 (define_insn "*bmi2_umulsidi3_1"
6519 [(set (match_operand:SI 0 "register_operand" "=r")
6521 (match_operand:SI 2 "nonimmediate_operand" "%d")
6522 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6523 (set (match_operand:SI 1 "register_operand" "=r")
6526 (mult:DI (zero_extend:DI (match_dup 2))
6527 (zero_extend:DI (match_dup 3)))
6529 "!TARGET_64BIT && TARGET_BMI2
6530 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6531 "mulx\t{%3, %0, %1|%1, %0, %3}"
6532 [(set_attr "type" "imulx")
6533 (set_attr "prefix" "vex")
6534 (set_attr "mode" "SI")])
6536 (define_insn "*umul<mode><dwi>3_1"
6537 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6540 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6542 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6543 (clobber (reg:CC FLAGS_REG))]
6544 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6547 mul{<imodesuffix>}\t%2"
6548 [(set_attr "isa" "bmi2,*")
6549 (set_attr "type" "imulx,imul")
6550 (set_attr "length_immediate" "*,0")
6551 (set (attr "athlon_decode")
6552 (cond [(eq_attr "alternative" "1")
6553 (if_then_else (eq_attr "cpu" "athlon")
6554 (const_string "vector")
6555 (const_string "double"))]
6556 (const_string "*")))
6557 (set_attr "amdfam10_decode" "*,double")
6558 (set_attr "bdver1_decode" "*,direct")
6559 (set_attr "prefix" "vex,orig")
6560 (set_attr "mode" "<MODE>")])
6562 ;; Convert mul to the mulx pattern to avoid flags dependency.
6564 [(set (match_operand:<DWI> 0 "register_operand")
6567 (match_operand:DWIH 1 "register_operand"))
6569 (match_operand:DWIH 2 "nonimmediate_operand"))))
6570 (clobber (reg:CC FLAGS_REG))]
6571 "TARGET_BMI2 && reload_completed
6572 && true_regnum (operands[1]) == DX_REG"
6573 [(parallel [(set (match_dup 3)
6574 (mult:DWIH (match_dup 1) (match_dup 2)))
6578 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6579 (zero_extend:<DWI> (match_dup 2)))
6582 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6584 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6587 (define_insn "*mul<mode><dwi>3_1"
6588 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6591 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6593 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6594 (clobber (reg:CC FLAGS_REG))]
6595 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6596 "imul{<imodesuffix>}\t%2"
6597 [(set_attr "type" "imul")
6598 (set_attr "length_immediate" "0")
6599 (set (attr "athlon_decode")
6600 (if_then_else (eq_attr "cpu" "athlon")
6601 (const_string "vector")
6602 (const_string "double")))
6603 (set_attr "amdfam10_decode" "double")
6604 (set_attr "bdver1_decode" "direct")
6605 (set_attr "mode" "<MODE>")])
6607 (define_insn "*<u>mulqihi3_1"
6608 [(set (match_operand:HI 0 "register_operand" "=a")
6611 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6613 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6614 (clobber (reg:CC FLAGS_REG))]
6616 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6617 "<sgnprefix>mul{b}\t%2"
6618 [(set_attr "type" "imul")
6619 (set_attr "length_immediate" "0")
6620 (set (attr "athlon_decode")
6621 (if_then_else (eq_attr "cpu" "athlon")
6622 (const_string "vector")
6623 (const_string "direct")))
6624 (set_attr "amdfam10_decode" "direct")
6625 (set_attr "bdver1_decode" "direct")
6626 (set_attr "mode" "QI")])
6628 (define_expand "<s>mul<mode>3_highpart"
6629 [(parallel [(set (match_operand:SWI48 0 "register_operand")
6634 (match_operand:SWI48 1 "nonimmediate_operand"))
6636 (match_operand:SWI48 2 "register_operand")))
6638 (clobber (match_scratch:SWI48 3))
6639 (clobber (reg:CC FLAGS_REG))])]
6641 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6643 (define_insn "*<s>muldi3_highpart_1"
6644 [(set (match_operand:DI 0 "register_operand" "=d")
6649 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6651 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6653 (clobber (match_scratch:DI 3 "=1"))
6654 (clobber (reg:CC FLAGS_REG))]
6656 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6657 "<sgnprefix>mul{q}\t%2"
6658 [(set_attr "type" "imul")
6659 (set_attr "length_immediate" "0")
6660 (set (attr "athlon_decode")
6661 (if_then_else (eq_attr "cpu" "athlon")
6662 (const_string "vector")
6663 (const_string "double")))
6664 (set_attr "amdfam10_decode" "double")
6665 (set_attr "bdver1_decode" "direct")
6666 (set_attr "mode" "DI")])
6668 (define_insn "*<s>mulsi3_highpart_1"
6669 [(set (match_operand:SI 0 "register_operand" "=d")
6674 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6676 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6678 (clobber (match_scratch:SI 3 "=1"))
6679 (clobber (reg:CC FLAGS_REG))]
6680 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6681 "<sgnprefix>mul{l}\t%2"
6682 [(set_attr "type" "imul")
6683 (set_attr "length_immediate" "0")
6684 (set (attr "athlon_decode")
6685 (if_then_else (eq_attr "cpu" "athlon")
6686 (const_string "vector")
6687 (const_string "double")))
6688 (set_attr "amdfam10_decode" "double")
6689 (set_attr "bdver1_decode" "direct")
6690 (set_attr "mode" "SI")])
6692 (define_insn "*<s>mulsi3_highpart_zext"
6693 [(set (match_operand:DI 0 "register_operand" "=d")
6694 (zero_extend:DI (truncate:SI
6696 (mult:DI (any_extend:DI
6697 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6699 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6701 (clobber (match_scratch:SI 3 "=1"))
6702 (clobber (reg:CC FLAGS_REG))]
6704 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6705 "<sgnprefix>mul{l}\t%2"
6706 [(set_attr "type" "imul")
6707 (set_attr "length_immediate" "0")
6708 (set (attr "athlon_decode")
6709 (if_then_else (eq_attr "cpu" "athlon")
6710 (const_string "vector")
6711 (const_string "double")))
6712 (set_attr "amdfam10_decode" "double")
6713 (set_attr "bdver1_decode" "direct")
6714 (set_attr "mode" "SI")])
6716 ;; The patterns that match these are at the end of this file.
6718 (define_expand "mulxf3"
6719 [(set (match_operand:XF 0 "register_operand")
6720 (mult:XF (match_operand:XF 1 "register_operand")
6721 (match_operand:XF 2 "register_operand")))]
6724 (define_expand "mul<mode>3"
6725 [(set (match_operand:MODEF 0 "register_operand")
6726 (mult:MODEF (match_operand:MODEF 1 "register_operand")
6727 (match_operand:MODEF 2 "nonimmediate_operand")))]
6728 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6729 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6731 ;; Divide instructions
6733 ;; The patterns that match these are at the end of this file.
6735 (define_expand "divxf3"
6736 [(set (match_operand:XF 0 "register_operand")
6737 (div:XF (match_operand:XF 1 "register_operand")
6738 (match_operand:XF 2 "register_operand")))]
6741 (define_expand "divdf3"
6742 [(set (match_operand:DF 0 "register_operand")
6743 (div:DF (match_operand:DF 1 "register_operand")
6744 (match_operand:DF 2 "nonimmediate_operand")))]
6745 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
6746 || (TARGET_SSE2 && TARGET_SSE_MATH)")
6748 (define_expand "divsf3"
6749 [(set (match_operand:SF 0 "register_operand")
6750 (div:SF (match_operand:SF 1 "register_operand")
6751 (match_operand:SF 2 "nonimmediate_operand")))]
6752 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
6757 && optimize_insn_for_speed_p ()
6758 && flag_finite_math_only && !flag_trapping_math
6759 && flag_unsafe_math_optimizations)
6761 ix86_emit_swdivsf (operands[0], operands[1],
6762 operands[2], SFmode);
6767 ;; Divmod instructions.
6769 (define_expand "divmod<mode>4"
6770 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6772 (match_operand:SWIM248 1 "register_operand")
6773 (match_operand:SWIM248 2 "nonimmediate_operand")))
6774 (set (match_operand:SWIM248 3 "register_operand")
6775 (mod:SWIM248 (match_dup 1) (match_dup 2)))
6776 (clobber (reg:CC FLAGS_REG))])])
6778 ;; Split with 8bit unsigned divide:
6779 ;; if (dividend an divisor are in [0-255])
6780 ;; use 8bit unsigned integer divide
6782 ;; use original integer divide
6784 [(set (match_operand:SWI48 0 "register_operand")
6785 (div:SWI48 (match_operand:SWI48 2 "register_operand")
6786 (match_operand:SWI48 3 "nonimmediate_operand")))
6787 (set (match_operand:SWI48 1 "register_operand")
6788 (mod:SWI48 (match_dup 2) (match_dup 3)))
6789 (clobber (reg:CC FLAGS_REG))]
6790 "TARGET_USE_8BIT_IDIV
6791 && TARGET_QIMODE_MATH
6792 && can_create_pseudo_p ()
6793 && !optimize_insn_for_size_p ()"
6795 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
6797 (define_insn_and_split "divmod<mode>4_1"
6798 [(set (match_operand:SWI48 0 "register_operand" "=a")
6799 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
6800 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
6801 (set (match_operand:SWI48 1 "register_operand" "=&d")
6802 (mod:SWI48 (match_dup 2) (match_dup 3)))
6803 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
6804 (clobber (reg:CC FLAGS_REG))]
6808 [(parallel [(set (match_dup 1)
6809 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
6810 (clobber (reg:CC FLAGS_REG))])
6811 (parallel [(set (match_dup 0)
6812 (div:SWI48 (match_dup 2) (match_dup 3)))
6814 (mod:SWI48 (match_dup 2) (match_dup 3)))
6816 (clobber (reg:CC FLAGS_REG))])]
6818 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
6820 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
6821 operands[4] = operands[2];
6824 /* Avoid use of cltd in favor of a mov+shift. */
6825 emit_move_insn (operands[1], operands[2]);
6826 operands[4] = operands[1];
6829 [(set_attr "type" "multi")
6830 (set_attr "mode" "<MODE>")])
6832 (define_insn_and_split "*divmod<mode>4"
6833 [(set (match_operand:SWIM248 0 "register_operand" "=a")
6834 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
6835 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
6836 (set (match_operand:SWIM248 1 "register_operand" "=&d")
6837 (mod:SWIM248 (match_dup 2) (match_dup 3)))
6838 (clobber (reg:CC FLAGS_REG))]
6842 [(parallel [(set (match_dup 1)
6843 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
6844 (clobber (reg:CC FLAGS_REG))])
6845 (parallel [(set (match_dup 0)
6846 (div:SWIM248 (match_dup 2) (match_dup 3)))
6848 (mod:SWIM248 (match_dup 2) (match_dup 3)))
6850 (clobber (reg:CC FLAGS_REG))])]
6852 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
6854 if (<MODE>mode != HImode
6855 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
6856 operands[4] = operands[2];
6859 /* Avoid use of cltd in favor of a mov+shift. */
6860 emit_move_insn (operands[1], operands[2]);
6861 operands[4] = operands[1];
6864 [(set_attr "type" "multi")
6865 (set_attr "mode" "<MODE>")])
6867 (define_insn "*divmod<mode>4_noext"
6868 [(set (match_operand:SWIM248 0 "register_operand" "=a")
6869 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
6870 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
6871 (set (match_operand:SWIM248 1 "register_operand" "=d")
6872 (mod:SWIM248 (match_dup 2) (match_dup 3)))
6873 (use (match_operand:SWIM248 4 "register_operand" "1"))
6874 (clobber (reg:CC FLAGS_REG))]
6876 "idiv{<imodesuffix>}\t%3"
6877 [(set_attr "type" "idiv")
6878 (set_attr "mode" "<MODE>")])
6880 (define_expand "divmodqi4"
6881 [(parallel [(set (match_operand:QI 0 "register_operand")
6883 (match_operand:QI 1 "register_operand")
6884 (match_operand:QI 2 "nonimmediate_operand")))
6885 (set (match_operand:QI 3 "register_operand")
6886 (mod:QI (match_dup 1) (match_dup 2)))
6887 (clobber (reg:CC FLAGS_REG))])]
6888 "TARGET_QIMODE_MATH"
6893 tmp0 = gen_reg_rtx (HImode);
6894 tmp1 = gen_reg_rtx (HImode);
6896 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
6898 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
6899 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
6901 /* Extract remainder from AH. */
6902 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
6903 insn = emit_move_insn (operands[3], tmp1);
6905 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
6906 set_unique_reg_note (insn, REG_EQUAL, mod);
6908 /* Extract quotient from AL. */
6909 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
6911 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
6912 set_unique_reg_note (insn, REG_EQUAL, div);
6917 ;; Divide AX by r/m8, with result stored in
6920 ;; Change div/mod to HImode and extend the second argument to HImode
6921 ;; so that mode of div/mod matches with mode of arguments. Otherwise
6922 ;; combine may fail.
6923 (define_insn "divmodhiqi3"
6924 [(set (match_operand:HI 0 "register_operand" "=a")
6929 (mod:HI (match_operand:HI 1 "register_operand" "0")
6931 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
6935 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
6936 (clobber (reg:CC FLAGS_REG))]
6937 "TARGET_QIMODE_MATH"
6939 [(set_attr "type" "idiv")
6940 (set_attr "mode" "QI")])
6942 (define_expand "udivmod<mode>4"
6943 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6945 (match_operand:SWIM248 1 "register_operand")
6946 (match_operand:SWIM248 2 "nonimmediate_operand")))
6947 (set (match_operand:SWIM248 3 "register_operand")
6948 (umod:SWIM248 (match_dup 1) (match_dup 2)))
6949 (clobber (reg:CC FLAGS_REG))])])
6951 ;; Split with 8bit unsigned divide:
6952 ;; if (dividend an divisor are in [0-255])
6953 ;; use 8bit unsigned integer divide
6955 ;; use original integer divide
6957 [(set (match_operand:SWI48 0 "register_operand")
6958 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
6959 (match_operand:SWI48 3 "nonimmediate_operand")))
6960 (set (match_operand:SWI48 1 "register_operand")
6961 (umod:SWI48 (match_dup 2) (match_dup 3)))
6962 (clobber (reg:CC FLAGS_REG))]
6963 "TARGET_USE_8BIT_IDIV
6964 && TARGET_QIMODE_MATH
6965 && can_create_pseudo_p ()
6966 && !optimize_insn_for_size_p ()"
6968 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
6970 (define_insn_and_split "udivmod<mode>4_1"
6971 [(set (match_operand:SWI48 0 "register_operand" "=a")
6972 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
6973 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
6974 (set (match_operand:SWI48 1 "register_operand" "=&d")
6975 (umod:SWI48 (match_dup 2) (match_dup 3)))
6976 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
6977 (clobber (reg:CC FLAGS_REG))]
6981 [(set (match_dup 1) (const_int 0))
6982 (parallel [(set (match_dup 0)
6983 (udiv:SWI48 (match_dup 2) (match_dup 3)))
6985 (umod:SWI48 (match_dup 2) (match_dup 3)))
6987 (clobber (reg:CC FLAGS_REG))])]
6989 [(set_attr "type" "multi")
6990 (set_attr "mode" "<MODE>")])
6992 (define_insn_and_split "*udivmod<mode>4"
6993 [(set (match_operand:SWIM248 0 "register_operand" "=a")
6994 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
6995 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
6996 (set (match_operand:SWIM248 1 "register_operand" "=&d")
6997 (umod:SWIM248 (match_dup 2) (match_dup 3)))
6998 (clobber (reg:CC FLAGS_REG))]
7002 [(set (match_dup 1) (const_int 0))
7003 (parallel [(set (match_dup 0)
7004 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7006 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7008 (clobber (reg:CC FLAGS_REG))])]
7010 [(set_attr "type" "multi")
7011 (set_attr "mode" "<MODE>")])
7013 (define_insn "*udivmod<mode>4_noext"
7014 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7015 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7016 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7017 (set (match_operand:SWIM248 1 "register_operand" "=d")
7018 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7019 (use (match_operand:SWIM248 4 "register_operand" "1"))
7020 (clobber (reg:CC FLAGS_REG))]
7022 "div{<imodesuffix>}\t%3"
7023 [(set_attr "type" "idiv")
7024 (set_attr "mode" "<MODE>")])
7026 (define_expand "udivmodqi4"
7027 [(parallel [(set (match_operand:QI 0 "register_operand")
7029 (match_operand:QI 1 "register_operand")
7030 (match_operand:QI 2 "nonimmediate_operand")))
7031 (set (match_operand:QI 3 "register_operand")
7032 (umod:QI (match_dup 1) (match_dup 2)))
7033 (clobber (reg:CC FLAGS_REG))])]
7034 "TARGET_QIMODE_MATH"
7039 tmp0 = gen_reg_rtx (HImode);
7040 tmp1 = gen_reg_rtx (HImode);
7042 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7044 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7045 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7047 /* Extract remainder from AH. */
7048 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7049 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7050 insn = emit_move_insn (operands[3], tmp1);
7052 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7053 set_unique_reg_note (insn, REG_EQUAL, mod);
7055 /* Extract quotient from AL. */
7056 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7058 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7059 set_unique_reg_note (insn, REG_EQUAL, div);
7064 (define_insn "udivmodhiqi3"
7065 [(set (match_operand:HI 0 "register_operand" "=a")
7070 (mod:HI (match_operand:HI 1 "register_operand" "0")
7072 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7076 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7077 (clobber (reg:CC FLAGS_REG))]
7078 "TARGET_QIMODE_MATH"
7080 [(set_attr "type" "idiv")
7081 (set_attr "mode" "QI")])
7083 ;; We cannot use div/idiv for double division, because it causes
7084 ;; "division by zero" on the overflow and that's not what we expect
7085 ;; from truncate. Because true (non truncating) double division is
7086 ;; never generated, we can't create this insn anyway.
7089 ; [(set (match_operand:SI 0 "register_operand" "=a")
7091 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7093 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7094 ; (set (match_operand:SI 3 "register_operand" "=d")
7096 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7097 ; (clobber (reg:CC FLAGS_REG))]
7099 ; "div{l}\t{%2, %0|%0, %2}"
7100 ; [(set_attr "type" "idiv")])
7102 ;;- Logical AND instructions
7104 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7105 ;; Note that this excludes ah.
7107 (define_expand "testsi_ccno_1"
7108 [(set (reg:CCNO FLAGS_REG)
7110 (and:SI (match_operand:SI 0 "nonimmediate_operand")
7111 (match_operand:SI 1 "x86_64_nonmemory_operand"))
7114 (define_expand "testqi_ccz_1"
7115 [(set (reg:CCZ FLAGS_REG)
7116 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7117 (match_operand:QI 1 "nonmemory_operand"))
7120 (define_expand "testdi_ccno_1"
7121 [(set (reg:CCNO FLAGS_REG)
7123 (and:DI (match_operand:DI 0 "nonimmediate_operand")
7124 (match_operand:DI 1 "x86_64_szext_general_operand"))
7126 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7128 (define_insn "*testdi_1"
7129 [(set (reg FLAGS_REG)
7132 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7133 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7135 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7136 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7138 test{l}\t{%k1, %k0|%k0, %k1}
7139 test{l}\t{%k1, %k0|%k0, %k1}
7140 test{q}\t{%1, %0|%0, %1}
7141 test{q}\t{%1, %0|%0, %1}
7142 test{q}\t{%1, %0|%0, %1}"
7143 [(set_attr "type" "test")
7144 (set_attr "modrm" "0,1,0,1,1")
7145 (set_attr "mode" "SI,SI,DI,DI,DI")])
7147 (define_insn "*testqi_1_maybe_si"
7148 [(set (reg FLAGS_REG)
7151 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7152 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7154 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7155 && ix86_match_ccmode (insn,
7156 CONST_INT_P (operands[1])
7157 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7159 if (which_alternative == 3)
7161 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7162 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7163 return "test{l}\t{%1, %k0|%k0, %1}";
7165 return "test{b}\t{%1, %0|%0, %1}";
7167 [(set_attr "type" "test")
7168 (set_attr "modrm" "0,1,1,1")
7169 (set_attr "mode" "QI,QI,QI,SI")
7170 (set_attr "pent_pair" "uv,np,uv,np")])
7172 (define_insn "*test<mode>_1"
7173 [(set (reg FLAGS_REG)
7176 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7177 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7179 "ix86_match_ccmode (insn, CCNOmode)
7180 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7181 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7182 [(set_attr "type" "test")
7183 (set_attr "modrm" "0,1,1")
7184 (set_attr "mode" "<MODE>")
7185 (set_attr "pent_pair" "uv,np,uv")])
7187 (define_expand "testqi_ext_ccno_0"
7188 [(set (reg:CCNO FLAGS_REG)
7192 (match_operand 0 "ext_register_operand")
7195 (match_operand 1 "const_int_operand"))
7198 (define_insn "*testqi_ext_0"
7199 [(set (reg FLAGS_REG)
7203 (match_operand 0 "ext_register_operand" "Q")
7206 (match_operand 1 "const_int_operand" "n"))
7208 "ix86_match_ccmode (insn, CCNOmode)"
7209 "test{b}\t{%1, %h0|%h0, %1}"
7210 [(set_attr "type" "test")
7211 (set_attr "mode" "QI")
7212 (set_attr "length_immediate" "1")
7213 (set_attr "modrm" "1")
7214 (set_attr "pent_pair" "np")])
7216 (define_insn "*testqi_ext_1"
7217 [(set (reg FLAGS_REG)
7221 (match_operand 0 "ext_register_operand" "Q,Q")
7225 (match_operand:QI 1 "nonimmediate_x64nomem_operand" "Q,m")))
7227 "ix86_match_ccmode (insn, CCNOmode)"
7228 "test{b}\t{%1, %h0|%h0, %1}"
7229 [(set_attr "isa" "*,nox64")
7230 (set_attr "type" "test")
7231 (set_attr "mode" "QI")])
7233 (define_insn "*testqi_ext_2"
7234 [(set (reg FLAGS_REG)
7238 (match_operand 0 "ext_register_operand" "Q")
7242 (match_operand 1 "ext_register_operand" "Q")
7246 "ix86_match_ccmode (insn, CCNOmode)"
7247 "test{b}\t{%h1, %h0|%h0, %h1}"
7248 [(set_attr "type" "test")
7249 (set_attr "mode" "QI")])
7251 ;; Combine likes to form bit extractions for some tests. Humor it.
7252 (define_insn "*testqi_ext_3"
7253 [(set (reg FLAGS_REG)
7254 (compare (zero_extract:SWI48
7255 (match_operand 0 "nonimmediate_operand" "rm")
7256 (match_operand:SWI48 1 "const_int_operand")
7257 (match_operand:SWI48 2 "const_int_operand"))
7259 "ix86_match_ccmode (insn, CCNOmode)
7260 && ((TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7261 || GET_MODE (operands[0]) == SImode
7262 || GET_MODE (operands[0]) == HImode
7263 || GET_MODE (operands[0]) == QImode)
7264 /* Ensure that resulting mask is zero or sign extended operand. */
7265 && INTVAL (operands[2]) >= 0
7266 && ((INTVAL (operands[1]) > 0
7267 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)
7268 || (<MODE>mode == DImode
7269 && INTVAL (operands[1]) > 32
7270 && INTVAL (operands[1]) + INTVAL (operands[2]) == 64))"
7274 [(set (match_operand 0 "flags_reg_operand")
7275 (match_operator 1 "compare_operator"
7277 (match_operand 2 "nonimmediate_operand")
7278 (match_operand 3 "const_int_operand")
7279 (match_operand 4 "const_int_operand"))
7281 "ix86_match_ccmode (insn, CCNOmode)"
7282 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7284 rtx val = operands[2];
7285 HOST_WIDE_INT len = INTVAL (operands[3]);
7286 HOST_WIDE_INT pos = INTVAL (operands[4]);
7288 enum machine_mode mode, submode;
7290 mode = GET_MODE (val);
7293 /* ??? Combine likes to put non-volatile mem extractions in QImode
7294 no matter the size of the test. So find a mode that works. */
7295 if (! MEM_VOLATILE_P (val))
7297 mode = smallest_mode_for_size (pos + len, MODE_INT);
7298 val = adjust_address (val, mode, 0);
7301 else if (GET_CODE (val) == SUBREG
7302 && (submode = GET_MODE (SUBREG_REG (val)),
7303 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7304 && pos + len <= GET_MODE_BITSIZE (submode)
7305 && GET_MODE_CLASS (submode) == MODE_INT)
7307 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7309 val = SUBREG_REG (val);
7311 else if (mode == HImode && pos + len <= 8)
7313 /* Small HImode tests can be converted to QImode. */
7315 val = gen_lowpart (QImode, val);
7318 if (len == HOST_BITS_PER_WIDE_INT)
7321 mask = ((HOST_WIDE_INT)1 << len) - 1;
7324 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7327 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7328 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7329 ;; this is relatively important trick.
7330 ;; Do the conversion only post-reload to avoid limiting of the register class
7333 [(set (match_operand 0 "flags_reg_operand")
7334 (match_operator 1 "compare_operator"
7335 [(and (match_operand 2 "register_operand")
7336 (match_operand 3 "const_int_operand"))
7339 && QI_REG_P (operands[2])
7340 && GET_MODE (operands[2]) != QImode
7341 && ((ix86_match_ccmode (insn, CCZmode)
7342 && !(INTVAL (operands[3]) & ~(255 << 8)))
7343 || (ix86_match_ccmode (insn, CCNOmode)
7344 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7347 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7351 operands[2] = gen_lowpart (SImode, operands[2]);
7352 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7356 [(set (match_operand 0 "flags_reg_operand")
7357 (match_operator 1 "compare_operator"
7358 [(and (match_operand 2 "nonimmediate_operand")
7359 (match_operand 3 "const_int_operand"))
7362 && GET_MODE (operands[2]) != QImode
7363 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7364 && ((ix86_match_ccmode (insn, CCZmode)
7365 && !(INTVAL (operands[3]) & ~255))
7366 || (ix86_match_ccmode (insn, CCNOmode)
7367 && !(INTVAL (operands[3]) & ~127)))"
7369 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7372 operands[2] = gen_lowpart (QImode, operands[2]);
7373 operands[3] = gen_lowpart (QImode, operands[3]);
7376 ;; %%% This used to optimize known byte-wide and operations to memory,
7377 ;; and sometimes to QImode registers. If this is considered useful,
7378 ;; it should be done with splitters.
7380 (define_expand "and<mode>3"
7381 [(set (match_operand:SWIM 0 "nonimmediate_operand")
7382 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7383 (match_operand:SWIM 2 "<general_szext_operand>")))]
7386 enum machine_mode mode = <MODE>mode;
7387 rtx (*insn) (rtx, rtx);
7389 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7391 HOST_WIDE_INT ival = INTVAL (operands[2]);
7393 if (ival == (HOST_WIDE_INT) 0xffffffff)
7395 else if (ival == 0xffff)
7397 else if (ival == 0xff)
7401 if (mode == <MODE>mode)
7403 ix86_expand_binary_operator (AND, <MODE>mode, operands);
7407 if (<MODE>mode == DImode)
7408 insn = (mode == SImode)
7409 ? gen_zero_extendsidi2
7411 ? gen_zero_extendhidi2
7412 : gen_zero_extendqidi2;
7413 else if (<MODE>mode == SImode)
7414 insn = (mode == HImode)
7415 ? gen_zero_extendhisi2
7416 : gen_zero_extendqisi2;
7417 else if (<MODE>mode == HImode)
7418 insn = gen_zero_extendqihi2;
7422 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7426 (define_insn "*anddi_1"
7427 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7429 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7430 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7431 (clobber (reg:CC FLAGS_REG))]
7432 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7434 switch (get_attr_type (insn))
7440 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7441 if (get_attr_mode (insn) == MODE_SI)
7442 return "and{l}\t{%k2, %k0|%k0, %k2}";
7444 return "and{q}\t{%2, %0|%0, %2}";
7447 [(set_attr "type" "alu,alu,alu,imovx")
7448 (set_attr "length_immediate" "*,*,*,0")
7449 (set (attr "prefix_rex")
7451 (and (eq_attr "type" "imovx")
7452 (and (match_test "INTVAL (operands[2]) == 0xff")
7453 (match_operand 1 "ext_QIreg_operand")))
7455 (const_string "*")))
7456 (set_attr "mode" "SI,DI,DI,SI")])
7458 (define_insn "*andsi_1"
7459 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya")
7460 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7461 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7462 (clobber (reg:CC FLAGS_REG))]
7463 "ix86_binary_operator_ok (AND, SImode, operands)"
7465 switch (get_attr_type (insn))
7471 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7472 return "and{l}\t{%2, %0|%0, %2}";
7475 [(set_attr "type" "alu,alu,imovx")
7476 (set (attr "prefix_rex")
7478 (and (eq_attr "type" "imovx")
7479 (and (match_test "INTVAL (operands[2]) == 0xff")
7480 (match_operand 1 "ext_QIreg_operand")))
7482 (const_string "*")))
7483 (set_attr "length_immediate" "*,*,0")
7484 (set_attr "mode" "SI")])
7486 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7487 (define_insn "*andsi_1_zext"
7488 [(set (match_operand:DI 0 "register_operand" "=r")
7490 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7491 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7492 (clobber (reg:CC FLAGS_REG))]
7493 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7494 "and{l}\t{%2, %k0|%k0, %2}"
7495 [(set_attr "type" "alu")
7496 (set_attr "mode" "SI")])
7498 (define_insn "*andhi_1"
7499 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya")
7500 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7501 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7502 (clobber (reg:CC FLAGS_REG))]
7503 "ix86_binary_operator_ok (AND, HImode, operands)"
7505 switch (get_attr_type (insn))
7511 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7512 return "and{w}\t{%2, %0|%0, %2}";
7515 [(set_attr "type" "alu,alu,imovx")
7516 (set_attr "length_immediate" "*,*,0")
7517 (set (attr "prefix_rex")
7519 (and (eq_attr "type" "imovx")
7520 (match_operand 1 "ext_QIreg_operand"))
7522 (const_string "*")))
7523 (set_attr "mode" "HI,HI,SI")])
7525 ;; %%% Potential partial reg stall on alternative 2. What to do?
7526 (define_insn "*andqi_1"
7527 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7528 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7529 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7530 (clobber (reg:CC FLAGS_REG))]
7531 "ix86_binary_operator_ok (AND, QImode, operands)"
7533 and{b}\t{%2, %0|%0, %2}
7534 and{b}\t{%2, %0|%0, %2}
7535 and{l}\t{%k2, %k0|%k0, %k2}"
7536 [(set_attr "type" "alu")
7537 (set_attr "mode" "QI,QI,SI")])
7539 (define_insn "*andqi_1_slp"
7540 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7541 (and:QI (match_dup 0)
7542 (match_operand:QI 1 "general_operand" "qn,qmn")))
7543 (clobber (reg:CC FLAGS_REG))]
7544 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7545 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7546 "and{b}\t{%1, %0|%0, %1}"
7547 [(set_attr "type" "alu1")
7548 (set_attr "mode" "QI")])
7550 ;; Turn *anddi_1 into *andsi_1_zext if possible.
7552 [(set (match_operand:DI 0 "register_operand")
7553 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
7554 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
7555 (clobber (reg:CC FLAGS_REG))]
7557 [(parallel [(set (match_dup 0)
7558 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
7559 (clobber (reg:CC FLAGS_REG))])]
7560 "operands[2] = gen_lowpart (SImode, operands[2]);")
7563 [(set (match_operand:SWI248 0 "register_operand")
7564 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
7565 (match_operand:SWI248 2 "const_int_operand")))
7566 (clobber (reg:CC FLAGS_REG))]
7568 && true_regnum (operands[0]) != true_regnum (operands[1])"
7571 HOST_WIDE_INT ival = INTVAL (operands[2]);
7572 enum machine_mode mode;
7573 rtx (*insn) (rtx, rtx);
7575 if (ival == (HOST_WIDE_INT) 0xffffffff)
7577 else if (ival == 0xffff)
7581 gcc_assert (ival == 0xff);
7585 if (<MODE>mode == DImode)
7586 insn = (mode == SImode)
7587 ? gen_zero_extendsidi2
7589 ? gen_zero_extendhidi2
7590 : gen_zero_extendqidi2;
7593 if (<MODE>mode != SImode)
7594 /* Zero extend to SImode to avoid partial register stalls. */
7595 operands[0] = gen_lowpart (SImode, operands[0]);
7597 insn = (mode == HImode)
7598 ? gen_zero_extendhisi2
7599 : gen_zero_extendqisi2;
7601 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7606 [(set (match_operand 0 "register_operand")
7608 (const_int -65536)))
7609 (clobber (reg:CC FLAGS_REG))]
7610 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7611 || optimize_function_for_size_p (cfun)"
7612 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7613 "operands[1] = gen_lowpart (HImode, operands[0]);")
7616 [(set (match_operand 0 "ext_register_operand")
7619 (clobber (reg:CC FLAGS_REG))]
7620 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7621 && reload_completed"
7622 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7623 "operands[1] = gen_lowpart (QImode, operands[0]);")
7626 [(set (match_operand 0 "ext_register_operand")
7628 (const_int -65281)))
7629 (clobber (reg:CC FLAGS_REG))]
7630 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7631 && reload_completed"
7632 [(parallel [(set (zero_extract:SI (match_dup 0)
7636 (zero_extract:SI (match_dup 0)
7639 (zero_extract:SI (match_dup 0)
7642 (clobber (reg:CC FLAGS_REG))])]
7643 "operands[0] = gen_lowpart (SImode, operands[0]);")
7645 (define_insn "*anddi_2"
7646 [(set (reg FLAGS_REG)
7649 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7650 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7652 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7653 (and:DI (match_dup 1) (match_dup 2)))]
7654 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7655 && ix86_binary_operator_ok (AND, DImode, operands)"
7657 and{l}\t{%k2, %k0|%k0, %k2}
7658 and{q}\t{%2, %0|%0, %2}
7659 and{q}\t{%2, %0|%0, %2}"
7660 [(set_attr "type" "alu")
7661 (set_attr "mode" "SI,DI,DI")])
7663 (define_insn "*andqi_2_maybe_si"
7664 [(set (reg FLAGS_REG)
7666 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7667 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7669 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7670 (and:QI (match_dup 1) (match_dup 2)))]
7671 "ix86_binary_operator_ok (AND, QImode, operands)
7672 && ix86_match_ccmode (insn,
7673 CONST_INT_P (operands[2])
7674 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7676 if (which_alternative == 2)
7678 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7679 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7680 return "and{l}\t{%2, %k0|%k0, %2}";
7682 return "and{b}\t{%2, %0|%0, %2}";
7684 [(set_attr "type" "alu")
7685 (set_attr "mode" "QI,QI,SI")])
7687 (define_insn "*and<mode>_2"
7688 [(set (reg FLAGS_REG)
7689 (compare (and:SWI124
7690 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7691 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7693 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7694 (and:SWI124 (match_dup 1) (match_dup 2)))]
7695 "ix86_match_ccmode (insn, CCNOmode)
7696 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7697 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7698 [(set_attr "type" "alu")
7699 (set_attr "mode" "<MODE>")])
7701 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7702 (define_insn "*andsi_2_zext"
7703 [(set (reg FLAGS_REG)
7705 (match_operand:SI 1 "nonimmediate_operand" "%0")
7706 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7708 (set (match_operand:DI 0 "register_operand" "=r")
7709 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7710 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7711 && ix86_binary_operator_ok (AND, SImode, operands)"
7712 "and{l}\t{%2, %k0|%k0, %2}"
7713 [(set_attr "type" "alu")
7714 (set_attr "mode" "SI")])
7716 (define_insn "*andqi_2_slp"
7717 [(set (reg FLAGS_REG)
7719 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7720 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
7722 (set (strict_low_part (match_dup 0))
7723 (and:QI (match_dup 0) (match_dup 1)))]
7724 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7725 && ix86_match_ccmode (insn, CCNOmode)
7726 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7727 "and{b}\t{%1, %0|%0, %1}"
7728 [(set_attr "type" "alu1")
7729 (set_attr "mode" "QI")])
7731 ;; ??? A bug in recog prevents it from recognizing a const_int as an
7732 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
7733 ;; for a QImode operand, which of course failed.
7734 (define_insn "andqi_ext_0"
7735 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7740 (match_operand 1 "ext_register_operand" "0")
7743 (match_operand 2 "const_int_operand" "n")))
7744 (clobber (reg:CC FLAGS_REG))]
7746 "and{b}\t{%2, %h0|%h0, %2}"
7747 [(set_attr "type" "alu")
7748 (set_attr "length_immediate" "1")
7749 (set_attr "modrm" "1")
7750 (set_attr "mode" "QI")])
7752 ;; Generated by peephole translating test to and. This shows up
7753 ;; often in fp comparisons.
7754 (define_insn "*andqi_ext_0_cc"
7755 [(set (reg FLAGS_REG)
7759 (match_operand 1 "ext_register_operand" "0")
7762 (match_operand 2 "const_int_operand" "n"))
7764 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7773 "ix86_match_ccmode (insn, CCNOmode)"
7774 "and{b}\t{%2, %h0|%h0, %2}"
7775 [(set_attr "type" "alu")
7776 (set_attr "length_immediate" "1")
7777 (set_attr "modrm" "1")
7778 (set_attr "mode" "QI")])
7780 (define_insn "*andqi_ext_1"
7781 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
7786 (match_operand 1 "ext_register_operand" "0,0")
7790 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
7791 (clobber (reg:CC FLAGS_REG))]
7793 "and{b}\t{%2, %h0|%h0, %2}"
7794 [(set_attr "isa" "*,nox64")
7795 (set_attr "type" "alu")
7796 (set_attr "length_immediate" "0")
7797 (set_attr "mode" "QI")])
7799 (define_insn "*andqi_ext_2"
7800 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7805 (match_operand 1 "ext_register_operand" "%0")
7809 (match_operand 2 "ext_register_operand" "Q")
7812 (clobber (reg:CC FLAGS_REG))]
7814 "and{b}\t{%h2, %h0|%h0, %h2}"
7815 [(set_attr "type" "alu")
7816 (set_attr "length_immediate" "0")
7817 (set_attr "mode" "QI")])
7819 ;; Convert wide AND instructions with immediate operand to shorter QImode
7820 ;; equivalents when possible.
7821 ;; Don't do the splitting with memory operands, since it introduces risk
7822 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
7823 ;; for size, but that can (should?) be handled by generic code instead.
7825 [(set (match_operand 0 "register_operand")
7826 (and (match_operand 1 "register_operand")
7827 (match_operand 2 "const_int_operand")))
7828 (clobber (reg:CC FLAGS_REG))]
7830 && QI_REG_P (operands[0])
7831 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7832 && !(~INTVAL (operands[2]) & ~(255 << 8))
7833 && GET_MODE (operands[0]) != QImode"
7834 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
7835 (and:SI (zero_extract:SI (match_dup 1)
7836 (const_int 8) (const_int 8))
7838 (clobber (reg:CC FLAGS_REG))])]
7840 operands[0] = gen_lowpart (SImode, operands[0]);
7841 operands[1] = gen_lowpart (SImode, operands[1]);
7842 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
7845 ;; Since AND can be encoded with sign extended immediate, this is only
7846 ;; profitable when 7th bit is not set.
7848 [(set (match_operand 0 "register_operand")
7849 (and (match_operand 1 "general_operand")
7850 (match_operand 2 "const_int_operand")))
7851 (clobber (reg:CC FLAGS_REG))]
7853 && ANY_QI_REG_P (operands[0])
7854 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7855 && !(~INTVAL (operands[2]) & ~255)
7856 && !(INTVAL (operands[2]) & 128)
7857 && GET_MODE (operands[0]) != QImode"
7858 [(parallel [(set (strict_low_part (match_dup 0))
7859 (and:QI (match_dup 1)
7861 (clobber (reg:CC FLAGS_REG))])]
7863 operands[0] = gen_lowpart (QImode, operands[0]);
7864 operands[1] = gen_lowpart (QImode, operands[1]);
7865 operands[2] = gen_lowpart (QImode, operands[2]);
7868 ;; Logical inclusive and exclusive OR instructions
7870 ;; %%% This used to optimize known byte-wide and operations to memory.
7871 ;; If this is considered useful, it should be done with splitters.
7873 (define_expand "<code><mode>3"
7874 [(set (match_operand:SWIM 0 "nonimmediate_operand")
7875 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7876 (match_operand:SWIM 2 "<general_operand>")))]
7878 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
7880 (define_insn "*<code><mode>_1"
7881 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
7883 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
7884 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
7885 (clobber (reg:CC FLAGS_REG))]
7886 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7887 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7888 [(set_attr "type" "alu")
7889 (set_attr "mode" "<MODE>")])
7891 ;; %%% Potential partial reg stall on alternative 2. What to do?
7892 (define_insn "*<code>qi_1"
7893 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
7894 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7895 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
7896 (clobber (reg:CC FLAGS_REG))]
7897 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
7899 <logic>{b}\t{%2, %0|%0, %2}
7900 <logic>{b}\t{%2, %0|%0, %2}
7901 <logic>{l}\t{%k2, %k0|%k0, %k2}"
7902 [(set_attr "type" "alu")
7903 (set_attr "mode" "QI,QI,SI")])
7905 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7906 (define_insn "*<code>si_1_zext"
7907 [(set (match_operand:DI 0 "register_operand" "=r")
7909 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7910 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7911 (clobber (reg:CC FLAGS_REG))]
7912 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7913 "<logic>{l}\t{%2, %k0|%k0, %2}"
7914 [(set_attr "type" "alu")
7915 (set_attr "mode" "SI")])
7917 (define_insn "*<code>si_1_zext_imm"
7918 [(set (match_operand:DI 0 "register_operand" "=r")
7920 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
7921 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
7922 (clobber (reg:CC FLAGS_REG))]
7923 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7924 "<logic>{l}\t{%2, %k0|%k0, %2}"
7925 [(set_attr "type" "alu")
7926 (set_attr "mode" "SI")])
7928 (define_insn "*<code>qi_1_slp"
7929 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
7930 (any_or:QI (match_dup 0)
7931 (match_operand:QI 1 "general_operand" "qmn,qn")))
7932 (clobber (reg:CC FLAGS_REG))]
7933 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7934 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7935 "<logic>{b}\t{%1, %0|%0, %1}"
7936 [(set_attr "type" "alu1")
7937 (set_attr "mode" "QI")])
7939 (define_insn "*<code><mode>_2"
7940 [(set (reg FLAGS_REG)
7941 (compare (any_or:SWI
7942 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
7943 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
7945 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
7946 (any_or:SWI (match_dup 1) (match_dup 2)))]
7947 "ix86_match_ccmode (insn, CCNOmode)
7948 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7949 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7950 [(set_attr "type" "alu")
7951 (set_attr "mode" "<MODE>")])
7953 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7954 ;; ??? Special case for immediate operand is missing - it is tricky.
7955 (define_insn "*<code>si_2_zext"
7956 [(set (reg FLAGS_REG)
7957 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7958 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7960 (set (match_operand:DI 0 "register_operand" "=r")
7961 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
7962 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7963 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7964 "<logic>{l}\t{%2, %k0|%k0, %2}"
7965 [(set_attr "type" "alu")
7966 (set_attr "mode" "SI")])
7968 (define_insn "*<code>si_2_zext_imm"
7969 [(set (reg FLAGS_REG)
7971 (match_operand:SI 1 "nonimmediate_operand" "%0")
7972 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
7974 (set (match_operand:DI 0 "register_operand" "=r")
7975 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
7976 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7977 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7978 "<logic>{l}\t{%2, %k0|%k0, %2}"
7979 [(set_attr "type" "alu")
7980 (set_attr "mode" "SI")])
7982 (define_insn "*<code>qi_2_slp"
7983 [(set (reg FLAGS_REG)
7984 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7985 (match_operand:QI 1 "general_operand" "qmn,qn"))
7987 (set (strict_low_part (match_dup 0))
7988 (any_or:QI (match_dup 0) (match_dup 1)))]
7989 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7990 && ix86_match_ccmode (insn, CCNOmode)
7991 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7992 "<logic>{b}\t{%1, %0|%0, %1}"
7993 [(set_attr "type" "alu1")
7994 (set_attr "mode" "QI")])
7996 (define_insn "*<code><mode>_3"
7997 [(set (reg FLAGS_REG)
7998 (compare (any_or:SWI
7999 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8000 (match_operand:SWI 2 "<general_operand>" "<g>"))
8002 (clobber (match_scratch:SWI 0 "=<r>"))]
8003 "ix86_match_ccmode (insn, CCNOmode)
8004 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8005 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8006 [(set_attr "type" "alu")
8007 (set_attr "mode" "<MODE>")])
8009 (define_insn "*<code>qi_ext_0"
8010 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8015 (match_operand 1 "ext_register_operand" "0")
8018 (match_operand 2 "const_int_operand" "n")))
8019 (clobber (reg:CC FLAGS_REG))]
8020 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8021 "<logic>{b}\t{%2, %h0|%h0, %2}"
8022 [(set_attr "type" "alu")
8023 (set_attr "length_immediate" "1")
8024 (set_attr "modrm" "1")
8025 (set_attr "mode" "QI")])
8027 (define_insn "*<code>qi_ext_1"
8028 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8033 (match_operand 1 "ext_register_operand" "0,0")
8037 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8038 (clobber (reg:CC FLAGS_REG))]
8039 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8040 "<logic>{b}\t{%2, %h0|%h0, %2}"
8041 [(set_attr "isa" "*,nox64")
8042 (set_attr "type" "alu")
8043 (set_attr "length_immediate" "0")
8044 (set_attr "mode" "QI")])
8046 (define_insn "*<code>qi_ext_2"
8047 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8051 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8054 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8057 (clobber (reg:CC FLAGS_REG))]
8058 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8059 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8060 [(set_attr "type" "alu")
8061 (set_attr "length_immediate" "0")
8062 (set_attr "mode" "QI")])
8065 [(set (match_operand 0 "register_operand")
8066 (any_or (match_operand 1 "register_operand")
8067 (match_operand 2 "const_int_operand")))
8068 (clobber (reg:CC FLAGS_REG))]
8070 && QI_REG_P (operands[0])
8071 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8072 && !(INTVAL (operands[2]) & ~(255 << 8))
8073 && GET_MODE (operands[0]) != QImode"
8074 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8075 (any_or:SI (zero_extract:SI (match_dup 1)
8076 (const_int 8) (const_int 8))
8078 (clobber (reg:CC FLAGS_REG))])]
8080 operands[0] = gen_lowpart (SImode, operands[0]);
8081 operands[1] = gen_lowpart (SImode, operands[1]);
8082 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8085 ;; Since OR can be encoded with sign extended immediate, this is only
8086 ;; profitable when 7th bit is set.
8088 [(set (match_operand 0 "register_operand")
8089 (any_or (match_operand 1 "general_operand")
8090 (match_operand 2 "const_int_operand")))
8091 (clobber (reg:CC FLAGS_REG))]
8093 && ANY_QI_REG_P (operands[0])
8094 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8095 && !(INTVAL (operands[2]) & ~255)
8096 && (INTVAL (operands[2]) & 128)
8097 && GET_MODE (operands[0]) != QImode"
8098 [(parallel [(set (strict_low_part (match_dup 0))
8099 (any_or:QI (match_dup 1)
8101 (clobber (reg:CC FLAGS_REG))])]
8103 operands[0] = gen_lowpart (QImode, operands[0]);
8104 operands[1] = gen_lowpart (QImode, operands[1]);
8105 operands[2] = gen_lowpart (QImode, operands[2]);
8108 (define_expand "xorqi_cc_ext_1"
8110 (set (reg:CCNO FLAGS_REG)
8114 (match_operand 1 "ext_register_operand")
8117 (match_operand:QI 2 "const_int_operand"))
8119 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8129 (define_insn "*xorqi_cc_ext_1"
8130 [(set (reg FLAGS_REG)
8134 (match_operand 1 "ext_register_operand" "0,0")
8137 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m"))
8139 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8148 "ix86_match_ccmode (insn, CCNOmode)"
8149 "xor{b}\t{%2, %h0|%h0, %2}"
8150 [(set_attr "isa" "*,nox64")
8151 (set_attr "type" "alu")
8152 (set_attr "modrm" "1")
8153 (set_attr "mode" "QI")])
8155 ;; Negation instructions
8157 (define_expand "neg<mode>2"
8158 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8159 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8161 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8163 (define_insn_and_split "*neg<dwi>2_doubleword"
8164 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8165 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8166 (clobber (reg:CC FLAGS_REG))]
8167 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8171 [(set (reg:CCZ FLAGS_REG)
8172 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8173 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8176 (plus:DWIH (match_dup 3)
8177 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8179 (clobber (reg:CC FLAGS_REG))])
8182 (neg:DWIH (match_dup 2)))
8183 (clobber (reg:CC FLAGS_REG))])]
8184 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8186 (define_insn "*neg<mode>2_1"
8187 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8188 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8189 (clobber (reg:CC FLAGS_REG))]
8190 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8191 "neg{<imodesuffix>}\t%0"
8192 [(set_attr "type" "negnot")
8193 (set_attr "mode" "<MODE>")])
8195 ;; Combine is quite creative about this pattern.
8196 (define_insn "*negsi2_1_zext"
8197 [(set (match_operand:DI 0 "register_operand" "=r")
8199 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8202 (clobber (reg:CC FLAGS_REG))]
8203 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8205 [(set_attr "type" "negnot")
8206 (set_attr "mode" "SI")])
8208 ;; The problem with neg is that it does not perform (compare x 0),
8209 ;; it really performs (compare 0 x), which leaves us with the zero
8210 ;; flag being the only useful item.
8212 (define_insn "*neg<mode>2_cmpz"
8213 [(set (reg:CCZ FLAGS_REG)
8215 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8217 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8218 (neg:SWI (match_dup 1)))]
8219 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8220 "neg{<imodesuffix>}\t%0"
8221 [(set_attr "type" "negnot")
8222 (set_attr "mode" "<MODE>")])
8224 (define_insn "*negsi2_cmpz_zext"
8225 [(set (reg:CCZ FLAGS_REG)
8229 (match_operand:DI 1 "register_operand" "0")
8233 (set (match_operand:DI 0 "register_operand" "=r")
8234 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8237 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8239 [(set_attr "type" "negnot")
8240 (set_attr "mode" "SI")])
8242 ;; Changing of sign for FP values is doable using integer unit too.
8244 (define_expand "<code><mode>2"
8245 [(set (match_operand:X87MODEF 0 "register_operand")
8246 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8247 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8248 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8250 (define_insn "*absneg<mode>2_mixed"
8251 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8252 (match_operator:MODEF 3 "absneg_operator"
8253 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8254 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8255 (clobber (reg:CC FLAGS_REG))]
8256 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8259 (define_insn "*absneg<mode>2_sse"
8260 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8261 (match_operator:MODEF 3 "absneg_operator"
8262 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8263 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8264 (clobber (reg:CC FLAGS_REG))]
8265 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8268 (define_insn "*absneg<mode>2_i387"
8269 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8270 (match_operator:X87MODEF 3 "absneg_operator"
8271 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8272 (use (match_operand 2))
8273 (clobber (reg:CC FLAGS_REG))]
8274 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8277 (define_expand "<code>tf2"
8278 [(set (match_operand:TF 0 "register_operand")
8279 (absneg:TF (match_operand:TF 1 "register_operand")))]
8281 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8283 (define_insn "*absnegtf2_sse"
8284 [(set (match_operand:TF 0 "register_operand" "=x,x")
8285 (match_operator:TF 3 "absneg_operator"
8286 [(match_operand:TF 1 "register_operand" "0,x")]))
8287 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8288 (clobber (reg:CC FLAGS_REG))]
8292 ;; Splitters for fp abs and neg.
8295 [(set (match_operand 0 "fp_register_operand")
8296 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8297 (use (match_operand 2))
8298 (clobber (reg:CC FLAGS_REG))]
8300 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8303 [(set (match_operand 0 "register_operand")
8304 (match_operator 3 "absneg_operator"
8305 [(match_operand 1 "register_operand")]))
8306 (use (match_operand 2 "nonimmediate_operand"))
8307 (clobber (reg:CC FLAGS_REG))]
8308 "reload_completed && SSE_REG_P (operands[0])"
8309 [(set (match_dup 0) (match_dup 3))]
8311 enum machine_mode mode = GET_MODE (operands[0]);
8312 enum machine_mode vmode = GET_MODE (operands[2]);
8315 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8316 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8317 if (operands_match_p (operands[0], operands[2]))
8320 operands[1] = operands[2];
8323 if (GET_CODE (operands[3]) == ABS)
8324 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8326 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8331 [(set (match_operand:SF 0 "register_operand")
8332 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8333 (use (match_operand:V4SF 2))
8334 (clobber (reg:CC FLAGS_REG))]
8336 [(parallel [(set (match_dup 0) (match_dup 1))
8337 (clobber (reg:CC FLAGS_REG))])]
8340 operands[0] = gen_lowpart (SImode, operands[0]);
8341 if (GET_CODE (operands[1]) == ABS)
8343 tmp = gen_int_mode (0x7fffffff, SImode);
8344 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8348 tmp = gen_int_mode (0x80000000, SImode);
8349 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8355 [(set (match_operand:DF 0 "register_operand")
8356 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8357 (use (match_operand 2))
8358 (clobber (reg:CC FLAGS_REG))]
8360 [(parallel [(set (match_dup 0) (match_dup 1))
8361 (clobber (reg:CC FLAGS_REG))])]
8366 tmp = gen_lowpart (DImode, operands[0]);
8367 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8370 if (GET_CODE (operands[1]) == ABS)
8373 tmp = gen_rtx_NOT (DImode, tmp);
8377 operands[0] = gen_highpart (SImode, operands[0]);
8378 if (GET_CODE (operands[1]) == ABS)
8380 tmp = gen_int_mode (0x7fffffff, SImode);
8381 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8385 tmp = gen_int_mode (0x80000000, SImode);
8386 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8393 [(set (match_operand:XF 0 "register_operand")
8394 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8395 (use (match_operand 2))
8396 (clobber (reg:CC FLAGS_REG))]
8398 [(parallel [(set (match_dup 0) (match_dup 1))
8399 (clobber (reg:CC FLAGS_REG))])]
8402 operands[0] = gen_rtx_REG (SImode,
8403 true_regnum (operands[0])
8404 + (TARGET_64BIT ? 1 : 2));
8405 if (GET_CODE (operands[1]) == ABS)
8407 tmp = GEN_INT (0x7fff);
8408 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8412 tmp = GEN_INT (0x8000);
8413 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8418 ;; Conditionalize these after reload. If they match before reload, we
8419 ;; lose the clobber and ability to use integer instructions.
8421 (define_insn "*<code><mode>2_1"
8422 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8423 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8425 && (reload_completed
8426 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8427 "f<absneg_mnemonic>"
8428 [(set_attr "type" "fsgn")
8429 (set_attr "mode" "<MODE>")])
8431 (define_insn "*<code>extendsfdf2"
8432 [(set (match_operand:DF 0 "register_operand" "=f")
8433 (absneg:DF (float_extend:DF
8434 (match_operand:SF 1 "register_operand" "0"))))]
8435 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8436 "f<absneg_mnemonic>"
8437 [(set_attr "type" "fsgn")
8438 (set_attr "mode" "DF")])
8440 (define_insn "*<code>extendsfxf2"
8441 [(set (match_operand:XF 0 "register_operand" "=f")
8442 (absneg:XF (float_extend:XF
8443 (match_operand:SF 1 "register_operand" "0"))))]
8445 "f<absneg_mnemonic>"
8446 [(set_attr "type" "fsgn")
8447 (set_attr "mode" "XF")])
8449 (define_insn "*<code>extenddfxf2"
8450 [(set (match_operand:XF 0 "register_operand" "=f")
8451 (absneg:XF (float_extend:XF
8452 (match_operand:DF 1 "register_operand" "0"))))]
8454 "f<absneg_mnemonic>"
8455 [(set_attr "type" "fsgn")
8456 (set_attr "mode" "XF")])
8458 ;; Copysign instructions
8460 (define_mode_iterator CSGNMODE [SF DF TF])
8461 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8463 (define_expand "copysign<mode>3"
8464 [(match_operand:CSGNMODE 0 "register_operand")
8465 (match_operand:CSGNMODE 1 "nonmemory_operand")
8466 (match_operand:CSGNMODE 2 "register_operand")]
8467 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8468 || (TARGET_SSE && (<MODE>mode == TFmode))"
8469 "ix86_expand_copysign (operands); DONE;")
8471 (define_insn_and_split "copysign<mode>3_const"
8472 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8474 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8475 (match_operand:CSGNMODE 2 "register_operand" "0")
8476 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8478 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8479 || (TARGET_SSE && (<MODE>mode == TFmode))"
8481 "&& reload_completed"
8483 "ix86_split_copysign_const (operands); DONE;")
8485 (define_insn "copysign<mode>3_var"
8486 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8488 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8489 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8490 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8491 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8493 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8494 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8495 || (TARGET_SSE && (<MODE>mode == TFmode))"
8499 [(set (match_operand:CSGNMODE 0 "register_operand")
8501 [(match_operand:CSGNMODE 2 "register_operand")
8502 (match_operand:CSGNMODE 3 "register_operand")
8503 (match_operand:<CSGNVMODE> 4)
8504 (match_operand:<CSGNVMODE> 5)]
8506 (clobber (match_scratch:<CSGNVMODE> 1))]
8507 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8508 || (TARGET_SSE && (<MODE>mode == TFmode)))
8509 && reload_completed"
8511 "ix86_split_copysign_var (operands); DONE;")
8513 ;; One complement instructions
8515 (define_expand "one_cmpl<mode>2"
8516 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8517 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
8519 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8521 (define_insn "*one_cmpl<mode>2_1"
8522 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8523 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8524 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8525 "not{<imodesuffix>}\t%0"
8526 [(set_attr "type" "negnot")
8527 (set_attr "mode" "<MODE>")])
8529 ;; %%% Potential partial reg stall on alternative 1. What to do?
8530 (define_insn "*one_cmplqi2_1"
8531 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8532 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8533 "ix86_unary_operator_ok (NOT, QImode, operands)"
8537 [(set_attr "type" "negnot")
8538 (set_attr "mode" "QI,SI")])
8540 ;; ??? Currently never generated - xor is used instead.
8541 (define_insn "*one_cmplsi2_1_zext"
8542 [(set (match_operand:DI 0 "register_operand" "=r")
8544 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8545 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8547 [(set_attr "type" "negnot")
8548 (set_attr "mode" "SI")])
8550 (define_insn "*one_cmpl<mode>2_2"
8551 [(set (reg FLAGS_REG)
8552 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8554 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8555 (not:SWI (match_dup 1)))]
8556 "ix86_match_ccmode (insn, CCNOmode)
8557 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8559 [(set_attr "type" "alu1")
8560 (set_attr "mode" "<MODE>")])
8563 [(set (match_operand 0 "flags_reg_operand")
8564 (match_operator 2 "compare_operator"
8565 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
8567 (set (match_operand:SWI 1 "nonimmediate_operand")
8568 (not:SWI (match_dup 3)))]
8569 "ix86_match_ccmode (insn, CCNOmode)"
8570 [(parallel [(set (match_dup 0)
8571 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8574 (xor:SWI (match_dup 3) (const_int -1)))])])
8576 ;; ??? Currently never generated - xor is used instead.
8577 (define_insn "*one_cmplsi2_2_zext"
8578 [(set (reg FLAGS_REG)
8579 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8581 (set (match_operand:DI 0 "register_operand" "=r")
8582 (zero_extend:DI (not:SI (match_dup 1))))]
8583 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8584 && ix86_unary_operator_ok (NOT, SImode, operands)"
8586 [(set_attr "type" "alu1")
8587 (set_attr "mode" "SI")])
8590 [(set (match_operand 0 "flags_reg_operand")
8591 (match_operator 2 "compare_operator"
8592 [(not:SI (match_operand:SI 3 "register_operand"))
8594 (set (match_operand:DI 1 "register_operand")
8595 (zero_extend:DI (not:SI (match_dup 3))))]
8596 "ix86_match_ccmode (insn, CCNOmode)"
8597 [(parallel [(set (match_dup 0)
8598 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8601 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8603 ;; Shift instructions
8605 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8606 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8607 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8608 ;; from the assembler input.
8610 ;; This instruction shifts the target reg/mem as usual, but instead of
8611 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8612 ;; is a left shift double, bits are taken from the high order bits of
8613 ;; reg, else if the insn is a shift right double, bits are taken from the
8614 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8615 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8617 ;; Since sh[lr]d does not change the `reg' operand, that is done
8618 ;; separately, making all shifts emit pairs of shift double and normal
8619 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8620 ;; support a 63 bit shift, each shift where the count is in a reg expands
8621 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8623 ;; If the shift count is a constant, we need never emit more than one
8624 ;; shift pair, instead using moves and sign extension for counts greater
8627 (define_expand "ashl<mode>3"
8628 [(set (match_operand:SDWIM 0 "<shift_operand>")
8629 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
8630 (match_operand:QI 2 "nonmemory_operand")))]
8632 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8634 (define_insn "*ashl<mode>3_doubleword"
8635 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8636 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8637 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8638 (clobber (reg:CC FLAGS_REG))]
8641 [(set_attr "type" "multi")])
8644 [(set (match_operand:DWI 0 "register_operand")
8645 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
8646 (match_operand:QI 2 "nonmemory_operand")))
8647 (clobber (reg:CC FLAGS_REG))]
8648 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8650 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8652 ;; By default we don't ask for a scratch register, because when DWImode
8653 ;; values are manipulated, registers are already at a premium. But if
8654 ;; we have one handy, we won't turn it away.
8657 [(match_scratch:DWIH 3 "r")
8658 (parallel [(set (match_operand:<DWI> 0 "register_operand")
8660 (match_operand:<DWI> 1 "nonmemory_operand")
8661 (match_operand:QI 2 "nonmemory_operand")))
8662 (clobber (reg:CC FLAGS_REG))])
8666 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
8668 (define_insn "x86_64_shld"
8669 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
8670 (ior:DI (ashift:DI (match_dup 0)
8671 (match_operand:QI 2 "nonmemory_operand" "Jc"))
8672 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8673 (minus:QI (const_int 64) (match_dup 2)))))
8674 (clobber (reg:CC FLAGS_REG))]
8676 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
8677 [(set_attr "type" "ishift")
8678 (set_attr "prefix_0f" "1")
8679 (set_attr "mode" "DI")
8680 (set_attr "athlon_decode" "vector")
8681 (set_attr "amdfam10_decode" "vector")
8682 (set_attr "bdver1_decode" "vector")])
8684 (define_insn "x86_shld"
8685 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
8686 (ior:SI (ashift:SI (match_dup 0)
8687 (match_operand:QI 2 "nonmemory_operand" "Ic"))
8688 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8689 (minus:QI (const_int 32) (match_dup 2)))))
8690 (clobber (reg:CC FLAGS_REG))]
8692 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
8693 [(set_attr "type" "ishift")
8694 (set_attr "prefix_0f" "1")
8695 (set_attr "mode" "SI")
8696 (set_attr "pent_pair" "np")
8697 (set_attr "athlon_decode" "vector")
8698 (set_attr "amdfam10_decode" "vector")
8699 (set_attr "bdver1_decode" "vector")])
8701 (define_expand "x86_shift<mode>_adj_1"
8702 [(set (reg:CCZ FLAGS_REG)
8703 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
8706 (set (match_operand:SWI48 0 "register_operand")
8707 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8708 (match_operand:SWI48 1 "register_operand")
8711 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8712 (match_operand:SWI48 3 "register_operand")
8715 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
8717 (define_expand "x86_shift<mode>_adj_2"
8718 [(use (match_operand:SWI48 0 "register_operand"))
8719 (use (match_operand:SWI48 1 "register_operand"))
8720 (use (match_operand:QI 2 "register_operand"))]
8723 rtx label = gen_label_rtx ();
8726 emit_insn (gen_testqi_ccz_1 (operands[2],
8727 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
8729 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
8730 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
8731 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
8732 gen_rtx_LABEL_REF (VOIDmode, label),
8734 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
8735 JUMP_LABEL (tmp) = label;
8737 emit_move_insn (operands[0], operands[1]);
8738 ix86_expand_clear (operands[1]);
8741 LABEL_NUSES (label) = 1;
8746 ;; Avoid useless masking of count operand.
8747 (define_insn "*ashl<mode>3_mask"
8748 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
8750 (match_operand:SWI48 1 "nonimmediate_operand" "0")
8753 (match_operand:SI 2 "register_operand" "c")
8754 (match_operand:SI 3 "const_int_operand" "n")) 0)))
8755 (clobber (reg:CC FLAGS_REG))]
8756 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
8757 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
8758 == GET_MODE_BITSIZE (<MODE>mode)-1"
8760 return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
8762 [(set_attr "type" "ishift")
8763 (set_attr "mode" "<MODE>")])
8765 (define_insn "*bmi2_ashl<mode>3_1"
8766 [(set (match_operand:SWI48 0 "register_operand" "=r")
8767 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
8768 (match_operand:SWI48 2 "register_operand" "r")))]
8770 "shlx\t{%2, %1, %0|%0, %1, %2}"
8771 [(set_attr "type" "ishiftx")
8772 (set_attr "mode" "<MODE>")])
8774 (define_insn "*ashl<mode>3_1"
8775 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
8776 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
8777 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
8778 (clobber (reg:CC FLAGS_REG))]
8779 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
8781 switch (get_attr_type (insn))
8788 gcc_assert (operands[2] == const1_rtx);
8789 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8790 return "add{<imodesuffix>}\t%0, %0";
8793 if (operands[2] == const1_rtx
8794 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
8795 return "sal{<imodesuffix>}\t%0";
8797 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
8800 [(set_attr "isa" "*,*,bmi2")
8802 (cond [(eq_attr "alternative" "1")
8803 (const_string "lea")
8804 (eq_attr "alternative" "2")
8805 (const_string "ishiftx")
8806 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
8807 (match_operand 0 "register_operand"))
8808 (match_operand 2 "const1_operand"))
8809 (const_string "alu")
8811 (const_string "ishift")))
8812 (set (attr "length_immediate")
8814 (ior (eq_attr "type" "alu")
8815 (and (eq_attr "type" "ishift")
8816 (and (match_operand 2 "const1_operand")
8817 (ior (match_test "TARGET_SHIFT1")
8818 (match_test "optimize_function_for_size_p (cfun)")))))
8820 (const_string "*")))
8821 (set_attr "mode" "<MODE>")])
8823 ;; Convert shift to the shiftx pattern to avoid flags dependency.
8825 [(set (match_operand:SWI48 0 "register_operand")
8826 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
8827 (match_operand:QI 2 "register_operand")))
8828 (clobber (reg:CC FLAGS_REG))]
8829 "TARGET_BMI2 && reload_completed"
8831 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
8832 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
8834 (define_insn "*bmi2_ashlsi3_1_zext"
8835 [(set (match_operand:DI 0 "register_operand" "=r")
8837 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
8838 (match_operand:SI 2 "register_operand" "r"))))]
8839 "TARGET_64BIT && TARGET_BMI2"
8840 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
8841 [(set_attr "type" "ishiftx")
8842 (set_attr "mode" "SI")])
8844 (define_insn "*ashlsi3_1_zext"
8845 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
8847 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
8848 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
8849 (clobber (reg:CC FLAGS_REG))]
8850 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
8852 switch (get_attr_type (insn))
8859 gcc_assert (operands[2] == const1_rtx);
8860 return "add{l}\t%k0, %k0";
8863 if (operands[2] == const1_rtx
8864 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
8865 return "sal{l}\t%k0";
8867 return "sal{l}\t{%2, %k0|%k0, %2}";
8870 [(set_attr "isa" "*,*,bmi2")
8872 (cond [(eq_attr "alternative" "1")
8873 (const_string "lea")
8874 (eq_attr "alternative" "2")
8875 (const_string "ishiftx")
8876 (and (match_test "TARGET_DOUBLE_WITH_ADD")
8877 (match_operand 2 "const1_operand"))
8878 (const_string "alu")
8880 (const_string "ishift")))
8881 (set (attr "length_immediate")
8883 (ior (eq_attr "type" "alu")
8884 (and (eq_attr "type" "ishift")
8885 (and (match_operand 2 "const1_operand")
8886 (ior (match_test "TARGET_SHIFT1")
8887 (match_test "optimize_function_for_size_p (cfun)")))))
8889 (const_string "*")))
8890 (set_attr "mode" "SI")])
8892 ;; Convert shift to the shiftx pattern to avoid flags dependency.
8894 [(set (match_operand:DI 0 "register_operand")
8896 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
8897 (match_operand:QI 2 "register_operand"))))
8898 (clobber (reg:CC FLAGS_REG))]
8899 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
8901 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
8902 "operands[2] = gen_lowpart (SImode, operands[2]);")
8904 (define_insn "*ashlhi3_1"
8905 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
8906 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
8907 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
8908 (clobber (reg:CC FLAGS_REG))]
8909 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
8911 switch (get_attr_type (insn))
8917 gcc_assert (operands[2] == const1_rtx);
8918 return "add{w}\t%0, %0";
8921 if (operands[2] == const1_rtx
8922 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
8923 return "sal{w}\t%0";
8925 return "sal{w}\t{%2, %0|%0, %2}";
8929 (cond [(eq_attr "alternative" "1")
8930 (const_string "lea")
8931 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
8932 (match_operand 0 "register_operand"))
8933 (match_operand 2 "const1_operand"))
8934 (const_string "alu")
8936 (const_string "ishift")))
8937 (set (attr "length_immediate")
8939 (ior (eq_attr "type" "alu")
8940 (and (eq_attr "type" "ishift")
8941 (and (match_operand 2 "const1_operand")
8942 (ior (match_test "TARGET_SHIFT1")
8943 (match_test "optimize_function_for_size_p (cfun)")))))
8945 (const_string "*")))
8946 (set_attr "mode" "HI,SI")])
8948 ;; %%% Potential partial reg stall on alternative 1. What to do?
8949 (define_insn "*ashlqi3_1"
8950 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
8951 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
8952 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
8953 (clobber (reg:CC FLAGS_REG))]
8954 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
8956 switch (get_attr_type (insn))
8962 gcc_assert (operands[2] == const1_rtx);
8963 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
8964 return "add{l}\t%k0, %k0";
8966 return "add{b}\t%0, %0";
8969 if (operands[2] == const1_rtx
8970 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
8972 if (get_attr_mode (insn) == MODE_SI)
8973 return "sal{l}\t%k0";
8975 return "sal{b}\t%0";
8979 if (get_attr_mode (insn) == MODE_SI)
8980 return "sal{l}\t{%2, %k0|%k0, %2}";
8982 return "sal{b}\t{%2, %0|%0, %2}";
8987 (cond [(eq_attr "alternative" "2")
8988 (const_string "lea")
8989 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
8990 (match_operand 0 "register_operand"))
8991 (match_operand 2 "const1_operand"))
8992 (const_string "alu")
8994 (const_string "ishift")))
8995 (set (attr "length_immediate")
8997 (ior (eq_attr "type" "alu")
8998 (and (eq_attr "type" "ishift")
8999 (and (match_operand 2 "const1_operand")
9000 (ior (match_test "TARGET_SHIFT1")
9001 (match_test "optimize_function_for_size_p (cfun)")))))
9003 (const_string "*")))
9004 (set_attr "mode" "QI,SI,SI")])
9006 (define_insn "*ashlqi3_1_slp"
9007 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9008 (ashift:QI (match_dup 0)
9009 (match_operand:QI 1 "nonmemory_operand" "cI")))
9010 (clobber (reg:CC FLAGS_REG))]
9011 "(optimize_function_for_size_p (cfun)
9012 || !TARGET_PARTIAL_FLAG_REG_STALL
9013 || (operands[1] == const1_rtx
9015 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9017 switch (get_attr_type (insn))
9020 gcc_assert (operands[1] == const1_rtx);
9021 return "add{b}\t%0, %0";
9024 if (operands[1] == const1_rtx
9025 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9026 return "sal{b}\t%0";
9028 return "sal{b}\t{%1, %0|%0, %1}";
9032 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9033 (match_operand 0 "register_operand"))
9034 (match_operand 1 "const1_operand"))
9035 (const_string "alu")
9037 (const_string "ishift1")))
9038 (set (attr "length_immediate")
9040 (ior (eq_attr "type" "alu")
9041 (and (eq_attr "type" "ishift1")
9042 (and (match_operand 1 "const1_operand")
9043 (ior (match_test "TARGET_SHIFT1")
9044 (match_test "optimize_function_for_size_p (cfun)")))))
9046 (const_string "*")))
9047 (set_attr "mode" "QI")])
9049 ;; Convert ashift to the lea pattern to avoid flags dependency.
9051 [(set (match_operand 0 "register_operand")
9052 (ashift (match_operand 1 "index_register_operand")
9053 (match_operand:QI 2 "const_int_operand")))
9054 (clobber (reg:CC FLAGS_REG))]
9055 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9057 && true_regnum (operands[0]) != true_regnum (operands[1])"
9060 enum machine_mode mode = GET_MODE (operands[0]);
9063 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9066 operands[0] = gen_lowpart (mode, operands[0]);
9067 operands[1] = gen_lowpart (mode, operands[1]);
9070 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9072 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9074 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9078 ;; Convert ashift to the lea pattern to avoid flags dependency.
9080 [(set (match_operand:DI 0 "register_operand")
9082 (ashift:SI (match_operand:SI 1 "index_register_operand")
9083 (match_operand:QI 2 "const_int_operand"))))
9084 (clobber (reg:CC FLAGS_REG))]
9085 "TARGET_64BIT && reload_completed
9086 && true_regnum (operands[0]) != true_regnum (operands[1])"
9088 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
9090 operands[1] = gen_lowpart (SImode, operands[1]);
9091 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), SImode);
9094 ;; This pattern can't accept a variable shift count, since shifts by
9095 ;; zero don't affect the flags. We assume that shifts by constant
9096 ;; zero are optimized away.
9097 (define_insn "*ashl<mode>3_cmp"
9098 [(set (reg FLAGS_REG)
9100 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9101 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9103 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9104 (ashift:SWI (match_dup 1) (match_dup 2)))]
9105 "(optimize_function_for_size_p (cfun)
9106 || !TARGET_PARTIAL_FLAG_REG_STALL
9107 || (operands[2] == const1_rtx
9109 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9110 && ix86_match_ccmode (insn, CCGOCmode)
9111 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9113 switch (get_attr_type (insn))
9116 gcc_assert (operands[2] == const1_rtx);
9117 return "add{<imodesuffix>}\t%0, %0";
9120 if (operands[2] == const1_rtx
9121 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9122 return "sal{<imodesuffix>}\t%0";
9124 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9128 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9129 (match_operand 0 "register_operand"))
9130 (match_operand 2 "const1_operand"))
9131 (const_string "alu")
9133 (const_string "ishift")))
9134 (set (attr "length_immediate")
9136 (ior (eq_attr "type" "alu")
9137 (and (eq_attr "type" "ishift")
9138 (and (match_operand 2 "const1_operand")
9139 (ior (match_test "TARGET_SHIFT1")
9140 (match_test "optimize_function_for_size_p (cfun)")))))
9142 (const_string "*")))
9143 (set_attr "mode" "<MODE>")])
9145 (define_insn "*ashlsi3_cmp_zext"
9146 [(set (reg FLAGS_REG)
9148 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9149 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9151 (set (match_operand:DI 0 "register_operand" "=r")
9152 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9154 && (optimize_function_for_size_p (cfun)
9155 || !TARGET_PARTIAL_FLAG_REG_STALL
9156 || (operands[2] == const1_rtx
9158 || TARGET_DOUBLE_WITH_ADD)))
9159 && ix86_match_ccmode (insn, CCGOCmode)
9160 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9162 switch (get_attr_type (insn))
9165 gcc_assert (operands[2] == const1_rtx);
9166 return "add{l}\t%k0, %k0";
9169 if (operands[2] == const1_rtx
9170 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9171 return "sal{l}\t%k0";
9173 return "sal{l}\t{%2, %k0|%k0, %2}";
9177 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9178 (match_operand 2 "const1_operand"))
9179 (const_string "alu")
9181 (const_string "ishift")))
9182 (set (attr "length_immediate")
9184 (ior (eq_attr "type" "alu")
9185 (and (eq_attr "type" "ishift")
9186 (and (match_operand 2 "const1_operand")
9187 (ior (match_test "TARGET_SHIFT1")
9188 (match_test "optimize_function_for_size_p (cfun)")))))
9190 (const_string "*")))
9191 (set_attr "mode" "SI")])
9193 (define_insn "*ashl<mode>3_cconly"
9194 [(set (reg FLAGS_REG)
9196 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9197 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9199 (clobber (match_scratch:SWI 0 "=<r>"))]
9200 "(optimize_function_for_size_p (cfun)
9201 || !TARGET_PARTIAL_FLAG_REG_STALL
9202 || (operands[2] == const1_rtx
9204 || TARGET_DOUBLE_WITH_ADD)))
9205 && ix86_match_ccmode (insn, CCGOCmode)"
9207 switch (get_attr_type (insn))
9210 gcc_assert (operands[2] == const1_rtx);
9211 return "add{<imodesuffix>}\t%0, %0";
9214 if (operands[2] == const1_rtx
9215 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9216 return "sal{<imodesuffix>}\t%0";
9218 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9222 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9223 (match_operand 0 "register_operand"))
9224 (match_operand 2 "const1_operand"))
9225 (const_string "alu")
9227 (const_string "ishift")))
9228 (set (attr "length_immediate")
9230 (ior (eq_attr "type" "alu")
9231 (and (eq_attr "type" "ishift")
9232 (and (match_operand 2 "const1_operand")
9233 (ior (match_test "TARGET_SHIFT1")
9234 (match_test "optimize_function_for_size_p (cfun)")))))
9236 (const_string "*")))
9237 (set_attr "mode" "<MODE>")])
9239 ;; See comment above `ashl<mode>3' about how this works.
9241 (define_expand "<shift_insn><mode>3"
9242 [(set (match_operand:SDWIM 0 "<shift_operand>")
9243 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9244 (match_operand:QI 2 "nonmemory_operand")))]
9246 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9248 ;; Avoid useless masking of count operand.
9249 (define_insn "*<shift_insn><mode>3_mask"
9250 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9252 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9255 (match_operand:SI 2 "register_operand" "c")
9256 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9257 (clobber (reg:CC FLAGS_REG))]
9258 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9259 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9260 == GET_MODE_BITSIZE (<MODE>mode)-1"
9262 return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9264 [(set_attr "type" "ishift")
9265 (set_attr "mode" "<MODE>")])
9267 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9268 [(set (match_operand:DWI 0 "register_operand" "=r")
9269 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9270 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9271 (clobber (reg:CC FLAGS_REG))]
9274 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9276 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9277 [(set_attr "type" "multi")])
9279 ;; By default we don't ask for a scratch register, because when DWImode
9280 ;; values are manipulated, registers are already at a premium. But if
9281 ;; we have one handy, we won't turn it away.
9284 [(match_scratch:DWIH 3 "r")
9285 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9287 (match_operand:<DWI> 1 "register_operand")
9288 (match_operand:QI 2 "nonmemory_operand")))
9289 (clobber (reg:CC FLAGS_REG))])
9293 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9295 (define_insn "x86_64_shrd"
9296 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9297 (ior:DI (ashiftrt:DI (match_dup 0)
9298 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9299 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9300 (minus:QI (const_int 64) (match_dup 2)))))
9301 (clobber (reg:CC FLAGS_REG))]
9303 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9304 [(set_attr "type" "ishift")
9305 (set_attr "prefix_0f" "1")
9306 (set_attr "mode" "DI")
9307 (set_attr "athlon_decode" "vector")
9308 (set_attr "amdfam10_decode" "vector")
9309 (set_attr "bdver1_decode" "vector")])
9311 (define_insn "x86_shrd"
9312 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9313 (ior:SI (ashiftrt:SI (match_dup 0)
9314 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9315 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9316 (minus:QI (const_int 32) (match_dup 2)))))
9317 (clobber (reg:CC FLAGS_REG))]
9319 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9320 [(set_attr "type" "ishift")
9321 (set_attr "prefix_0f" "1")
9322 (set_attr "mode" "SI")
9323 (set_attr "pent_pair" "np")
9324 (set_attr "athlon_decode" "vector")
9325 (set_attr "amdfam10_decode" "vector")
9326 (set_attr "bdver1_decode" "vector")])
9328 (define_insn "ashrdi3_cvt"
9329 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9330 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9331 (match_operand:QI 2 "const_int_operand")))
9332 (clobber (reg:CC FLAGS_REG))]
9333 "TARGET_64BIT && INTVAL (operands[2]) == 63
9334 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9335 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9338 sar{q}\t{%2, %0|%0, %2}"
9339 [(set_attr "type" "imovx,ishift")
9340 (set_attr "prefix_0f" "0,*")
9341 (set_attr "length_immediate" "0,*")
9342 (set_attr "modrm" "0,1")
9343 (set_attr "mode" "DI")])
9345 (define_insn "ashrsi3_cvt"
9346 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9347 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9348 (match_operand:QI 2 "const_int_operand")))
9349 (clobber (reg:CC FLAGS_REG))]
9350 "INTVAL (operands[2]) == 31
9351 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9352 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9355 sar{l}\t{%2, %0|%0, %2}"
9356 [(set_attr "type" "imovx,ishift")
9357 (set_attr "prefix_0f" "0,*")
9358 (set_attr "length_immediate" "0,*")
9359 (set_attr "modrm" "0,1")
9360 (set_attr "mode" "SI")])
9362 (define_insn "*ashrsi3_cvt_zext"
9363 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9365 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9366 (match_operand:QI 2 "const_int_operand"))))
9367 (clobber (reg:CC FLAGS_REG))]
9368 "TARGET_64BIT && INTVAL (operands[2]) == 31
9369 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9370 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9373 sar{l}\t{%2, %k0|%k0, %2}"
9374 [(set_attr "type" "imovx,ishift")
9375 (set_attr "prefix_0f" "0,*")
9376 (set_attr "length_immediate" "0,*")
9377 (set_attr "modrm" "0,1")
9378 (set_attr "mode" "SI")])
9380 (define_expand "x86_shift<mode>_adj_3"
9381 [(use (match_operand:SWI48 0 "register_operand"))
9382 (use (match_operand:SWI48 1 "register_operand"))
9383 (use (match_operand:QI 2 "register_operand"))]
9386 rtx label = gen_label_rtx ();
9389 emit_insn (gen_testqi_ccz_1 (operands[2],
9390 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9392 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9393 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9394 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9395 gen_rtx_LABEL_REF (VOIDmode, label),
9397 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9398 JUMP_LABEL (tmp) = label;
9400 emit_move_insn (operands[0], operands[1]);
9401 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9402 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9404 LABEL_NUSES (label) = 1;
9409 (define_insn "*bmi2_<shift_insn><mode>3_1"
9410 [(set (match_operand:SWI48 0 "register_operand" "=r")
9411 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9412 (match_operand:SWI48 2 "register_operand" "r")))]
9414 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9415 [(set_attr "type" "ishiftx")
9416 (set_attr "mode" "<MODE>")])
9418 (define_insn "*<shift_insn><mode>3_1"
9419 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9421 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9422 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9423 (clobber (reg:CC FLAGS_REG))]
9424 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9426 switch (get_attr_type (insn))
9432 if (operands[2] == const1_rtx
9433 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9434 return "<shift>{<imodesuffix>}\t%0";
9436 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9439 [(set_attr "isa" "*,bmi2")
9440 (set_attr "type" "ishift,ishiftx")
9441 (set (attr "length_immediate")
9443 (and (match_operand 2 "const1_operand")
9444 (ior (match_test "TARGET_SHIFT1")
9445 (match_test "optimize_function_for_size_p (cfun)")))
9447 (const_string "*")))
9448 (set_attr "mode" "<MODE>")])
9450 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9452 [(set (match_operand:SWI48 0 "register_operand")
9453 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9454 (match_operand:QI 2 "register_operand")))
9455 (clobber (reg:CC FLAGS_REG))]
9456 "TARGET_BMI2 && reload_completed"
9458 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9459 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9461 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9462 [(set (match_operand:DI 0 "register_operand" "=r")
9464 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9465 (match_operand:SI 2 "register_operand" "r"))))]
9466 "TARGET_64BIT && TARGET_BMI2"
9467 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9468 [(set_attr "type" "ishiftx")
9469 (set_attr "mode" "SI")])
9471 (define_insn "*<shift_insn>si3_1_zext"
9472 [(set (match_operand:DI 0 "register_operand" "=r,r")
9474 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9475 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9476 (clobber (reg:CC FLAGS_REG))]
9477 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9479 switch (get_attr_type (insn))
9485 if (operands[2] == const1_rtx
9486 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9487 return "<shift>{l}\t%k0";
9489 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9492 [(set_attr "isa" "*,bmi2")
9493 (set_attr "type" "ishift,ishiftx")
9494 (set (attr "length_immediate")
9496 (and (match_operand 2 "const1_operand")
9497 (ior (match_test "TARGET_SHIFT1")
9498 (match_test "optimize_function_for_size_p (cfun)")))
9500 (const_string "*")))
9501 (set_attr "mode" "SI")])
9503 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9505 [(set (match_operand:DI 0 "register_operand")
9507 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
9508 (match_operand:QI 2 "register_operand"))))
9509 (clobber (reg:CC FLAGS_REG))]
9510 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9512 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9513 "operands[2] = gen_lowpart (SImode, operands[2]);")
9515 (define_insn "*<shift_insn><mode>3_1"
9516 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9518 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9519 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9520 (clobber (reg:CC FLAGS_REG))]
9521 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9523 if (operands[2] == const1_rtx
9524 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9525 return "<shift>{<imodesuffix>}\t%0";
9527 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9529 [(set_attr "type" "ishift")
9530 (set (attr "length_immediate")
9532 (and (match_operand 2 "const1_operand")
9533 (ior (match_test "TARGET_SHIFT1")
9534 (match_test "optimize_function_for_size_p (cfun)")))
9536 (const_string "*")))
9537 (set_attr "mode" "<MODE>")])
9539 (define_insn "*<shift_insn>qi3_1_slp"
9540 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9541 (any_shiftrt:QI (match_dup 0)
9542 (match_operand:QI 1 "nonmemory_operand" "cI")))
9543 (clobber (reg:CC FLAGS_REG))]
9544 "(optimize_function_for_size_p (cfun)
9545 || !TARGET_PARTIAL_REG_STALL
9546 || (operands[1] == const1_rtx
9549 if (operands[1] == const1_rtx
9550 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9551 return "<shift>{b}\t%0";
9553 return "<shift>{b}\t{%1, %0|%0, %1}";
9555 [(set_attr "type" "ishift1")
9556 (set (attr "length_immediate")
9558 (and (match_operand 1 "const1_operand")
9559 (ior (match_test "TARGET_SHIFT1")
9560 (match_test "optimize_function_for_size_p (cfun)")))
9562 (const_string "*")))
9563 (set_attr "mode" "QI")])
9565 ;; This pattern can't accept a variable shift count, since shifts by
9566 ;; zero don't affect the flags. We assume that shifts by constant
9567 ;; zero are optimized away.
9568 (define_insn "*<shift_insn><mode>3_cmp"
9569 [(set (reg FLAGS_REG)
9572 (match_operand:SWI 1 "nonimmediate_operand" "0")
9573 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9575 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9576 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9577 "(optimize_function_for_size_p (cfun)
9578 || !TARGET_PARTIAL_FLAG_REG_STALL
9579 || (operands[2] == const1_rtx
9581 && ix86_match_ccmode (insn, CCGOCmode)
9582 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9584 if (operands[2] == const1_rtx
9585 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9586 return "<shift>{<imodesuffix>}\t%0";
9588 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9590 [(set_attr "type" "ishift")
9591 (set (attr "length_immediate")
9593 (and (match_operand 2 "const1_operand")
9594 (ior (match_test "TARGET_SHIFT1")
9595 (match_test "optimize_function_for_size_p (cfun)")))
9597 (const_string "*")))
9598 (set_attr "mode" "<MODE>")])
9600 (define_insn "*<shift_insn>si3_cmp_zext"
9601 [(set (reg FLAGS_REG)
9603 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9604 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9606 (set (match_operand:DI 0 "register_operand" "=r")
9607 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9609 && (optimize_function_for_size_p (cfun)
9610 || !TARGET_PARTIAL_FLAG_REG_STALL
9611 || (operands[2] == const1_rtx
9613 && ix86_match_ccmode (insn, CCGOCmode)
9614 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9616 if (operands[2] == const1_rtx
9617 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9618 return "<shift>{l}\t%k0";
9620 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9622 [(set_attr "type" "ishift")
9623 (set (attr "length_immediate")
9625 (and (match_operand 2 "const1_operand")
9626 (ior (match_test "TARGET_SHIFT1")
9627 (match_test "optimize_function_for_size_p (cfun)")))
9629 (const_string "*")))
9630 (set_attr "mode" "SI")])
9632 (define_insn "*<shift_insn><mode>3_cconly"
9633 [(set (reg FLAGS_REG)
9636 (match_operand:SWI 1 "register_operand" "0")
9637 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9639 (clobber (match_scratch:SWI 0 "=<r>"))]
9640 "(optimize_function_for_size_p (cfun)
9641 || !TARGET_PARTIAL_FLAG_REG_STALL
9642 || (operands[2] == const1_rtx
9644 && ix86_match_ccmode (insn, CCGOCmode)"
9646 if (operands[2] == const1_rtx
9647 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9648 return "<shift>{<imodesuffix>}\t%0";
9650 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9652 [(set_attr "type" "ishift")
9653 (set (attr "length_immediate")
9655 (and (match_operand 2 "const1_operand")
9656 (ior (match_test "TARGET_SHIFT1")
9657 (match_test "optimize_function_for_size_p (cfun)")))
9659 (const_string "*")))
9660 (set_attr "mode" "<MODE>")])
9662 ;; Rotate instructions
9664 (define_expand "<rotate_insn>ti3"
9665 [(set (match_operand:TI 0 "register_operand")
9666 (any_rotate:TI (match_operand:TI 1 "register_operand")
9667 (match_operand:QI 2 "nonmemory_operand")))]
9670 if (const_1_to_63_operand (operands[2], VOIDmode))
9671 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
9672 (operands[0], operands[1], operands[2]));
9679 (define_expand "<rotate_insn>di3"
9680 [(set (match_operand:DI 0 "shiftdi_operand")
9681 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
9682 (match_operand:QI 2 "nonmemory_operand")))]
9686 ix86_expand_binary_operator (<CODE>, DImode, operands);
9687 else if (const_1_to_31_operand (operands[2], VOIDmode))
9688 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
9689 (operands[0], operands[1], operands[2]));
9696 (define_expand "<rotate_insn><mode>3"
9697 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
9698 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
9699 (match_operand:QI 2 "nonmemory_operand")))]
9701 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9703 ;; Avoid useless masking of count operand.
9704 (define_insn "*<rotate_insn><mode>3_mask"
9705 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9707 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9710 (match_operand:SI 2 "register_operand" "c")
9711 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9712 (clobber (reg:CC FLAGS_REG))]
9713 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9714 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9715 == GET_MODE_BITSIZE (<MODE>mode)-1"
9717 return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9719 [(set_attr "type" "rotate")
9720 (set_attr "mode" "<MODE>")])
9722 ;; Implement rotation using two double-precision
9723 ;; shift instructions and a scratch register.
9725 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
9726 [(set (match_operand:<DWI> 0 "register_operand" "=r")
9727 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
9728 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
9729 (clobber (reg:CC FLAGS_REG))
9730 (clobber (match_scratch:DWIH 3 "=&r"))]
9734 [(set (match_dup 3) (match_dup 4))
9737 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
9738 (lshiftrt:DWIH (match_dup 5)
9739 (minus:QI (match_dup 6) (match_dup 2)))))
9740 (clobber (reg:CC FLAGS_REG))])
9743 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
9744 (lshiftrt:DWIH (match_dup 3)
9745 (minus:QI (match_dup 6) (match_dup 2)))))
9746 (clobber (reg:CC FLAGS_REG))])]
9748 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
9750 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
9753 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
9754 [(set (match_operand:<DWI> 0 "register_operand" "=r")
9755 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
9756 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
9757 (clobber (reg:CC FLAGS_REG))
9758 (clobber (match_scratch:DWIH 3 "=&r"))]
9762 [(set (match_dup 3) (match_dup 4))
9765 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
9766 (ashift:DWIH (match_dup 5)
9767 (minus:QI (match_dup 6) (match_dup 2)))))
9768 (clobber (reg:CC FLAGS_REG))])
9771 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
9772 (ashift:DWIH (match_dup 3)
9773 (minus:QI (match_dup 6) (match_dup 2)))))
9774 (clobber (reg:CC FLAGS_REG))])]
9776 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
9778 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
9781 (define_insn "*bmi2_rorx<mode>3_1"
9782 [(set (match_operand:SWI48 0 "register_operand" "=r")
9783 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9784 (match_operand:QI 2 "immediate_operand" "<S>")))]
9786 "rorx\t{%2, %1, %0|%0, %1, %2}"
9787 [(set_attr "type" "rotatex")
9788 (set_attr "mode" "<MODE>")])
9790 (define_insn "*<rotate_insn><mode>3_1"
9791 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9793 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9794 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
9795 (clobber (reg:CC FLAGS_REG))]
9796 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9798 switch (get_attr_type (insn))
9804 if (operands[2] == const1_rtx
9805 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9806 return "<rotate>{<imodesuffix>}\t%0";
9808 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
9811 [(set_attr "isa" "*,bmi2")
9812 (set_attr "type" "rotate,rotatex")
9813 (set (attr "length_immediate")
9815 (and (eq_attr "type" "rotate")
9816 (and (match_operand 2 "const1_operand")
9817 (ior (match_test "TARGET_SHIFT1")
9818 (match_test "optimize_function_for_size_p (cfun)"))))
9820 (const_string "*")))
9821 (set_attr "mode" "<MODE>")])
9823 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
9825 [(set (match_operand:SWI48 0 "register_operand")
9826 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9827 (match_operand:QI 2 "immediate_operand")))
9828 (clobber (reg:CC FLAGS_REG))]
9829 "TARGET_BMI2 && reload_completed"
9831 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
9834 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
9838 [(set (match_operand:SWI48 0 "register_operand")
9839 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9840 (match_operand:QI 2 "immediate_operand")))
9841 (clobber (reg:CC FLAGS_REG))]
9842 "TARGET_BMI2 && reload_completed"
9844 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
9846 (define_insn "*bmi2_rorxsi3_1_zext"
9847 [(set (match_operand:DI 0 "register_operand" "=r")
9849 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9850 (match_operand:QI 2 "immediate_operand" "I"))))]
9851 "TARGET_64BIT && TARGET_BMI2"
9852 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
9853 [(set_attr "type" "rotatex")
9854 (set_attr "mode" "SI")])
9856 (define_insn "*<rotate_insn>si3_1_zext"
9857 [(set (match_operand:DI 0 "register_operand" "=r,r")
9859 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9860 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
9861 (clobber (reg:CC FLAGS_REG))]
9862 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9864 switch (get_attr_type (insn))
9870 if (operands[2] == const1_rtx
9871 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9872 return "<rotate>{l}\t%k0";
9874 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
9877 [(set_attr "isa" "*,bmi2")
9878 (set_attr "type" "rotate,rotatex")
9879 (set (attr "length_immediate")
9881 (and (eq_attr "type" "rotate")
9882 (and (match_operand 2 "const1_operand")
9883 (ior (match_test "TARGET_SHIFT1")
9884 (match_test "optimize_function_for_size_p (cfun)"))))
9886 (const_string "*")))
9887 (set_attr "mode" "SI")])
9889 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
9891 [(set (match_operand:DI 0 "register_operand")
9893 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
9894 (match_operand:QI 2 "immediate_operand"))))
9895 (clobber (reg:CC FLAGS_REG))]
9896 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9898 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
9901 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
9905 [(set (match_operand:DI 0 "register_operand")
9907 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
9908 (match_operand:QI 2 "immediate_operand"))))
9909 (clobber (reg:CC FLAGS_REG))]
9910 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9912 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
9914 (define_insn "*<rotate_insn><mode>3_1"
9915 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9916 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9917 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9918 (clobber (reg:CC FLAGS_REG))]
9919 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9921 if (operands[2] == const1_rtx
9922 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9923 return "<rotate>{<imodesuffix>}\t%0";
9925 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
9927 [(set_attr "type" "rotate")
9928 (set (attr "length_immediate")
9930 (and (match_operand 2 "const1_operand")
9931 (ior (match_test "TARGET_SHIFT1")
9932 (match_test "optimize_function_for_size_p (cfun)")))
9934 (const_string "*")))
9935 (set_attr "mode" "<MODE>")])
9937 (define_insn "*<rotate_insn>qi3_1_slp"
9938 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9939 (any_rotate:QI (match_dup 0)
9940 (match_operand:QI 1 "nonmemory_operand" "cI")))
9941 (clobber (reg:CC FLAGS_REG))]
9942 "(optimize_function_for_size_p (cfun)
9943 || !TARGET_PARTIAL_REG_STALL
9944 || (operands[1] == const1_rtx
9947 if (operands[1] == const1_rtx
9948 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9949 return "<rotate>{b}\t%0";
9951 return "<rotate>{b}\t{%1, %0|%0, %1}";
9953 [(set_attr "type" "rotate1")
9954 (set (attr "length_immediate")
9956 (and (match_operand 1 "const1_operand")
9957 (ior (match_test "TARGET_SHIFT1")
9958 (match_test "optimize_function_for_size_p (cfun)")))
9960 (const_string "*")))
9961 (set_attr "mode" "QI")])
9964 [(set (match_operand:HI 0 "register_operand")
9965 (any_rotate:HI (match_dup 0) (const_int 8)))
9966 (clobber (reg:CC FLAGS_REG))]
9968 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
9969 [(parallel [(set (strict_low_part (match_dup 0))
9970 (bswap:HI (match_dup 0)))
9971 (clobber (reg:CC FLAGS_REG))])])
9973 ;; Bit set / bit test instructions
9975 (define_expand "extv"
9976 [(set (match_operand:SI 0 "register_operand")
9977 (sign_extract:SI (match_operand:SI 1 "register_operand")
9978 (match_operand:SI 2 "const8_operand")
9979 (match_operand:SI 3 "const8_operand")))]
9982 /* Handle extractions from %ah et al. */
9983 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
9986 /* From mips.md: extract_bit_field doesn't verify that our source
9987 matches the predicate, so check it again here. */
9988 if (! ext_register_operand (operands[1], VOIDmode))
9992 (define_expand "extzv"
9993 [(set (match_operand:SI 0 "register_operand")
9994 (zero_extract:SI (match_operand 1 "ext_register_operand")
9995 (match_operand:SI 2 "const8_operand")
9996 (match_operand:SI 3 "const8_operand")))]
9999 /* Handle extractions from %ah et al. */
10000 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10003 /* From mips.md: extract_bit_field doesn't verify that our source
10004 matches the predicate, so check it again here. */
10005 if (! ext_register_operand (operands[1], VOIDmode))
10009 (define_expand "insv"
10010 [(set (zero_extract (match_operand 0 "register_operand")
10011 (match_operand 1 "const_int_operand")
10012 (match_operand 2 "const_int_operand"))
10013 (match_operand 3 "register_operand"))]
10016 rtx (*gen_mov_insv_1) (rtx, rtx);
10018 if (ix86_expand_pinsr (operands))
10021 /* Handle insertions to %ah et al. */
10022 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10025 /* From mips.md: insert_bit_field doesn't verify that our source
10026 matches the predicate, so check it again here. */
10027 if (! ext_register_operand (operands[0], VOIDmode))
10030 gen_mov_insv_1 = (TARGET_64BIT
10031 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10033 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10037 ;; %%% bts, btr, btc, bt.
10038 ;; In general these instructions are *slow* when applied to memory,
10039 ;; since they enforce atomic operation. When applied to registers,
10040 ;; it depends on the cpu implementation. They're never faster than
10041 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10042 ;; no point. But in 64-bit, we can't hold the relevant immediates
10043 ;; within the instruction itself, so operating on bits in the high
10044 ;; 32-bits of a register becomes easier.
10046 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10047 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10048 ;; negdf respectively, so they can never be disabled entirely.
10050 (define_insn "*btsq"
10051 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10053 (match_operand:DI 1 "const_0_to_63_operand"))
10055 (clobber (reg:CC FLAGS_REG))]
10056 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10057 "bts{q}\t{%1, %0|%0, %1}"
10058 [(set_attr "type" "alu1")
10059 (set_attr "prefix_0f" "1")
10060 (set_attr "mode" "DI")])
10062 (define_insn "*btrq"
10063 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10065 (match_operand:DI 1 "const_0_to_63_operand"))
10067 (clobber (reg:CC FLAGS_REG))]
10068 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10069 "btr{q}\t{%1, %0|%0, %1}"
10070 [(set_attr "type" "alu1")
10071 (set_attr "prefix_0f" "1")
10072 (set_attr "mode" "DI")])
10074 (define_insn "*btcq"
10075 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10077 (match_operand:DI 1 "const_0_to_63_operand"))
10078 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10079 (clobber (reg:CC FLAGS_REG))]
10080 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10081 "btc{q}\t{%1, %0|%0, %1}"
10082 [(set_attr "type" "alu1")
10083 (set_attr "prefix_0f" "1")
10084 (set_attr "mode" "DI")])
10086 ;; Allow Nocona to avoid these instructions if a register is available.
10089 [(match_scratch:DI 2 "r")
10090 (parallel [(set (zero_extract:DI
10091 (match_operand:DI 0 "register_operand")
10093 (match_operand:DI 1 "const_0_to_63_operand"))
10095 (clobber (reg:CC FLAGS_REG))])]
10096 "TARGET_64BIT && !TARGET_USE_BT"
10099 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10102 if (HOST_BITS_PER_WIDE_INT >= 64)
10103 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10104 else if (i < HOST_BITS_PER_WIDE_INT)
10105 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10107 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10109 op1 = immed_double_const (lo, hi, DImode);
10112 emit_move_insn (operands[2], op1);
10116 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10121 [(match_scratch:DI 2 "r")
10122 (parallel [(set (zero_extract:DI
10123 (match_operand:DI 0 "register_operand")
10125 (match_operand:DI 1 "const_0_to_63_operand"))
10127 (clobber (reg:CC FLAGS_REG))])]
10128 "TARGET_64BIT && !TARGET_USE_BT"
10131 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10134 if (HOST_BITS_PER_WIDE_INT >= 64)
10135 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10136 else if (i < HOST_BITS_PER_WIDE_INT)
10137 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10139 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10141 op1 = immed_double_const (~lo, ~hi, DImode);
10144 emit_move_insn (operands[2], op1);
10148 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10153 [(match_scratch:DI 2 "r")
10154 (parallel [(set (zero_extract:DI
10155 (match_operand:DI 0 "register_operand")
10157 (match_operand:DI 1 "const_0_to_63_operand"))
10158 (not:DI (zero_extract:DI
10159 (match_dup 0) (const_int 1) (match_dup 1))))
10160 (clobber (reg:CC FLAGS_REG))])]
10161 "TARGET_64BIT && !TARGET_USE_BT"
10164 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10167 if (HOST_BITS_PER_WIDE_INT >= 64)
10168 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10169 else if (i < HOST_BITS_PER_WIDE_INT)
10170 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10172 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10174 op1 = immed_double_const (lo, hi, DImode);
10177 emit_move_insn (operands[2], op1);
10181 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10185 (define_insn "*bt<mode>"
10186 [(set (reg:CCC FLAGS_REG)
10188 (zero_extract:SWI48
10189 (match_operand:SWI48 0 "register_operand" "r")
10191 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10193 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10194 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10195 [(set_attr "type" "alu1")
10196 (set_attr "prefix_0f" "1")
10197 (set_attr "mode" "<MODE>")])
10199 ;; Store-flag instructions.
10201 ;; For all sCOND expanders, also expand the compare or test insn that
10202 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10204 (define_insn_and_split "*setcc_di_1"
10205 [(set (match_operand:DI 0 "register_operand" "=q")
10206 (match_operator:DI 1 "ix86_comparison_operator"
10207 [(reg FLAGS_REG) (const_int 0)]))]
10208 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10210 "&& reload_completed"
10211 [(set (match_dup 2) (match_dup 1))
10212 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10214 PUT_MODE (operands[1], QImode);
10215 operands[2] = gen_lowpart (QImode, operands[0]);
10218 (define_insn_and_split "*setcc_si_1_and"
10219 [(set (match_operand:SI 0 "register_operand" "=q")
10220 (match_operator:SI 1 "ix86_comparison_operator"
10221 [(reg FLAGS_REG) (const_int 0)]))
10222 (clobber (reg:CC FLAGS_REG))]
10223 "!TARGET_PARTIAL_REG_STALL
10224 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10226 "&& reload_completed"
10227 [(set (match_dup 2) (match_dup 1))
10228 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10229 (clobber (reg:CC FLAGS_REG))])]
10231 PUT_MODE (operands[1], QImode);
10232 operands[2] = gen_lowpart (QImode, operands[0]);
10235 (define_insn_and_split "*setcc_si_1_movzbl"
10236 [(set (match_operand:SI 0 "register_operand" "=q")
10237 (match_operator:SI 1 "ix86_comparison_operator"
10238 [(reg FLAGS_REG) (const_int 0)]))]
10239 "!TARGET_PARTIAL_REG_STALL
10240 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10242 "&& reload_completed"
10243 [(set (match_dup 2) (match_dup 1))
10244 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10246 PUT_MODE (operands[1], QImode);
10247 operands[2] = gen_lowpart (QImode, operands[0]);
10250 (define_insn "*setcc_qi"
10251 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10252 (match_operator:QI 1 "ix86_comparison_operator"
10253 [(reg FLAGS_REG) (const_int 0)]))]
10256 [(set_attr "type" "setcc")
10257 (set_attr "mode" "QI")])
10259 (define_insn "*setcc_qi_slp"
10260 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10261 (match_operator:QI 1 "ix86_comparison_operator"
10262 [(reg FLAGS_REG) (const_int 0)]))]
10265 [(set_attr "type" "setcc")
10266 (set_attr "mode" "QI")])
10268 ;; In general it is not safe to assume too much about CCmode registers,
10269 ;; so simplify-rtx stops when it sees a second one. Under certain
10270 ;; conditions this is safe on x86, so help combine not create
10277 [(set (match_operand:QI 0 "nonimmediate_operand")
10278 (ne:QI (match_operator 1 "ix86_comparison_operator"
10279 [(reg FLAGS_REG) (const_int 0)])
10282 [(set (match_dup 0) (match_dup 1))]
10283 "PUT_MODE (operands[1], QImode);")
10286 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10287 (ne:QI (match_operator 1 "ix86_comparison_operator"
10288 [(reg FLAGS_REG) (const_int 0)])
10291 [(set (match_dup 0) (match_dup 1))]
10292 "PUT_MODE (operands[1], QImode);")
10295 [(set (match_operand:QI 0 "nonimmediate_operand")
10296 (eq:QI (match_operator 1 "ix86_comparison_operator"
10297 [(reg FLAGS_REG) (const_int 0)])
10300 [(set (match_dup 0) (match_dup 1))]
10302 rtx new_op1 = copy_rtx (operands[1]);
10303 operands[1] = new_op1;
10304 PUT_MODE (new_op1, QImode);
10305 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10306 GET_MODE (XEXP (new_op1, 0))));
10308 /* Make sure that (a) the CCmode we have for the flags is strong
10309 enough for the reversed compare or (b) we have a valid FP compare. */
10310 if (! ix86_comparison_operator (new_op1, VOIDmode))
10315 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10316 (eq:QI (match_operator 1 "ix86_comparison_operator"
10317 [(reg FLAGS_REG) (const_int 0)])
10320 [(set (match_dup 0) (match_dup 1))]
10322 rtx new_op1 = copy_rtx (operands[1]);
10323 operands[1] = new_op1;
10324 PUT_MODE (new_op1, QImode);
10325 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10326 GET_MODE (XEXP (new_op1, 0))));
10328 /* Make sure that (a) the CCmode we have for the flags is strong
10329 enough for the reversed compare or (b) we have a valid FP compare. */
10330 if (! ix86_comparison_operator (new_op1, VOIDmode))
10334 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10335 ;; subsequent logical operations are used to imitate conditional moves.
10336 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10339 (define_insn "setcc_<mode>_sse"
10340 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10341 (match_operator:MODEF 3 "sse_comparison_operator"
10342 [(match_operand:MODEF 1 "register_operand" "0,x")
10343 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10344 "SSE_FLOAT_MODE_P (<MODE>mode)"
10346 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10347 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10348 [(set_attr "isa" "noavx,avx")
10349 (set_attr "type" "ssecmp")
10350 (set_attr "length_immediate" "1")
10351 (set_attr "prefix" "orig,vex")
10352 (set_attr "mode" "<MODE>")])
10354 ;; Basic conditional jump instructions.
10355 ;; We ignore the overflow flag for signed branch instructions.
10357 (define_insn "*jcc_1"
10359 (if_then_else (match_operator 1 "ix86_comparison_operator"
10360 [(reg FLAGS_REG) (const_int 0)])
10361 (label_ref (match_operand 0))
10365 [(set_attr "type" "ibr")
10366 (set_attr "modrm" "0")
10367 (set (attr "length")
10368 (if_then_else (and (ge (minus (match_dup 0) (pc))
10370 (lt (minus (match_dup 0) (pc))
10375 (define_insn "*jcc_2"
10377 (if_then_else (match_operator 1 "ix86_comparison_operator"
10378 [(reg FLAGS_REG) (const_int 0)])
10380 (label_ref (match_operand 0))))]
10383 [(set_attr "type" "ibr")
10384 (set_attr "modrm" "0")
10385 (set (attr "length")
10386 (if_then_else (and (ge (minus (match_dup 0) (pc))
10388 (lt (minus (match_dup 0) (pc))
10393 ;; In general it is not safe to assume too much about CCmode registers,
10394 ;; so simplify-rtx stops when it sees a second one. Under certain
10395 ;; conditions this is safe on x86, so help combine not create
10403 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10404 [(reg FLAGS_REG) (const_int 0)])
10406 (label_ref (match_operand 1))
10410 (if_then_else (match_dup 0)
10411 (label_ref (match_dup 1))
10413 "PUT_MODE (operands[0], VOIDmode);")
10417 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10418 [(reg FLAGS_REG) (const_int 0)])
10420 (label_ref (match_operand 1))
10424 (if_then_else (match_dup 0)
10425 (label_ref (match_dup 1))
10428 rtx new_op0 = copy_rtx (operands[0]);
10429 operands[0] = new_op0;
10430 PUT_MODE (new_op0, VOIDmode);
10431 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10432 GET_MODE (XEXP (new_op0, 0))));
10434 /* Make sure that (a) the CCmode we have for the flags is strong
10435 enough for the reversed compare or (b) we have a valid FP compare. */
10436 if (! ix86_comparison_operator (new_op0, VOIDmode))
10440 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10441 ;; pass generates from shift insn with QImode operand. Actually, the mode
10442 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10443 ;; appropriate modulo of the bit offset value.
10445 (define_insn_and_split "*jcc_bt<mode>"
10447 (if_then_else (match_operator 0 "bt_comparison_operator"
10448 [(zero_extract:SWI48
10449 (match_operand:SWI48 1 "register_operand" "r")
10452 (match_operand:QI 2 "register_operand" "r")))
10454 (label_ref (match_operand 3))
10456 (clobber (reg:CC FLAGS_REG))]
10457 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10460 [(set (reg:CCC FLAGS_REG)
10462 (zero_extract:SWI48
10468 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10469 (label_ref (match_dup 3))
10472 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10474 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10477 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10478 ;; also for DImode, this is what combine produces.
10479 (define_insn_and_split "*jcc_bt<mode>_mask"
10481 (if_then_else (match_operator 0 "bt_comparison_operator"
10482 [(zero_extract:SWI48
10483 (match_operand:SWI48 1 "register_operand" "r")
10486 (match_operand:SI 2 "register_operand" "r")
10487 (match_operand:SI 3 "const_int_operand" "n")))])
10488 (label_ref (match_operand 4))
10490 (clobber (reg:CC FLAGS_REG))]
10491 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10492 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10493 == GET_MODE_BITSIZE (<MODE>mode)-1"
10496 [(set (reg:CCC FLAGS_REG)
10498 (zero_extract:SWI48
10504 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10505 (label_ref (match_dup 4))
10508 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10510 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10513 (define_insn_and_split "*jcc_btsi_1"
10515 (if_then_else (match_operator 0 "bt_comparison_operator"
10518 (match_operand:SI 1 "register_operand" "r")
10519 (match_operand:QI 2 "register_operand" "r"))
10522 (label_ref (match_operand 3))
10524 (clobber (reg:CC FLAGS_REG))]
10525 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10528 [(set (reg:CCC FLAGS_REG)
10536 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10537 (label_ref (match_dup 3))
10540 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10542 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10545 ;; avoid useless masking of bit offset operand
10546 (define_insn_and_split "*jcc_btsi_mask_1"
10549 (match_operator 0 "bt_comparison_operator"
10552 (match_operand:SI 1 "register_operand" "r")
10555 (match_operand:SI 2 "register_operand" "r")
10556 (match_operand:SI 3 "const_int_operand" "n")) 0))
10559 (label_ref (match_operand 4))
10561 (clobber (reg:CC FLAGS_REG))]
10562 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10563 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10566 [(set (reg:CCC FLAGS_REG)
10574 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10575 (label_ref (match_dup 4))
10577 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10579 ;; Define combination compare-and-branch fp compare instructions to help
10582 (define_insn "*jcc<mode>_0_i387"
10584 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
10585 [(match_operand:X87MODEF 1 "register_operand" "f")
10586 (match_operand:X87MODEF 2 "const0_operand")])
10587 (label_ref (match_operand 3))
10589 (clobber (reg:CCFP FPSR_REG))
10590 (clobber (reg:CCFP FLAGS_REG))
10591 (clobber (match_scratch:HI 4 "=a"))]
10592 "TARGET_80387 && !TARGET_CMOVE"
10595 (define_insn "*jcc<mode>_0_r_i387"
10597 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
10598 [(match_operand:X87MODEF 1 "register_operand" "f")
10599 (match_operand:X87MODEF 2 "const0_operand")])
10601 (label_ref (match_operand 3))))
10602 (clobber (reg:CCFP FPSR_REG))
10603 (clobber (reg:CCFP FLAGS_REG))
10604 (clobber (match_scratch:HI 4 "=a"))]
10605 "TARGET_80387 && !TARGET_CMOVE"
10608 (define_insn "*jccxf_i387"
10610 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
10611 [(match_operand:XF 1 "register_operand" "f")
10612 (match_operand:XF 2 "register_operand" "f")])
10613 (label_ref (match_operand 3))
10615 (clobber (reg:CCFP FPSR_REG))
10616 (clobber (reg:CCFP FLAGS_REG))
10617 (clobber (match_scratch:HI 4 "=a"))]
10618 "TARGET_80387 && !TARGET_CMOVE"
10621 (define_insn "*jccxf_r_i387"
10623 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
10624 [(match_operand:XF 1 "register_operand" "f")
10625 (match_operand:XF 2 "register_operand" "f")])
10627 (label_ref (match_operand 3))))
10628 (clobber (reg:CCFP FPSR_REG))
10629 (clobber (reg:CCFP FLAGS_REG))
10630 (clobber (match_scratch:HI 4 "=a"))]
10631 "TARGET_80387 && !TARGET_CMOVE"
10634 (define_insn "*jcc<mode>_i387"
10636 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
10637 [(match_operand:MODEF 1 "register_operand" "f")
10638 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
10639 (label_ref (match_operand 3))
10641 (clobber (reg:CCFP FPSR_REG))
10642 (clobber (reg:CCFP FLAGS_REG))
10643 (clobber (match_scratch:HI 4 "=a"))]
10644 "TARGET_80387 && !TARGET_CMOVE"
10647 (define_insn "*jcc<mode>_r_i387"
10649 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
10650 [(match_operand:MODEF 1 "register_operand" "f")
10651 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
10653 (label_ref (match_operand 3))))
10654 (clobber (reg:CCFP FPSR_REG))
10655 (clobber (reg:CCFP FLAGS_REG))
10656 (clobber (match_scratch:HI 4 "=a"))]
10657 "TARGET_80387 && !TARGET_CMOVE"
10660 (define_insn "*jccu<mode>_i387"
10662 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
10663 [(match_operand:X87MODEF 1 "register_operand" "f")
10664 (match_operand:X87MODEF 2 "register_operand" "f")])
10665 (label_ref (match_operand 3))
10667 (clobber (reg:CCFP FPSR_REG))
10668 (clobber (reg:CCFP FLAGS_REG))
10669 (clobber (match_scratch:HI 4 "=a"))]
10670 "TARGET_80387 && !TARGET_CMOVE"
10673 (define_insn "*jccu<mode>_r_i387"
10675 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
10676 [(match_operand:X87MODEF 1 "register_operand" "f")
10677 (match_operand:X87MODEF 2 "register_operand" "f")])
10679 (label_ref (match_operand 3))))
10680 (clobber (reg:CCFP FPSR_REG))
10681 (clobber (reg:CCFP FLAGS_REG))
10682 (clobber (match_scratch:HI 4 "=a"))]
10683 "TARGET_80387 && !TARGET_CMOVE"
10688 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10689 [(match_operand:X87MODEF 1 "register_operand")
10690 (match_operand:X87MODEF 2 "nonimmediate_operand")])
10692 (match_operand 4)))
10693 (clobber (reg:CCFP FPSR_REG))
10694 (clobber (reg:CCFP FLAGS_REG))]
10695 "TARGET_80387 && !TARGET_CMOVE
10696 && reload_completed"
10699 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10700 operands[3], operands[4], NULL_RTX, NULL_RTX);
10706 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10707 [(match_operand:X87MODEF 1 "register_operand")
10708 (match_operand:X87MODEF 2 "general_operand")])
10710 (match_operand 4)))
10711 (clobber (reg:CCFP FPSR_REG))
10712 (clobber (reg:CCFP FLAGS_REG))
10713 (clobber (match_scratch:HI 5))]
10714 "TARGET_80387 && !TARGET_CMOVE
10715 && reload_completed"
10718 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10719 operands[3], operands[4], operands[5], NULL_RTX);
10723 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
10724 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
10725 ;; with a precedence over other operators and is always put in the first
10726 ;; place. Swap condition and operands to match ficom instruction.
10728 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
10731 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
10732 [(match_operator:X87MODEF 1 "float_operator"
10733 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
10734 (match_operand:X87MODEF 3 "register_operand" "f,f")])
10735 (label_ref (match_operand 4))
10737 (clobber (reg:CCFP FPSR_REG))
10738 (clobber (reg:CCFP FLAGS_REG))
10739 (clobber (match_scratch:HI 5 "=a,a"))]
10740 "TARGET_80387 && !TARGET_CMOVE
10741 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
10742 || optimize_function_for_size_p (cfun))"
10745 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
10748 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
10749 [(match_operator:X87MODEF 1 "float_operator"
10750 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
10751 (match_operand:X87MODEF 3 "register_operand" "f,f")])
10753 (label_ref (match_operand 4))))
10754 (clobber (reg:CCFP FPSR_REG))
10755 (clobber (reg:CCFP FLAGS_REG))
10756 (clobber (match_scratch:HI 5 "=a,a"))]
10757 "TARGET_80387 && !TARGET_CMOVE
10758 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
10759 || optimize_function_for_size_p (cfun))"
10765 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
10766 [(match_operator:X87MODEF 1 "float_operator"
10767 [(match_operand:SWI24 2 "memory_operand")])
10768 (match_operand:X87MODEF 3 "register_operand")])
10770 (match_operand 5)))
10771 (clobber (reg:CCFP FPSR_REG))
10772 (clobber (reg:CCFP FLAGS_REG))
10773 (clobber (match_scratch:HI 6))]
10774 "TARGET_80387 && !TARGET_CMOVE
10775 && reload_completed"
10778 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
10779 gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
10780 operands[4], operands[5], operands[6], NULL_RTX);
10784 ;; %%% Kill this when reload knows how to do it.
10788 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
10789 [(match_operator:X87MODEF 1 "float_operator"
10790 [(match_operand:SWI24 2 "register_operand")])
10791 (match_operand:X87MODEF 3 "register_operand")])
10793 (match_operand 5)))
10794 (clobber (reg:CCFP FPSR_REG))
10795 (clobber (reg:CCFP FLAGS_REG))
10796 (clobber (match_scratch:HI 6))]
10797 "TARGET_80387 && !TARGET_CMOVE
10798 && reload_completed"
10801 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
10803 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
10804 gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]),
10805 operands[4], operands[5], operands[6], operands[2]);
10809 ;; Unconditional and other jump instructions
10811 (define_insn "jump"
10813 (label_ref (match_operand 0)))]
10816 [(set_attr "type" "ibr")
10817 (set (attr "length")
10818 (if_then_else (and (ge (minus (match_dup 0) (pc))
10820 (lt (minus (match_dup 0) (pc))
10824 (set_attr "modrm" "0")])
10826 (define_expand "indirect_jump"
10827 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
10831 operands[0] = convert_memory_address (word_mode, operands[0]);
10834 (define_insn "*indirect_jump"
10835 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))]
10838 [(set_attr "type" "ibr")
10839 (set_attr "length_immediate" "0")])
10841 (define_expand "tablejump"
10842 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
10843 (use (label_ref (match_operand 1)))])]
10846 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
10847 relative. Convert the relative address to an absolute address. */
10851 enum rtx_code code;
10853 /* We can't use @GOTOFF for text labels on VxWorks;
10854 see gotoff_operand. */
10855 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
10859 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
10861 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
10865 op1 = pic_offset_table_rtx;
10870 op0 = pic_offset_table_rtx;
10874 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
10879 operands[0] = convert_memory_address (word_mode, operands[0]);
10882 (define_insn "*tablejump_1"
10883 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))
10884 (use (label_ref (match_operand 1)))]
10887 [(set_attr "type" "ibr")
10888 (set_attr "length_immediate" "0")])
10890 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
10893 [(set (reg FLAGS_REG) (match_operand 0))
10894 (set (match_operand:QI 1 "register_operand")
10895 (match_operator:QI 2 "ix86_comparison_operator"
10896 [(reg FLAGS_REG) (const_int 0)]))
10897 (set (match_operand 3 "q_regs_operand")
10898 (zero_extend (match_dup 1)))]
10899 "(peep2_reg_dead_p (3, operands[1])
10900 || operands_match_p (operands[1], operands[3]))
10901 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
10902 [(set (match_dup 4) (match_dup 0))
10903 (set (strict_low_part (match_dup 5))
10906 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
10907 operands[5] = gen_lowpart (QImode, operands[3]);
10908 ix86_expand_clear (operands[3]);
10912 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
10913 (match_operand 4)])
10914 (set (match_operand:QI 1 "register_operand")
10915 (match_operator:QI 2 "ix86_comparison_operator"
10916 [(reg FLAGS_REG) (const_int 0)]))
10917 (set (match_operand 3 "q_regs_operand")
10918 (zero_extend (match_dup 1)))]
10919 "(peep2_reg_dead_p (3, operands[1])
10920 || operands_match_p (operands[1], operands[3]))
10921 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
10922 [(parallel [(set (match_dup 5) (match_dup 0))
10924 (set (strict_low_part (match_dup 6))
10927 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
10928 operands[6] = gen_lowpart (QImode, operands[3]);
10929 ix86_expand_clear (operands[3]);
10932 ;; Similar, but match zero extend with andsi3.
10935 [(set (reg FLAGS_REG) (match_operand 0))
10936 (set (match_operand:QI 1 "register_operand")
10937 (match_operator:QI 2 "ix86_comparison_operator"
10938 [(reg FLAGS_REG) (const_int 0)]))
10939 (parallel [(set (match_operand:SI 3 "q_regs_operand")
10940 (and:SI (match_dup 3) (const_int 255)))
10941 (clobber (reg:CC FLAGS_REG))])]
10942 "REGNO (operands[1]) == REGNO (operands[3])
10943 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
10944 [(set (match_dup 4) (match_dup 0))
10945 (set (strict_low_part (match_dup 5))
10948 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
10949 operands[5] = gen_lowpart (QImode, operands[3]);
10950 ix86_expand_clear (operands[3]);
10954 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
10955 (match_operand 4)])
10956 (set (match_operand:QI 1 "register_operand")
10957 (match_operator:QI 2 "ix86_comparison_operator"
10958 [(reg FLAGS_REG) (const_int 0)]))
10959 (parallel [(set (match_operand 3 "q_regs_operand")
10960 (zero_extend (match_dup 1)))
10961 (clobber (reg:CC FLAGS_REG))])]
10962 "(peep2_reg_dead_p (3, operands[1])
10963 || operands_match_p (operands[1], operands[3]))
10964 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
10965 [(parallel [(set (match_dup 5) (match_dup 0))
10967 (set (strict_low_part (match_dup 6))
10970 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
10971 operands[6] = gen_lowpart (QImode, operands[3]);
10972 ix86_expand_clear (operands[3]);
10975 ;; Call instructions.
10977 ;; The predicates normally associated with named expanders are not properly
10978 ;; checked for calls. This is a bug in the generic code, but it isn't that
10979 ;; easy to fix. Ignore it for now and be prepared to fix things up.
10981 ;; P6 processors will jump to the address after the decrement when %esp
10982 ;; is used as a call operand, so they will execute return address as a code.
10983 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
10985 ;; Register constraint for call instruction.
10986 (define_mode_attr c [(SI "l") (DI "r")])
10988 ;; Call subroutine returning no value.
10990 (define_expand "call"
10991 [(call (match_operand:QI 0)
10993 (use (match_operand 2))]
10996 ix86_expand_call (NULL, operands[0], operands[1],
10997 operands[2], NULL, false);
11001 (define_expand "sibcall"
11002 [(call (match_operand:QI 0)
11004 (use (match_operand 2))]
11007 ix86_expand_call (NULL, operands[0], operands[1],
11008 operands[2], NULL, true);
11012 (define_insn "*call"
11013 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11014 (match_operand 1))]
11015 "!SIBLING_CALL_P (insn)"
11016 "* return ix86_output_call_insn (insn, operands[0]);"
11017 [(set_attr "type" "call")])
11019 (define_insn "*call_rex64_ms_sysv"
11020 [(match_parallel 2 "call_rex64_ms_sysv_operation"
11021 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11023 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)])]
11024 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11025 "* return ix86_output_call_insn (insn, operands[0]);"
11026 [(set_attr "type" "call")])
11028 (define_insn "*sibcall"
11029 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11030 (match_operand 1))]
11031 "SIBLING_CALL_P (insn)"
11032 "* return ix86_output_call_insn (insn, operands[0]);"
11033 [(set_attr "type" "call")])
11035 (define_expand "call_pop"
11036 [(parallel [(call (match_operand:QI 0)
11037 (match_operand:SI 1))
11038 (set (reg:SI SP_REG)
11039 (plus:SI (reg:SI SP_REG)
11040 (match_operand:SI 3)))])]
11043 ix86_expand_call (NULL, operands[0], operands[1],
11044 operands[2], operands[3], false);
11048 (define_insn "*call_pop"
11049 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11051 (set (reg:SI SP_REG)
11052 (plus:SI (reg:SI SP_REG)
11053 (match_operand:SI 2 "immediate_operand" "i")))]
11054 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11055 "* return ix86_output_call_insn (insn, operands[0]);"
11056 [(set_attr "type" "call")])
11058 (define_insn "*sibcall_pop"
11059 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11061 (set (reg:SI SP_REG)
11062 (plus:SI (reg:SI SP_REG)
11063 (match_operand:SI 2 "immediate_operand" "i")))]
11064 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11065 "* return ix86_output_call_insn (insn, operands[0]);"
11066 [(set_attr "type" "call")])
11068 ;; Call subroutine, returning value in operand 0
11070 (define_expand "call_value"
11071 [(set (match_operand 0)
11072 (call (match_operand:QI 1)
11073 (match_operand 2)))
11074 (use (match_operand 3))]
11077 ix86_expand_call (operands[0], operands[1], operands[2],
11078 operands[3], NULL, false);
11082 (define_expand "sibcall_value"
11083 [(set (match_operand 0)
11084 (call (match_operand:QI 1)
11085 (match_operand 2)))
11086 (use (match_operand 3))]
11089 ix86_expand_call (operands[0], operands[1], operands[2],
11090 operands[3], NULL, true);
11094 (define_insn "*call_value"
11095 [(set (match_operand 0)
11096 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11097 (match_operand 2)))]
11098 "!SIBLING_CALL_P (insn)"
11099 "* return ix86_output_call_insn (insn, operands[1]);"
11100 [(set_attr "type" "callv")])
11102 (define_insn "*sibcall_value"
11103 [(set (match_operand 0)
11104 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11105 (match_operand 2)))]
11106 "SIBLING_CALL_P (insn)"
11107 "* return ix86_output_call_insn (insn, operands[1]);"
11108 [(set_attr "type" "callv")])
11110 (define_insn "*call_value_rex64_ms_sysv"
11111 [(match_parallel 3 "call_rex64_ms_sysv_operation"
11112 [(set (match_operand 0)
11113 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11114 (match_operand 2)))
11115 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)])]
11116 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11117 "* return ix86_output_call_insn (insn, operands[1]);"
11118 [(set_attr "type" "callv")])
11120 (define_expand "call_value_pop"
11121 [(parallel [(set (match_operand 0)
11122 (call (match_operand:QI 1)
11123 (match_operand:SI 2)))
11124 (set (reg:SI SP_REG)
11125 (plus:SI (reg:SI SP_REG)
11126 (match_operand:SI 4)))])]
11129 ix86_expand_call (operands[0], operands[1], operands[2],
11130 operands[3], operands[4], false);
11134 (define_insn "*call_value_pop"
11135 [(set (match_operand 0)
11136 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11137 (match_operand 2)))
11138 (set (reg:SI SP_REG)
11139 (plus:SI (reg:SI SP_REG)
11140 (match_operand:SI 3 "immediate_operand" "i")))]
11141 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11142 "* return ix86_output_call_insn (insn, operands[1]);"
11143 [(set_attr "type" "callv")])
11145 (define_insn "*sibcall_value_pop"
11146 [(set (match_operand 0)
11147 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11148 (match_operand 2)))
11149 (set (reg:SI SP_REG)
11150 (plus:SI (reg:SI SP_REG)
11151 (match_operand:SI 3 "immediate_operand" "i")))]
11152 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11153 "* return ix86_output_call_insn (insn, operands[1]);"
11154 [(set_attr "type" "callv")])
11156 ;; Call subroutine returning any type.
11158 (define_expand "untyped_call"
11159 [(parallel [(call (match_operand 0)
11162 (match_operand 2)])]
11167 /* In order to give reg-stack an easier job in validating two
11168 coprocessor registers as containing a possible return value,
11169 simply pretend the untyped call returns a complex long double
11172 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11173 and should have the default ABI. */
11175 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11176 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11177 operands[0], const0_rtx,
11178 GEN_INT ((TARGET_64BIT
11179 ? (ix86_abi == SYSV_ABI
11180 ? X86_64_SSE_REGPARM_MAX
11181 : X86_64_MS_SSE_REGPARM_MAX)
11182 : X86_32_SSE_REGPARM_MAX)
11186 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11188 rtx set = XVECEXP (operands[2], 0, i);
11189 emit_move_insn (SET_DEST (set), SET_SRC (set));
11192 /* The optimizer does not know that the call sets the function value
11193 registers we stored in the result block. We avoid problems by
11194 claiming that all hard registers are used and clobbered at this
11196 emit_insn (gen_blockage ());
11201 ;; Prologue and epilogue instructions
11203 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11204 ;; all of memory. This blocks insns from being moved across this point.
11206 (define_insn "blockage"
11207 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11210 [(set_attr "length" "0")])
11212 ;; Do not schedule instructions accessing memory across this point.
11214 (define_expand "memory_blockage"
11215 [(set (match_dup 0)
11216 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11219 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11220 MEM_VOLATILE_P (operands[0]) = 1;
11223 (define_insn "*memory_blockage"
11224 [(set (match_operand:BLK 0)
11225 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11228 [(set_attr "length" "0")])
11230 ;; As USE insns aren't meaningful after reload, this is used instead
11231 ;; to prevent deleting instructions setting registers for PIC code
11232 (define_insn "prologue_use"
11233 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
11236 [(set_attr "length" "0")])
11238 ;; Insn emitted into the body of a function to return from a function.
11239 ;; This is only done if the function's epilogue is known to be simple.
11240 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11242 (define_expand "return"
11244 "ix86_can_use_return_insn_p ()"
11246 if (crtl->args.pops_args)
11248 rtx popc = GEN_INT (crtl->args.pops_args);
11249 emit_jump_insn (gen_simple_return_pop_internal (popc));
11254 ;; We need to disable this for TARGET_SEH, as otherwise
11255 ;; shrink-wrapped prologue gets enabled too. This might exceed
11256 ;; the maximum size of prologue in unwind information.
11258 (define_expand "simple_return"
11262 if (crtl->args.pops_args)
11264 rtx popc = GEN_INT (crtl->args.pops_args);
11265 emit_jump_insn (gen_simple_return_pop_internal (popc));
11270 (define_insn "simple_return_internal"
11274 [(set_attr "length" "1")
11275 (set_attr "atom_unit" "jeu")
11276 (set_attr "length_immediate" "0")
11277 (set_attr "modrm" "0")])
11279 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11280 ;; instruction Athlon and K8 have.
11282 (define_insn "simple_return_internal_long"
11284 (unspec [(const_int 0)] UNSPEC_REP)]
11287 [(set_attr "length" "2")
11288 (set_attr "atom_unit" "jeu")
11289 (set_attr "length_immediate" "0")
11290 (set_attr "prefix_rep" "1")
11291 (set_attr "modrm" "0")])
11293 (define_insn "simple_return_pop_internal"
11295 (use (match_operand:SI 0 "const_int_operand"))]
11298 [(set_attr "length" "3")
11299 (set_attr "atom_unit" "jeu")
11300 (set_attr "length_immediate" "2")
11301 (set_attr "modrm" "0")])
11303 (define_insn "simple_return_indirect_internal"
11305 (use (match_operand:SI 0 "register_operand" "r"))]
11308 [(set_attr "type" "ibr")
11309 (set_attr "length_immediate" "0")])
11315 [(set_attr "length" "1")
11316 (set_attr "length_immediate" "0")
11317 (set_attr "modrm" "0")])
11319 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11320 (define_insn "nops"
11321 [(unspec_volatile [(match_operand 0 "const_int_operand")]
11325 int num = INTVAL (operands[0]);
11327 gcc_assert (IN_RANGE (num, 1, 8));
11330 fputs ("\tnop\n", asm_out_file);
11334 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11335 (set_attr "length_immediate" "0")
11336 (set_attr "modrm" "0")])
11338 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11339 ;; branch prediction penalty for the third jump in a 16-byte
11343 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
11346 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11347 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11349 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11350 The align insn is used to avoid 3 jump instructions in the row to improve
11351 branch prediction and the benefits hardly outweigh the cost of extra 8
11352 nops on the average inserted by full alignment pseudo operation. */
11356 [(set_attr "length" "16")])
11358 (define_expand "prologue"
11361 "ix86_expand_prologue (); DONE;")
11363 (define_insn "set_got"
11364 [(set (match_operand:SI 0 "register_operand" "=r")
11365 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11366 (clobber (reg:CC FLAGS_REG))]
11368 "* return output_set_got (operands[0], NULL_RTX);"
11369 [(set_attr "type" "multi")
11370 (set_attr "length" "12")])
11372 (define_insn "set_got_labelled"
11373 [(set (match_operand:SI 0 "register_operand" "=r")
11374 (unspec:SI [(label_ref (match_operand 1))]
11376 (clobber (reg:CC FLAGS_REG))]
11378 "* return output_set_got (operands[0], operands[1]);"
11379 [(set_attr "type" "multi")
11380 (set_attr "length" "12")])
11382 (define_insn "set_got_rex64"
11383 [(set (match_operand:DI 0 "register_operand" "=r")
11384 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11386 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11387 [(set_attr "type" "lea")
11388 (set_attr "length_address" "4")
11389 (set_attr "mode" "DI")])
11391 (define_insn "set_rip_rex64"
11392 [(set (match_operand:DI 0 "register_operand" "=r")
11393 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
11395 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11396 [(set_attr "type" "lea")
11397 (set_attr "length_address" "4")
11398 (set_attr "mode" "DI")])
11400 (define_insn "set_got_offset_rex64"
11401 [(set (match_operand:DI 0 "register_operand" "=r")
11403 [(label_ref (match_operand 1))]
11404 UNSPEC_SET_GOT_OFFSET))]
11406 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11407 [(set_attr "type" "imov")
11408 (set_attr "length_immediate" "0")
11409 (set_attr "length_address" "8")
11410 (set_attr "mode" "DI")])
11412 (define_expand "epilogue"
11415 "ix86_expand_epilogue (1); DONE;")
11417 (define_expand "sibcall_epilogue"
11420 "ix86_expand_epilogue (0); DONE;")
11422 (define_expand "eh_return"
11423 [(use (match_operand 0 "register_operand"))]
11426 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11428 /* Tricky bit: we write the address of the handler to which we will
11429 be returning into someone else's stack frame, one word below the
11430 stack address we wish to restore. */
11431 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11432 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
11433 tmp = gen_rtx_MEM (Pmode, tmp);
11434 emit_move_insn (tmp, ra);
11436 emit_jump_insn (gen_eh_return_internal ());
11441 (define_insn_and_split "eh_return_internal"
11445 "epilogue_completed"
11447 "ix86_expand_epilogue (2); DONE;")
11449 (define_insn "leave"
11450 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11451 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11452 (clobber (mem:BLK (scratch)))]
11455 [(set_attr "type" "leave")])
11457 (define_insn "leave_rex64"
11458 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11459 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11460 (clobber (mem:BLK (scratch)))]
11463 [(set_attr "type" "leave")])
11465 ;; Handle -fsplit-stack.
11467 (define_expand "split_stack_prologue"
11471 ix86_expand_split_stack_prologue ();
11475 ;; In order to support the call/return predictor, we use a return
11476 ;; instruction which the middle-end doesn't see.
11477 (define_insn "split_stack_return"
11478 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
11479 UNSPECV_SPLIT_STACK_RETURN)]
11482 if (operands[0] == const0_rtx)
11487 [(set_attr "atom_unit" "jeu")
11488 (set_attr "modrm" "0")
11489 (set (attr "length")
11490 (if_then_else (match_operand:SI 0 "const0_operand")
11493 (set (attr "length_immediate")
11494 (if_then_else (match_operand:SI 0 "const0_operand")
11498 ;; If there are operand 0 bytes available on the stack, jump to
11501 (define_expand "split_stack_space_check"
11502 [(set (pc) (if_then_else
11503 (ltu (minus (reg SP_REG)
11504 (match_operand 0 "register_operand"))
11505 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11506 (label_ref (match_operand 1))
11510 rtx reg, size, limit;
11512 reg = gen_reg_rtx (Pmode);
11513 size = force_reg (Pmode, operands[0]);
11514 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11515 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11516 UNSPEC_STACK_CHECK);
11517 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11518 ix86_expand_branch (GEU, reg, limit, operands[1]);
11523 ;; Bit manipulation instructions.
11525 (define_expand "ffs<mode>2"
11526 [(set (match_dup 2) (const_int -1))
11527 (parallel [(set (match_dup 3) (match_dup 4))
11528 (set (match_operand:SWI48 0 "register_operand")
11530 (match_operand:SWI48 1 "nonimmediate_operand")))])
11531 (set (match_dup 0) (if_then_else:SWI48
11532 (eq (match_dup 3) (const_int 0))
11535 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11536 (clobber (reg:CC FLAGS_REG))])]
11539 enum machine_mode flags_mode;
11541 if (<MODE>mode == SImode && !TARGET_CMOVE)
11543 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11547 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
11549 operands[2] = gen_reg_rtx (<MODE>mode);
11550 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
11551 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
11554 (define_insn_and_split "ffssi2_no_cmove"
11555 [(set (match_operand:SI 0 "register_operand" "=r")
11556 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11557 (clobber (match_scratch:SI 2 "=&q"))
11558 (clobber (reg:CC FLAGS_REG))]
11561 "&& reload_completed"
11562 [(parallel [(set (match_dup 4) (match_dup 5))
11563 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11564 (set (strict_low_part (match_dup 3))
11565 (eq:QI (match_dup 4) (const_int 0)))
11566 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11567 (clobber (reg:CC FLAGS_REG))])
11568 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11569 (clobber (reg:CC FLAGS_REG))])
11570 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11571 (clobber (reg:CC FLAGS_REG))])]
11573 enum machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
11575 operands[3] = gen_lowpart (QImode, operands[2]);
11576 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
11577 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
11579 ix86_expand_clear (operands[2]);
11582 (define_insn "*tzcnt<mode>_1"
11583 [(set (reg:CCC FLAGS_REG)
11584 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11586 (set (match_operand:SWI48 0 "register_operand" "=r")
11587 (ctz:SWI48 (match_dup 1)))]
11589 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11590 [(set_attr "type" "alu1")
11591 (set_attr "prefix_0f" "1")
11592 (set_attr "prefix_rep" "1")
11593 (set_attr "btver2_decode" "double")
11594 (set_attr "mode" "<MODE>")])
11596 (define_insn "*bsf<mode>_1"
11597 [(set (reg:CCZ FLAGS_REG)
11598 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11600 (set (match_operand:SWI48 0 "register_operand" "=r")
11601 (ctz:SWI48 (match_dup 1)))]
11603 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11604 [(set_attr "type" "alu1")
11605 (set_attr "prefix_0f" "1")
11606 (set_attr "btver2_decode" "double")
11607 (set_attr "mode" "<MODE>")])
11609 (define_insn "ctz<mode>2"
11610 [(set (match_operand:SWI248 0 "register_operand" "=r")
11611 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11612 (clobber (reg:CC FLAGS_REG))]
11616 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11617 else if (optimize_function_for_size_p (cfun))
11619 else if (TARGET_GENERIC)
11620 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
11621 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
11623 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
11625 [(set_attr "type" "alu1")
11626 (set_attr "prefix_0f" "1")
11627 (set (attr "prefix_rep")
11629 (ior (match_test "TARGET_BMI")
11630 (and (not (match_test "optimize_function_for_size_p (cfun)"))
11631 (match_test "TARGET_GENERIC")))
11633 (const_string "0")))
11634 (set_attr "mode" "<MODE>")])
11636 (define_expand "clz<mode>2"
11638 [(set (match_operand:SWI248 0 "register_operand")
11641 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
11642 (clobber (reg:CC FLAGS_REG))])
11644 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
11645 (clobber (reg:CC FLAGS_REG))])]
11650 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
11653 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11656 (define_insn "clz<mode>2_lzcnt"
11657 [(set (match_operand:SWI248 0 "register_operand" "=r")
11658 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11659 (clobber (reg:CC FLAGS_REG))]
11661 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11662 [(set_attr "prefix_rep" "1")
11663 (set_attr "type" "bitmanip")
11664 (set_attr "mode" "<MODE>")])
11666 ;; BMI instructions.
11667 (define_insn "*bmi_andn_<mode>"
11668 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
11671 (match_operand:SWI48 1 "register_operand" "r,r"))
11672 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
11673 (clobber (reg:CC FLAGS_REG))]
11675 "andn\t{%2, %1, %0|%0, %1, %2}"
11676 [(set_attr "type" "bitmanip")
11677 (set_attr "btver2_decode" "direct, double")
11678 (set_attr "mode" "<MODE>")])
11680 (define_insn "bmi_bextr_<mode>"
11681 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
11682 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r,r")
11683 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")]
11685 (clobber (reg:CC FLAGS_REG))]
11687 "bextr\t{%2, %1, %0|%0, %1, %2}"
11688 [(set_attr "type" "bitmanip")
11689 (set_attr "btver2_decode" "direct, double")
11690 (set_attr "mode" "<MODE>")])
11692 (define_insn "*bmi_blsi_<mode>"
11693 [(set (match_operand:SWI48 0 "register_operand" "=r")
11696 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
11698 (clobber (reg:CC FLAGS_REG))]
11700 "blsi\t{%1, %0|%0, %1}"
11701 [(set_attr "type" "bitmanip")
11702 (set_attr "btver2_decode" "double")
11703 (set_attr "mode" "<MODE>")])
11705 (define_insn "*bmi_blsmsk_<mode>"
11706 [(set (match_operand:SWI48 0 "register_operand" "=r")
11709 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11712 (clobber (reg:CC FLAGS_REG))]
11714 "blsmsk\t{%1, %0|%0, %1}"
11715 [(set_attr "type" "bitmanip")
11716 (set_attr "btver2_decode" "double")
11717 (set_attr "mode" "<MODE>")])
11719 (define_insn "*bmi_blsr_<mode>"
11720 [(set (match_operand:SWI48 0 "register_operand" "=r")
11723 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11726 (clobber (reg:CC FLAGS_REG))]
11728 "blsr\t{%1, %0|%0, %1}"
11729 [(set_attr "type" "bitmanip")
11730 (set_attr "btver2_decode" "double")
11731 (set_attr "mode" "<MODE>")])
11733 ;; BMI2 instructions.
11734 (define_insn "bmi2_bzhi_<mode>3"
11735 [(set (match_operand:SWI48 0 "register_operand" "=r")
11736 (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
11737 (lshiftrt:SWI48 (const_int -1)
11738 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
11739 (clobber (reg:CC FLAGS_REG))]
11741 "bzhi\t{%2, %1, %0|%0, %1, %2}"
11742 [(set_attr "type" "bitmanip")
11743 (set_attr "prefix" "vex")
11744 (set_attr "mode" "<MODE>")])
11746 (define_insn "bmi2_pdep_<mode>3"
11747 [(set (match_operand:SWI48 0 "register_operand" "=r")
11748 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
11749 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
11752 "pdep\t{%2, %1, %0|%0, %1, %2}"
11753 [(set_attr "type" "bitmanip")
11754 (set_attr "prefix" "vex")
11755 (set_attr "mode" "<MODE>")])
11757 (define_insn "bmi2_pext_<mode>3"
11758 [(set (match_operand:SWI48 0 "register_operand" "=r")
11759 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
11760 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
11763 "pext\t{%2, %1, %0|%0, %1, %2}"
11764 [(set_attr "type" "bitmanip")
11765 (set_attr "prefix" "vex")
11766 (set_attr "mode" "<MODE>")])
11768 ;; TBM instructions.
11769 (define_insn "tbm_bextri_<mode>"
11770 [(set (match_operand:SWI48 0 "register_operand" "=r")
11771 (zero_extract:SWI48
11772 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11773 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
11774 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
11775 (clobber (reg:CC FLAGS_REG))]
11778 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
11779 return "bextr\t{%2, %1, %0|%0, %1, %2}";
11781 [(set_attr "type" "bitmanip")
11782 (set_attr "mode" "<MODE>")])
11784 (define_insn "*tbm_blcfill_<mode>"
11785 [(set (match_operand:SWI48 0 "register_operand" "=r")
11788 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11791 (clobber (reg:CC FLAGS_REG))]
11793 "blcfill\t{%1, %0|%0, %1}"
11794 [(set_attr "type" "bitmanip")
11795 (set_attr "mode" "<MODE>")])
11797 (define_insn "*tbm_blci_<mode>"
11798 [(set (match_operand:SWI48 0 "register_operand" "=r")
11802 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11805 (clobber (reg:CC FLAGS_REG))]
11807 "blci\t{%1, %0|%0, %1}"
11808 [(set_attr "type" "bitmanip")
11809 (set_attr "mode" "<MODE>")])
11811 (define_insn "*tbm_blcic_<mode>"
11812 [(set (match_operand:SWI48 0 "register_operand" "=r")
11815 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11819 (clobber (reg:CC FLAGS_REG))]
11821 "blcic\t{%1, %0|%0, %1}"
11822 [(set_attr "type" "bitmanip")
11823 (set_attr "mode" "<MODE>")])
11825 (define_insn "*tbm_blcmsk_<mode>"
11826 [(set (match_operand:SWI48 0 "register_operand" "=r")
11829 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11832 (clobber (reg:CC FLAGS_REG))]
11834 "blcmsk\t{%1, %0|%0, %1}"
11835 [(set_attr "type" "bitmanip")
11836 (set_attr "mode" "<MODE>")])
11838 (define_insn "*tbm_blcs_<mode>"
11839 [(set (match_operand:SWI48 0 "register_operand" "=r")
11842 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11845 (clobber (reg:CC FLAGS_REG))]
11847 "blcs\t{%1, %0|%0, %1}"
11848 [(set_attr "type" "bitmanip")
11849 (set_attr "mode" "<MODE>")])
11851 (define_insn "*tbm_blsfill_<mode>"
11852 [(set (match_operand:SWI48 0 "register_operand" "=r")
11855 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11858 (clobber (reg:CC FLAGS_REG))]
11860 "blsfill\t{%1, %0|%0, %1}"
11861 [(set_attr "type" "bitmanip")
11862 (set_attr "mode" "<MODE>")])
11864 (define_insn "*tbm_blsic_<mode>"
11865 [(set (match_operand:SWI48 0 "register_operand" "=r")
11868 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11872 (clobber (reg:CC FLAGS_REG))]
11874 "blsic\t{%1, %0|%0, %1}"
11875 [(set_attr "type" "bitmanip")
11876 (set_attr "mode" "<MODE>")])
11878 (define_insn "*tbm_t1mskc_<mode>"
11879 [(set (match_operand:SWI48 0 "register_operand" "=r")
11882 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11886 (clobber (reg:CC FLAGS_REG))]
11888 "t1mskc\t{%1, %0|%0, %1}"
11889 [(set_attr "type" "bitmanip")
11890 (set_attr "mode" "<MODE>")])
11892 (define_insn "*tbm_tzmsk_<mode>"
11893 [(set (match_operand:SWI48 0 "register_operand" "=r")
11896 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11900 (clobber (reg:CC FLAGS_REG))]
11902 "tzmsk\t{%1, %0|%0, %1}"
11903 [(set_attr "type" "bitmanip")
11904 (set_attr "mode" "<MODE>")])
11906 (define_insn "bsr_rex64"
11907 [(set (match_operand:DI 0 "register_operand" "=r")
11908 (minus:DI (const_int 63)
11909 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
11910 (clobber (reg:CC FLAGS_REG))]
11912 "bsr{q}\t{%1, %0|%0, %1}"
11913 [(set_attr "type" "alu1")
11914 (set_attr "prefix_0f" "1")
11915 (set_attr "mode" "DI")])
11918 [(set (match_operand:SI 0 "register_operand" "=r")
11919 (minus:SI (const_int 31)
11920 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
11921 (clobber (reg:CC FLAGS_REG))]
11923 "bsr{l}\t{%1, %0|%0, %1}"
11924 [(set_attr "type" "alu1")
11925 (set_attr "prefix_0f" "1")
11926 (set_attr "mode" "SI")])
11928 (define_insn "*bsrhi"
11929 [(set (match_operand:HI 0 "register_operand" "=r")
11930 (minus:HI (const_int 15)
11931 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
11932 (clobber (reg:CC FLAGS_REG))]
11934 "bsr{w}\t{%1, %0|%0, %1}"
11935 [(set_attr "type" "alu1")
11936 (set_attr "prefix_0f" "1")
11937 (set_attr "mode" "HI")])
11939 (define_insn "popcount<mode>2"
11940 [(set (match_operand:SWI248 0 "register_operand" "=r")
11942 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11943 (clobber (reg:CC FLAGS_REG))]
11947 return "popcnt\t{%1, %0|%0, %1}";
11949 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11952 [(set_attr "prefix_rep" "1")
11953 (set_attr "type" "bitmanip")
11954 (set_attr "mode" "<MODE>")])
11956 (define_insn "*popcount<mode>2_cmp"
11957 [(set (reg FLAGS_REG)
11960 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
11962 (set (match_operand:SWI248 0 "register_operand" "=r")
11963 (popcount:SWI248 (match_dup 1)))]
11964 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
11967 return "popcnt\t{%1, %0|%0, %1}";
11969 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11972 [(set_attr "prefix_rep" "1")
11973 (set_attr "type" "bitmanip")
11974 (set_attr "mode" "<MODE>")])
11976 (define_insn "*popcountsi2_cmp_zext"
11977 [(set (reg FLAGS_REG)
11979 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
11981 (set (match_operand:DI 0 "register_operand" "=r")
11982 (zero_extend:DI(popcount:SI (match_dup 1))))]
11983 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
11986 return "popcnt\t{%1, %0|%0, %1}";
11988 return "popcnt{l}\t{%1, %0|%0, %1}";
11991 [(set_attr "prefix_rep" "1")
11992 (set_attr "type" "bitmanip")
11993 (set_attr "mode" "SI")])
11995 (define_expand "bswapdi2"
11996 [(set (match_operand:DI 0 "register_operand")
11997 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
12001 operands[1] = force_reg (DImode, operands[1]);
12004 (define_expand "bswapsi2"
12005 [(set (match_operand:SI 0 "register_operand")
12006 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
12011 else if (TARGET_BSWAP)
12012 operands[1] = force_reg (SImode, operands[1]);
12015 rtx x = operands[0];
12017 emit_move_insn (x, operands[1]);
12018 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12019 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12020 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12025 (define_insn "*bswap<mode>2_movbe"
12026 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12027 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12029 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12032 movbe\t{%1, %0|%0, %1}
12033 movbe\t{%1, %0|%0, %1}"
12034 [(set_attr "type" "bitmanip,imov,imov")
12035 (set_attr "modrm" "0,1,1")
12036 (set_attr "prefix_0f" "*,1,1")
12037 (set_attr "prefix_extra" "*,1,1")
12038 (set_attr "mode" "<MODE>")])
12040 (define_insn "*bswap<mode>2"
12041 [(set (match_operand:SWI48 0 "register_operand" "=r")
12042 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12045 [(set_attr "type" "bitmanip")
12046 (set_attr "modrm" "0")
12047 (set_attr "mode" "<MODE>")])
12049 (define_insn "*bswaphi_lowpart_1"
12050 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12051 (bswap:HI (match_dup 0)))
12052 (clobber (reg:CC FLAGS_REG))]
12053 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12055 xchg{b}\t{%h0, %b0|%b0, %h0}
12056 rol{w}\t{$8, %0|%0, 8}"
12057 [(set_attr "length" "2,4")
12058 (set_attr "mode" "QI,HI")])
12060 (define_insn "bswaphi_lowpart"
12061 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12062 (bswap:HI (match_dup 0)))
12063 (clobber (reg:CC FLAGS_REG))]
12065 "rol{w}\t{$8, %0|%0, 8}"
12066 [(set_attr "length" "4")
12067 (set_attr "mode" "HI")])
12069 (define_expand "paritydi2"
12070 [(set (match_operand:DI 0 "register_operand")
12071 (parity:DI (match_operand:DI 1 "register_operand")))]
12074 rtx scratch = gen_reg_rtx (QImode);
12077 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12078 NULL_RTX, operands[1]));
12080 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12081 gen_rtx_REG (CCmode, FLAGS_REG),
12083 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12086 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12089 rtx tmp = gen_reg_rtx (SImode);
12091 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12092 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12097 (define_expand "paritysi2"
12098 [(set (match_operand:SI 0 "register_operand")
12099 (parity:SI (match_operand:SI 1 "register_operand")))]
12102 rtx scratch = gen_reg_rtx (QImode);
12105 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12107 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12108 gen_rtx_REG (CCmode, FLAGS_REG),
12110 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12112 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12116 (define_insn_and_split "paritydi2_cmp"
12117 [(set (reg:CC FLAGS_REG)
12118 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12120 (clobber (match_scratch:DI 0 "=r"))
12121 (clobber (match_scratch:SI 1 "=&r"))
12122 (clobber (match_scratch:HI 2 "=Q"))]
12125 "&& reload_completed"
12127 [(set (match_dup 1)
12128 (xor:SI (match_dup 1) (match_dup 4)))
12129 (clobber (reg:CC FLAGS_REG))])
12131 [(set (reg:CC FLAGS_REG)
12132 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12133 (clobber (match_dup 1))
12134 (clobber (match_dup 2))])]
12136 operands[4] = gen_lowpart (SImode, operands[3]);
12140 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12141 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12144 operands[1] = gen_highpart (SImode, operands[3]);
12147 (define_insn_and_split "paritysi2_cmp"
12148 [(set (reg:CC FLAGS_REG)
12149 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12151 (clobber (match_scratch:SI 0 "=r"))
12152 (clobber (match_scratch:HI 1 "=&Q"))]
12155 "&& reload_completed"
12157 [(set (match_dup 1)
12158 (xor:HI (match_dup 1) (match_dup 3)))
12159 (clobber (reg:CC FLAGS_REG))])
12161 [(set (reg:CC FLAGS_REG)
12162 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12163 (clobber (match_dup 1))])]
12165 operands[3] = gen_lowpart (HImode, operands[2]);
12167 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12168 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12171 (define_insn "*parityhi2_cmp"
12172 [(set (reg:CC FLAGS_REG)
12173 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12175 (clobber (match_scratch:HI 0 "=Q"))]
12177 "xor{b}\t{%h0, %b0|%b0, %h0}"
12178 [(set_attr "length" "2")
12179 (set_attr "mode" "HI")])
12182 ;; Thread-local storage patterns for ELF.
12184 ;; Note that these code sequences must appear exactly as shown
12185 ;; in order to allow linker relaxation.
12187 (define_insn "*tls_global_dynamic_32_gnu"
12188 [(set (match_operand:SI 0 "register_operand" "=a")
12190 [(match_operand:SI 1 "register_operand" "b")
12191 (match_operand 2 "tls_symbolic_operand")
12192 (match_operand 3 "constant_call_address_operand" "z")]
12194 (clobber (match_scratch:SI 4 "=d"))
12195 (clobber (match_scratch:SI 5 "=c"))
12196 (clobber (reg:CC FLAGS_REG))]
12197 "!TARGET_64BIT && TARGET_GNU_TLS"
12200 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12201 if (TARGET_SUN_TLS)
12202 #ifdef HAVE_AS_IX86_TLSGDPLT
12203 return "call\t%a2@tlsgdplt";
12205 return "call\t%p3@plt";
12207 return "call\t%P3";
12209 [(set_attr "type" "multi")
12210 (set_attr "length" "12")])
12212 (define_expand "tls_global_dynamic_32"
12214 [(set (match_operand:SI 0 "register_operand")
12215 (unspec:SI [(match_operand:SI 2 "register_operand")
12216 (match_operand 1 "tls_symbolic_operand")
12217 (match_operand 3 "constant_call_address_operand")]
12219 (clobber (match_scratch:SI 4))
12220 (clobber (match_scratch:SI 5))
12221 (clobber (reg:CC FLAGS_REG))])])
12223 (define_insn "*tls_global_dynamic_64_<mode>"
12224 [(set (match_operand:P 0 "register_operand" "=a")
12226 (mem:QI (match_operand 2 "constant_call_address_operand" "z"))
12227 (match_operand 3)))
12228 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12233 fputs (ASM_BYTE "0x66\n", asm_out_file);
12235 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12236 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12237 fputs ("\trex64\n", asm_out_file);
12238 if (TARGET_SUN_TLS)
12239 return "call\t%p2@plt";
12240 return "call\t%P2";
12242 [(set_attr "type" "multi")
12243 (set (attr "length")
12244 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12246 (define_expand "tls_global_dynamic_64_<mode>"
12248 [(set (match_operand:P 0 "register_operand")
12250 (mem:QI (match_operand 2 "constant_call_address_operand"))
12252 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12256 (define_insn "*tls_local_dynamic_base_32_gnu"
12257 [(set (match_operand:SI 0 "register_operand" "=a")
12259 [(match_operand:SI 1 "register_operand" "b")
12260 (match_operand 2 "constant_call_address_operand" "z")]
12261 UNSPEC_TLS_LD_BASE))
12262 (clobber (match_scratch:SI 3 "=d"))
12263 (clobber (match_scratch:SI 4 "=c"))
12264 (clobber (reg:CC FLAGS_REG))]
12265 "!TARGET_64BIT && TARGET_GNU_TLS"
12268 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12269 if (TARGET_SUN_TLS)
12270 #ifdef HAVE_AS_IX86_TLSLDMPLT
12271 return "call\t%&@tlsldmplt";
12273 return "call\t%p2@plt";
12275 return "call\t%P2";
12277 [(set_attr "type" "multi")
12278 (set_attr "length" "11")])
12280 (define_expand "tls_local_dynamic_base_32"
12282 [(set (match_operand:SI 0 "register_operand")
12284 [(match_operand:SI 1 "register_operand")
12285 (match_operand 2 "constant_call_address_operand")]
12286 UNSPEC_TLS_LD_BASE))
12287 (clobber (match_scratch:SI 3))
12288 (clobber (match_scratch:SI 4))
12289 (clobber (reg:CC FLAGS_REG))])])
12291 (define_insn "*tls_local_dynamic_base_64_<mode>"
12292 [(set (match_operand:P 0 "register_operand" "=a")
12294 (mem:QI (match_operand 1 "constant_call_address_operand" "z"))
12295 (match_operand 2)))
12296 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12300 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12301 if (TARGET_SUN_TLS)
12302 return "call\t%p1@plt";
12303 return "call\t%P1";
12305 [(set_attr "type" "multi")
12306 (set_attr "length" "12")])
12308 (define_expand "tls_local_dynamic_base_64_<mode>"
12310 [(set (match_operand:P 0 "register_operand")
12312 (mem:QI (match_operand 1 "constant_call_address_operand"))
12314 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12317 ;; Local dynamic of a single variable is a lose. Show combine how
12318 ;; to convert that back to global dynamic.
12320 (define_insn_and_split "*tls_local_dynamic_32_once"
12321 [(set (match_operand:SI 0 "register_operand" "=a")
12323 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12324 (match_operand 2 "constant_call_address_operand" "z")]
12325 UNSPEC_TLS_LD_BASE)
12326 (const:SI (unspec:SI
12327 [(match_operand 3 "tls_symbolic_operand")]
12329 (clobber (match_scratch:SI 4 "=d"))
12330 (clobber (match_scratch:SI 5 "=c"))
12331 (clobber (reg:CC FLAGS_REG))]
12336 [(set (match_dup 0)
12337 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12339 (clobber (match_dup 4))
12340 (clobber (match_dup 5))
12341 (clobber (reg:CC FLAGS_REG))])])
12343 ;; Segment register for the thread base ptr load
12344 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12346 ;; Load and add the thread base pointer from %<tp_seg>:0.
12347 (define_insn "*load_tp_x32"
12348 [(set (match_operand:SI 0 "register_operand" "=r")
12349 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12351 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12352 [(set_attr "type" "imov")
12353 (set_attr "modrm" "0")
12354 (set_attr "length" "7")
12355 (set_attr "memory" "load")
12356 (set_attr "imm_disp" "false")])
12358 (define_insn "*load_tp_x32_zext"
12359 [(set (match_operand:DI 0 "register_operand" "=r")
12360 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12362 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12363 [(set_attr "type" "imov")
12364 (set_attr "modrm" "0")
12365 (set_attr "length" "7")
12366 (set_attr "memory" "load")
12367 (set_attr "imm_disp" "false")])
12369 (define_insn "*load_tp_<mode>"
12370 [(set (match_operand:P 0 "register_operand" "=r")
12371 (unspec:P [(const_int 0)] UNSPEC_TP))]
12373 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12374 [(set_attr "type" "imov")
12375 (set_attr "modrm" "0")
12376 (set_attr "length" "7")
12377 (set_attr "memory" "load")
12378 (set_attr "imm_disp" "false")])
12380 (define_insn "*add_tp_x32"
12381 [(set (match_operand:SI 0 "register_operand" "=r")
12382 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12383 (match_operand:SI 1 "register_operand" "0")))
12384 (clobber (reg:CC FLAGS_REG))]
12386 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12387 [(set_attr "type" "alu")
12388 (set_attr "modrm" "0")
12389 (set_attr "length" "7")
12390 (set_attr "memory" "load")
12391 (set_attr "imm_disp" "false")])
12393 (define_insn "*add_tp_x32_zext"
12394 [(set (match_operand:DI 0 "register_operand" "=r")
12396 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12397 (match_operand:SI 1 "register_operand" "0"))))
12398 (clobber (reg:CC FLAGS_REG))]
12400 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12401 [(set_attr "type" "alu")
12402 (set_attr "modrm" "0")
12403 (set_attr "length" "7")
12404 (set_attr "memory" "load")
12405 (set_attr "imm_disp" "false")])
12407 (define_insn "*add_tp_<mode>"
12408 [(set (match_operand:P 0 "register_operand" "=r")
12409 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12410 (match_operand:P 1 "register_operand" "0")))
12411 (clobber (reg:CC FLAGS_REG))]
12413 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12414 [(set_attr "type" "alu")
12415 (set_attr "modrm" "0")
12416 (set_attr "length" "7")
12417 (set_attr "memory" "load")
12418 (set_attr "imm_disp" "false")])
12420 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12421 ;; %rax as destination of the initial executable code sequence.
12422 (define_insn "tls_initial_exec_64_sun"
12423 [(set (match_operand:DI 0 "register_operand" "=a")
12425 [(match_operand 1 "tls_symbolic_operand")]
12426 UNSPEC_TLS_IE_SUN))
12427 (clobber (reg:CC FLAGS_REG))]
12428 "TARGET_64BIT && TARGET_SUN_TLS"
12431 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12432 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12434 [(set_attr "type" "multi")])
12436 ;; GNU2 TLS patterns can be split.
12438 (define_expand "tls_dynamic_gnu2_32"
12439 [(set (match_dup 3)
12440 (plus:SI (match_operand:SI 2 "register_operand")
12442 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
12445 [(set (match_operand:SI 0 "register_operand")
12446 (unspec:SI [(match_dup 1) (match_dup 3)
12447 (match_dup 2) (reg:SI SP_REG)]
12449 (clobber (reg:CC FLAGS_REG))])]
12450 "!TARGET_64BIT && TARGET_GNU2_TLS"
12452 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12453 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12456 (define_insn "*tls_dynamic_gnu2_lea_32"
12457 [(set (match_operand:SI 0 "register_operand" "=r")
12458 (plus:SI (match_operand:SI 1 "register_operand" "b")
12460 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
12461 UNSPEC_TLSDESC))))]
12462 "!TARGET_64BIT && TARGET_GNU2_TLS"
12463 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
12464 [(set_attr "type" "lea")
12465 (set_attr "mode" "SI")
12466 (set_attr "length" "6")
12467 (set_attr "length_address" "4")])
12469 (define_insn "*tls_dynamic_gnu2_call_32"
12470 [(set (match_operand:SI 0 "register_operand" "=a")
12471 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
12472 (match_operand:SI 2 "register_operand" "0")
12473 ;; we have to make sure %ebx still points to the GOT
12474 (match_operand:SI 3 "register_operand" "b")
12477 (clobber (reg:CC FLAGS_REG))]
12478 "!TARGET_64BIT && TARGET_GNU2_TLS"
12479 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12480 [(set_attr "type" "call")
12481 (set_attr "length" "2")
12482 (set_attr "length_address" "0")])
12484 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12485 [(set (match_operand:SI 0 "register_operand" "=&a")
12487 (unspec:SI [(match_operand 3 "tls_modbase_operand")
12488 (match_operand:SI 4)
12489 (match_operand:SI 2 "register_operand" "b")
12492 (const:SI (unspec:SI
12493 [(match_operand 1 "tls_symbolic_operand")]
12495 (clobber (reg:CC FLAGS_REG))]
12496 "!TARGET_64BIT && TARGET_GNU2_TLS"
12499 [(set (match_dup 0) (match_dup 5))]
12501 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12502 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12505 (define_expand "tls_dynamic_gnu2_64"
12506 [(set (match_dup 2)
12507 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
12510 [(set (match_operand:DI 0 "register_operand")
12511 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12513 (clobber (reg:CC FLAGS_REG))])]
12514 "TARGET_64BIT && TARGET_GNU2_TLS"
12516 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12517 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12520 (define_insn "*tls_dynamic_gnu2_lea_64"
12521 [(set (match_operand:DI 0 "register_operand" "=r")
12522 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
12524 "TARGET_64BIT && TARGET_GNU2_TLS"
12525 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
12526 [(set_attr "type" "lea")
12527 (set_attr "mode" "DI")
12528 (set_attr "length" "7")
12529 (set_attr "length_address" "4")])
12531 (define_insn "*tls_dynamic_gnu2_call_64"
12532 [(set (match_operand:DI 0 "register_operand" "=a")
12533 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
12534 (match_operand:DI 2 "register_operand" "0")
12537 (clobber (reg:CC FLAGS_REG))]
12538 "TARGET_64BIT && TARGET_GNU2_TLS"
12539 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12540 [(set_attr "type" "call")
12541 (set_attr "length" "2")
12542 (set_attr "length_address" "0")])
12544 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12545 [(set (match_operand:DI 0 "register_operand" "=&a")
12547 (unspec:DI [(match_operand 2 "tls_modbase_operand")
12548 (match_operand:DI 3)
12551 (const:DI (unspec:DI
12552 [(match_operand 1 "tls_symbolic_operand")]
12554 (clobber (reg:CC FLAGS_REG))]
12555 "TARGET_64BIT && TARGET_GNU2_TLS"
12558 [(set (match_dup 0) (match_dup 4))]
12560 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12561 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12564 ;; These patterns match the binary 387 instructions for addM3, subM3,
12565 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12566 ;; SFmode. The first is the normal insn, the second the same insn but
12567 ;; with one operand a conversion, and the third the same insn but with
12568 ;; the other operand a conversion. The conversion may be SFmode or
12569 ;; SImode if the target mode DFmode, but only SImode if the target mode
12572 ;; Gcc is slightly more smart about handling normal two address instructions
12573 ;; so use special patterns for add and mull.
12575 (define_insn "*fop_<mode>_comm_mixed"
12576 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12577 (match_operator:MODEF 3 "binary_fp_operator"
12578 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12579 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12580 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12581 && COMMUTATIVE_ARITH_P (operands[3])
12582 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12583 "* return output_387_binary_op (insn, operands);"
12584 [(set (attr "type")
12585 (if_then_else (eq_attr "alternative" "1,2")
12586 (if_then_else (match_operand:MODEF 3 "mult_operator")
12587 (const_string "ssemul")
12588 (const_string "sseadd"))
12589 (if_then_else (match_operand:MODEF 3 "mult_operator")
12590 (const_string "fmul")
12591 (const_string "fop"))))
12592 (set_attr "isa" "*,noavx,avx")
12593 (set_attr "prefix" "orig,orig,vex")
12594 (set_attr "mode" "<MODE>")])
12596 (define_insn "*fop_<mode>_comm_sse"
12597 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12598 (match_operator:MODEF 3 "binary_fp_operator"
12599 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12600 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12601 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12602 && COMMUTATIVE_ARITH_P (operands[3])
12603 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12604 "* return output_387_binary_op (insn, operands);"
12605 [(set (attr "type")
12606 (if_then_else (match_operand:MODEF 3 "mult_operator")
12607 (const_string "ssemul")
12608 (const_string "sseadd")))
12609 (set_attr "isa" "noavx,avx")
12610 (set_attr "prefix" "orig,vex")
12611 (set_attr "mode" "<MODE>")])
12613 (define_insn "*fop_<mode>_comm_i387"
12614 [(set (match_operand:MODEF 0 "register_operand" "=f")
12615 (match_operator:MODEF 3 "binary_fp_operator"
12616 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12617 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12618 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12619 && COMMUTATIVE_ARITH_P (operands[3])
12620 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12621 "* return output_387_binary_op (insn, operands);"
12622 [(set (attr "type")
12623 (if_then_else (match_operand:MODEF 3 "mult_operator")
12624 (const_string "fmul")
12625 (const_string "fop")))
12626 (set_attr "mode" "<MODE>")])
12628 (define_insn "*fop_<mode>_1_mixed"
12629 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
12630 (match_operator:MODEF 3 "binary_fp_operator"
12631 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
12632 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
12633 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12634 && !COMMUTATIVE_ARITH_P (operands[3])
12635 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12636 "* return output_387_binary_op (insn, operands);"
12637 [(set (attr "type")
12638 (cond [(and (eq_attr "alternative" "2,3")
12639 (match_operand:MODEF 3 "mult_operator"))
12640 (const_string "ssemul")
12641 (and (eq_attr "alternative" "2,3")
12642 (match_operand:MODEF 3 "div_operator"))
12643 (const_string "ssediv")
12644 (eq_attr "alternative" "2,3")
12645 (const_string "sseadd")
12646 (match_operand:MODEF 3 "mult_operator")
12647 (const_string "fmul")
12648 (match_operand:MODEF 3 "div_operator")
12649 (const_string "fdiv")
12651 (const_string "fop")))
12652 (set_attr "isa" "*,*,noavx,avx")
12653 (set_attr "prefix" "orig,orig,orig,vex")
12654 (set_attr "mode" "<MODE>")])
12656 (define_insn "*rcpsf2_sse"
12657 [(set (match_operand:SF 0 "register_operand" "=x")
12658 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12661 "%vrcpss\t{%1, %d0|%d0, %1}"
12662 [(set_attr "type" "sse")
12663 (set_attr "atom_sse_attr" "rcp")
12664 (set_attr "btver2_sse_attr" "rcp")
12665 (set_attr "prefix" "maybe_vex")
12666 (set_attr "mode" "SF")])
12668 (define_insn "*fop_<mode>_1_sse"
12669 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12670 (match_operator:MODEF 3 "binary_fp_operator"
12671 [(match_operand:MODEF 1 "register_operand" "0,x")
12672 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12673 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12674 && !COMMUTATIVE_ARITH_P (operands[3])"
12675 "* return output_387_binary_op (insn, operands);"
12676 [(set (attr "type")
12677 (cond [(match_operand:MODEF 3 "mult_operator")
12678 (const_string "ssemul")
12679 (match_operand:MODEF 3 "div_operator")
12680 (const_string "ssediv")
12682 (const_string "sseadd")))
12683 (set_attr "isa" "noavx,avx")
12684 (set_attr "prefix" "orig,vex")
12685 (set_attr "mode" "<MODE>")])
12687 ;; This pattern is not fully shadowed by the pattern above.
12688 (define_insn "*fop_<mode>_1_i387"
12689 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12690 (match_operator:MODEF 3 "binary_fp_operator"
12691 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12692 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12693 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12694 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12695 && !COMMUTATIVE_ARITH_P (operands[3])
12696 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12697 "* return output_387_binary_op (insn, operands);"
12698 [(set (attr "type")
12699 (cond [(match_operand:MODEF 3 "mult_operator")
12700 (const_string "fmul")
12701 (match_operand:MODEF 3 "div_operator")
12702 (const_string "fdiv")
12704 (const_string "fop")))
12705 (set_attr "mode" "<MODE>")])
12707 ;; ??? Add SSE splitters for these!
12708 (define_insn "*fop_<MODEF:mode>_2_i387"
12709 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12710 (match_operator:MODEF 3 "binary_fp_operator"
12712 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
12713 (match_operand:MODEF 2 "register_operand" "0,0")]))]
12714 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
12715 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12716 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12717 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12718 [(set (attr "type")
12719 (cond [(match_operand:MODEF 3 "mult_operator")
12720 (const_string "fmul")
12721 (match_operand:MODEF 3 "div_operator")
12722 (const_string "fdiv")
12724 (const_string "fop")))
12725 (set_attr "fp_int_src" "true")
12726 (set_attr "mode" "<SWI24:MODE>")])
12728 (define_insn "*fop_<MODEF:mode>_3_i387"
12729 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12730 (match_operator:MODEF 3 "binary_fp_operator"
12731 [(match_operand:MODEF 1 "register_operand" "0,0")
12733 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
12734 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
12735 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12736 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12737 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12738 [(set (attr "type")
12739 (cond [(match_operand:MODEF 3 "mult_operator")
12740 (const_string "fmul")
12741 (match_operand:MODEF 3 "div_operator")
12742 (const_string "fdiv")
12744 (const_string "fop")))
12745 (set_attr "fp_int_src" "true")
12746 (set_attr "mode" "<MODE>")])
12748 (define_insn "*fop_df_4_i387"
12749 [(set (match_operand:DF 0 "register_operand" "=f,f")
12750 (match_operator:DF 3 "binary_fp_operator"
12752 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12753 (match_operand:DF 2 "register_operand" "0,f")]))]
12754 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12755 && !(TARGET_SSE2 && TARGET_SSE_MATH)
12756 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12757 "* return output_387_binary_op (insn, operands);"
12758 [(set (attr "type")
12759 (cond [(match_operand:DF 3 "mult_operator")
12760 (const_string "fmul")
12761 (match_operand:DF 3 "div_operator")
12762 (const_string "fdiv")
12764 (const_string "fop")))
12765 (set_attr "mode" "SF")])
12767 (define_insn "*fop_df_5_i387"
12768 [(set (match_operand:DF 0 "register_operand" "=f,f")
12769 (match_operator:DF 3 "binary_fp_operator"
12770 [(match_operand:DF 1 "register_operand" "0,f")
12772 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12773 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12774 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12775 "* return output_387_binary_op (insn, operands);"
12776 [(set (attr "type")
12777 (cond [(match_operand:DF 3 "mult_operator")
12778 (const_string "fmul")
12779 (match_operand:DF 3 "div_operator")
12780 (const_string "fdiv")
12782 (const_string "fop")))
12783 (set_attr "mode" "SF")])
12785 (define_insn "*fop_df_6_i387"
12786 [(set (match_operand:DF 0 "register_operand" "=f,f")
12787 (match_operator:DF 3 "binary_fp_operator"
12789 (match_operand:SF 1 "register_operand" "0,f"))
12791 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12792 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12793 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12794 "* return output_387_binary_op (insn, operands);"
12795 [(set (attr "type")
12796 (cond [(match_operand:DF 3 "mult_operator")
12797 (const_string "fmul")
12798 (match_operand:DF 3 "div_operator")
12799 (const_string "fdiv")
12801 (const_string "fop")))
12802 (set_attr "mode" "SF")])
12804 (define_insn "*fop_xf_comm_i387"
12805 [(set (match_operand:XF 0 "register_operand" "=f")
12806 (match_operator:XF 3 "binary_fp_operator"
12807 [(match_operand:XF 1 "register_operand" "%0")
12808 (match_operand:XF 2 "register_operand" "f")]))]
12810 && COMMUTATIVE_ARITH_P (operands[3])"
12811 "* return output_387_binary_op (insn, operands);"
12812 [(set (attr "type")
12813 (if_then_else (match_operand:XF 3 "mult_operator")
12814 (const_string "fmul")
12815 (const_string "fop")))
12816 (set_attr "mode" "XF")])
12818 (define_insn "*fop_xf_1_i387"
12819 [(set (match_operand:XF 0 "register_operand" "=f,f")
12820 (match_operator:XF 3 "binary_fp_operator"
12821 [(match_operand:XF 1 "register_operand" "0,f")
12822 (match_operand:XF 2 "register_operand" "f,0")]))]
12824 && !COMMUTATIVE_ARITH_P (operands[3])"
12825 "* return output_387_binary_op (insn, operands);"
12826 [(set (attr "type")
12827 (cond [(match_operand:XF 3 "mult_operator")
12828 (const_string "fmul")
12829 (match_operand:XF 3 "div_operator")
12830 (const_string "fdiv")
12832 (const_string "fop")))
12833 (set_attr "mode" "XF")])
12835 (define_insn "*fop_xf_2_i387"
12836 [(set (match_operand:XF 0 "register_operand" "=f,f")
12837 (match_operator:XF 3 "binary_fp_operator"
12839 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
12840 (match_operand:XF 2 "register_operand" "0,0")]))]
12841 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12842 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12843 [(set (attr "type")
12844 (cond [(match_operand:XF 3 "mult_operator")
12845 (const_string "fmul")
12846 (match_operand:XF 3 "div_operator")
12847 (const_string "fdiv")
12849 (const_string "fop")))
12850 (set_attr "fp_int_src" "true")
12851 (set_attr "mode" "<MODE>")])
12853 (define_insn "*fop_xf_3_i387"
12854 [(set (match_operand:XF 0 "register_operand" "=f,f")
12855 (match_operator:XF 3 "binary_fp_operator"
12856 [(match_operand:XF 1 "register_operand" "0,0")
12858 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
12859 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12860 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12861 [(set (attr "type")
12862 (cond [(match_operand:XF 3 "mult_operator")
12863 (const_string "fmul")
12864 (match_operand:XF 3 "div_operator")
12865 (const_string "fdiv")
12867 (const_string "fop")))
12868 (set_attr "fp_int_src" "true")
12869 (set_attr "mode" "<MODE>")])
12871 (define_insn "*fop_xf_4_i387"
12872 [(set (match_operand:XF 0 "register_operand" "=f,f")
12873 (match_operator:XF 3 "binary_fp_operator"
12875 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
12876 (match_operand:XF 2 "register_operand" "0,f")]))]
12878 "* return output_387_binary_op (insn, operands);"
12879 [(set (attr "type")
12880 (cond [(match_operand:XF 3 "mult_operator")
12881 (const_string "fmul")
12882 (match_operand:XF 3 "div_operator")
12883 (const_string "fdiv")
12885 (const_string "fop")))
12886 (set_attr "mode" "<MODE>")])
12888 (define_insn "*fop_xf_5_i387"
12889 [(set (match_operand:XF 0 "register_operand" "=f,f")
12890 (match_operator:XF 3 "binary_fp_operator"
12891 [(match_operand:XF 1 "register_operand" "0,f")
12893 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12895 "* return output_387_binary_op (insn, operands);"
12896 [(set (attr "type")
12897 (cond [(match_operand:XF 3 "mult_operator")
12898 (const_string "fmul")
12899 (match_operand:XF 3 "div_operator")
12900 (const_string "fdiv")
12902 (const_string "fop")))
12903 (set_attr "mode" "<MODE>")])
12905 (define_insn "*fop_xf_6_i387"
12906 [(set (match_operand:XF 0 "register_operand" "=f,f")
12907 (match_operator:XF 3 "binary_fp_operator"
12909 (match_operand:MODEF 1 "register_operand" "0,f"))
12911 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12913 "* return output_387_binary_op (insn, operands);"
12914 [(set (attr "type")
12915 (cond [(match_operand:XF 3 "mult_operator")
12916 (const_string "fmul")
12917 (match_operand:XF 3 "div_operator")
12918 (const_string "fdiv")
12920 (const_string "fop")))
12921 (set_attr "mode" "<MODE>")])
12924 [(set (match_operand 0 "register_operand")
12925 (match_operator 3 "binary_fp_operator"
12926 [(float (match_operand:SWI24 1 "register_operand"))
12927 (match_operand 2 "register_operand")]))]
12929 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12930 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
12933 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
12934 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12935 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12936 gen_rtx_fmt_ee (GET_CODE (operands[3]),
12937 GET_MODE (operands[3]),
12940 ix86_free_from_memory (GET_MODE (operands[1]));
12945 [(set (match_operand 0 "register_operand")
12946 (match_operator 3 "binary_fp_operator"
12947 [(match_operand 1 "register_operand")
12948 (float (match_operand:SWI24 2 "register_operand"))]))]
12950 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12951 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
12954 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
12955 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12956 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12957 gen_rtx_fmt_ee (GET_CODE (operands[3]),
12958 GET_MODE (operands[3]),
12961 ix86_free_from_memory (GET_MODE (operands[2]));
12965 ;; FPU special functions.
12967 ;; This pattern implements a no-op XFmode truncation for
12968 ;; all fancy i386 XFmode math functions.
12970 (define_insn "truncxf<mode>2_i387_noop_unspec"
12971 [(set (match_operand:MODEF 0 "register_operand" "=f")
12972 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
12973 UNSPEC_TRUNC_NOOP))]
12974 "TARGET_USE_FANCY_MATH_387"
12975 "* return output_387_reg_move (insn, operands);"
12976 [(set_attr "type" "fmov")
12977 (set_attr "mode" "<MODE>")])
12979 (define_insn "sqrtxf2"
12980 [(set (match_operand:XF 0 "register_operand" "=f")
12981 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
12982 "TARGET_USE_FANCY_MATH_387"
12984 [(set_attr "type" "fpspc")
12985 (set_attr "mode" "XF")
12986 (set_attr "athlon_decode" "direct")
12987 (set_attr "amdfam10_decode" "direct")
12988 (set_attr "bdver1_decode" "direct")])
12990 (define_insn "sqrt_extend<mode>xf2_i387"
12991 [(set (match_operand:XF 0 "register_operand" "=f")
12994 (match_operand:MODEF 1 "register_operand" "0"))))]
12995 "TARGET_USE_FANCY_MATH_387"
12997 [(set_attr "type" "fpspc")
12998 (set_attr "mode" "XF")
12999 (set_attr "athlon_decode" "direct")
13000 (set_attr "amdfam10_decode" "direct")
13001 (set_attr "bdver1_decode" "direct")])
13003 (define_insn "*rsqrtsf2_sse"
13004 [(set (match_operand:SF 0 "register_operand" "=x")
13005 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13008 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13009 [(set_attr "type" "sse")
13010 (set_attr "atom_sse_attr" "rcp")
13011 (set_attr "btver2_sse_attr" "rcp")
13012 (set_attr "prefix" "maybe_vex")
13013 (set_attr "mode" "SF")])
13015 (define_expand "rsqrtsf2"
13016 [(set (match_operand:SF 0 "register_operand")
13017 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
13021 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13025 (define_insn "*sqrt<mode>2_sse"
13026 [(set (match_operand:MODEF 0 "register_operand" "=x")
13028 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13029 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13030 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13031 [(set_attr "type" "sse")
13032 (set_attr "atom_sse_attr" "sqrt")
13033 (set_attr "btver2_sse_attr" "sqrt")
13034 (set_attr "prefix" "maybe_vex")
13035 (set_attr "mode" "<MODE>")
13036 (set_attr "athlon_decode" "*")
13037 (set_attr "amdfam10_decode" "*")
13038 (set_attr "bdver1_decode" "*")])
13040 (define_expand "sqrt<mode>2"
13041 [(set (match_operand:MODEF 0 "register_operand")
13043 (match_operand:MODEF 1 "nonimmediate_operand")))]
13044 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13045 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13047 if (<MODE>mode == SFmode
13049 && TARGET_RECIP_SQRT
13050 && !optimize_function_for_size_p (cfun)
13051 && flag_finite_math_only && !flag_trapping_math
13052 && flag_unsafe_math_optimizations)
13054 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13058 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13060 rtx op0 = gen_reg_rtx (XFmode);
13061 rtx op1 = force_reg (<MODE>mode, operands[1]);
13063 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13064 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13069 (define_insn "fpremxf4_i387"
13070 [(set (match_operand:XF 0 "register_operand" "=f")
13071 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13072 (match_operand:XF 3 "register_operand" "1")]
13074 (set (match_operand:XF 1 "register_operand" "=u")
13075 (unspec:XF [(match_dup 2) (match_dup 3)]
13077 (set (reg:CCFP FPSR_REG)
13078 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13080 "TARGET_USE_FANCY_MATH_387"
13082 [(set_attr "type" "fpspc")
13083 (set_attr "mode" "XF")])
13085 (define_expand "fmodxf3"
13086 [(use (match_operand:XF 0 "register_operand"))
13087 (use (match_operand:XF 1 "general_operand"))
13088 (use (match_operand:XF 2 "general_operand"))]
13089 "TARGET_USE_FANCY_MATH_387"
13091 rtx label = gen_label_rtx ();
13093 rtx op1 = gen_reg_rtx (XFmode);
13094 rtx op2 = gen_reg_rtx (XFmode);
13096 emit_move_insn (op2, operands[2]);
13097 emit_move_insn (op1, operands[1]);
13099 emit_label (label);
13100 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13101 ix86_emit_fp_unordered_jump (label);
13102 LABEL_NUSES (label) = 1;
13104 emit_move_insn (operands[0], op1);
13108 (define_expand "fmod<mode>3"
13109 [(use (match_operand:MODEF 0 "register_operand"))
13110 (use (match_operand:MODEF 1 "general_operand"))
13111 (use (match_operand:MODEF 2 "general_operand"))]
13112 "TARGET_USE_FANCY_MATH_387"
13114 rtx (*gen_truncxf) (rtx, rtx);
13116 rtx label = gen_label_rtx ();
13118 rtx op1 = gen_reg_rtx (XFmode);
13119 rtx op2 = gen_reg_rtx (XFmode);
13121 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13122 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13124 emit_label (label);
13125 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13126 ix86_emit_fp_unordered_jump (label);
13127 LABEL_NUSES (label) = 1;
13129 /* Truncate the result properly for strict SSE math. */
13130 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13131 && !TARGET_MIX_SSE_I387)
13132 gen_truncxf = gen_truncxf<mode>2;
13134 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13136 emit_insn (gen_truncxf (operands[0], op1));
13140 (define_insn "fprem1xf4_i387"
13141 [(set (match_operand:XF 0 "register_operand" "=f")
13142 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13143 (match_operand:XF 3 "register_operand" "1")]
13145 (set (match_operand:XF 1 "register_operand" "=u")
13146 (unspec:XF [(match_dup 2) (match_dup 3)]
13148 (set (reg:CCFP FPSR_REG)
13149 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13151 "TARGET_USE_FANCY_MATH_387"
13153 [(set_attr "type" "fpspc")
13154 (set_attr "mode" "XF")])
13156 (define_expand "remainderxf3"
13157 [(use (match_operand:XF 0 "register_operand"))
13158 (use (match_operand:XF 1 "general_operand"))
13159 (use (match_operand:XF 2 "general_operand"))]
13160 "TARGET_USE_FANCY_MATH_387"
13162 rtx label = gen_label_rtx ();
13164 rtx op1 = gen_reg_rtx (XFmode);
13165 rtx op2 = gen_reg_rtx (XFmode);
13167 emit_move_insn (op2, operands[2]);
13168 emit_move_insn (op1, operands[1]);
13170 emit_label (label);
13171 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13172 ix86_emit_fp_unordered_jump (label);
13173 LABEL_NUSES (label) = 1;
13175 emit_move_insn (operands[0], op1);
13179 (define_expand "remainder<mode>3"
13180 [(use (match_operand:MODEF 0 "register_operand"))
13181 (use (match_operand:MODEF 1 "general_operand"))
13182 (use (match_operand:MODEF 2 "general_operand"))]
13183 "TARGET_USE_FANCY_MATH_387"
13185 rtx (*gen_truncxf) (rtx, rtx);
13187 rtx label = gen_label_rtx ();
13189 rtx op1 = gen_reg_rtx (XFmode);
13190 rtx op2 = gen_reg_rtx (XFmode);
13192 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13193 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13195 emit_label (label);
13197 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13198 ix86_emit_fp_unordered_jump (label);
13199 LABEL_NUSES (label) = 1;
13201 /* Truncate the result properly for strict SSE math. */
13202 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13203 && !TARGET_MIX_SSE_I387)
13204 gen_truncxf = gen_truncxf<mode>2;
13206 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13208 emit_insn (gen_truncxf (operands[0], op1));
13212 (define_int_iterator SINCOS
13216 (define_int_attr sincos
13217 [(UNSPEC_SIN "sin")
13218 (UNSPEC_COS "cos")])
13220 (define_insn "*<sincos>xf2_i387"
13221 [(set (match_operand:XF 0 "register_operand" "=f")
13222 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13224 "TARGET_USE_FANCY_MATH_387
13225 && flag_unsafe_math_optimizations"
13227 [(set_attr "type" "fpspc")
13228 (set_attr "mode" "XF")])
13230 (define_insn "*<sincos>_extend<mode>xf2_i387"
13231 [(set (match_operand:XF 0 "register_operand" "=f")
13232 (unspec:XF [(float_extend:XF
13233 (match_operand:MODEF 1 "register_operand" "0"))]
13235 "TARGET_USE_FANCY_MATH_387
13236 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13237 || TARGET_MIX_SSE_I387)
13238 && flag_unsafe_math_optimizations"
13240 [(set_attr "type" "fpspc")
13241 (set_attr "mode" "XF")])
13243 ;; When sincos pattern is defined, sin and cos builtin functions will be
13244 ;; expanded to sincos pattern with one of its outputs left unused.
13245 ;; CSE pass will figure out if two sincos patterns can be combined,
13246 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13247 ;; depending on the unused output.
13249 (define_insn "sincosxf3"
13250 [(set (match_operand:XF 0 "register_operand" "=f")
13251 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13252 UNSPEC_SINCOS_COS))
13253 (set (match_operand:XF 1 "register_operand" "=u")
13254 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13255 "TARGET_USE_FANCY_MATH_387
13256 && flag_unsafe_math_optimizations"
13258 [(set_attr "type" "fpspc")
13259 (set_attr "mode" "XF")])
13262 [(set (match_operand:XF 0 "register_operand")
13263 (unspec:XF [(match_operand:XF 2 "register_operand")]
13264 UNSPEC_SINCOS_COS))
13265 (set (match_operand:XF 1 "register_operand")
13266 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13267 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13268 && can_create_pseudo_p ()"
13269 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13272 [(set (match_operand:XF 0 "register_operand")
13273 (unspec:XF [(match_operand:XF 2 "register_operand")]
13274 UNSPEC_SINCOS_COS))
13275 (set (match_operand:XF 1 "register_operand")
13276 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13277 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13278 && can_create_pseudo_p ()"
13279 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13281 (define_insn "sincos_extend<mode>xf3_i387"
13282 [(set (match_operand:XF 0 "register_operand" "=f")
13283 (unspec:XF [(float_extend:XF
13284 (match_operand:MODEF 2 "register_operand" "0"))]
13285 UNSPEC_SINCOS_COS))
13286 (set (match_operand:XF 1 "register_operand" "=u")
13287 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13288 "TARGET_USE_FANCY_MATH_387
13289 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13290 || TARGET_MIX_SSE_I387)
13291 && flag_unsafe_math_optimizations"
13293 [(set_attr "type" "fpspc")
13294 (set_attr "mode" "XF")])
13297 [(set (match_operand:XF 0 "register_operand")
13298 (unspec:XF [(float_extend:XF
13299 (match_operand:MODEF 2 "register_operand"))]
13300 UNSPEC_SINCOS_COS))
13301 (set (match_operand:XF 1 "register_operand")
13302 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13303 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13304 && can_create_pseudo_p ()"
13305 [(set (match_dup 1)
13306 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13309 [(set (match_operand:XF 0 "register_operand")
13310 (unspec:XF [(float_extend:XF
13311 (match_operand:MODEF 2 "register_operand"))]
13312 UNSPEC_SINCOS_COS))
13313 (set (match_operand:XF 1 "register_operand")
13314 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13315 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13316 && can_create_pseudo_p ()"
13317 [(set (match_dup 0)
13318 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13320 (define_expand "sincos<mode>3"
13321 [(use (match_operand:MODEF 0 "register_operand"))
13322 (use (match_operand:MODEF 1 "register_operand"))
13323 (use (match_operand:MODEF 2 "register_operand"))]
13324 "TARGET_USE_FANCY_MATH_387
13325 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13326 || TARGET_MIX_SSE_I387)
13327 && flag_unsafe_math_optimizations"
13329 rtx op0 = gen_reg_rtx (XFmode);
13330 rtx op1 = gen_reg_rtx (XFmode);
13332 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13333 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13334 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13338 (define_insn "fptanxf4_i387"
13339 [(set (match_operand:XF 0 "register_operand" "=f")
13340 (match_operand:XF 3 "const_double_operand" "F"))
13341 (set (match_operand:XF 1 "register_operand" "=u")
13342 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13344 "TARGET_USE_FANCY_MATH_387
13345 && flag_unsafe_math_optimizations
13346 && standard_80387_constant_p (operands[3]) == 2"
13348 [(set_attr "type" "fpspc")
13349 (set_attr "mode" "XF")])
13351 (define_insn "fptan_extend<mode>xf4_i387"
13352 [(set (match_operand:MODEF 0 "register_operand" "=f")
13353 (match_operand:MODEF 3 "const_double_operand" "F"))
13354 (set (match_operand:XF 1 "register_operand" "=u")
13355 (unspec:XF [(float_extend:XF
13356 (match_operand:MODEF 2 "register_operand" "0"))]
13358 "TARGET_USE_FANCY_MATH_387
13359 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13360 || TARGET_MIX_SSE_I387)
13361 && flag_unsafe_math_optimizations
13362 && standard_80387_constant_p (operands[3]) == 2"
13364 [(set_attr "type" "fpspc")
13365 (set_attr "mode" "XF")])
13367 (define_expand "tanxf2"
13368 [(use (match_operand:XF 0 "register_operand"))
13369 (use (match_operand:XF 1 "register_operand"))]
13370 "TARGET_USE_FANCY_MATH_387
13371 && flag_unsafe_math_optimizations"
13373 rtx one = gen_reg_rtx (XFmode);
13374 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13376 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13380 (define_expand "tan<mode>2"
13381 [(use (match_operand:MODEF 0 "register_operand"))
13382 (use (match_operand:MODEF 1 "register_operand"))]
13383 "TARGET_USE_FANCY_MATH_387
13384 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13385 || TARGET_MIX_SSE_I387)
13386 && flag_unsafe_math_optimizations"
13388 rtx op0 = gen_reg_rtx (XFmode);
13390 rtx one = gen_reg_rtx (<MODE>mode);
13391 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13393 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13394 operands[1], op2));
13395 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13399 (define_insn "*fpatanxf3_i387"
13400 [(set (match_operand:XF 0 "register_operand" "=f")
13401 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13402 (match_operand:XF 2 "register_operand" "u")]
13404 (clobber (match_scratch:XF 3 "=2"))]
13405 "TARGET_USE_FANCY_MATH_387
13406 && flag_unsafe_math_optimizations"
13408 [(set_attr "type" "fpspc")
13409 (set_attr "mode" "XF")])
13411 (define_insn "fpatan_extend<mode>xf3_i387"
13412 [(set (match_operand:XF 0 "register_operand" "=f")
13413 (unspec:XF [(float_extend:XF
13414 (match_operand:MODEF 1 "register_operand" "0"))
13416 (match_operand:MODEF 2 "register_operand" "u"))]
13418 (clobber (match_scratch:XF 3 "=2"))]
13419 "TARGET_USE_FANCY_MATH_387
13420 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13421 || TARGET_MIX_SSE_I387)
13422 && flag_unsafe_math_optimizations"
13424 [(set_attr "type" "fpspc")
13425 (set_attr "mode" "XF")])
13427 (define_expand "atan2xf3"
13428 [(parallel [(set (match_operand:XF 0 "register_operand")
13429 (unspec:XF [(match_operand:XF 2 "register_operand")
13430 (match_operand:XF 1 "register_operand")]
13432 (clobber (match_scratch:XF 3))])]
13433 "TARGET_USE_FANCY_MATH_387
13434 && flag_unsafe_math_optimizations")
13436 (define_expand "atan2<mode>3"
13437 [(use (match_operand:MODEF 0 "register_operand"))
13438 (use (match_operand:MODEF 1 "register_operand"))
13439 (use (match_operand:MODEF 2 "register_operand"))]
13440 "TARGET_USE_FANCY_MATH_387
13441 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13442 || TARGET_MIX_SSE_I387)
13443 && flag_unsafe_math_optimizations"
13445 rtx op0 = gen_reg_rtx (XFmode);
13447 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13448 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13452 (define_expand "atanxf2"
13453 [(parallel [(set (match_operand:XF 0 "register_operand")
13454 (unspec:XF [(match_dup 2)
13455 (match_operand:XF 1 "register_operand")]
13457 (clobber (match_scratch:XF 3))])]
13458 "TARGET_USE_FANCY_MATH_387
13459 && flag_unsafe_math_optimizations"
13461 operands[2] = gen_reg_rtx (XFmode);
13462 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13465 (define_expand "atan<mode>2"
13466 [(use (match_operand:MODEF 0 "register_operand"))
13467 (use (match_operand:MODEF 1 "register_operand"))]
13468 "TARGET_USE_FANCY_MATH_387
13469 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13470 || TARGET_MIX_SSE_I387)
13471 && flag_unsafe_math_optimizations"
13473 rtx op0 = gen_reg_rtx (XFmode);
13475 rtx op2 = gen_reg_rtx (<MODE>mode);
13476 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13478 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13479 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13483 (define_expand "asinxf2"
13484 [(set (match_dup 2)
13485 (mult:XF (match_operand:XF 1 "register_operand")
13487 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13488 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13489 (parallel [(set (match_operand:XF 0 "register_operand")
13490 (unspec:XF [(match_dup 5) (match_dup 1)]
13492 (clobber (match_scratch:XF 6))])]
13493 "TARGET_USE_FANCY_MATH_387
13494 && flag_unsafe_math_optimizations"
13498 if (optimize_insn_for_size_p ())
13501 for (i = 2; i < 6; i++)
13502 operands[i] = gen_reg_rtx (XFmode);
13504 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13507 (define_expand "asin<mode>2"
13508 [(use (match_operand:MODEF 0 "register_operand"))
13509 (use (match_operand:MODEF 1 "general_operand"))]
13510 "TARGET_USE_FANCY_MATH_387
13511 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13512 || TARGET_MIX_SSE_I387)
13513 && flag_unsafe_math_optimizations"
13515 rtx op0 = gen_reg_rtx (XFmode);
13516 rtx op1 = gen_reg_rtx (XFmode);
13518 if (optimize_insn_for_size_p ())
13521 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13522 emit_insn (gen_asinxf2 (op0, op1));
13523 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13527 (define_expand "acosxf2"
13528 [(set (match_dup 2)
13529 (mult:XF (match_operand:XF 1 "register_operand")
13531 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13532 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13533 (parallel [(set (match_operand:XF 0 "register_operand")
13534 (unspec:XF [(match_dup 1) (match_dup 5)]
13536 (clobber (match_scratch:XF 6))])]
13537 "TARGET_USE_FANCY_MATH_387
13538 && flag_unsafe_math_optimizations"
13542 if (optimize_insn_for_size_p ())
13545 for (i = 2; i < 6; i++)
13546 operands[i] = gen_reg_rtx (XFmode);
13548 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13551 (define_expand "acos<mode>2"
13552 [(use (match_operand:MODEF 0 "register_operand"))
13553 (use (match_operand:MODEF 1 "general_operand"))]
13554 "TARGET_USE_FANCY_MATH_387
13555 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13556 || TARGET_MIX_SSE_I387)
13557 && flag_unsafe_math_optimizations"
13559 rtx op0 = gen_reg_rtx (XFmode);
13560 rtx op1 = gen_reg_rtx (XFmode);
13562 if (optimize_insn_for_size_p ())
13565 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13566 emit_insn (gen_acosxf2 (op0, op1));
13567 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13571 (define_insn "fyl2xxf3_i387"
13572 [(set (match_operand:XF 0 "register_operand" "=f")
13573 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13574 (match_operand:XF 2 "register_operand" "u")]
13576 (clobber (match_scratch:XF 3 "=2"))]
13577 "TARGET_USE_FANCY_MATH_387
13578 && flag_unsafe_math_optimizations"
13580 [(set_attr "type" "fpspc")
13581 (set_attr "mode" "XF")])
13583 (define_insn "fyl2x_extend<mode>xf3_i387"
13584 [(set (match_operand:XF 0 "register_operand" "=f")
13585 (unspec:XF [(float_extend:XF
13586 (match_operand:MODEF 1 "register_operand" "0"))
13587 (match_operand:XF 2 "register_operand" "u")]
13589 (clobber (match_scratch:XF 3 "=2"))]
13590 "TARGET_USE_FANCY_MATH_387
13591 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13592 || TARGET_MIX_SSE_I387)
13593 && flag_unsafe_math_optimizations"
13595 [(set_attr "type" "fpspc")
13596 (set_attr "mode" "XF")])
13598 (define_expand "logxf2"
13599 [(parallel [(set (match_operand:XF 0 "register_operand")
13600 (unspec:XF [(match_operand:XF 1 "register_operand")
13601 (match_dup 2)] UNSPEC_FYL2X))
13602 (clobber (match_scratch:XF 3))])]
13603 "TARGET_USE_FANCY_MATH_387
13604 && flag_unsafe_math_optimizations"
13606 operands[2] = gen_reg_rtx (XFmode);
13607 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13610 (define_expand "log<mode>2"
13611 [(use (match_operand:MODEF 0 "register_operand"))
13612 (use (match_operand:MODEF 1 "register_operand"))]
13613 "TARGET_USE_FANCY_MATH_387
13614 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13615 || TARGET_MIX_SSE_I387)
13616 && flag_unsafe_math_optimizations"
13618 rtx op0 = gen_reg_rtx (XFmode);
13620 rtx op2 = gen_reg_rtx (XFmode);
13621 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13623 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13624 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13628 (define_expand "log10xf2"
13629 [(parallel [(set (match_operand:XF 0 "register_operand")
13630 (unspec:XF [(match_operand:XF 1 "register_operand")
13631 (match_dup 2)] UNSPEC_FYL2X))
13632 (clobber (match_scratch:XF 3))])]
13633 "TARGET_USE_FANCY_MATH_387
13634 && flag_unsafe_math_optimizations"
13636 operands[2] = gen_reg_rtx (XFmode);
13637 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13640 (define_expand "log10<mode>2"
13641 [(use (match_operand:MODEF 0 "register_operand"))
13642 (use (match_operand:MODEF 1 "register_operand"))]
13643 "TARGET_USE_FANCY_MATH_387
13644 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13645 || TARGET_MIX_SSE_I387)
13646 && flag_unsafe_math_optimizations"
13648 rtx op0 = gen_reg_rtx (XFmode);
13650 rtx op2 = gen_reg_rtx (XFmode);
13651 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13653 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13654 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13658 (define_expand "log2xf2"
13659 [(parallel [(set (match_operand:XF 0 "register_operand")
13660 (unspec:XF [(match_operand:XF 1 "register_operand")
13661 (match_dup 2)] UNSPEC_FYL2X))
13662 (clobber (match_scratch:XF 3))])]
13663 "TARGET_USE_FANCY_MATH_387
13664 && flag_unsafe_math_optimizations"
13666 operands[2] = gen_reg_rtx (XFmode);
13667 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13670 (define_expand "log2<mode>2"
13671 [(use (match_operand:MODEF 0 "register_operand"))
13672 (use (match_operand:MODEF 1 "register_operand"))]
13673 "TARGET_USE_FANCY_MATH_387
13674 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13675 || TARGET_MIX_SSE_I387)
13676 && flag_unsafe_math_optimizations"
13678 rtx op0 = gen_reg_rtx (XFmode);
13680 rtx op2 = gen_reg_rtx (XFmode);
13681 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13683 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13684 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13688 (define_insn "fyl2xp1xf3_i387"
13689 [(set (match_operand:XF 0 "register_operand" "=f")
13690 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13691 (match_operand:XF 2 "register_operand" "u")]
13693 (clobber (match_scratch:XF 3 "=2"))]
13694 "TARGET_USE_FANCY_MATH_387
13695 && flag_unsafe_math_optimizations"
13697 [(set_attr "type" "fpspc")
13698 (set_attr "mode" "XF")])
13700 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13701 [(set (match_operand:XF 0 "register_operand" "=f")
13702 (unspec:XF [(float_extend:XF
13703 (match_operand:MODEF 1 "register_operand" "0"))
13704 (match_operand:XF 2 "register_operand" "u")]
13706 (clobber (match_scratch:XF 3 "=2"))]
13707 "TARGET_USE_FANCY_MATH_387
13708 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13709 || TARGET_MIX_SSE_I387)
13710 && flag_unsafe_math_optimizations"
13712 [(set_attr "type" "fpspc")
13713 (set_attr "mode" "XF")])
13715 (define_expand "log1pxf2"
13716 [(use (match_operand:XF 0 "register_operand"))
13717 (use (match_operand:XF 1 "register_operand"))]
13718 "TARGET_USE_FANCY_MATH_387
13719 && flag_unsafe_math_optimizations"
13721 if (optimize_insn_for_size_p ())
13724 ix86_emit_i387_log1p (operands[0], operands[1]);
13728 (define_expand "log1p<mode>2"
13729 [(use (match_operand:MODEF 0 "register_operand"))
13730 (use (match_operand:MODEF 1 "register_operand"))]
13731 "TARGET_USE_FANCY_MATH_387
13732 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13733 || TARGET_MIX_SSE_I387)
13734 && flag_unsafe_math_optimizations"
13738 if (optimize_insn_for_size_p ())
13741 op0 = gen_reg_rtx (XFmode);
13743 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13745 ix86_emit_i387_log1p (op0, operands[1]);
13746 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13750 (define_insn "fxtractxf3_i387"
13751 [(set (match_operand:XF 0 "register_operand" "=f")
13752 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13753 UNSPEC_XTRACT_FRACT))
13754 (set (match_operand:XF 1 "register_operand" "=u")
13755 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13756 "TARGET_USE_FANCY_MATH_387
13757 && flag_unsafe_math_optimizations"
13759 [(set_attr "type" "fpspc")
13760 (set_attr "mode" "XF")])
13762 (define_insn "fxtract_extend<mode>xf3_i387"
13763 [(set (match_operand:XF 0 "register_operand" "=f")
13764 (unspec:XF [(float_extend:XF
13765 (match_operand:MODEF 2 "register_operand" "0"))]
13766 UNSPEC_XTRACT_FRACT))
13767 (set (match_operand:XF 1 "register_operand" "=u")
13768 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13769 "TARGET_USE_FANCY_MATH_387
13770 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13771 || TARGET_MIX_SSE_I387)
13772 && flag_unsafe_math_optimizations"
13774 [(set_attr "type" "fpspc")
13775 (set_attr "mode" "XF")])
13777 (define_expand "logbxf2"
13778 [(parallel [(set (match_dup 2)
13779 (unspec:XF [(match_operand:XF 1 "register_operand")]
13780 UNSPEC_XTRACT_FRACT))
13781 (set (match_operand:XF 0 "register_operand")
13782 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13783 "TARGET_USE_FANCY_MATH_387
13784 && flag_unsafe_math_optimizations"
13785 "operands[2] = gen_reg_rtx (XFmode);")
13787 (define_expand "logb<mode>2"
13788 [(use (match_operand:MODEF 0 "register_operand"))
13789 (use (match_operand:MODEF 1 "register_operand"))]
13790 "TARGET_USE_FANCY_MATH_387
13791 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13792 || TARGET_MIX_SSE_I387)
13793 && flag_unsafe_math_optimizations"
13795 rtx op0 = gen_reg_rtx (XFmode);
13796 rtx op1 = gen_reg_rtx (XFmode);
13798 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13799 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13803 (define_expand "ilogbxf2"
13804 [(use (match_operand:SI 0 "register_operand"))
13805 (use (match_operand:XF 1 "register_operand"))]
13806 "TARGET_USE_FANCY_MATH_387
13807 && flag_unsafe_math_optimizations"
13811 if (optimize_insn_for_size_p ())
13814 op0 = gen_reg_rtx (XFmode);
13815 op1 = gen_reg_rtx (XFmode);
13817 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13818 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13822 (define_expand "ilogb<mode>2"
13823 [(use (match_operand:SI 0 "register_operand"))
13824 (use (match_operand:MODEF 1 "register_operand"))]
13825 "TARGET_USE_FANCY_MATH_387
13826 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13827 || TARGET_MIX_SSE_I387)
13828 && flag_unsafe_math_optimizations"
13832 if (optimize_insn_for_size_p ())
13835 op0 = gen_reg_rtx (XFmode);
13836 op1 = gen_reg_rtx (XFmode);
13838 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13839 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13843 (define_insn "*f2xm1xf2_i387"
13844 [(set (match_operand:XF 0 "register_operand" "=f")
13845 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13847 "TARGET_USE_FANCY_MATH_387
13848 && flag_unsafe_math_optimizations"
13850 [(set_attr "type" "fpspc")
13851 (set_attr "mode" "XF")])
13853 (define_insn "*fscalexf4_i387"
13854 [(set (match_operand:XF 0 "register_operand" "=f")
13855 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13856 (match_operand:XF 3 "register_operand" "1")]
13857 UNSPEC_FSCALE_FRACT))
13858 (set (match_operand:XF 1 "register_operand" "=u")
13859 (unspec:XF [(match_dup 2) (match_dup 3)]
13860 UNSPEC_FSCALE_EXP))]
13861 "TARGET_USE_FANCY_MATH_387
13862 && flag_unsafe_math_optimizations"
13864 [(set_attr "type" "fpspc")
13865 (set_attr "mode" "XF")])
13867 (define_expand "expNcorexf3"
13868 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
13869 (match_operand:XF 2 "register_operand")))
13870 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13871 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13872 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13873 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
13874 (parallel [(set (match_operand:XF 0 "register_operand")
13875 (unspec:XF [(match_dup 8) (match_dup 4)]
13876 UNSPEC_FSCALE_FRACT))
13878 (unspec:XF [(match_dup 8) (match_dup 4)]
13879 UNSPEC_FSCALE_EXP))])]
13880 "TARGET_USE_FANCY_MATH_387
13881 && flag_unsafe_math_optimizations"
13885 if (optimize_insn_for_size_p ())
13888 for (i = 3; i < 10; i++)
13889 operands[i] = gen_reg_rtx (XFmode);
13891 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
13894 (define_expand "expxf2"
13895 [(use (match_operand:XF 0 "register_operand"))
13896 (use (match_operand:XF 1 "register_operand"))]
13897 "TARGET_USE_FANCY_MATH_387
13898 && flag_unsafe_math_optimizations"
13902 if (optimize_insn_for_size_p ())
13905 op2 = gen_reg_rtx (XFmode);
13906 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
13908 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13912 (define_expand "exp<mode>2"
13913 [(use (match_operand:MODEF 0 "register_operand"))
13914 (use (match_operand:MODEF 1 "general_operand"))]
13915 "TARGET_USE_FANCY_MATH_387
13916 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13917 || TARGET_MIX_SSE_I387)
13918 && flag_unsafe_math_optimizations"
13922 if (optimize_insn_for_size_p ())
13925 op0 = gen_reg_rtx (XFmode);
13926 op1 = gen_reg_rtx (XFmode);
13928 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13929 emit_insn (gen_expxf2 (op0, op1));
13930 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13934 (define_expand "exp10xf2"
13935 [(use (match_operand:XF 0 "register_operand"))
13936 (use (match_operand:XF 1 "register_operand"))]
13937 "TARGET_USE_FANCY_MATH_387
13938 && flag_unsafe_math_optimizations"
13942 if (optimize_insn_for_size_p ())
13945 op2 = gen_reg_rtx (XFmode);
13946 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
13948 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13952 (define_expand "exp10<mode>2"
13953 [(use (match_operand:MODEF 0 "register_operand"))
13954 (use (match_operand:MODEF 1 "general_operand"))]
13955 "TARGET_USE_FANCY_MATH_387
13956 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13957 || TARGET_MIX_SSE_I387)
13958 && flag_unsafe_math_optimizations"
13962 if (optimize_insn_for_size_p ())
13965 op0 = gen_reg_rtx (XFmode);
13966 op1 = gen_reg_rtx (XFmode);
13968 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13969 emit_insn (gen_exp10xf2 (op0, op1));
13970 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13974 (define_expand "exp2xf2"
13975 [(use (match_operand:XF 0 "register_operand"))
13976 (use (match_operand:XF 1 "register_operand"))]
13977 "TARGET_USE_FANCY_MATH_387
13978 && flag_unsafe_math_optimizations"
13982 if (optimize_insn_for_size_p ())
13985 op2 = gen_reg_rtx (XFmode);
13986 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13988 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13992 (define_expand "exp2<mode>2"
13993 [(use (match_operand:MODEF 0 "register_operand"))
13994 (use (match_operand:MODEF 1 "general_operand"))]
13995 "TARGET_USE_FANCY_MATH_387
13996 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13997 || TARGET_MIX_SSE_I387)
13998 && flag_unsafe_math_optimizations"
14002 if (optimize_insn_for_size_p ())
14005 op0 = gen_reg_rtx (XFmode);
14006 op1 = gen_reg_rtx (XFmode);
14008 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14009 emit_insn (gen_exp2xf2 (op0, op1));
14010 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14014 (define_expand "expm1xf2"
14015 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14017 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14018 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14019 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14020 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14021 (parallel [(set (match_dup 7)
14022 (unspec:XF [(match_dup 6) (match_dup 4)]
14023 UNSPEC_FSCALE_FRACT))
14025 (unspec:XF [(match_dup 6) (match_dup 4)]
14026 UNSPEC_FSCALE_EXP))])
14027 (parallel [(set (match_dup 10)
14028 (unspec:XF [(match_dup 9) (match_dup 8)]
14029 UNSPEC_FSCALE_FRACT))
14030 (set (match_dup 11)
14031 (unspec:XF [(match_dup 9) (match_dup 8)]
14032 UNSPEC_FSCALE_EXP))])
14033 (set (match_dup 12) (minus:XF (match_dup 10)
14034 (float_extend:XF (match_dup 13))))
14035 (set (match_operand:XF 0 "register_operand")
14036 (plus:XF (match_dup 12) (match_dup 7)))]
14037 "TARGET_USE_FANCY_MATH_387
14038 && flag_unsafe_math_optimizations"
14042 if (optimize_insn_for_size_p ())
14045 for (i = 2; i < 13; i++)
14046 operands[i] = gen_reg_rtx (XFmode);
14049 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14051 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14054 (define_expand "expm1<mode>2"
14055 [(use (match_operand:MODEF 0 "register_operand"))
14056 (use (match_operand:MODEF 1 "general_operand"))]
14057 "TARGET_USE_FANCY_MATH_387
14058 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14059 || TARGET_MIX_SSE_I387)
14060 && flag_unsafe_math_optimizations"
14064 if (optimize_insn_for_size_p ())
14067 op0 = gen_reg_rtx (XFmode);
14068 op1 = gen_reg_rtx (XFmode);
14070 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14071 emit_insn (gen_expm1xf2 (op0, op1));
14072 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14076 (define_expand "ldexpxf3"
14077 [(set (match_dup 3)
14078 (float:XF (match_operand:SI 2 "register_operand")))
14079 (parallel [(set (match_operand:XF 0 " register_operand")
14080 (unspec:XF [(match_operand:XF 1 "register_operand")
14082 UNSPEC_FSCALE_FRACT))
14084 (unspec:XF [(match_dup 1) (match_dup 3)]
14085 UNSPEC_FSCALE_EXP))])]
14086 "TARGET_USE_FANCY_MATH_387
14087 && flag_unsafe_math_optimizations"
14089 if (optimize_insn_for_size_p ())
14092 operands[3] = gen_reg_rtx (XFmode);
14093 operands[4] = gen_reg_rtx (XFmode);
14096 (define_expand "ldexp<mode>3"
14097 [(use (match_operand:MODEF 0 "register_operand"))
14098 (use (match_operand:MODEF 1 "general_operand"))
14099 (use (match_operand:SI 2 "register_operand"))]
14100 "TARGET_USE_FANCY_MATH_387
14101 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14102 || TARGET_MIX_SSE_I387)
14103 && flag_unsafe_math_optimizations"
14107 if (optimize_insn_for_size_p ())
14110 op0 = gen_reg_rtx (XFmode);
14111 op1 = gen_reg_rtx (XFmode);
14113 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14114 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14115 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14119 (define_expand "scalbxf3"
14120 [(parallel [(set (match_operand:XF 0 " register_operand")
14121 (unspec:XF [(match_operand:XF 1 "register_operand")
14122 (match_operand:XF 2 "register_operand")]
14123 UNSPEC_FSCALE_FRACT))
14125 (unspec:XF [(match_dup 1) (match_dup 2)]
14126 UNSPEC_FSCALE_EXP))])]
14127 "TARGET_USE_FANCY_MATH_387
14128 && flag_unsafe_math_optimizations"
14130 if (optimize_insn_for_size_p ())
14133 operands[3] = gen_reg_rtx (XFmode);
14136 (define_expand "scalb<mode>3"
14137 [(use (match_operand:MODEF 0 "register_operand"))
14138 (use (match_operand:MODEF 1 "general_operand"))
14139 (use (match_operand:MODEF 2 "general_operand"))]
14140 "TARGET_USE_FANCY_MATH_387
14141 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14142 || TARGET_MIX_SSE_I387)
14143 && flag_unsafe_math_optimizations"
14147 if (optimize_insn_for_size_p ())
14150 op0 = gen_reg_rtx (XFmode);
14151 op1 = gen_reg_rtx (XFmode);
14152 op2 = gen_reg_rtx (XFmode);
14154 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14155 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14156 emit_insn (gen_scalbxf3 (op0, op1, op2));
14157 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14161 (define_expand "significandxf2"
14162 [(parallel [(set (match_operand:XF 0 "register_operand")
14163 (unspec:XF [(match_operand:XF 1 "register_operand")]
14164 UNSPEC_XTRACT_FRACT))
14166 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14167 "TARGET_USE_FANCY_MATH_387
14168 && flag_unsafe_math_optimizations"
14169 "operands[2] = gen_reg_rtx (XFmode);")
14171 (define_expand "significand<mode>2"
14172 [(use (match_operand:MODEF 0 "register_operand"))
14173 (use (match_operand:MODEF 1 "register_operand"))]
14174 "TARGET_USE_FANCY_MATH_387
14175 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14176 || TARGET_MIX_SSE_I387)
14177 && flag_unsafe_math_optimizations"
14179 rtx op0 = gen_reg_rtx (XFmode);
14180 rtx op1 = gen_reg_rtx (XFmode);
14182 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14183 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14188 (define_insn "sse4_1_round<mode>2"
14189 [(set (match_operand:MODEF 0 "register_operand" "=x")
14190 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14191 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14194 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14195 [(set_attr "type" "ssecvt")
14196 (set_attr "prefix_extra" "1")
14197 (set_attr "prefix" "maybe_vex")
14198 (set_attr "mode" "<MODE>")])
14200 (define_insn "rintxf2"
14201 [(set (match_operand:XF 0 "register_operand" "=f")
14202 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14204 "TARGET_USE_FANCY_MATH_387
14205 && flag_unsafe_math_optimizations"
14207 [(set_attr "type" "fpspc")
14208 (set_attr "mode" "XF")])
14210 (define_expand "rint<mode>2"
14211 [(use (match_operand:MODEF 0 "register_operand"))
14212 (use (match_operand:MODEF 1 "register_operand"))]
14213 "(TARGET_USE_FANCY_MATH_387
14214 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14215 || TARGET_MIX_SSE_I387)
14216 && flag_unsafe_math_optimizations)
14217 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14218 && !flag_trapping_math)"
14220 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14221 && !flag_trapping_math)
14224 emit_insn (gen_sse4_1_round<mode>2
14225 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14226 else if (optimize_insn_for_size_p ())
14229 ix86_expand_rint (operands[0], operands[1]);
14233 rtx op0 = gen_reg_rtx (XFmode);
14234 rtx op1 = gen_reg_rtx (XFmode);
14236 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14237 emit_insn (gen_rintxf2 (op0, op1));
14239 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14244 (define_expand "round<mode>2"
14245 [(match_operand:X87MODEF 0 "register_operand")
14246 (match_operand:X87MODEF 1 "nonimmediate_operand")]
14247 "(TARGET_USE_FANCY_MATH_387
14248 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14249 || TARGET_MIX_SSE_I387)
14250 && flag_unsafe_math_optimizations)
14251 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14252 && !flag_trapping_math && !flag_rounding_math)"
14254 if (optimize_insn_for_size_p ())
14257 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14258 && !flag_trapping_math && !flag_rounding_math)
14262 operands[1] = force_reg (<MODE>mode, operands[1]);
14263 ix86_expand_round_sse4 (operands[0], operands[1]);
14265 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14266 ix86_expand_round (operands[0], operands[1]);
14268 ix86_expand_rounddf_32 (operands[0], operands[1]);
14272 operands[1] = force_reg (<MODE>mode, operands[1]);
14273 ix86_emit_i387_round (operands[0], operands[1]);
14278 (define_insn_and_split "*fistdi2_1"
14279 [(set (match_operand:DI 0 "nonimmediate_operand")
14280 (unspec:DI [(match_operand:XF 1 "register_operand")]
14282 "TARGET_USE_FANCY_MATH_387
14283 && can_create_pseudo_p ()"
14288 if (memory_operand (operands[0], VOIDmode))
14289 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14292 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14293 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14298 [(set_attr "type" "fpspc")
14299 (set_attr "mode" "DI")])
14301 (define_insn "fistdi2"
14302 [(set (match_operand:DI 0 "memory_operand" "=m")
14303 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14305 (clobber (match_scratch:XF 2 "=&1f"))]
14306 "TARGET_USE_FANCY_MATH_387"
14307 "* return output_fix_trunc (insn, operands, false);"
14308 [(set_attr "type" "fpspc")
14309 (set_attr "mode" "DI")])
14311 (define_insn "fistdi2_with_temp"
14312 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14313 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14315 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14316 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14317 "TARGET_USE_FANCY_MATH_387"
14319 [(set_attr "type" "fpspc")
14320 (set_attr "mode" "DI")])
14323 [(set (match_operand:DI 0 "register_operand")
14324 (unspec:DI [(match_operand:XF 1 "register_operand")]
14326 (clobber (match_operand:DI 2 "memory_operand"))
14327 (clobber (match_scratch 3))]
14329 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14330 (clobber (match_dup 3))])
14331 (set (match_dup 0) (match_dup 2))])
14334 [(set (match_operand:DI 0 "memory_operand")
14335 (unspec:DI [(match_operand:XF 1 "register_operand")]
14337 (clobber (match_operand:DI 2 "memory_operand"))
14338 (clobber (match_scratch 3))]
14340 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14341 (clobber (match_dup 3))])])
14343 (define_insn_and_split "*fist<mode>2_1"
14344 [(set (match_operand:SWI24 0 "register_operand")
14345 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14347 "TARGET_USE_FANCY_MATH_387
14348 && can_create_pseudo_p ()"
14353 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14354 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14358 [(set_attr "type" "fpspc")
14359 (set_attr "mode" "<MODE>")])
14361 (define_insn "fist<mode>2"
14362 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14363 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14365 "TARGET_USE_FANCY_MATH_387"
14366 "* return output_fix_trunc (insn, operands, false);"
14367 [(set_attr "type" "fpspc")
14368 (set_attr "mode" "<MODE>")])
14370 (define_insn "fist<mode>2_with_temp"
14371 [(set (match_operand:SWI24 0 "register_operand" "=r")
14372 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14374 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14375 "TARGET_USE_FANCY_MATH_387"
14377 [(set_attr "type" "fpspc")
14378 (set_attr "mode" "<MODE>")])
14381 [(set (match_operand:SWI24 0 "register_operand")
14382 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14384 (clobber (match_operand:SWI24 2 "memory_operand"))]
14386 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14387 (set (match_dup 0) (match_dup 2))])
14390 [(set (match_operand:SWI24 0 "memory_operand")
14391 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14393 (clobber (match_operand:SWI24 2 "memory_operand"))]
14395 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14397 (define_expand "lrintxf<mode>2"
14398 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
14399 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
14401 "TARGET_USE_FANCY_MATH_387")
14403 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
14404 [(set (match_operand:SWI48 0 "nonimmediate_operand")
14405 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
14406 UNSPEC_FIX_NOTRUNC))]
14407 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
14409 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14410 [(match_operand:SWI248x 0 "nonimmediate_operand")
14411 (match_operand:X87MODEF 1 "register_operand")]
14412 "(TARGET_USE_FANCY_MATH_387
14413 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14414 || TARGET_MIX_SSE_I387)
14415 && flag_unsafe_math_optimizations)
14416 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14417 && <SWI248x:MODE>mode != HImode
14418 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14419 && !flag_trapping_math && !flag_rounding_math)"
14421 if (optimize_insn_for_size_p ())
14424 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14425 && <SWI248x:MODE>mode != HImode
14426 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14427 && !flag_trapping_math && !flag_rounding_math)
14428 ix86_expand_lround (operands[0], operands[1]);
14430 ix86_emit_i387_round (operands[0], operands[1]);
14434 (define_int_iterator FRNDINT_ROUNDING
14435 [UNSPEC_FRNDINT_FLOOR
14436 UNSPEC_FRNDINT_CEIL
14437 UNSPEC_FRNDINT_TRUNC])
14439 (define_int_iterator FIST_ROUNDING
14443 ;; Base name for define_insn
14444 (define_int_attr rounding_insn
14445 [(UNSPEC_FRNDINT_FLOOR "floor")
14446 (UNSPEC_FRNDINT_CEIL "ceil")
14447 (UNSPEC_FRNDINT_TRUNC "btrunc")
14448 (UNSPEC_FIST_FLOOR "floor")
14449 (UNSPEC_FIST_CEIL "ceil")])
14451 (define_int_attr rounding
14452 [(UNSPEC_FRNDINT_FLOOR "floor")
14453 (UNSPEC_FRNDINT_CEIL "ceil")
14454 (UNSPEC_FRNDINT_TRUNC "trunc")
14455 (UNSPEC_FIST_FLOOR "floor")
14456 (UNSPEC_FIST_CEIL "ceil")])
14458 (define_int_attr ROUNDING
14459 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
14460 (UNSPEC_FRNDINT_CEIL "CEIL")
14461 (UNSPEC_FRNDINT_TRUNC "TRUNC")
14462 (UNSPEC_FIST_FLOOR "FLOOR")
14463 (UNSPEC_FIST_CEIL "CEIL")])
14465 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14466 (define_insn_and_split "frndintxf2_<rounding>"
14467 [(set (match_operand:XF 0 "register_operand")
14468 (unspec:XF [(match_operand:XF 1 "register_operand")]
14470 (clobber (reg:CC FLAGS_REG))]
14471 "TARGET_USE_FANCY_MATH_387
14472 && flag_unsafe_math_optimizations
14473 && can_create_pseudo_p ()"
14478 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
14480 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14481 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
14483 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
14484 operands[2], operands[3]));
14487 [(set_attr "type" "frndint")
14488 (set_attr "i387_cw" "<rounding>")
14489 (set_attr "mode" "XF")])
14491 (define_insn "frndintxf2_<rounding>_i387"
14492 [(set (match_operand:XF 0 "register_operand" "=f")
14493 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14495 (use (match_operand:HI 2 "memory_operand" "m"))
14496 (use (match_operand:HI 3 "memory_operand" "m"))]
14497 "TARGET_USE_FANCY_MATH_387
14498 && flag_unsafe_math_optimizations"
14499 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14500 [(set_attr "type" "frndint")
14501 (set_attr "i387_cw" "<rounding>")
14502 (set_attr "mode" "XF")])
14504 (define_expand "<rounding_insn>xf2"
14505 [(parallel [(set (match_operand:XF 0 "register_operand")
14506 (unspec:XF [(match_operand:XF 1 "register_operand")]
14508 (clobber (reg:CC FLAGS_REG))])]
14509 "TARGET_USE_FANCY_MATH_387
14510 && flag_unsafe_math_optimizations
14511 && !optimize_insn_for_size_p ()")
14513 (define_expand "<rounding_insn><mode>2"
14514 [(parallel [(set (match_operand:MODEF 0 "register_operand")
14515 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
14517 (clobber (reg:CC FLAGS_REG))])]
14518 "(TARGET_USE_FANCY_MATH_387
14519 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14520 || TARGET_MIX_SSE_I387)
14521 && flag_unsafe_math_optimizations)
14522 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14523 && !flag_trapping_math)"
14525 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14526 && !flag_trapping_math)
14529 emit_insn (gen_sse4_1_round<mode>2
14530 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
14531 else if (optimize_insn_for_size_p ())
14533 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14535 if (ROUND_<ROUNDING> == ROUND_FLOOR)
14536 ix86_expand_floorceil (operands[0], operands[1], true);
14537 else if (ROUND_<ROUNDING> == ROUND_CEIL)
14538 ix86_expand_floorceil (operands[0], operands[1], false);
14539 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
14540 ix86_expand_trunc (operands[0], operands[1]);
14542 gcc_unreachable ();
14546 if (ROUND_<ROUNDING> == ROUND_FLOOR)
14547 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
14548 else if (ROUND_<ROUNDING> == ROUND_CEIL)
14549 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
14550 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
14551 ix86_expand_truncdf_32 (operands[0], operands[1]);
14553 gcc_unreachable ();
14560 if (optimize_insn_for_size_p ())
14563 op0 = gen_reg_rtx (XFmode);
14564 op1 = gen_reg_rtx (XFmode);
14565 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14566 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
14568 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14573 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14574 (define_insn_and_split "frndintxf2_mask_pm"
14575 [(set (match_operand:XF 0 "register_operand")
14576 (unspec:XF [(match_operand:XF 1 "register_operand")]
14577 UNSPEC_FRNDINT_MASK_PM))
14578 (clobber (reg:CC FLAGS_REG))]
14579 "TARGET_USE_FANCY_MATH_387
14580 && flag_unsafe_math_optimizations
14581 && can_create_pseudo_p ()"
14586 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
14588 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14589 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
14591 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
14592 operands[2], operands[3]));
14595 [(set_attr "type" "frndint")
14596 (set_attr "i387_cw" "mask_pm")
14597 (set_attr "mode" "XF")])
14599 (define_insn "frndintxf2_mask_pm_i387"
14600 [(set (match_operand:XF 0 "register_operand" "=f")
14601 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14602 UNSPEC_FRNDINT_MASK_PM))
14603 (use (match_operand:HI 2 "memory_operand" "m"))
14604 (use (match_operand:HI 3 "memory_operand" "m"))]
14605 "TARGET_USE_FANCY_MATH_387
14606 && flag_unsafe_math_optimizations"
14607 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
14608 [(set_attr "type" "frndint")
14609 (set_attr "i387_cw" "mask_pm")
14610 (set_attr "mode" "XF")])
14612 (define_expand "nearbyintxf2"
14613 [(parallel [(set (match_operand:XF 0 "register_operand")
14614 (unspec:XF [(match_operand:XF 1 "register_operand")]
14615 UNSPEC_FRNDINT_MASK_PM))
14616 (clobber (reg:CC FLAGS_REG))])]
14617 "TARGET_USE_FANCY_MATH_387
14618 && flag_unsafe_math_optimizations")
14620 (define_expand "nearbyint<mode>2"
14621 [(use (match_operand:MODEF 0 "register_operand"))
14622 (use (match_operand:MODEF 1 "register_operand"))]
14623 "TARGET_USE_FANCY_MATH_387
14624 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14625 || TARGET_MIX_SSE_I387)
14626 && flag_unsafe_math_optimizations"
14628 rtx op0 = gen_reg_rtx (XFmode);
14629 rtx op1 = gen_reg_rtx (XFmode);
14631 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14632 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
14634 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14638 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14639 (define_insn_and_split "*fist<mode>2_<rounding>_1"
14640 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
14641 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
14643 (clobber (reg:CC FLAGS_REG))]
14644 "TARGET_USE_FANCY_MATH_387
14645 && flag_unsafe_math_optimizations
14646 && can_create_pseudo_p ()"
14651 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
14653 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14654 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
14655 if (memory_operand (operands[0], VOIDmode))
14656 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
14657 operands[2], operands[3]));
14660 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14661 emit_insn (gen_fist<mode>2_<rounding>_with_temp
14662 (operands[0], operands[1], operands[2],
14663 operands[3], operands[4]));
14667 [(set_attr "type" "fistp")
14668 (set_attr "i387_cw" "<rounding>")
14669 (set_attr "mode" "<MODE>")])
14671 (define_insn "fistdi2_<rounding>"
14672 [(set (match_operand:DI 0 "memory_operand" "=m")
14673 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14675 (use (match_operand:HI 2 "memory_operand" "m"))
14676 (use (match_operand:HI 3 "memory_operand" "m"))
14677 (clobber (match_scratch:XF 4 "=&1f"))]
14678 "TARGET_USE_FANCY_MATH_387
14679 && flag_unsafe_math_optimizations"
14680 "* return output_fix_trunc (insn, operands, false);"
14681 [(set_attr "type" "fistp")
14682 (set_attr "i387_cw" "<rounding>")
14683 (set_attr "mode" "DI")])
14685 (define_insn "fistdi2_<rounding>_with_temp"
14686 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14687 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14689 (use (match_operand:HI 2 "memory_operand" "m,m"))
14690 (use (match_operand:HI 3 "memory_operand" "m,m"))
14691 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14692 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14693 "TARGET_USE_FANCY_MATH_387
14694 && flag_unsafe_math_optimizations"
14696 [(set_attr "type" "fistp")
14697 (set_attr "i387_cw" "<rounding>")
14698 (set_attr "mode" "DI")])
14701 [(set (match_operand:DI 0 "register_operand")
14702 (unspec:DI [(match_operand:XF 1 "register_operand")]
14704 (use (match_operand:HI 2 "memory_operand"))
14705 (use (match_operand:HI 3 "memory_operand"))
14706 (clobber (match_operand:DI 4 "memory_operand"))
14707 (clobber (match_scratch 5))]
14709 [(parallel [(set (match_dup 4)
14710 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
14711 (use (match_dup 2))
14712 (use (match_dup 3))
14713 (clobber (match_dup 5))])
14714 (set (match_dup 0) (match_dup 4))])
14717 [(set (match_operand:DI 0 "memory_operand")
14718 (unspec:DI [(match_operand:XF 1 "register_operand")]
14720 (use (match_operand:HI 2 "memory_operand"))
14721 (use (match_operand:HI 3 "memory_operand"))
14722 (clobber (match_operand:DI 4 "memory_operand"))
14723 (clobber (match_scratch 5))]
14725 [(parallel [(set (match_dup 0)
14726 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
14727 (use (match_dup 2))
14728 (use (match_dup 3))
14729 (clobber (match_dup 5))])])
14731 (define_insn "fist<mode>2_<rounding>"
14732 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14733 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14735 (use (match_operand:HI 2 "memory_operand" "m"))
14736 (use (match_operand:HI 3 "memory_operand" "m"))]
14737 "TARGET_USE_FANCY_MATH_387
14738 && flag_unsafe_math_optimizations"
14739 "* return output_fix_trunc (insn, operands, false);"
14740 [(set_attr "type" "fistp")
14741 (set_attr "i387_cw" "<rounding>")
14742 (set_attr "mode" "<MODE>")])
14744 (define_insn "fist<mode>2_<rounding>_with_temp"
14745 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
14746 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
14748 (use (match_operand:HI 2 "memory_operand" "m,m"))
14749 (use (match_operand:HI 3 "memory_operand" "m,m"))
14750 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
14751 "TARGET_USE_FANCY_MATH_387
14752 && flag_unsafe_math_optimizations"
14754 [(set_attr "type" "fistp")
14755 (set_attr "i387_cw" "<rounding>")
14756 (set_attr "mode" "<MODE>")])
14759 [(set (match_operand:SWI24 0 "register_operand")
14760 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14762 (use (match_operand:HI 2 "memory_operand"))
14763 (use (match_operand:HI 3 "memory_operand"))
14764 (clobber (match_operand:SWI24 4 "memory_operand"))]
14766 [(parallel [(set (match_dup 4)
14767 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
14768 (use (match_dup 2))
14769 (use (match_dup 3))])
14770 (set (match_dup 0) (match_dup 4))])
14773 [(set (match_operand:SWI24 0 "memory_operand")
14774 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14776 (use (match_operand:HI 2 "memory_operand"))
14777 (use (match_operand:HI 3 "memory_operand"))
14778 (clobber (match_operand:SWI24 4 "memory_operand"))]
14780 [(parallel [(set (match_dup 0)
14781 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
14782 (use (match_dup 2))
14783 (use (match_dup 3))])])
14785 (define_expand "l<rounding_insn>xf<mode>2"
14786 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
14787 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
14789 (clobber (reg:CC FLAGS_REG))])]
14790 "TARGET_USE_FANCY_MATH_387
14791 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14792 && flag_unsafe_math_optimizations")
14794 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
14795 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
14796 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
14798 (clobber (reg:CC FLAGS_REG))])]
14799 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14800 && !flag_trapping_math"
14802 if (TARGET_64BIT && optimize_insn_for_size_p ())
14805 if (ROUND_<ROUNDING> == ROUND_FLOOR)
14806 ix86_expand_lfloorceil (operands[0], operands[1], true);
14807 else if (ROUND_<ROUNDING> == ROUND_CEIL)
14808 ix86_expand_lfloorceil (operands[0], operands[1], false);
14810 gcc_unreachable ();
14815 (define_insn "fxam<mode>2_i387"
14816 [(set (match_operand:HI 0 "register_operand" "=a")
14818 [(match_operand:X87MODEF 1 "register_operand" "f")]
14820 "TARGET_USE_FANCY_MATH_387"
14821 "fxam\n\tfnstsw\t%0"
14822 [(set_attr "type" "multi")
14823 (set_attr "length" "4")
14824 (set_attr "unit" "i387")
14825 (set_attr "mode" "<MODE>")])
14827 (define_insn_and_split "fxam<mode>2_i387_with_temp"
14828 [(set (match_operand:HI 0 "register_operand")
14830 [(match_operand:MODEF 1 "memory_operand")]
14832 "TARGET_USE_FANCY_MATH_387
14833 && can_create_pseudo_p ()"
14836 [(set (match_dup 2)(match_dup 1))
14838 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
14840 operands[2] = gen_reg_rtx (<MODE>mode);
14842 MEM_VOLATILE_P (operands[1]) = 1;
14844 [(set_attr "type" "multi")
14845 (set_attr "unit" "i387")
14846 (set_attr "mode" "<MODE>")])
14848 (define_expand "isinfxf2"
14849 [(use (match_operand:SI 0 "register_operand"))
14850 (use (match_operand:XF 1 "register_operand"))]
14851 "TARGET_USE_FANCY_MATH_387
14852 && TARGET_C99_FUNCTIONS"
14854 rtx mask = GEN_INT (0x45);
14855 rtx val = GEN_INT (0x05);
14859 rtx scratch = gen_reg_rtx (HImode);
14860 rtx res = gen_reg_rtx (QImode);
14862 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
14864 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
14865 emit_insn (gen_cmpqi_ext_3 (scratch, val));
14866 cond = gen_rtx_fmt_ee (EQ, QImode,
14867 gen_rtx_REG (CCmode, FLAGS_REG),
14869 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
14870 emit_insn (gen_zero_extendqisi2 (operands[0], res));
14874 (define_expand "isinf<mode>2"
14875 [(use (match_operand:SI 0 "register_operand"))
14876 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
14877 "TARGET_USE_FANCY_MATH_387
14878 && TARGET_C99_FUNCTIONS
14879 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14881 rtx mask = GEN_INT (0x45);
14882 rtx val = GEN_INT (0x05);
14886 rtx scratch = gen_reg_rtx (HImode);
14887 rtx res = gen_reg_rtx (QImode);
14889 /* Remove excess precision by forcing value through memory. */
14890 if (memory_operand (operands[1], VOIDmode))
14891 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
14894 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14896 emit_move_insn (temp, operands[1]);
14897 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
14900 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
14901 emit_insn (gen_cmpqi_ext_3 (scratch, val));
14902 cond = gen_rtx_fmt_ee (EQ, QImode,
14903 gen_rtx_REG (CCmode, FLAGS_REG),
14905 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
14906 emit_insn (gen_zero_extendqisi2 (operands[0], res));
14910 (define_expand "signbitxf2"
14911 [(use (match_operand:SI 0 "register_operand"))
14912 (use (match_operand:XF 1 "register_operand"))]
14913 "TARGET_USE_FANCY_MATH_387"
14915 rtx scratch = gen_reg_rtx (HImode);
14917 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
14918 emit_insn (gen_andsi3 (operands[0],
14919 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
14923 (define_insn "movmsk_df"
14924 [(set (match_operand:SI 0 "register_operand" "=r")
14926 [(match_operand:DF 1 "register_operand" "x")]
14928 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
14929 "%vmovmskpd\t{%1, %0|%0, %1}"
14930 [(set_attr "type" "ssemov")
14931 (set_attr "prefix" "maybe_vex")
14932 (set_attr "mode" "DF")])
14934 ;; Use movmskpd in SSE mode to avoid store forwarding stall
14935 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
14936 (define_expand "signbitdf2"
14937 [(use (match_operand:SI 0 "register_operand"))
14938 (use (match_operand:DF 1 "register_operand"))]
14939 "TARGET_USE_FANCY_MATH_387
14940 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14942 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
14944 emit_insn (gen_movmsk_df (operands[0], operands[1]));
14945 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
14949 rtx scratch = gen_reg_rtx (HImode);
14951 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
14952 emit_insn (gen_andsi3 (operands[0],
14953 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
14958 (define_expand "signbitsf2"
14959 [(use (match_operand:SI 0 "register_operand"))
14960 (use (match_operand:SF 1 "register_operand"))]
14961 "TARGET_USE_FANCY_MATH_387
14962 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
14964 rtx scratch = gen_reg_rtx (HImode);
14966 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
14967 emit_insn (gen_andsi3 (operands[0],
14968 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
14972 ;; Block operation instructions
14975 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
14978 [(set_attr "length" "1")
14979 (set_attr "length_immediate" "0")
14980 (set_attr "modrm" "0")])
14982 (define_expand "movmem<mode>"
14983 [(use (match_operand:BLK 0 "memory_operand"))
14984 (use (match_operand:BLK 1 "memory_operand"))
14985 (use (match_operand:SWI48 2 "nonmemory_operand"))
14986 (use (match_operand:SWI48 3 "const_int_operand"))
14987 (use (match_operand:SI 4 "const_int_operand"))
14988 (use (match_operand:SI 5 "const_int_operand"))]
14991 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
14992 operands[4], operands[5]))
14998 ;; Most CPUs don't like single string operations
14999 ;; Handle this case here to simplify previous expander.
15001 (define_expand "strmov"
15002 [(set (match_dup 4) (match_operand 3 "memory_operand"))
15003 (set (match_operand 1 "memory_operand") (match_dup 4))
15004 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
15005 (clobber (reg:CC FLAGS_REG))])
15006 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
15007 (clobber (reg:CC FLAGS_REG))])]
15010 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15012 /* If .md ever supports :P for Pmode, these can be directly
15013 in the pattern above. */
15014 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15015 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15017 /* Can't use this if the user has appropriated esi or edi. */
15018 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15019 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15021 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15022 operands[2], operands[3],
15023 operands[5], operands[6]));
15027 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15030 (define_expand "strmov_singleop"
15031 [(parallel [(set (match_operand 1 "memory_operand")
15032 (match_operand 3 "memory_operand"))
15033 (set (match_operand 0 "register_operand")
15035 (set (match_operand 2 "register_operand")
15036 (match_operand 5))])]
15038 "ix86_current_function_needs_cld = 1;")
15040 (define_insn "*strmovdi_rex_1"
15041 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15042 (mem:DI (match_operand:P 3 "register_operand" "1")))
15043 (set (match_operand:P 0 "register_operand" "=D")
15044 (plus:P (match_dup 2)
15046 (set (match_operand:P 1 "register_operand" "=S")
15047 (plus:P (match_dup 3)
15050 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15052 [(set_attr "type" "str")
15053 (set_attr "memory" "both")
15054 (set_attr "mode" "DI")])
15056 (define_insn "*strmovsi_1"
15057 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15058 (mem:SI (match_operand:P 3 "register_operand" "1")))
15059 (set (match_operand:P 0 "register_operand" "=D")
15060 (plus:P (match_dup 2)
15062 (set (match_operand:P 1 "register_operand" "=S")
15063 (plus:P (match_dup 3)
15065 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15067 [(set_attr "type" "str")
15068 (set_attr "memory" "both")
15069 (set_attr "mode" "SI")])
15071 (define_insn "*strmovhi_1"
15072 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15073 (mem:HI (match_operand:P 3 "register_operand" "1")))
15074 (set (match_operand:P 0 "register_operand" "=D")
15075 (plus:P (match_dup 2)
15077 (set (match_operand:P 1 "register_operand" "=S")
15078 (plus:P (match_dup 3)
15080 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15082 [(set_attr "type" "str")
15083 (set_attr "memory" "both")
15084 (set_attr "mode" "HI")])
15086 (define_insn "*strmovqi_1"
15087 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15088 (mem:QI (match_operand:P 3 "register_operand" "1")))
15089 (set (match_operand:P 0 "register_operand" "=D")
15090 (plus:P (match_dup 2)
15092 (set (match_operand:P 1 "register_operand" "=S")
15093 (plus:P (match_dup 3)
15095 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15097 [(set_attr "type" "str")
15098 (set_attr "memory" "both")
15099 (set (attr "prefix_rex")
15101 (match_test "<P:MODE>mode == DImode")
15103 (const_string "*")))
15104 (set_attr "mode" "QI")])
15106 (define_expand "rep_mov"
15107 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
15108 (set (match_operand 0 "register_operand")
15110 (set (match_operand 2 "register_operand")
15112 (set (match_operand 1 "memory_operand")
15113 (match_operand 3 "memory_operand"))
15114 (use (match_dup 4))])]
15116 "ix86_current_function_needs_cld = 1;")
15118 (define_insn "*rep_movdi_rex64"
15119 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15120 (set (match_operand:P 0 "register_operand" "=D")
15121 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15123 (match_operand:P 3 "register_operand" "0")))
15124 (set (match_operand:P 1 "register_operand" "=S")
15125 (plus:P (ashift:P (match_dup 5) (const_int 3))
15126 (match_operand:P 4 "register_operand" "1")))
15127 (set (mem:BLK (match_dup 3))
15128 (mem:BLK (match_dup 4)))
15129 (use (match_dup 5))]
15131 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15133 [(set_attr "type" "str")
15134 (set_attr "prefix_rep" "1")
15135 (set_attr "memory" "both")
15136 (set_attr "mode" "DI")])
15138 (define_insn "*rep_movsi"
15139 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15140 (set (match_operand:P 0 "register_operand" "=D")
15141 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15143 (match_operand:P 3 "register_operand" "0")))
15144 (set (match_operand:P 1 "register_operand" "=S")
15145 (plus:P (ashift:P (match_dup 5) (const_int 2))
15146 (match_operand:P 4 "register_operand" "1")))
15147 (set (mem:BLK (match_dup 3))
15148 (mem:BLK (match_dup 4)))
15149 (use (match_dup 5))]
15150 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15151 "%^rep{%;} movs{l|d}"
15152 [(set_attr "type" "str")
15153 (set_attr "prefix_rep" "1")
15154 (set_attr "memory" "both")
15155 (set_attr "mode" "SI")])
15157 (define_insn "*rep_movqi"
15158 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15159 (set (match_operand:P 0 "register_operand" "=D")
15160 (plus:P (match_operand:P 3 "register_operand" "0")
15161 (match_operand:P 5 "register_operand" "2")))
15162 (set (match_operand:P 1 "register_operand" "=S")
15163 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15164 (set (mem:BLK (match_dup 3))
15165 (mem:BLK (match_dup 4)))
15166 (use (match_dup 5))]
15167 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15169 [(set_attr "type" "str")
15170 (set_attr "prefix_rep" "1")
15171 (set_attr "memory" "both")
15172 (set_attr "mode" "QI")])
15174 (define_expand "setmem<mode>"
15175 [(use (match_operand:BLK 0 "memory_operand"))
15176 (use (match_operand:SWI48 1 "nonmemory_operand"))
15177 (use (match_operand:QI 2 "nonmemory_operand"))
15178 (use (match_operand 3 "const_int_operand"))
15179 (use (match_operand:SI 4 "const_int_operand"))
15180 (use (match_operand:SI 5 "const_int_operand"))]
15183 if (ix86_expand_setmem (operands[0], operands[1],
15184 operands[2], operands[3],
15185 operands[4], operands[5]))
15191 ;; Most CPUs don't like single string operations
15192 ;; Handle this case here to simplify previous expander.
15194 (define_expand "strset"
15195 [(set (match_operand 1 "memory_operand")
15196 (match_operand 2 "register_operand"))
15197 (parallel [(set (match_operand 0 "register_operand")
15199 (clobber (reg:CC FLAGS_REG))])]
15202 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15203 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15205 /* If .md ever supports :P for Pmode, this can be directly
15206 in the pattern above. */
15207 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15208 GEN_INT (GET_MODE_SIZE (GET_MODE
15210 /* Can't use this if the user has appropriated eax or edi. */
15211 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15212 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15214 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15220 (define_expand "strset_singleop"
15221 [(parallel [(set (match_operand 1 "memory_operand")
15222 (match_operand 2 "register_operand"))
15223 (set (match_operand 0 "register_operand")
15225 (unspec [(const_int 0)] UNSPEC_STOS)])]
15227 "ix86_current_function_needs_cld = 1;")
15229 (define_insn "*strsetdi_rex_1"
15230 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
15231 (match_operand:DI 2 "register_operand" "a"))
15232 (set (match_operand:P 0 "register_operand" "=D")
15233 (plus:P (match_dup 1)
15235 (unspec [(const_int 0)] UNSPEC_STOS)]
15237 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15239 [(set_attr "type" "str")
15240 (set_attr "memory" "store")
15241 (set_attr "mode" "DI")])
15243 (define_insn "*strsetsi_1"
15244 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15245 (match_operand:SI 2 "register_operand" "a"))
15246 (set (match_operand:P 0 "register_operand" "=D")
15247 (plus:P (match_dup 1)
15249 (unspec [(const_int 0)] UNSPEC_STOS)]
15250 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15252 [(set_attr "type" "str")
15253 (set_attr "memory" "store")
15254 (set_attr "mode" "SI")])
15256 (define_insn "*strsethi_1"
15257 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15258 (match_operand:HI 2 "register_operand" "a"))
15259 (set (match_operand:P 0 "register_operand" "=D")
15260 (plus:P (match_dup 1)
15262 (unspec [(const_int 0)] UNSPEC_STOS)]
15263 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15265 [(set_attr "type" "str")
15266 (set_attr "memory" "store")
15267 (set_attr "mode" "HI")])
15269 (define_insn "*strsetqi_1"
15270 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15271 (match_operand:QI 2 "register_operand" "a"))
15272 (set (match_operand:P 0 "register_operand" "=D")
15273 (plus:P (match_dup 1)
15275 (unspec [(const_int 0)] UNSPEC_STOS)]
15276 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15278 [(set_attr "type" "str")
15279 (set_attr "memory" "store")
15280 (set (attr "prefix_rex")
15282 (match_test "<P:MODE>mode == DImode")
15284 (const_string "*")))
15285 (set_attr "mode" "QI")])
15287 (define_expand "rep_stos"
15288 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
15289 (set (match_operand 0 "register_operand")
15291 (set (match_operand 2 "memory_operand") (const_int 0))
15292 (use (match_operand 3 "register_operand"))
15293 (use (match_dup 1))])]
15295 "ix86_current_function_needs_cld = 1;")
15297 (define_insn "*rep_stosdi_rex64"
15298 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15299 (set (match_operand:P 0 "register_operand" "=D")
15300 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15302 (match_operand:P 3 "register_operand" "0")))
15303 (set (mem:BLK (match_dup 3))
15305 (use (match_operand:DI 2 "register_operand" "a"))
15306 (use (match_dup 4))]
15308 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15310 [(set_attr "type" "str")
15311 (set_attr "prefix_rep" "1")
15312 (set_attr "memory" "store")
15313 (set_attr "mode" "DI")])
15315 (define_insn "*rep_stossi"
15316 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15317 (set (match_operand:P 0 "register_operand" "=D")
15318 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15320 (match_operand:P 3 "register_operand" "0")))
15321 (set (mem:BLK (match_dup 3))
15323 (use (match_operand:SI 2 "register_operand" "a"))
15324 (use (match_dup 4))]
15325 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15326 "%^rep{%;} stos{l|d}"
15327 [(set_attr "type" "str")
15328 (set_attr "prefix_rep" "1")
15329 (set_attr "memory" "store")
15330 (set_attr "mode" "SI")])
15332 (define_insn "*rep_stosqi"
15333 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15334 (set (match_operand:P 0 "register_operand" "=D")
15335 (plus:P (match_operand:P 3 "register_operand" "0")
15336 (match_operand:P 4 "register_operand" "1")))
15337 (set (mem:BLK (match_dup 3))
15339 (use (match_operand:QI 2 "register_operand" "a"))
15340 (use (match_dup 4))]
15341 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15343 [(set_attr "type" "str")
15344 (set_attr "prefix_rep" "1")
15345 (set_attr "memory" "store")
15346 (set (attr "prefix_rex")
15348 (match_test "<P:MODE>mode == DImode")
15350 (const_string "*")))
15351 (set_attr "mode" "QI")])
15353 (define_expand "cmpstrnsi"
15354 [(set (match_operand:SI 0 "register_operand")
15355 (compare:SI (match_operand:BLK 1 "general_operand")
15356 (match_operand:BLK 2 "general_operand")))
15357 (use (match_operand 3 "general_operand"))
15358 (use (match_operand 4 "immediate_operand"))]
15361 rtx addr1, addr2, out, outlow, count, countreg, align;
15363 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15366 /* Can't use this if the user has appropriated ecx, esi or edi. */
15367 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
15372 out = gen_reg_rtx (SImode);
15374 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
15375 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
15376 if (addr1 != XEXP (operands[1], 0))
15377 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15378 if (addr2 != XEXP (operands[2], 0))
15379 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15381 count = operands[3];
15382 countreg = ix86_zero_extend_to_Pmode (count);
15384 /* %%% Iff we are testing strict equality, we can use known alignment
15385 to good advantage. This may be possible with combine, particularly
15386 once cc0 is dead. */
15387 align = operands[4];
15389 if (CONST_INT_P (count))
15391 if (INTVAL (count) == 0)
15393 emit_move_insn (operands[0], const0_rtx);
15396 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15397 operands[1], operands[2]));
15401 rtx (*gen_cmp) (rtx, rtx);
15403 gen_cmp = (TARGET_64BIT
15404 ? gen_cmpdi_1 : gen_cmpsi_1);
15406 emit_insn (gen_cmp (countreg, countreg));
15407 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15408 operands[1], operands[2]));
15411 outlow = gen_lowpart (QImode, out);
15412 emit_insn (gen_cmpintqi (outlow));
15413 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15415 if (operands[0] != out)
15416 emit_move_insn (operands[0], out);
15421 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15423 (define_expand "cmpintqi"
15424 [(set (match_dup 1)
15425 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15427 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15428 (parallel [(set (match_operand:QI 0 "register_operand")
15429 (minus:QI (match_dup 1)
15431 (clobber (reg:CC FLAGS_REG))])]
15434 operands[1] = gen_reg_rtx (QImode);
15435 operands[2] = gen_reg_rtx (QImode);
15438 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15439 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
15441 (define_expand "cmpstrnqi_nz_1"
15442 [(parallel [(set (reg:CC FLAGS_REG)
15443 (compare:CC (match_operand 4 "memory_operand")
15444 (match_operand 5 "memory_operand")))
15445 (use (match_operand 2 "register_operand"))
15446 (use (match_operand:SI 3 "immediate_operand"))
15447 (clobber (match_operand 0 "register_operand"))
15448 (clobber (match_operand 1 "register_operand"))
15449 (clobber (match_dup 2))])]
15451 "ix86_current_function_needs_cld = 1;")
15453 (define_insn "*cmpstrnqi_nz_1"
15454 [(set (reg:CC FLAGS_REG)
15455 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15456 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
15457 (use (match_operand:P 6 "register_operand" "2"))
15458 (use (match_operand:SI 3 "immediate_operand" "i"))
15459 (clobber (match_operand:P 0 "register_operand" "=S"))
15460 (clobber (match_operand:P 1 "register_operand" "=D"))
15461 (clobber (match_operand:P 2 "register_operand" "=c"))]
15462 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15464 [(set_attr "type" "str")
15465 (set_attr "mode" "QI")
15466 (set (attr "prefix_rex")
15468 (match_test "<P:MODE>mode == DImode")
15470 (const_string "*")))
15471 (set_attr "prefix_rep" "1")])
15473 ;; The same, but the count is not known to not be zero.
15475 (define_expand "cmpstrnqi_1"
15476 [(parallel [(set (reg:CC FLAGS_REG)
15477 (if_then_else:CC (ne (match_operand 2 "register_operand")
15479 (compare:CC (match_operand 4 "memory_operand")
15480 (match_operand 5 "memory_operand"))
15482 (use (match_operand:SI 3 "immediate_operand"))
15483 (use (reg:CC FLAGS_REG))
15484 (clobber (match_operand 0 "register_operand"))
15485 (clobber (match_operand 1 "register_operand"))
15486 (clobber (match_dup 2))])]
15488 "ix86_current_function_needs_cld = 1;")
15490 (define_insn "*cmpstrnqi_1"
15491 [(set (reg:CC FLAGS_REG)
15492 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
15494 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15495 (mem:BLK (match_operand:P 5 "register_operand" "1")))
15497 (use (match_operand:SI 3 "immediate_operand" "i"))
15498 (use (reg:CC FLAGS_REG))
15499 (clobber (match_operand:P 0 "register_operand" "=S"))
15500 (clobber (match_operand:P 1 "register_operand" "=D"))
15501 (clobber (match_operand:P 2 "register_operand" "=c"))]
15502 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15504 [(set_attr "type" "str")
15505 (set_attr "mode" "QI")
15506 (set (attr "prefix_rex")
15508 (match_test "<P:MODE>mode == DImode")
15510 (const_string "*")))
15511 (set_attr "prefix_rep" "1")])
15513 (define_expand "strlen<mode>"
15514 [(set (match_operand:P 0 "register_operand")
15515 (unspec:P [(match_operand:BLK 1 "general_operand")
15516 (match_operand:QI 2 "immediate_operand")
15517 (match_operand 3 "immediate_operand")]
15521 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15527 (define_expand "strlenqi_1"
15528 [(parallel [(set (match_operand 0 "register_operand")
15530 (clobber (match_operand 1 "register_operand"))
15531 (clobber (reg:CC FLAGS_REG))])]
15533 "ix86_current_function_needs_cld = 1;")
15535 (define_insn "*strlenqi_1"
15536 [(set (match_operand:P 0 "register_operand" "=&c")
15537 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
15538 (match_operand:QI 2 "register_operand" "a")
15539 (match_operand:P 3 "immediate_operand" "i")
15540 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
15541 (clobber (match_operand:P 1 "register_operand" "=D"))
15542 (clobber (reg:CC FLAGS_REG))]
15543 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15544 "%^repnz{%;} scasb"
15545 [(set_attr "type" "str")
15546 (set_attr "mode" "QI")
15547 (set (attr "prefix_rex")
15549 (match_test "<P:MODE>mode == DImode")
15551 (const_string "*")))
15552 (set_attr "prefix_rep" "1")])
15554 ;; Peephole optimizations to clean up after cmpstrn*. This should be
15555 ;; handled in combine, but it is not currently up to the task.
15556 ;; When used for their truth value, the cmpstrn* expanders generate
15565 ;; The intermediate three instructions are unnecessary.
15567 ;; This one handles cmpstrn*_nz_1...
15570 (set (reg:CC FLAGS_REG)
15571 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
15572 (mem:BLK (match_operand 5 "register_operand"))))
15573 (use (match_operand 6 "register_operand"))
15574 (use (match_operand:SI 3 "immediate_operand"))
15575 (clobber (match_operand 0 "register_operand"))
15576 (clobber (match_operand 1 "register_operand"))
15577 (clobber (match_operand 2 "register_operand"))])
15578 (set (match_operand:QI 7 "register_operand")
15579 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15580 (set (match_operand:QI 8 "register_operand")
15581 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15582 (set (reg FLAGS_REG)
15583 (compare (match_dup 7) (match_dup 8)))
15585 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15587 (set (reg:CC FLAGS_REG)
15588 (compare:CC (mem:BLK (match_dup 4))
15589 (mem:BLK (match_dup 5))))
15590 (use (match_dup 6))
15591 (use (match_dup 3))
15592 (clobber (match_dup 0))
15593 (clobber (match_dup 1))
15594 (clobber (match_dup 2))])])
15596 ;; ...and this one handles cmpstrn*_1.
15599 (set (reg:CC FLAGS_REG)
15600 (if_then_else:CC (ne (match_operand 6 "register_operand")
15602 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
15603 (mem:BLK (match_operand 5 "register_operand")))
15605 (use (match_operand:SI 3 "immediate_operand"))
15606 (use (reg:CC FLAGS_REG))
15607 (clobber (match_operand 0 "register_operand"))
15608 (clobber (match_operand 1 "register_operand"))
15609 (clobber (match_operand 2 "register_operand"))])
15610 (set (match_operand:QI 7 "register_operand")
15611 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15612 (set (match_operand:QI 8 "register_operand")
15613 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15614 (set (reg FLAGS_REG)
15615 (compare (match_dup 7) (match_dup 8)))
15617 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15619 (set (reg:CC FLAGS_REG)
15620 (if_then_else:CC (ne (match_dup 6)
15622 (compare:CC (mem:BLK (match_dup 4))
15623 (mem:BLK (match_dup 5)))
15625 (use (match_dup 3))
15626 (use (reg:CC FLAGS_REG))
15627 (clobber (match_dup 0))
15628 (clobber (match_dup 1))
15629 (clobber (match_dup 2))])])
15631 ;; Conditional move instructions.
15633 (define_expand "mov<mode>cc"
15634 [(set (match_operand:SWIM 0 "register_operand")
15635 (if_then_else:SWIM (match_operand 1 "comparison_operator")
15636 (match_operand:SWIM 2 "<general_operand>")
15637 (match_operand:SWIM 3 "<general_operand>")))]
15639 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
15641 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
15642 ;; the register first winds up with `sbbl $0,reg', which is also weird.
15643 ;; So just document what we're doing explicitly.
15645 (define_expand "x86_mov<mode>cc_0_m1"
15647 [(set (match_operand:SWI48 0 "register_operand")
15648 (if_then_else:SWI48
15649 (match_operator:SWI48 2 "ix86_carry_flag_operator"
15650 [(match_operand 1 "flags_reg_operand")
15654 (clobber (reg:CC FLAGS_REG))])])
15656 (define_insn "*x86_mov<mode>cc_0_m1"
15657 [(set (match_operand:SWI48 0 "register_operand" "=r")
15658 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15659 [(reg FLAGS_REG) (const_int 0)])
15662 (clobber (reg:CC FLAGS_REG))]
15664 "sbb{<imodesuffix>}\t%0, %0"
15665 ; Since we don't have the proper number of operands for an alu insn,
15666 ; fill in all the blanks.
15667 [(set_attr "type" "alu")
15668 (set_attr "use_carry" "1")
15669 (set_attr "pent_pair" "pu")
15670 (set_attr "memory" "none")
15671 (set_attr "imm_disp" "false")
15672 (set_attr "mode" "<MODE>")
15673 (set_attr "length_immediate" "0")])
15675 (define_insn "*x86_mov<mode>cc_0_m1_se"
15676 [(set (match_operand:SWI48 0 "register_operand" "=r")
15677 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15678 [(reg FLAGS_REG) (const_int 0)])
15681 (clobber (reg:CC FLAGS_REG))]
15683 "sbb{<imodesuffix>}\t%0, %0"
15684 [(set_attr "type" "alu")
15685 (set_attr "use_carry" "1")
15686 (set_attr "pent_pair" "pu")
15687 (set_attr "memory" "none")
15688 (set_attr "imm_disp" "false")
15689 (set_attr "mode" "<MODE>")
15690 (set_attr "length_immediate" "0")])
15692 (define_insn "*x86_mov<mode>cc_0_m1_neg"
15693 [(set (match_operand:SWI48 0 "register_operand" "=r")
15694 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15695 [(reg FLAGS_REG) (const_int 0)])))
15696 (clobber (reg:CC FLAGS_REG))]
15698 "sbb{<imodesuffix>}\t%0, %0"
15699 [(set_attr "type" "alu")
15700 (set_attr "use_carry" "1")
15701 (set_attr "pent_pair" "pu")
15702 (set_attr "memory" "none")
15703 (set_attr "imm_disp" "false")
15704 (set_attr "mode" "<MODE>")
15705 (set_attr "length_immediate" "0")])
15707 (define_insn "*mov<mode>cc_noc"
15708 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
15709 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
15710 [(reg FLAGS_REG) (const_int 0)])
15711 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
15712 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
15713 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
15715 cmov%O2%C1\t{%2, %0|%0, %2}
15716 cmov%O2%c1\t{%3, %0|%0, %3}"
15717 [(set_attr "type" "icmov")
15718 (set_attr "mode" "<MODE>")])
15720 ;; Don't do conditional moves with memory inputs. This splitter helps
15721 ;; register starved x86_32 by forcing inputs into registers before reload.
15723 [(set (match_operand:SWI248 0 "register_operand")
15724 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
15725 [(reg FLAGS_REG) (const_int 0)])
15726 (match_operand:SWI248 2 "nonimmediate_operand")
15727 (match_operand:SWI248 3 "nonimmediate_operand")))]
15728 "!TARGET_64BIT && TARGET_CMOVE
15729 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
15730 && (MEM_P (operands[2]) || MEM_P (operands[3]))
15731 && can_create_pseudo_p ()
15732 && optimize_insn_for_speed_p ()"
15733 [(set (match_dup 0)
15734 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
15736 if (MEM_P (operands[2]))
15737 operands[2] = force_reg (<MODE>mode, operands[2]);
15738 if (MEM_P (operands[3]))
15739 operands[3] = force_reg (<MODE>mode, operands[3]);
15742 (define_insn "*movqicc_noc"
15743 [(set (match_operand:QI 0 "register_operand" "=r,r")
15744 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
15745 [(reg FLAGS_REG) (const_int 0)])
15746 (match_operand:QI 2 "register_operand" "r,0")
15747 (match_operand:QI 3 "register_operand" "0,r")))]
15748 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
15750 [(set_attr "type" "icmov")
15751 (set_attr "mode" "QI")])
15754 [(set (match_operand:SWI12 0 "register_operand")
15755 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
15756 [(reg FLAGS_REG) (const_int 0)])
15757 (match_operand:SWI12 2 "register_operand")
15758 (match_operand:SWI12 3 "register_operand")))]
15759 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
15760 && reload_completed"
15761 [(set (match_dup 0)
15762 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
15764 operands[0] = gen_lowpart (SImode, operands[0]);
15765 operands[2] = gen_lowpart (SImode, operands[2]);
15766 operands[3] = gen_lowpart (SImode, operands[3]);
15769 ;; Don't do conditional moves with memory inputs
15771 [(match_scratch:SWI248 2 "r")
15772 (set (match_operand:SWI248 0 "register_operand")
15773 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
15774 [(reg FLAGS_REG) (const_int 0)])
15776 (match_operand:SWI248 3 "memory_operand")))]
15777 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
15778 && optimize_insn_for_speed_p ()"
15779 [(set (match_dup 2) (match_dup 3))
15781 (if_then_else:SWI248 (match_dup 1) (match_dup 0) (match_dup 2)))])
15784 [(match_scratch:SWI248 2 "r")
15785 (set (match_operand:SWI248 0 "register_operand")
15786 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
15787 [(reg FLAGS_REG) (const_int 0)])
15788 (match_operand:SWI248 3 "memory_operand")
15790 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
15791 && optimize_insn_for_speed_p ()"
15792 [(set (match_dup 2) (match_dup 3))
15794 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 0)))])
15796 (define_expand "mov<mode>cc"
15797 [(set (match_operand:X87MODEF 0 "register_operand")
15798 (if_then_else:X87MODEF
15799 (match_operand 1 "comparison_operator")
15800 (match_operand:X87MODEF 2 "register_operand")
15801 (match_operand:X87MODEF 3 "register_operand")))]
15802 "(TARGET_80387 && TARGET_CMOVE)
15803 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15804 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
15806 (define_insn "*movxfcc_1"
15807 [(set (match_operand:XF 0 "register_operand" "=f,f")
15808 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
15809 [(reg FLAGS_REG) (const_int 0)])
15810 (match_operand:XF 2 "register_operand" "f,0")
15811 (match_operand:XF 3 "register_operand" "0,f")))]
15812 "TARGET_80387 && TARGET_CMOVE"
15814 fcmov%F1\t{%2, %0|%0, %2}
15815 fcmov%f1\t{%3, %0|%0, %3}"
15816 [(set_attr "type" "fcmov")
15817 (set_attr "mode" "XF")])
15819 (define_insn "*movdfcc_1"
15820 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
15821 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
15822 [(reg FLAGS_REG) (const_int 0)])
15823 (match_operand:DF 2 "nonimmediate_operand"
15825 (match_operand:DF 3 "nonimmediate_operand"
15826 "0 ,f,0 ,rm,0, rm")))]
15827 "TARGET_80387 && TARGET_CMOVE
15828 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
15830 fcmov%F1\t{%2, %0|%0, %2}
15831 fcmov%f1\t{%3, %0|%0, %3}
15834 cmov%O2%C1\t{%2, %0|%0, %2}
15835 cmov%O2%c1\t{%3, %0|%0, %3}"
15836 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
15837 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
15838 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
15841 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
15842 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
15843 [(reg FLAGS_REG) (const_int 0)])
15844 (match_operand:DF 2 "nonimmediate_operand")
15845 (match_operand:DF 3 "nonimmediate_operand")))]
15846 "!TARGET_64BIT && reload_completed"
15847 [(set (match_dup 2)
15848 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
15850 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
15852 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
15853 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
15856 (define_insn "*movsfcc_1_387"
15857 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
15858 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
15859 [(reg FLAGS_REG) (const_int 0)])
15860 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
15861 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
15862 "TARGET_80387 && TARGET_CMOVE
15863 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
15865 fcmov%F1\t{%2, %0|%0, %2}
15866 fcmov%f1\t{%3, %0|%0, %3}
15867 cmov%O2%C1\t{%2, %0|%0, %2}
15868 cmov%O2%c1\t{%3, %0|%0, %3}"
15869 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
15870 (set_attr "mode" "SF,SF,SI,SI")])
15872 ;; Don't do conditional moves with memory inputs. This splitter helps
15873 ;; register starved x86_32 by forcing inputs into registers before reload.
15875 [(set (match_operand:MODEF 0 "register_operand")
15876 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
15877 [(reg FLAGS_REG) (const_int 0)])
15878 (match_operand:MODEF 2 "nonimmediate_operand")
15879 (match_operand:MODEF 3 "nonimmediate_operand")))]
15880 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
15881 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
15882 && (MEM_P (operands[2]) || MEM_P (operands[3]))
15883 && can_create_pseudo_p ()
15884 && optimize_insn_for_speed_p ()"
15885 [(set (match_dup 0)
15886 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
15888 if (MEM_P (operands[2]))
15889 operands[2] = force_reg (<MODE>mode, operands[2]);
15890 if (MEM_P (operands[3]))
15891 operands[3] = force_reg (<MODE>mode, operands[3]);
15894 ;; Don't do conditional moves with memory inputs
15896 [(match_scratch:MODEF 2 "r")
15897 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
15898 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
15899 [(reg FLAGS_REG) (const_int 0)])
15901 (match_operand:MODEF 3 "memory_operand")))]
15902 "(<MODE>mode != DFmode || TARGET_64BIT)
15903 && TARGET_80387 && TARGET_CMOVE
15904 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
15905 && optimize_insn_for_speed_p ()"
15906 [(set (match_dup 2) (match_dup 3))
15908 (if_then_else:MODEF (match_dup 1) (match_dup 0) (match_dup 2)))])
15911 [(match_scratch:MODEF 2 "r")
15912 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
15913 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
15914 [(reg FLAGS_REG) (const_int 0)])
15915 (match_operand:MODEF 3 "memory_operand")
15917 "(<MODE>mode != DFmode || TARGET_64BIT)
15918 && TARGET_80387 && TARGET_CMOVE
15919 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
15920 && optimize_insn_for_speed_p ()"
15921 [(set (match_dup 2) (match_dup 3))
15923 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 0)))])
15925 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
15926 ;; the scalar versions to have only XMM registers as operands.
15928 ;; XOP conditional move
15929 (define_insn "*xop_pcmov_<mode>"
15930 [(set (match_operand:MODEF 0 "register_operand" "=x")
15931 (if_then_else:MODEF
15932 (match_operand:MODEF 1 "register_operand" "x")
15933 (match_operand:MODEF 2 "register_operand" "x")
15934 (match_operand:MODEF 3 "register_operand" "x")))]
15936 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
15937 [(set_attr "type" "sse4arg")])
15939 ;; These versions of the min/max patterns are intentionally ignorant of
15940 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
15941 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
15942 ;; are undefined in this condition, we're certain this is correct.
15944 (define_insn "<code><mode>3"
15945 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
15947 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
15948 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
15949 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15951 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
15952 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
15953 [(set_attr "isa" "noavx,avx")
15954 (set_attr "prefix" "orig,vex")
15955 (set_attr "type" "sseadd")
15956 (set_attr "mode" "<MODE>")])
15958 ;; These versions of the min/max patterns implement exactly the operations
15959 ;; min = (op1 < op2 ? op1 : op2)
15960 ;; max = (!(op1 < op2) ? op1 : op2)
15961 ;; Their operands are not commutative, and thus they may be used in the
15962 ;; presence of -0.0 and NaN.
15964 (define_int_iterator IEEE_MAXMIN
15968 (define_int_attr ieee_maxmin
15969 [(UNSPEC_IEEE_MAX "max")
15970 (UNSPEC_IEEE_MIN "min")])
15972 (define_insn "*ieee_s<ieee_maxmin><mode>3"
15973 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
15975 [(match_operand:MODEF 1 "register_operand" "0,x")
15976 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
15978 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15980 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
15981 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
15982 [(set_attr "isa" "noavx,avx")
15983 (set_attr "prefix" "orig,vex")
15984 (set_attr "type" "sseadd")
15985 (set_attr "mode" "<MODE>")])
15987 ;; Make two stack loads independent:
15989 ;; fld %st(0) -> fld bb
15990 ;; fmul bb fmul %st(1), %st
15992 ;; Actually we only match the last two instructions for simplicity.
15994 [(set (match_operand 0 "fp_register_operand")
15995 (match_operand 1 "fp_register_operand"))
15997 (match_operator 2 "binary_fp_operator"
15999 (match_operand 3 "memory_operand")]))]
16000 "REGNO (operands[0]) != REGNO (operands[1])"
16001 [(set (match_dup 0) (match_dup 3))
16002 (set (match_dup 0) (match_dup 4))]
16004 ;; The % modifier is not operational anymore in peephole2's, so we have to
16005 ;; swap the operands manually in the case of addition and multiplication.
16009 if (COMMUTATIVE_ARITH_P (operands[2]))
16010 op0 = operands[0], op1 = operands[1];
16012 op0 = operands[1], op1 = operands[0];
16014 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16015 GET_MODE (operands[2]),
16019 ;; Conditional addition patterns
16020 (define_expand "add<mode>cc"
16021 [(match_operand:SWI 0 "register_operand")
16022 (match_operand 1 "ordered_comparison_operator")
16023 (match_operand:SWI 2 "register_operand")
16024 (match_operand:SWI 3 "const_int_operand")]
16026 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16028 ;; Misc patterns (?)
16030 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16031 ;; Otherwise there will be nothing to keep
16033 ;; [(set (reg ebp) (reg esp))]
16034 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16035 ;; (clobber (eflags)]
16036 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16038 ;; in proper program order.
16040 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16041 [(set (match_operand:P 0 "register_operand" "=r,r")
16042 (plus:P (match_operand:P 1 "register_operand" "0,r")
16043 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16044 (clobber (reg:CC FLAGS_REG))
16045 (clobber (mem:BLK (scratch)))]
16048 switch (get_attr_type (insn))
16051 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16054 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16055 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16056 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16058 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16061 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16062 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16065 [(set (attr "type")
16066 (cond [(and (eq_attr "alternative" "0")
16067 (not (match_test "TARGET_OPT_AGU")))
16068 (const_string "alu")
16069 (match_operand:<MODE> 2 "const0_operand")
16070 (const_string "imov")
16072 (const_string "lea")))
16073 (set (attr "length_immediate")
16074 (cond [(eq_attr "type" "imov")
16076 (and (eq_attr "type" "alu")
16077 (match_operand 2 "const128_operand"))
16080 (const_string "*")))
16081 (set_attr "mode" "<MODE>")])
16083 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16084 [(set (match_operand:P 0 "register_operand" "=r")
16085 (minus:P (match_operand:P 1 "register_operand" "0")
16086 (match_operand:P 2 "register_operand" "r")))
16087 (clobber (reg:CC FLAGS_REG))
16088 (clobber (mem:BLK (scratch)))]
16090 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16091 [(set_attr "type" "alu")
16092 (set_attr "mode" "<MODE>")])
16094 (define_insn "allocate_stack_worker_probe_<mode>"
16095 [(set (match_operand:P 0 "register_operand" "=a")
16096 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16097 UNSPECV_STACK_PROBE))
16098 (clobber (reg:CC FLAGS_REG))]
16099 "ix86_target_stack_probe ()"
16100 "call\t___chkstk_ms"
16101 [(set_attr "type" "multi")
16102 (set_attr "length" "5")])
16104 (define_expand "allocate_stack"
16105 [(match_operand 0 "register_operand")
16106 (match_operand 1 "general_operand")]
16107 "ix86_target_stack_probe ()"
16111 #ifndef CHECK_STACK_LIMIT
16112 #define CHECK_STACK_LIMIT 0
16115 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16116 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16120 rtx (*insn) (rtx, rtx);
16122 x = copy_to_mode_reg (Pmode, operands[1]);
16124 insn = (TARGET_64BIT
16125 ? gen_allocate_stack_worker_probe_di
16126 : gen_allocate_stack_worker_probe_si);
16128 emit_insn (insn (x, x));
16131 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16132 stack_pointer_rtx, 0, OPTAB_DIRECT);
16134 if (x != stack_pointer_rtx)
16135 emit_move_insn (stack_pointer_rtx, x);
16137 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16141 ;; Use IOR for stack probes, this is shorter.
16142 (define_expand "probe_stack"
16143 [(match_operand 0 "memory_operand")]
16146 rtx (*gen_ior3) (rtx, rtx, rtx);
16148 gen_ior3 = (GET_MODE (operands[0]) == DImode
16149 ? gen_iordi3 : gen_iorsi3);
16151 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16155 (define_insn "adjust_stack_and_probe<mode>"
16156 [(set (match_operand:P 0 "register_operand" "=r")
16157 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16158 UNSPECV_PROBE_STACK_RANGE))
16159 (set (reg:P SP_REG)
16160 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16161 (clobber (reg:CC FLAGS_REG))
16162 (clobber (mem:BLK (scratch)))]
16164 "* return output_adjust_stack_and_probe (operands[0]);"
16165 [(set_attr "type" "multi")])
16167 (define_insn "probe_stack_range<mode>"
16168 [(set (match_operand:P 0 "register_operand" "=r")
16169 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16170 (match_operand:P 2 "const_int_operand" "n")]
16171 UNSPECV_PROBE_STACK_RANGE))
16172 (clobber (reg:CC FLAGS_REG))]
16174 "* return output_probe_stack_range (operands[0], operands[2]);"
16175 [(set_attr "type" "multi")])
16177 (define_expand "builtin_setjmp_receiver"
16178 [(label_ref (match_operand 0))]
16179 "!TARGET_64BIT && flag_pic"
16185 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16186 rtx label_rtx = gen_label_rtx ();
16187 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16188 xops[0] = xops[1] = picreg;
16189 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16190 ix86_expand_binary_operator (MINUS, SImode, xops);
16194 emit_insn (gen_set_got (pic_offset_table_rtx));
16198 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16201 [(set (match_operand 0 "register_operand")
16202 (match_operator 3 "promotable_binary_operator"
16203 [(match_operand 1 "register_operand")
16204 (match_operand 2 "aligned_operand")]))
16205 (clobber (reg:CC FLAGS_REG))]
16206 "! TARGET_PARTIAL_REG_STALL && reload_completed
16207 && ((GET_MODE (operands[0]) == HImode
16208 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16209 /* ??? next two lines just !satisfies_constraint_K (...) */
16210 || !CONST_INT_P (operands[2])
16211 || satisfies_constraint_K (operands[2])))
16212 || (GET_MODE (operands[0]) == QImode
16213 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16214 [(parallel [(set (match_dup 0)
16215 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16216 (clobber (reg:CC FLAGS_REG))])]
16218 operands[0] = gen_lowpart (SImode, operands[0]);
16219 operands[1] = gen_lowpart (SImode, operands[1]);
16220 if (GET_CODE (operands[3]) != ASHIFT)
16221 operands[2] = gen_lowpart (SImode, operands[2]);
16222 PUT_MODE (operands[3], SImode);
16225 ; Promote the QImode tests, as i386 has encoding of the AND
16226 ; instruction with 32-bit sign-extended immediate and thus the
16227 ; instruction size is unchanged, except in the %eax case for
16228 ; which it is increased by one byte, hence the ! optimize_size.
16230 [(set (match_operand 0 "flags_reg_operand")
16231 (match_operator 2 "compare_operator"
16232 [(and (match_operand 3 "aligned_operand")
16233 (match_operand 4 "const_int_operand"))
16235 (set (match_operand 1 "register_operand")
16236 (and (match_dup 3) (match_dup 4)))]
16237 "! TARGET_PARTIAL_REG_STALL && reload_completed
16238 && optimize_insn_for_speed_p ()
16239 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16240 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16241 /* Ensure that the operand will remain sign-extended immediate. */
16242 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16243 [(parallel [(set (match_dup 0)
16244 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16247 (and:SI (match_dup 3) (match_dup 4)))])]
16250 = gen_int_mode (INTVAL (operands[4])
16251 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16252 operands[1] = gen_lowpart (SImode, operands[1]);
16253 operands[3] = gen_lowpart (SImode, operands[3]);
16256 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16257 ; the TEST instruction with 32-bit sign-extended immediate and thus
16258 ; the instruction size would at least double, which is not what we
16259 ; want even with ! optimize_size.
16261 [(set (match_operand 0 "flags_reg_operand")
16262 (match_operator 1 "compare_operator"
16263 [(and (match_operand:HI 2 "aligned_operand")
16264 (match_operand:HI 3 "const_int_operand"))
16266 "! TARGET_PARTIAL_REG_STALL && reload_completed
16267 && ! TARGET_FAST_PREFIX
16268 && optimize_insn_for_speed_p ()
16269 /* Ensure that the operand will remain sign-extended immediate. */
16270 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16271 [(set (match_dup 0)
16272 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16276 = gen_int_mode (INTVAL (operands[3])
16277 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16278 operands[2] = gen_lowpart (SImode, operands[2]);
16282 [(set (match_operand 0 "register_operand")
16283 (neg (match_operand 1 "register_operand")))
16284 (clobber (reg:CC FLAGS_REG))]
16285 "! TARGET_PARTIAL_REG_STALL && reload_completed
16286 && (GET_MODE (operands[0]) == HImode
16287 || (GET_MODE (operands[0]) == QImode
16288 && (TARGET_PROMOTE_QImode
16289 || optimize_insn_for_size_p ())))"
16290 [(parallel [(set (match_dup 0)
16291 (neg:SI (match_dup 1)))
16292 (clobber (reg:CC FLAGS_REG))])]
16294 operands[0] = gen_lowpart (SImode, operands[0]);
16295 operands[1] = gen_lowpart (SImode, operands[1]);
16299 [(set (match_operand 0 "register_operand")
16300 (not (match_operand 1 "register_operand")))]
16301 "! TARGET_PARTIAL_REG_STALL && reload_completed
16302 && (GET_MODE (operands[0]) == HImode
16303 || (GET_MODE (operands[0]) == QImode
16304 && (TARGET_PROMOTE_QImode
16305 || optimize_insn_for_size_p ())))"
16306 [(set (match_dup 0)
16307 (not:SI (match_dup 1)))]
16309 operands[0] = gen_lowpart (SImode, operands[0]);
16310 operands[1] = gen_lowpart (SImode, operands[1]);
16313 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16314 ;; transform a complex memory operation into two memory to register operations.
16316 ;; Don't push memory operands
16318 [(set (match_operand:SWI 0 "push_operand")
16319 (match_operand:SWI 1 "memory_operand"))
16320 (match_scratch:SWI 2 "<r>")]
16321 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16322 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16323 [(set (match_dup 2) (match_dup 1))
16324 (set (match_dup 0) (match_dup 2))])
16326 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16329 [(set (match_operand:SF 0 "push_operand")
16330 (match_operand:SF 1 "memory_operand"))
16331 (match_scratch:SF 2 "r")]
16332 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16333 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16334 [(set (match_dup 2) (match_dup 1))
16335 (set (match_dup 0) (match_dup 2))])
16337 ;; Don't move an immediate directly to memory when the instruction
16338 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
16340 [(match_scratch:SWI124 1 "<r>")
16341 (set (match_operand:SWI124 0 "memory_operand")
16343 "optimize_insn_for_speed_p ()
16344 && ((<MODE>mode == HImode
16345 && TARGET_LCP_STALL)
16346 || (!TARGET_USE_MOV0
16347 && TARGET_SPLIT_LONG_MOVES
16348 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
16349 && peep2_regno_dead_p (0, FLAGS_REG)"
16350 [(parallel [(set (match_dup 2) (const_int 0))
16351 (clobber (reg:CC FLAGS_REG))])
16352 (set (match_dup 0) (match_dup 1))]
16353 "operands[2] = gen_lowpart (SImode, operands[1]);")
16356 [(match_scratch:SWI124 2 "<r>")
16357 (set (match_operand:SWI124 0 "memory_operand")
16358 (match_operand:SWI124 1 "immediate_operand"))]
16359 "optimize_insn_for_speed_p ()
16360 && ((<MODE>mode == HImode
16361 && TARGET_LCP_STALL)
16362 || (TARGET_SPLIT_LONG_MOVES
16363 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
16364 [(set (match_dup 2) (match_dup 1))
16365 (set (match_dup 0) (match_dup 2))])
16367 ;; Don't compare memory with zero, load and use a test instead.
16369 [(set (match_operand 0 "flags_reg_operand")
16370 (match_operator 1 "compare_operator"
16371 [(match_operand:SI 2 "memory_operand")
16373 (match_scratch:SI 3 "r")]
16374 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16375 [(set (match_dup 3) (match_dup 2))
16376 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16378 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16379 ;; Don't split NOTs with a displacement operand, because resulting XOR
16380 ;; will not be pairable anyway.
16382 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16383 ;; represented using a modRM byte. The XOR replacement is long decoded,
16384 ;; so this split helps here as well.
16386 ;; Note: Can't do this as a regular split because we can't get proper
16387 ;; lifetime information then.
16390 [(set (match_operand:SWI124 0 "nonimmediate_operand")
16391 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
16392 "optimize_insn_for_speed_p ()
16393 && ((TARGET_NOT_UNPAIRABLE
16394 && (!MEM_P (operands[0])
16395 || !memory_displacement_operand (operands[0], <MODE>mode)))
16396 || (TARGET_NOT_VECTORMODE
16397 && long_memory_operand (operands[0], <MODE>mode)))
16398 && peep2_regno_dead_p (0, FLAGS_REG)"
16399 [(parallel [(set (match_dup 0)
16400 (xor:SWI124 (match_dup 1) (const_int -1)))
16401 (clobber (reg:CC FLAGS_REG))])])
16403 ;; Non pairable "test imm, reg" instructions can be translated to
16404 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16405 ;; byte opcode instead of two, have a short form for byte operands),
16406 ;; so do it for other CPUs as well. Given that the value was dead,
16407 ;; this should not create any new dependencies. Pass on the sub-word
16408 ;; versions if we're concerned about partial register stalls.
16411 [(set (match_operand 0 "flags_reg_operand")
16412 (match_operator 1 "compare_operator"
16413 [(and:SI (match_operand:SI 2 "register_operand")
16414 (match_operand:SI 3 "immediate_operand"))
16416 "ix86_match_ccmode (insn, CCNOmode)
16417 && (true_regnum (operands[2]) != AX_REG
16418 || satisfies_constraint_K (operands[3]))
16419 && peep2_reg_dead_p (1, operands[2])"
16421 [(set (match_dup 0)
16422 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16425 (and:SI (match_dup 2) (match_dup 3)))])])
16427 ;; We don't need to handle HImode case, because it will be promoted to SImode
16428 ;; on ! TARGET_PARTIAL_REG_STALL
16431 [(set (match_operand 0 "flags_reg_operand")
16432 (match_operator 1 "compare_operator"
16433 [(and:QI (match_operand:QI 2 "register_operand")
16434 (match_operand:QI 3 "immediate_operand"))
16436 "! TARGET_PARTIAL_REG_STALL
16437 && ix86_match_ccmode (insn, CCNOmode)
16438 && true_regnum (operands[2]) != AX_REG
16439 && peep2_reg_dead_p (1, operands[2])"
16441 [(set (match_dup 0)
16442 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16445 (and:QI (match_dup 2) (match_dup 3)))])])
16448 [(set (match_operand 0 "flags_reg_operand")
16449 (match_operator 1 "compare_operator"
16452 (match_operand 2 "ext_register_operand")
16455 (match_operand 3 "const_int_operand"))
16457 "! TARGET_PARTIAL_REG_STALL
16458 && ix86_match_ccmode (insn, CCNOmode)
16459 && true_regnum (operands[2]) != AX_REG
16460 && peep2_reg_dead_p (1, operands[2])"
16461 [(parallel [(set (match_dup 0)
16470 (set (zero_extract:SI (match_dup 2)
16478 (match_dup 3)))])])
16480 ;; Don't do logical operations with memory inputs.
16482 [(match_scratch:SI 2 "r")
16483 (parallel [(set (match_operand:SI 0 "register_operand")
16484 (match_operator:SI 3 "arith_or_logical_operator"
16486 (match_operand:SI 1 "memory_operand")]))
16487 (clobber (reg:CC FLAGS_REG))])]
16488 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
16489 [(set (match_dup 2) (match_dup 1))
16490 (parallel [(set (match_dup 0)
16491 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16492 (clobber (reg:CC FLAGS_REG))])])
16495 [(match_scratch:SI 2 "r")
16496 (parallel [(set (match_operand:SI 0 "register_operand")
16497 (match_operator:SI 3 "arith_or_logical_operator"
16498 [(match_operand:SI 1 "memory_operand")
16500 (clobber (reg:CC FLAGS_REG))])]
16501 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
16502 [(set (match_dup 2) (match_dup 1))
16503 (parallel [(set (match_dup 0)
16504 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16505 (clobber (reg:CC FLAGS_REG))])])
16507 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
16508 ;; refers to the destination of the load!
16511 [(set (match_operand:SI 0 "register_operand")
16512 (match_operand:SI 1 "register_operand"))
16513 (parallel [(set (match_dup 0)
16514 (match_operator:SI 3 "commutative_operator"
16516 (match_operand:SI 2 "memory_operand")]))
16517 (clobber (reg:CC FLAGS_REG))])]
16518 "REGNO (operands[0]) != REGNO (operands[1])
16519 && GENERAL_REGNO_P (REGNO (operands[0]))
16520 && GENERAL_REGNO_P (REGNO (operands[1]))"
16521 [(set (match_dup 0) (match_dup 4))
16522 (parallel [(set (match_dup 0)
16523 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16524 (clobber (reg:CC FLAGS_REG))])]
16525 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
16528 [(set (match_operand 0 "register_operand")
16529 (match_operand 1 "register_operand"))
16531 (match_operator 3 "commutative_operator"
16533 (match_operand 2 "memory_operand")]))]
16534 "REGNO (operands[0]) != REGNO (operands[1])
16535 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
16536 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
16537 [(set (match_dup 0) (match_dup 2))
16539 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
16541 ; Don't do logical operations with memory outputs
16543 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16544 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
16545 ; the same decoder scheduling characteristics as the original.
16548 [(match_scratch:SI 2 "r")
16549 (parallel [(set (match_operand:SI 0 "memory_operand")
16550 (match_operator:SI 3 "arith_or_logical_operator"
16552 (match_operand:SI 1 "nonmemory_operand")]))
16553 (clobber (reg:CC FLAGS_REG))])]
16554 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16555 /* Do not split stack checking probes. */
16556 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16557 [(set (match_dup 2) (match_dup 0))
16558 (parallel [(set (match_dup 2)
16559 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16560 (clobber (reg:CC FLAGS_REG))])
16561 (set (match_dup 0) (match_dup 2))])
16564 [(match_scratch:SI 2 "r")
16565 (parallel [(set (match_operand:SI 0 "memory_operand")
16566 (match_operator:SI 3 "arith_or_logical_operator"
16567 [(match_operand:SI 1 "nonmemory_operand")
16569 (clobber (reg:CC FLAGS_REG))])]
16570 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16571 /* Do not split stack checking probes. */
16572 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16573 [(set (match_dup 2) (match_dup 0))
16574 (parallel [(set (match_dup 2)
16575 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16576 (clobber (reg:CC FLAGS_REG))])
16577 (set (match_dup 0) (match_dup 2))])
16579 ;; Attempt to use arith or logical operations with memory outputs with
16580 ;; setting of flags.
16582 [(set (match_operand:SWI 0 "register_operand")
16583 (match_operand:SWI 1 "memory_operand"))
16584 (parallel [(set (match_dup 0)
16585 (match_operator:SWI 3 "plusminuslogic_operator"
16587 (match_operand:SWI 2 "<nonmemory_operand>")]))
16588 (clobber (reg:CC FLAGS_REG))])
16589 (set (match_dup 1) (match_dup 0))
16590 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16591 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16592 && peep2_reg_dead_p (4, operands[0])
16593 && !reg_overlap_mentioned_p (operands[0], operands[1])
16594 && (<MODE>mode != QImode
16595 || immediate_operand (operands[2], QImode)
16596 || q_regs_operand (operands[2], QImode))
16597 && ix86_match_ccmode (peep2_next_insn (3),
16598 (GET_CODE (operands[3]) == PLUS
16599 || GET_CODE (operands[3]) == MINUS)
16600 ? CCGOCmode : CCNOmode)"
16601 [(parallel [(set (match_dup 4) (match_dup 5))
16602 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
16603 (match_dup 2)]))])]
16605 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
16606 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16607 copy_rtx (operands[1]),
16608 copy_rtx (operands[2]));
16609 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
16610 operands[5], const0_rtx);
16614 [(parallel [(set (match_operand:SWI 0 "register_operand")
16615 (match_operator:SWI 2 "plusminuslogic_operator"
16617 (match_operand:SWI 1 "memory_operand")]))
16618 (clobber (reg:CC FLAGS_REG))])
16619 (set (match_dup 1) (match_dup 0))
16620 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16621 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16622 && GET_CODE (operands[2]) != MINUS
16623 && peep2_reg_dead_p (3, operands[0])
16624 && !reg_overlap_mentioned_p (operands[0], operands[1])
16625 && ix86_match_ccmode (peep2_next_insn (2),
16626 GET_CODE (operands[2]) == PLUS
16627 ? CCGOCmode : CCNOmode)"
16628 [(parallel [(set (match_dup 3) (match_dup 4))
16629 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
16630 (match_dup 0)]))])]
16632 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
16633 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
16634 copy_rtx (operands[1]),
16635 copy_rtx (operands[0]));
16636 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
16637 operands[4], const0_rtx);
16641 [(set (match_operand:SWI12 0 "register_operand")
16642 (match_operand:SWI12 1 "memory_operand"))
16643 (parallel [(set (match_operand:SI 4 "register_operand")
16644 (match_operator:SI 3 "plusminuslogic_operator"
16646 (match_operand:SI 2 "nonmemory_operand")]))
16647 (clobber (reg:CC FLAGS_REG))])
16648 (set (match_dup 1) (match_dup 0))
16649 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16650 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16651 && REG_P (operands[0]) && REG_P (operands[4])
16652 && REGNO (operands[0]) == REGNO (operands[4])
16653 && peep2_reg_dead_p (4, operands[0])
16654 && (<MODE>mode != QImode
16655 || immediate_operand (operands[2], SImode)
16656 || q_regs_operand (operands[2], SImode))
16657 && !reg_overlap_mentioned_p (operands[0], operands[1])
16658 && ix86_match_ccmode (peep2_next_insn (3),
16659 (GET_CODE (operands[3]) == PLUS
16660 || GET_CODE (operands[3]) == MINUS)
16661 ? CCGOCmode : CCNOmode)"
16662 [(parallel [(set (match_dup 4) (match_dup 5))
16663 (set (match_dup 1) (match_dup 6))])]
16665 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
16666 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
16667 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16668 copy_rtx (operands[1]), operands[2]);
16669 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
16670 operands[5], const0_rtx);
16671 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16672 copy_rtx (operands[1]),
16673 copy_rtx (operands[2]));
16676 ;; Attempt to always use XOR for zeroing registers.
16678 [(set (match_operand 0 "register_operand")
16679 (match_operand 1 "const0_operand"))]
16680 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
16681 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16682 && GENERAL_REG_P (operands[0])
16683 && peep2_regno_dead_p (0, FLAGS_REG)"
16684 [(parallel [(set (match_dup 0) (const_int 0))
16685 (clobber (reg:CC FLAGS_REG))])]
16686 "operands[0] = gen_lowpart (word_mode, operands[0]);")
16689 [(set (strict_low_part (match_operand 0 "register_operand"))
16691 "(GET_MODE (operands[0]) == QImode
16692 || GET_MODE (operands[0]) == HImode)
16693 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16694 && peep2_regno_dead_p (0, FLAGS_REG)"
16695 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
16696 (clobber (reg:CC FLAGS_REG))])])
16698 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
16700 [(set (match_operand:SWI248 0 "register_operand")
16702 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
16703 && peep2_regno_dead_p (0, FLAGS_REG)"
16704 [(parallel [(set (match_dup 0) (const_int -1))
16705 (clobber (reg:CC FLAGS_REG))])]
16707 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
16708 operands[0] = gen_lowpart (SImode, operands[0]);
16711 ;; Attempt to convert simple lea to add/shift.
16712 ;; These can be created by move expanders.
16713 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
16714 ;; relevant lea instructions were already split.
16717 [(set (match_operand:SWI48 0 "register_operand")
16718 (plus:SWI48 (match_dup 0)
16719 (match_operand:SWI48 1 "<nonmemory_operand>")))]
16721 && peep2_regno_dead_p (0, FLAGS_REG)"
16722 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
16723 (clobber (reg:CC FLAGS_REG))])])
16726 [(set (match_operand:SWI48 0 "register_operand")
16727 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
16730 && peep2_regno_dead_p (0, FLAGS_REG)"
16731 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
16732 (clobber (reg:CC FLAGS_REG))])])
16735 [(set (match_operand:DI 0 "register_operand")
16737 (plus:SI (match_operand:SI 1 "register_operand")
16738 (match_operand:SI 2 "nonmemory_operand"))))]
16739 "TARGET_64BIT && !TARGET_OPT_AGU
16740 && REGNO (operands[0]) == REGNO (operands[1])
16741 && peep2_regno_dead_p (0, FLAGS_REG)"
16742 [(parallel [(set (match_dup 0)
16743 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
16744 (clobber (reg:CC FLAGS_REG))])])
16747 [(set (match_operand:DI 0 "register_operand")
16749 (plus:SI (match_operand:SI 1 "nonmemory_operand")
16750 (match_operand:SI 2 "register_operand"))))]
16751 "TARGET_64BIT && !TARGET_OPT_AGU
16752 && REGNO (operands[0]) == REGNO (operands[2])
16753 && peep2_regno_dead_p (0, FLAGS_REG)"
16754 [(parallel [(set (match_dup 0)
16755 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
16756 (clobber (reg:CC FLAGS_REG))])])
16759 [(set (match_operand:SWI48 0 "register_operand")
16760 (mult:SWI48 (match_dup 0)
16761 (match_operand:SWI48 1 "const_int_operand")))]
16762 "exact_log2 (INTVAL (operands[1])) >= 0
16763 && peep2_regno_dead_p (0, FLAGS_REG)"
16764 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
16765 (clobber (reg:CC FLAGS_REG))])]
16766 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
16769 [(set (match_operand:DI 0 "register_operand")
16771 (mult:SI (match_operand:SI 1 "register_operand")
16772 (match_operand:SI 2 "const_int_operand"))))]
16774 && exact_log2 (INTVAL (operands[2])) >= 0
16775 && REGNO (operands[0]) == REGNO (operands[1])
16776 && peep2_regno_dead_p (0, FLAGS_REG)"
16777 [(parallel [(set (match_dup 0)
16778 (zero_extend (ashift:SI (match_dup 1) (match_dup 2))))
16779 (clobber (reg:CC FLAGS_REG))])]
16780 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
16782 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
16783 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
16784 ;; On many CPUs it is also faster, since special hardware to avoid esp
16785 ;; dependencies is present.
16787 ;; While some of these conversions may be done using splitters, we use
16788 ;; peepholes in order to allow combine_stack_adjustments pass to see
16789 ;; nonobfuscated RTL.
16791 ;; Convert prologue esp subtractions to push.
16792 ;; We need register to push. In order to keep verify_flow_info happy we have
16794 ;; - use scratch and clobber it in order to avoid dependencies
16795 ;; - use already live register
16796 ;; We can't use the second way right now, since there is no reliable way how to
16797 ;; verify that given register is live. First choice will also most likely in
16798 ;; fewer dependencies. On the place of esp adjustments it is very likely that
16799 ;; call clobbered registers are dead. We may want to use base pointer as an
16800 ;; alternative when no register is available later.
16803 [(match_scratch:W 1 "r")
16804 (parallel [(set (reg:P SP_REG)
16805 (plus:P (reg:P SP_REG)
16806 (match_operand:P 0 "const_int_operand")))
16807 (clobber (reg:CC FLAGS_REG))
16808 (clobber (mem:BLK (scratch)))])]
16809 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16810 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
16811 [(clobber (match_dup 1))
16812 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16813 (clobber (mem:BLK (scratch)))])])
16816 [(match_scratch:W 1 "r")
16817 (parallel [(set (reg:P SP_REG)
16818 (plus:P (reg:P SP_REG)
16819 (match_operand:P 0 "const_int_operand")))
16820 (clobber (reg:CC FLAGS_REG))
16821 (clobber (mem:BLK (scratch)))])]
16822 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16823 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
16824 [(clobber (match_dup 1))
16825 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16826 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16827 (clobber (mem:BLK (scratch)))])])
16829 ;; Convert esp subtractions to push.
16831 [(match_scratch:W 1 "r")
16832 (parallel [(set (reg:P SP_REG)
16833 (plus:P (reg:P SP_REG)
16834 (match_operand:P 0 "const_int_operand")))
16835 (clobber (reg:CC FLAGS_REG))])]
16836 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16837 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
16838 [(clobber (match_dup 1))
16839 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
16842 [(match_scratch:W 1 "r")
16843 (parallel [(set (reg:P SP_REG)
16844 (plus:P (reg:P SP_REG)
16845 (match_operand:P 0 "const_int_operand")))
16846 (clobber (reg:CC FLAGS_REG))])]
16847 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16848 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
16849 [(clobber (match_dup 1))
16850 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16851 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
16853 ;; Convert epilogue deallocator to pop.
16855 [(match_scratch:W 1 "r")
16856 (parallel [(set (reg:P SP_REG)
16857 (plus:P (reg:P SP_REG)
16858 (match_operand:P 0 "const_int_operand")))
16859 (clobber (reg:CC FLAGS_REG))
16860 (clobber (mem:BLK (scratch)))])]
16861 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
16862 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
16863 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
16864 (clobber (mem:BLK (scratch)))])])
16866 ;; Two pops case is tricky, since pop causes dependency
16867 ;; on destination register. We use two registers if available.
16869 [(match_scratch:W 1 "r")
16870 (match_scratch:W 2 "r")
16871 (parallel [(set (reg:P SP_REG)
16872 (plus:P (reg:P SP_REG)
16873 (match_operand:P 0 "const_int_operand")))
16874 (clobber (reg:CC FLAGS_REG))
16875 (clobber (mem:BLK (scratch)))])]
16876 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
16877 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
16878 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
16879 (clobber (mem:BLK (scratch)))])
16880 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
16883 [(match_scratch:W 1 "r")
16884 (parallel [(set (reg:P SP_REG)
16885 (plus:P (reg:P SP_REG)
16886 (match_operand:P 0 "const_int_operand")))
16887 (clobber (reg:CC FLAGS_REG))
16888 (clobber (mem:BLK (scratch)))])]
16889 "optimize_insn_for_size_p ()
16890 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
16891 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
16892 (clobber (mem:BLK (scratch)))])
16893 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
16895 ;; Convert esp additions to pop.
16897 [(match_scratch:W 1 "r")
16898 (parallel [(set (reg:P SP_REG)
16899 (plus:P (reg:P SP_REG)
16900 (match_operand:P 0 "const_int_operand")))
16901 (clobber (reg:CC FLAGS_REG))])]
16902 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
16903 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
16905 ;; Two pops case is tricky, since pop causes dependency
16906 ;; on destination register. We use two registers if available.
16908 [(match_scratch:W 1 "r")
16909 (match_scratch:W 2 "r")
16910 (parallel [(set (reg:P SP_REG)
16911 (plus:P (reg:P SP_REG)
16912 (match_operand:P 0 "const_int_operand")))
16913 (clobber (reg:CC FLAGS_REG))])]
16914 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
16915 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
16916 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
16919 [(match_scratch:W 1 "r")
16920 (parallel [(set (reg:P SP_REG)
16921 (plus:P (reg:P SP_REG)
16922 (match_operand:P 0 "const_int_operand")))
16923 (clobber (reg:CC FLAGS_REG))])]
16924 "optimize_insn_for_size_p ()
16925 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
16926 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
16927 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
16929 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
16930 ;; required and register dies. Similarly for 128 to -128.
16932 [(set (match_operand 0 "flags_reg_operand")
16933 (match_operator 1 "compare_operator"
16934 [(match_operand 2 "register_operand")
16935 (match_operand 3 "const_int_operand")]))]
16936 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
16937 && incdec_operand (operands[3], GET_MODE (operands[3])))
16938 || (!TARGET_FUSE_CMP_AND_BRANCH
16939 && INTVAL (operands[3]) == 128))
16940 && ix86_match_ccmode (insn, CCGCmode)
16941 && peep2_reg_dead_p (1, operands[2])"
16942 [(parallel [(set (match_dup 0)
16943 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
16944 (clobber (match_dup 2))])])
16946 ;; Convert imul by three, five and nine into lea
16949 [(set (match_operand:SWI48 0 "register_operand")
16950 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
16951 (match_operand:SWI48 2 "const359_operand")))
16952 (clobber (reg:CC FLAGS_REG))])]
16953 "!TARGET_PARTIAL_REG_STALL
16954 || <MODE>mode == SImode
16955 || optimize_function_for_size_p (cfun)"
16956 [(set (match_dup 0)
16957 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
16959 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
16963 [(set (match_operand:SWI48 0 "register_operand")
16964 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
16965 (match_operand:SWI48 2 "const359_operand")))
16966 (clobber (reg:CC FLAGS_REG))])]
16967 "optimize_insn_for_speed_p ()
16968 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
16969 [(set (match_dup 0) (match_dup 1))
16971 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
16973 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
16975 ;; imul $32bit_imm, mem, reg is vector decoded, while
16976 ;; imul $32bit_imm, reg, reg is direct decoded.
16978 [(match_scratch:SWI48 3 "r")
16979 (parallel [(set (match_operand:SWI48 0 "register_operand")
16980 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
16981 (match_operand:SWI48 2 "immediate_operand")))
16982 (clobber (reg:CC FLAGS_REG))])]
16983 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
16984 && !satisfies_constraint_K (operands[2])"
16985 [(set (match_dup 3) (match_dup 1))
16986 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
16987 (clobber (reg:CC FLAGS_REG))])])
16990 [(match_scratch:SI 3 "r")
16991 (parallel [(set (match_operand:DI 0 "register_operand")
16993 (mult:SI (match_operand:SI 1 "memory_operand")
16994 (match_operand:SI 2 "immediate_operand"))))
16995 (clobber (reg:CC FLAGS_REG))])]
16997 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
16998 && !satisfies_constraint_K (operands[2])"
16999 [(set (match_dup 3) (match_dup 1))
17000 (parallel [(set (match_dup 0)
17001 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17002 (clobber (reg:CC FLAGS_REG))])])
17004 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17005 ;; Convert it into imul reg, reg
17006 ;; It would be better to force assembler to encode instruction using long
17007 ;; immediate, but there is apparently no way to do so.
17009 [(parallel [(set (match_operand:SWI248 0 "register_operand")
17011 (match_operand:SWI248 1 "nonimmediate_operand")
17012 (match_operand:SWI248 2 "const_int_operand")))
17013 (clobber (reg:CC FLAGS_REG))])
17014 (match_scratch:SWI248 3 "r")]
17015 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17016 && satisfies_constraint_K (operands[2])"
17017 [(set (match_dup 3) (match_dup 2))
17018 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17019 (clobber (reg:CC FLAGS_REG))])]
17021 if (!rtx_equal_p (operands[0], operands[1]))
17022 emit_move_insn (operands[0], operands[1]);
17025 ;; After splitting up read-modify operations, array accesses with memory
17026 ;; operands might end up in form:
17028 ;; movl 4(%esp), %edx
17030 ;; instead of pre-splitting:
17032 ;; addl 4(%esp), %eax
17034 ;; movl 4(%esp), %edx
17035 ;; leal (%edx,%eax,4), %eax
17038 [(match_scratch:W 5 "r")
17039 (parallel [(set (match_operand 0 "register_operand")
17040 (ashift (match_operand 1 "register_operand")
17041 (match_operand 2 "const_int_operand")))
17042 (clobber (reg:CC FLAGS_REG))])
17043 (parallel [(set (match_operand 3 "register_operand")
17044 (plus (match_dup 0)
17045 (match_operand 4 "x86_64_general_operand")))
17046 (clobber (reg:CC FLAGS_REG))])]
17047 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17048 /* Validate MODE for lea. */
17049 && ((!TARGET_PARTIAL_REG_STALL
17050 && (GET_MODE (operands[0]) == QImode
17051 || GET_MODE (operands[0]) == HImode))
17052 || GET_MODE (operands[0]) == SImode
17053 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17054 && (rtx_equal_p (operands[0], operands[3])
17055 || peep2_reg_dead_p (2, operands[0]))
17056 /* We reorder load and the shift. */
17057 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17058 [(set (match_dup 5) (match_dup 4))
17059 (set (match_dup 0) (match_dup 1))]
17061 enum machine_mode op1mode = GET_MODE (operands[1]);
17062 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17063 int scale = 1 << INTVAL (operands[2]);
17064 rtx index = gen_lowpart (word_mode, operands[1]);
17065 rtx base = gen_lowpart (word_mode, operands[5]);
17066 rtx dest = gen_lowpart (mode, operands[3]);
17068 operands[1] = gen_rtx_PLUS (word_mode, base,
17069 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
17070 operands[5] = base;
17071 if (mode != word_mode)
17072 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17073 if (op1mode != word_mode)
17074 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17075 operands[0] = dest;
17078 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17079 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17080 ;; caught for use by garbage collectors and the like. Using an insn that
17081 ;; maps to SIGILL makes it more likely the program will rightfully die.
17082 ;; Keeping with tradition, "6" is in honor of #UD.
17083 (define_insn "trap"
17084 [(trap_if (const_int 1) (const_int 6))]
17086 { return ASM_SHORT "0x0b0f"; }
17087 [(set_attr "length" "2")])
17089 (define_expand "prefetch"
17090 [(prefetch (match_operand 0 "address_operand")
17091 (match_operand:SI 1 "const_int_operand")
17092 (match_operand:SI 2 "const_int_operand"))]
17093 "TARGET_PREFETCH_SSE || TARGET_PRFCHW"
17095 bool write = INTVAL (operands[1]) != 0;
17096 int locality = INTVAL (operands[2]);
17098 gcc_assert (IN_RANGE (locality, 0, 3));
17100 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17101 supported by SSE counterpart or the SSE prefetch is not available
17102 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17104 if (TARGET_PRFCHW && (write || !TARGET_PREFETCH_SSE))
17105 operands[2] = GEN_INT (3);
17107 operands[1] = const0_rtx;
17110 (define_insn "*prefetch_sse"
17111 [(prefetch (match_operand 0 "address_operand" "p")
17113 (match_operand:SI 1 "const_int_operand"))]
17114 "TARGET_PREFETCH_SSE"
17116 static const char * const patterns[4] = {
17117 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17120 int locality = INTVAL (operands[1]);
17121 gcc_assert (IN_RANGE (locality, 0, 3));
17123 return patterns[locality];
17125 [(set_attr "type" "sse")
17126 (set_attr "atom_sse_attr" "prefetch")
17127 (set (attr "length_address")
17128 (symbol_ref "memory_address_length (operands[0], false)"))
17129 (set_attr "memory" "none")])
17131 (define_insn "*prefetch_3dnow"
17132 [(prefetch (match_operand 0 "address_operand" "p")
17133 (match_operand:SI 1 "const_int_operand" "n")
17137 if (INTVAL (operands[1]) == 0)
17138 return "prefetch\t%a0";
17140 return "prefetchw\t%a0";
17142 [(set_attr "type" "mmx")
17143 (set (attr "length_address")
17144 (symbol_ref "memory_address_length (operands[0], false)"))
17145 (set_attr "memory" "none")])
17147 (define_expand "stack_protect_set"
17148 [(match_operand 0 "memory_operand")
17149 (match_operand 1 "memory_operand")]
17150 "TARGET_SSP_TLS_GUARD"
17152 rtx (*insn)(rtx, rtx);
17154 #ifdef TARGET_THREAD_SSP_OFFSET
17155 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17156 insn = (TARGET_LP64
17157 ? gen_stack_tls_protect_set_di
17158 : gen_stack_tls_protect_set_si);
17160 insn = (TARGET_LP64
17161 ? gen_stack_protect_set_di
17162 : gen_stack_protect_set_si);
17165 emit_insn (insn (operands[0], operands[1]));
17169 (define_insn "stack_protect_set_<mode>"
17170 [(set (match_operand:PTR 0 "memory_operand" "=m")
17171 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17173 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17174 (clobber (reg:CC FLAGS_REG))]
17175 "TARGET_SSP_TLS_GUARD"
17176 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17177 [(set_attr "type" "multi")])
17179 (define_insn "stack_tls_protect_set_<mode>"
17180 [(set (match_operand:PTR 0 "memory_operand" "=m")
17181 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17182 UNSPEC_SP_TLS_SET))
17183 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17184 (clobber (reg:CC FLAGS_REG))]
17186 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17187 [(set_attr "type" "multi")])
17189 (define_expand "stack_protect_test"
17190 [(match_operand 0 "memory_operand")
17191 (match_operand 1 "memory_operand")
17193 "TARGET_SSP_TLS_GUARD"
17195 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17197 rtx (*insn)(rtx, rtx, rtx);
17199 #ifdef TARGET_THREAD_SSP_OFFSET
17200 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17201 insn = (TARGET_LP64
17202 ? gen_stack_tls_protect_test_di
17203 : gen_stack_tls_protect_test_si);
17205 insn = (TARGET_LP64
17206 ? gen_stack_protect_test_di
17207 : gen_stack_protect_test_si);
17210 emit_insn (insn (flags, operands[0], operands[1]));
17212 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17213 flags, const0_rtx, operands[2]));
17217 (define_insn "stack_protect_test_<mode>"
17218 [(set (match_operand:CCZ 0 "flags_reg_operand")
17219 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17220 (match_operand:PTR 2 "memory_operand" "m")]
17222 (clobber (match_scratch:PTR 3 "=&r"))]
17223 "TARGET_SSP_TLS_GUARD"
17224 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17225 [(set_attr "type" "multi")])
17227 (define_insn "stack_tls_protect_test_<mode>"
17228 [(set (match_operand:CCZ 0 "flags_reg_operand")
17229 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17230 (match_operand:PTR 2 "const_int_operand" "i")]
17231 UNSPEC_SP_TLS_TEST))
17232 (clobber (match_scratch:PTR 3 "=r"))]
17234 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17235 [(set_attr "type" "multi")])
17237 (define_insn "sse4_2_crc32<mode>"
17238 [(set (match_operand:SI 0 "register_operand" "=r")
17240 [(match_operand:SI 1 "register_operand" "0")
17241 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17243 "TARGET_SSE4_2 || TARGET_CRC32"
17244 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17245 [(set_attr "type" "sselog1")
17246 (set_attr "prefix_rep" "1")
17247 (set_attr "prefix_extra" "1")
17248 (set (attr "prefix_data16")
17249 (if_then_else (match_operand:HI 2)
17251 (const_string "*")))
17252 (set (attr "prefix_rex")
17253 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
17255 (const_string "*")))
17256 (set_attr "mode" "SI")])
17258 (define_insn "sse4_2_crc32di"
17259 [(set (match_operand:DI 0 "register_operand" "=r")
17261 [(match_operand:DI 1 "register_operand" "0")
17262 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17264 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17265 "crc32{q}\t{%2, %0|%0, %2}"
17266 [(set_attr "type" "sselog1")
17267 (set_attr "prefix_rep" "1")
17268 (set_attr "prefix_extra" "1")
17269 (set_attr "mode" "DI")])
17271 (define_insn "rdpmc"
17272 [(set (match_operand:DI 0 "register_operand" "=A")
17273 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17277 [(set_attr "type" "other")
17278 (set_attr "length" "2")])
17280 (define_insn "rdpmc_rex64"
17281 [(set (match_operand:DI 0 "register_operand" "=a")
17282 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17284 (set (match_operand:DI 1 "register_operand" "=d")
17285 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
17288 [(set_attr "type" "other")
17289 (set_attr "length" "2")])
17291 (define_insn "rdtsc"
17292 [(set (match_operand:DI 0 "register_operand" "=A")
17293 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17296 [(set_attr "type" "other")
17297 (set_attr "length" "2")])
17299 (define_insn "rdtsc_rex64"
17300 [(set (match_operand:DI 0 "register_operand" "=a")
17301 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17302 (set (match_operand:DI 1 "register_operand" "=d")
17303 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17306 [(set_attr "type" "other")
17307 (set_attr "length" "2")])
17309 (define_insn "rdtscp"
17310 [(set (match_operand:DI 0 "register_operand" "=A")
17311 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17312 (set (match_operand:SI 1 "register_operand" "=c")
17313 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17316 [(set_attr "type" "other")
17317 (set_attr "length" "3")])
17319 (define_insn "rdtscp_rex64"
17320 [(set (match_operand:DI 0 "register_operand" "=a")
17321 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17322 (set (match_operand:DI 1 "register_operand" "=d")
17323 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17324 (set (match_operand:SI 2 "register_operand" "=c")
17325 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17328 [(set_attr "type" "other")
17329 (set_attr "length" "3")])
17331 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17333 ;; FXSR, XSAVE and XSAVEOPT instructions
17335 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17337 (define_insn "fxsave"
17338 [(set (match_operand:BLK 0 "memory_operand" "=m")
17339 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
17342 [(set_attr "type" "other")
17343 (set_attr "memory" "store")
17344 (set (attr "length")
17345 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17347 (define_insn "fxsave64"
17348 [(set (match_operand:BLK 0 "memory_operand" "=m")
17349 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
17350 "TARGET_64BIT && TARGET_FXSR"
17352 [(set_attr "type" "other")
17353 (set_attr "memory" "store")
17354 (set (attr "length")
17355 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17357 (define_insn "fxrstor"
17358 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
17362 [(set_attr "type" "other")
17363 (set_attr "memory" "load")
17364 (set (attr "length")
17365 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17367 (define_insn "fxrstor64"
17368 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
17369 UNSPECV_FXRSTOR64)]
17370 "TARGET_64BIT && TARGET_FXSR"
17372 [(set_attr "type" "other")
17373 (set_attr "memory" "load")
17374 (set (attr "length")
17375 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17377 (define_int_iterator ANY_XSAVE
17379 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")])
17381 (define_int_iterator ANY_XSAVE64
17383 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")])
17385 (define_int_attr xsave
17386 [(UNSPECV_XSAVE "xsave")
17387 (UNSPECV_XSAVE64 "xsave64")
17388 (UNSPECV_XSAVEOPT "xsaveopt")
17389 (UNSPECV_XSAVEOPT64 "xsaveopt64")])
17391 (define_insn "<xsave>"
17392 [(set (match_operand:BLK 0 "memory_operand" "=m")
17393 (unspec_volatile:BLK
17394 [(match_operand:DI 1 "register_operand" "A")]
17396 "!TARGET_64BIT && TARGET_XSAVE"
17398 [(set_attr "type" "other")
17399 (set_attr "memory" "store")
17400 (set (attr "length")
17401 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17403 (define_insn "<xsave>_rex64"
17404 [(set (match_operand:BLK 0 "memory_operand" "=m")
17405 (unspec_volatile:BLK
17406 [(match_operand:SI 1 "register_operand" "a")
17407 (match_operand:SI 2 "register_operand" "d")]
17409 "TARGET_64BIT && TARGET_XSAVE"
17411 [(set_attr "type" "other")
17412 (set_attr "memory" "store")
17413 (set (attr "length")
17414 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17416 (define_insn "<xsave>"
17417 [(set (match_operand:BLK 0 "memory_operand" "=m")
17418 (unspec_volatile:BLK
17419 [(match_operand:SI 1 "register_operand" "a")
17420 (match_operand:SI 2 "register_operand" "d")]
17422 "TARGET_64BIT && TARGET_XSAVE"
17424 [(set_attr "type" "other")
17425 (set_attr "memory" "store")
17426 (set (attr "length")
17427 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17429 (define_insn "xrstor"
17430 [(unspec_volatile:BLK
17431 [(match_operand:BLK 0 "memory_operand" "m")
17432 (match_operand:DI 1 "register_operand" "A")]
17434 "!TARGET_64BIT && TARGET_XSAVE"
17436 [(set_attr "type" "other")
17437 (set_attr "memory" "load")
17438 (set (attr "length")
17439 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17441 (define_insn "xrstor_rex64"
17442 [(unspec_volatile:BLK
17443 [(match_operand:BLK 0 "memory_operand" "m")
17444 (match_operand:SI 1 "register_operand" "a")
17445 (match_operand:SI 2 "register_operand" "d")]
17447 "TARGET_64BIT && TARGET_XSAVE"
17449 [(set_attr "type" "other")
17450 (set_attr "memory" "load")
17451 (set (attr "length")
17452 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17454 (define_insn "xrstor64"
17455 [(unspec_volatile:BLK
17456 [(match_operand:BLK 0 "memory_operand" "m")
17457 (match_operand:SI 1 "register_operand" "a")
17458 (match_operand:SI 2 "register_operand" "d")]
17460 "TARGET_64BIT && TARGET_XSAVE"
17462 [(set_attr "type" "other")
17463 (set_attr "memory" "load")
17464 (set (attr "length")
17465 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17467 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17469 ;; LWP instructions
17471 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17473 (define_expand "lwp_llwpcb"
17474 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17475 UNSPECV_LLWP_INTRINSIC)]
17478 (define_insn "*lwp_llwpcb<mode>1"
17479 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17480 UNSPECV_LLWP_INTRINSIC)]
17483 [(set_attr "type" "lwp")
17484 (set_attr "mode" "<MODE>")
17485 (set_attr "length" "5")])
17487 (define_expand "lwp_slwpcb"
17488 [(set (match_operand 0 "register_operand" "=r")
17489 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17494 insn = (Pmode == DImode
17496 : gen_lwp_slwpcbsi);
17498 emit_insn (insn (operands[0]));
17502 (define_insn "lwp_slwpcb<mode>"
17503 [(set (match_operand:P 0 "register_operand" "=r")
17504 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17507 [(set_attr "type" "lwp")
17508 (set_attr "mode" "<MODE>")
17509 (set_attr "length" "5")])
17511 (define_expand "lwp_lwpval<mode>3"
17512 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
17513 (match_operand:SI 2 "nonimmediate_operand" "rm")
17514 (match_operand:SI 3 "const_int_operand" "i")]
17515 UNSPECV_LWPVAL_INTRINSIC)]
17517 ;; Avoid unused variable warning.
17518 "(void) operands[0];")
17520 (define_insn "*lwp_lwpval<mode>3_1"
17521 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
17522 (match_operand:SI 1 "nonimmediate_operand" "rm")
17523 (match_operand:SI 2 "const_int_operand" "i")]
17524 UNSPECV_LWPVAL_INTRINSIC)]
17526 "lwpval\t{%2, %1, %0|%0, %1, %2}"
17527 [(set_attr "type" "lwp")
17528 (set_attr "mode" "<MODE>")
17529 (set (attr "length")
17530 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17532 (define_expand "lwp_lwpins<mode>3"
17533 [(set (reg:CCC FLAGS_REG)
17534 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
17535 (match_operand:SI 2 "nonimmediate_operand" "rm")
17536 (match_operand:SI 3 "const_int_operand" "i")]
17537 UNSPECV_LWPINS_INTRINSIC))
17538 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
17539 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
17542 (define_insn "*lwp_lwpins<mode>3_1"
17543 [(set (reg:CCC FLAGS_REG)
17544 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
17545 (match_operand:SI 1 "nonimmediate_operand" "rm")
17546 (match_operand:SI 2 "const_int_operand" "i")]
17547 UNSPECV_LWPINS_INTRINSIC))]
17549 "lwpins\t{%2, %1, %0|%0, %1, %2}"
17550 [(set_attr "type" "lwp")
17551 (set_attr "mode" "<MODE>")
17552 (set (attr "length")
17553 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17555 (define_int_iterator RDFSGSBASE
17559 (define_int_iterator WRFSGSBASE
17563 (define_int_attr fsgs
17564 [(UNSPECV_RDFSBASE "fs")
17565 (UNSPECV_RDGSBASE "gs")
17566 (UNSPECV_WRFSBASE "fs")
17567 (UNSPECV_WRGSBASE "gs")])
17569 (define_insn "rd<fsgs>base<mode>"
17570 [(set (match_operand:SWI48 0 "register_operand" "=r")
17571 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
17572 "TARGET_64BIT && TARGET_FSGSBASE"
17574 [(set_attr "type" "other")
17575 (set_attr "prefix_extra" "2")])
17577 (define_insn "wr<fsgs>base<mode>"
17578 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17580 "TARGET_64BIT && TARGET_FSGSBASE"
17582 [(set_attr "type" "other")
17583 (set_attr "prefix_extra" "2")])
17585 (define_insn "rdrand<mode>_1"
17586 [(set (match_operand:SWI248 0 "register_operand" "=r")
17587 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
17588 (set (reg:CCC FLAGS_REG)
17589 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
17592 [(set_attr "type" "other")
17593 (set_attr "prefix_extra" "1")])
17595 (define_insn "rdseed<mode>_1"
17596 [(set (match_operand:SWI248 0 "register_operand" "=r")
17597 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
17598 (set (reg:CCC FLAGS_REG)
17599 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
17602 [(set_attr "type" "other")
17603 (set_attr "prefix_extra" "1")])
17605 (define_expand "pause"
17606 [(set (match_dup 0)
17607 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
17610 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
17611 MEM_VOLATILE_P (operands[0]) = 1;
17614 ;; Use "rep; nop", instead of "pause", to support older assemblers.
17615 ;; They have the same encoding.
17616 (define_insn "*pause"
17617 [(set (match_operand:BLK 0)
17618 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
17621 [(set_attr "length" "2")
17622 (set_attr "memory" "unknown")])
17624 (define_expand "xbegin"
17625 [(set (match_operand:SI 0 "register_operand")
17626 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
17629 rtx label = gen_label_rtx ();
17631 /* xbegin is emitted as jump_insn, so reload won't be able
17632 to reload its operand. Force the value into AX hard register. */
17633 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
17634 emit_move_insn (ax_reg, constm1_rtx);
17636 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
17638 emit_label (label);
17639 LABEL_NUSES (label) = 1;
17641 emit_move_insn (operands[0], ax_reg);
17646 (define_insn "xbegin_1"
17648 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
17650 (label_ref (match_operand 1))
17652 (set (match_operand:SI 0 "register_operand" "+a")
17653 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
17656 [(set_attr "type" "other")
17657 (set_attr "length" "6")])
17659 (define_insn "xend"
17660 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
17663 [(set_attr "type" "other")
17664 (set_attr "length" "3")])
17666 (define_insn "xabort"
17667 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
17671 [(set_attr "type" "other")
17672 (set_attr "length" "3")])
17674 (define_expand "xtest"
17675 [(set (match_operand:QI 0 "register_operand")
17676 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
17679 emit_insn (gen_xtest_1 ());
17681 ix86_expand_setcc (operands[0], NE,
17682 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
17686 (define_insn "xtest_1"
17687 [(set (reg:CCZ FLAGS_REG)
17688 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
17691 [(set_attr "type" "other")
17692 (set_attr "length" "3")])
17696 (include "sync.md")