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,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,sselog1,
619 sseshuf1,sseadd1,sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
620 (match_operand 2 "memory_operand"))
621 (const_string "load")
622 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
623 (match_operand 3 "memory_operand"))
624 (const_string "load")
626 (const_string "none")))
628 ;; Indicates if an instruction has both an immediate and a displacement.
630 (define_attr "imm_disp" "false,true,unknown"
631 (cond [(eq_attr "type" "other,multi")
632 (const_string "unknown")
633 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
634 (and (match_operand 0 "memory_displacement_operand")
635 (match_operand 1 "immediate_operand")))
636 (const_string "true")
637 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
638 (and (match_operand 0 "memory_displacement_operand")
639 (match_operand 2 "immediate_operand")))
640 (const_string "true")
642 (const_string "false")))
644 ;; Indicates if an FP operation has an integer source.
646 (define_attr "fp_int_src" "false,true"
647 (const_string "false"))
649 ;; Defines rounding mode of an FP operation.
651 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
652 (const_string "any"))
654 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
655 (define_attr "use_carry" "0,1" (const_string "0"))
657 ;; Define attribute to indicate unaligned ssemov insns
658 (define_attr "movu" "0,1" (const_string "0"))
660 ;; Used to control the "enabled" attribute on a per-instruction basis.
661 (define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
662 sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
663 avx2,noavx2,bmi2,fma4,fma"
664 (const_string "base"))
666 (define_attr "enabled" ""
667 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
668 (eq_attr "isa" "x64_sse4")
669 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
670 (eq_attr "isa" "x64_sse4_noavx")
671 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
672 (eq_attr "isa" "x64_avx")
673 (symbol_ref "TARGET_64BIT && TARGET_AVX")
674 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
675 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
676 (eq_attr "isa" "sse2_noavx")
677 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
678 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
679 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
680 (eq_attr "isa" "sse4_noavx")
681 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
682 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
683 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
684 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
685 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
686 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
687 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
688 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
692 ;; Describe a user's asm statement.
693 (define_asm_attributes
694 [(set_attr "length" "128")
695 (set_attr "type" "multi")])
697 (define_code_iterator plusminus [plus minus])
699 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
701 ;; Base name for define_insn
702 (define_code_attr plusminus_insn
703 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
704 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
706 ;; Base name for insn mnemonic.
707 (define_code_attr plusminus_mnemonic
708 [(plus "add") (ss_plus "adds") (us_plus "addus")
709 (minus "sub") (ss_minus "subs") (us_minus "subus")])
710 (define_code_attr plusminus_carry_mnemonic
711 [(plus "adc") (minus "sbb")])
713 ;; Mark commutative operators as such in constraints.
714 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
715 (minus "") (ss_minus "") (us_minus "")])
717 ;; Mapping of max and min
718 (define_code_iterator maxmin [smax smin umax umin])
720 ;; Mapping of signed max and min
721 (define_code_iterator smaxmin [smax smin])
723 ;; Mapping of unsigned max and min
724 (define_code_iterator umaxmin [umax umin])
726 ;; Base name for integer and FP insn mnemonic
727 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
728 (umax "maxu") (umin "minu")])
729 (define_code_attr maxmin_float [(smax "max") (smin "min")])
731 ;; Mapping of logic operators
732 (define_code_iterator any_logic [and ior xor])
733 (define_code_iterator any_or [ior xor])
735 ;; Base name for insn mnemonic.
736 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
738 ;; Mapping of logic-shift operators
739 (define_code_iterator any_lshift [ashift lshiftrt])
741 ;; Mapping of shift-right operators
742 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
744 ;; Mapping of all shift operators
745 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
747 ;; Base name for define_insn
748 (define_code_attr shift_insn
749 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
751 ;; Base name for insn mnemonic.
752 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
753 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
755 ;; Mapping of rotate operators
756 (define_code_iterator any_rotate [rotate rotatert])
758 ;; Base name for define_insn
759 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
761 ;; Base name for insn mnemonic.
762 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
764 ;; Mapping of abs neg operators
765 (define_code_iterator absneg [abs neg])
767 ;; Base name for x87 insn mnemonic.
768 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
770 ;; Used in signed and unsigned widening multiplications.
771 (define_code_iterator any_extend [sign_extend zero_extend])
773 ;; Prefix for insn menmonic.
774 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
776 ;; Prefix for define_insn
777 (define_code_attr u [(sign_extend "") (zero_extend "u")])
778 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
779 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
781 ;; All integer modes.
782 (define_mode_iterator SWI1248x [QI HI SI DI])
784 ;; All integer modes without QImode.
785 (define_mode_iterator SWI248x [HI SI DI])
787 ;; All integer modes without QImode and HImode.
788 (define_mode_iterator SWI48x [SI DI])
790 ;; All integer modes without SImode and DImode.
791 (define_mode_iterator SWI12 [QI HI])
793 ;; All integer modes without DImode.
794 (define_mode_iterator SWI124 [QI HI SI])
796 ;; All integer modes without QImode and DImode.
797 (define_mode_iterator SWI24 [HI SI])
799 ;; Single word integer modes.
800 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
802 ;; Single word integer modes without QImode.
803 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
805 ;; Single word integer modes without QImode and HImode.
806 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
808 ;; All math-dependant single and double word integer modes.
809 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
810 (HI "TARGET_HIMODE_MATH")
811 SI DI (TI "TARGET_64BIT")])
813 ;; Math-dependant single word integer modes.
814 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
815 (HI "TARGET_HIMODE_MATH")
816 SI (DI "TARGET_64BIT")])
818 ;; Math-dependant integer modes without DImode.
819 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
820 (HI "TARGET_HIMODE_MATH")
823 ;; Math-dependant single word integer modes without QImode.
824 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
825 SI (DI "TARGET_64BIT")])
827 ;; Double word integer modes.
828 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
829 (TI "TARGET_64BIT")])
831 ;; Double word integer modes as mode attribute.
832 (define_mode_attr DWI [(SI "DI") (DI "TI")])
833 (define_mode_attr dwi [(SI "di") (DI "ti")])
835 ;; Half mode for double word integer modes.
836 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
837 (DI "TARGET_64BIT")])
839 ;; Instruction suffix for integer modes.
840 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
842 ;; Pointer size prefix for integer modes (Intel asm dialect)
843 (define_mode_attr iptrsize [(QI "BYTE")
848 ;; Register class for integer modes.
849 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
851 ;; Immediate operand constraint for integer modes.
852 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
854 ;; General operand constraint for word modes.
855 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
857 ;; Immediate operand constraint for double integer modes.
858 (define_mode_attr di [(SI "nF") (DI "e")])
860 ;; Immediate operand constraint for shifts.
861 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
863 ;; General operand predicate for integer modes.
864 (define_mode_attr general_operand
865 [(QI "general_operand")
866 (HI "general_operand")
867 (SI "x86_64_general_operand")
868 (DI "x86_64_general_operand")
869 (TI "x86_64_general_operand")])
871 ;; General sign/zero extend operand predicate for integer modes.
872 (define_mode_attr general_szext_operand
873 [(QI "general_operand")
874 (HI "general_operand")
875 (SI "x86_64_szext_general_operand")
876 (DI "x86_64_szext_general_operand")])
878 ;; Immediate operand predicate for integer modes.
879 (define_mode_attr immediate_operand
880 [(QI "immediate_operand")
881 (HI "immediate_operand")
882 (SI "x86_64_immediate_operand")
883 (DI "x86_64_immediate_operand")])
885 ;; Nonmemory operand predicate for integer modes.
886 (define_mode_attr nonmemory_operand
887 [(QI "nonmemory_operand")
888 (HI "nonmemory_operand")
889 (SI "x86_64_nonmemory_operand")
890 (DI "x86_64_nonmemory_operand")])
892 ;; Operand predicate for shifts.
893 (define_mode_attr shift_operand
894 [(QI "nonimmediate_operand")
895 (HI "nonimmediate_operand")
896 (SI "nonimmediate_operand")
897 (DI "shiftdi_operand")
898 (TI "register_operand")])
900 ;; Operand predicate for shift argument.
901 (define_mode_attr shift_immediate_operand
902 [(QI "const_1_to_31_operand")
903 (HI "const_1_to_31_operand")
904 (SI "const_1_to_31_operand")
905 (DI "const_1_to_63_operand")])
907 ;; Input operand predicate for arithmetic left shifts.
908 (define_mode_attr ashl_input_operand
909 [(QI "nonimmediate_operand")
910 (HI "nonimmediate_operand")
911 (SI "nonimmediate_operand")
912 (DI "ashldi_input_operand")
913 (TI "reg_or_pm1_operand")])
915 ;; SSE and x87 SFmode and DFmode floating point modes
916 (define_mode_iterator MODEF [SF DF])
918 ;; All x87 floating point modes
919 (define_mode_iterator X87MODEF [SF DF XF])
921 ;; SSE instruction suffix for various modes
922 (define_mode_attr ssemodesuffix
924 (V8SF "ps") (V4DF "pd")
925 (V4SF "ps") (V2DF "pd")
926 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
927 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
929 ;; SSE vector suffix for floating point modes
930 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
932 ;; SSE vector mode corresponding to a scalar mode
933 (define_mode_attr ssevecmode
934 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
935 (define_mode_attr ssevecmodelower
936 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
938 ;; Instruction suffix for REX 64bit operators.
939 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
941 ;; This mode iterator allows :P to be used for patterns that operate on
942 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
943 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
945 ;; This mode iterator allows :W to be used for patterns that operate on
946 ;; word_mode sized quantities.
947 (define_mode_iterator W
948 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
950 ;; This mode iterator allows :PTR to be used for patterns that operate on
951 ;; ptr_mode sized quantities.
952 (define_mode_iterator PTR
953 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
955 ;; Scheduling descriptions
957 (include "pentium.md")
960 (include "athlon.md")
961 (include "bdver1.md")
962 (include "bdver3.md")
963 (include "btver2.md")
969 ;; Operand and operator predicates and constraints
971 (include "predicates.md")
972 (include "constraints.md")
975 ;; Compare and branch/compare and store instructions.
977 (define_expand "cbranch<mode>4"
978 [(set (reg:CC FLAGS_REG)
979 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
980 (match_operand:SDWIM 2 "<general_operand>")))
981 (set (pc) (if_then_else
982 (match_operator 0 "ordered_comparison_operator"
983 [(reg:CC FLAGS_REG) (const_int 0)])
984 (label_ref (match_operand 3))
988 if (MEM_P (operands[1]) && MEM_P (operands[2]))
989 operands[1] = force_reg (<MODE>mode, operands[1]);
990 ix86_expand_branch (GET_CODE (operands[0]),
991 operands[1], operands[2], operands[3]);
995 (define_expand "cstore<mode>4"
996 [(set (reg:CC FLAGS_REG)
997 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
998 (match_operand:SWIM 3 "<general_operand>")))
999 (set (match_operand:QI 0 "register_operand")
1000 (match_operator 1 "ordered_comparison_operator"
1001 [(reg:CC FLAGS_REG) (const_int 0)]))]
1004 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1005 operands[2] = force_reg (<MODE>mode, operands[2]);
1006 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1007 operands[2], operands[3]);
1011 (define_expand "cmp<mode>_1"
1012 [(set (reg:CC FLAGS_REG)
1013 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1014 (match_operand:SWI48 1 "<general_operand>")))])
1016 (define_insn "*cmp<mode>_ccno_1"
1017 [(set (reg FLAGS_REG)
1018 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1019 (match_operand:SWI 1 "const0_operand")))]
1020 "ix86_match_ccmode (insn, CCNOmode)"
1022 test{<imodesuffix>}\t%0, %0
1023 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1024 [(set_attr "type" "test,icmp")
1025 (set_attr "length_immediate" "0,1")
1026 (set_attr "mode" "<MODE>")])
1028 (define_insn "*cmp<mode>_1"
1029 [(set (reg FLAGS_REG)
1030 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1031 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1032 "ix86_match_ccmode (insn, CCmode)"
1033 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1034 [(set_attr "type" "icmp")
1035 (set_attr "mode" "<MODE>")])
1037 (define_insn "*cmp<mode>_minus_1"
1038 [(set (reg FLAGS_REG)
1040 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1041 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1043 "ix86_match_ccmode (insn, CCGOCmode)"
1044 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1045 [(set_attr "type" "icmp")
1046 (set_attr "mode" "<MODE>")])
1048 (define_insn "*cmpqi_ext_1"
1049 [(set (reg FLAGS_REG)
1051 (match_operand:QI 0 "nonimmediate_x64nomem_operand" "Q,m")
1054 (match_operand 1 "ext_register_operand" "Q,Q")
1056 (const_int 8)) 0)))]
1057 "ix86_match_ccmode (insn, CCmode)"
1058 "cmp{b}\t{%h1, %0|%0, %h1}"
1059 [(set_attr "isa" "*,nox64")
1060 (set_attr "type" "icmp")
1061 (set_attr "mode" "QI")])
1063 (define_insn "*cmpqi_ext_2"
1064 [(set (reg FLAGS_REG)
1068 (match_operand 0 "ext_register_operand" "Q")
1071 (match_operand:QI 1 "const0_operand")))]
1072 "ix86_match_ccmode (insn, CCNOmode)"
1074 [(set_attr "type" "test")
1075 (set_attr "length_immediate" "0")
1076 (set_attr "mode" "QI")])
1078 (define_expand "cmpqi_ext_3"
1079 [(set (reg:CC FLAGS_REG)
1083 (match_operand 0 "ext_register_operand")
1086 (match_operand:QI 1 "const_int_operand")))])
1088 (define_insn "*cmpqi_ext_3"
1089 [(set (reg FLAGS_REG)
1093 (match_operand 0 "ext_register_operand" "Q,Q")
1096 (match_operand:QI 1 "general_x64nomem_operand" "Qn,m")))]
1097 "ix86_match_ccmode (insn, CCmode)"
1098 "cmp{b}\t{%1, %h0|%h0, %1}"
1099 [(set_attr "isa" "*,nox64")
1100 (set_attr "type" "icmp")
1101 (set_attr "modrm" "1")
1102 (set_attr "mode" "QI")])
1104 (define_insn "*cmpqi_ext_4"
1105 [(set (reg FLAGS_REG)
1109 (match_operand 0 "ext_register_operand" "Q")
1114 (match_operand 1 "ext_register_operand" "Q")
1116 (const_int 8)) 0)))]
1117 "ix86_match_ccmode (insn, CCmode)"
1118 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1119 [(set_attr "type" "icmp")
1120 (set_attr "mode" "QI")])
1122 ;; These implement float point compares.
1123 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1124 ;; which would allow mix and match FP modes on the compares. Which is what
1125 ;; the old patterns did, but with many more of them.
1127 (define_expand "cbranchxf4"
1128 [(set (reg:CC FLAGS_REG)
1129 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1130 (match_operand:XF 2 "nonmemory_operand")))
1131 (set (pc) (if_then_else
1132 (match_operator 0 "ix86_fp_comparison_operator"
1135 (label_ref (match_operand 3))
1139 ix86_expand_branch (GET_CODE (operands[0]),
1140 operands[1], operands[2], operands[3]);
1144 (define_expand "cstorexf4"
1145 [(set (reg:CC FLAGS_REG)
1146 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1147 (match_operand:XF 3 "nonmemory_operand")))
1148 (set (match_operand:QI 0 "register_operand")
1149 (match_operator 1 "ix86_fp_comparison_operator"
1154 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1155 operands[2], operands[3]);
1159 (define_expand "cbranch<mode>4"
1160 [(set (reg:CC FLAGS_REG)
1161 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1162 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1163 (set (pc) (if_then_else
1164 (match_operator 0 "ix86_fp_comparison_operator"
1167 (label_ref (match_operand 3))
1169 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1171 ix86_expand_branch (GET_CODE (operands[0]),
1172 operands[1], operands[2], operands[3]);
1176 (define_expand "cstore<mode>4"
1177 [(set (reg:CC FLAGS_REG)
1178 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1179 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1180 (set (match_operand:QI 0 "register_operand")
1181 (match_operator 1 "ix86_fp_comparison_operator"
1184 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1186 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1187 operands[2], operands[3]);
1191 (define_expand "cbranchcc4"
1192 [(set (pc) (if_then_else
1193 (match_operator 0 "comparison_operator"
1194 [(match_operand 1 "flags_reg_operand")
1195 (match_operand 2 "const0_operand")])
1196 (label_ref (match_operand 3))
1200 ix86_expand_branch (GET_CODE (operands[0]),
1201 operands[1], operands[2], operands[3]);
1205 (define_expand "cstorecc4"
1206 [(set (match_operand:QI 0 "register_operand")
1207 (match_operator 1 "comparison_operator"
1208 [(match_operand 2 "flags_reg_operand")
1209 (match_operand 3 "const0_operand")]))]
1212 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1213 operands[2], operands[3]);
1218 ;; FP compares, step 1:
1219 ;; Set the FP condition codes.
1221 ;; CCFPmode compare with exceptions
1222 ;; CCFPUmode compare with no exceptions
1224 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1225 ;; used to manage the reg stack popping would not be preserved.
1227 (define_insn "*cmp<mode>_0_i387"
1228 [(set (match_operand:HI 0 "register_operand" "=a")
1231 (match_operand:X87MODEF 1 "register_operand" "f")
1232 (match_operand:X87MODEF 2 "const0_operand"))]
1235 "* return output_fp_compare (insn, operands, false, false);"
1236 [(set_attr "type" "multi")
1237 (set_attr "unit" "i387")
1238 (set_attr "mode" "<MODE>")])
1240 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1241 [(set (reg:CCFP FLAGS_REG)
1243 (match_operand:X87MODEF 1 "register_operand" "f")
1244 (match_operand:X87MODEF 2 "const0_operand")))
1245 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1246 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1248 "&& reload_completed"
1251 [(compare:CCFP (match_dup 1)(match_dup 2))]
1253 (set (reg:CC FLAGS_REG)
1254 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1256 [(set_attr "type" "multi")
1257 (set_attr "unit" "i387")
1258 (set_attr "mode" "<MODE>")])
1260 (define_insn "*cmpxf_i387"
1261 [(set (match_operand:HI 0 "register_operand" "=a")
1264 (match_operand:XF 1 "register_operand" "f")
1265 (match_operand:XF 2 "register_operand" "f"))]
1268 "* return output_fp_compare (insn, operands, false, false);"
1269 [(set_attr "type" "multi")
1270 (set_attr "unit" "i387")
1271 (set_attr "mode" "XF")])
1273 (define_insn_and_split "*cmpxf_cc_i387"
1274 [(set (reg:CCFP FLAGS_REG)
1276 (match_operand:XF 1 "register_operand" "f")
1277 (match_operand:XF 2 "register_operand" "f")))
1278 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1279 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1281 "&& reload_completed"
1284 [(compare:CCFP (match_dup 1)(match_dup 2))]
1286 (set (reg:CC FLAGS_REG)
1287 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1289 [(set_attr "type" "multi")
1290 (set_attr "unit" "i387")
1291 (set_attr "mode" "XF")])
1293 (define_insn "*cmp<mode>_i387"
1294 [(set (match_operand:HI 0 "register_operand" "=a")
1297 (match_operand:MODEF 1 "register_operand" "f")
1298 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1301 "* return output_fp_compare (insn, operands, false, false);"
1302 [(set_attr "type" "multi")
1303 (set_attr "unit" "i387")
1304 (set_attr "mode" "<MODE>")])
1306 (define_insn_and_split "*cmp<mode>_cc_i387"
1307 [(set (reg:CCFP FLAGS_REG)
1309 (match_operand:MODEF 1 "register_operand" "f")
1310 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1311 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1312 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1314 "&& reload_completed"
1317 [(compare:CCFP (match_dup 1)(match_dup 2))]
1319 (set (reg:CC FLAGS_REG)
1320 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1322 [(set_attr "type" "multi")
1323 (set_attr "unit" "i387")
1324 (set_attr "mode" "<MODE>")])
1326 (define_insn "*cmpu<mode>_i387"
1327 [(set (match_operand:HI 0 "register_operand" "=a")
1330 (match_operand:X87MODEF 1 "register_operand" "f")
1331 (match_operand:X87MODEF 2 "register_operand" "f"))]
1334 "* return output_fp_compare (insn, operands, false, true);"
1335 [(set_attr "type" "multi")
1336 (set_attr "unit" "i387")
1337 (set_attr "mode" "<MODE>")])
1339 (define_insn_and_split "*cmpu<mode>_cc_i387"
1340 [(set (reg:CCFPU FLAGS_REG)
1342 (match_operand:X87MODEF 1 "register_operand" "f")
1343 (match_operand:X87MODEF 2 "register_operand" "f")))
1344 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1345 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1347 "&& reload_completed"
1350 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1352 (set (reg:CC FLAGS_REG)
1353 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1355 [(set_attr "type" "multi")
1356 (set_attr "unit" "i387")
1357 (set_attr "mode" "<MODE>")])
1359 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1360 [(set (match_operand:HI 0 "register_operand" "=a")
1363 (match_operand:X87MODEF 1 "register_operand" "f")
1364 (match_operator:X87MODEF 3 "float_operator"
1365 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1368 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1369 || optimize_function_for_size_p (cfun))"
1370 "* return output_fp_compare (insn, operands, false, false);"
1371 [(set_attr "type" "multi")
1372 (set_attr "unit" "i387")
1373 (set_attr "fp_int_src" "true")
1374 (set_attr "mode" "<SWI24:MODE>")])
1376 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1377 [(set (reg:CCFP FLAGS_REG)
1379 (match_operand:X87MODEF 1 "register_operand" "f")
1380 (match_operator:X87MODEF 3 "float_operator"
1381 [(match_operand:SWI24 2 "memory_operand" "m")])))
1382 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1383 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1384 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1385 || optimize_function_for_size_p (cfun))"
1387 "&& reload_completed"
1392 (match_op_dup 3 [(match_dup 2)]))]
1394 (set (reg:CC FLAGS_REG)
1395 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1397 [(set_attr "type" "multi")
1398 (set_attr "unit" "i387")
1399 (set_attr "fp_int_src" "true")
1400 (set_attr "mode" "<SWI24:MODE>")])
1402 ;; FP compares, step 2
1403 ;; Move the fpsw to ax.
1405 (define_insn "x86_fnstsw_1"
1406 [(set (match_operand:HI 0 "register_operand" "=a")
1407 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1410 [(set (attr "length")
1411 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1412 (set_attr "mode" "SI")
1413 (set_attr "unit" "i387")])
1415 ;; FP compares, step 3
1416 ;; Get ax into flags, general case.
1418 (define_insn "x86_sahf_1"
1419 [(set (reg:CC FLAGS_REG)
1420 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1424 #ifndef HAVE_AS_IX86_SAHF
1426 return ASM_BYTE "0x9e";
1431 [(set_attr "length" "1")
1432 (set_attr "athlon_decode" "vector")
1433 (set_attr "amdfam10_decode" "direct")
1434 (set_attr "bdver1_decode" "direct")
1435 (set_attr "mode" "SI")])
1437 ;; Pentium Pro can do steps 1 through 3 in one go.
1438 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1439 ;; (these i387 instructions set flags directly)
1441 (define_mode_iterator FPCMP [CCFP CCFPU])
1442 (define_mode_attr unord [(CCFP "") (CCFPU "u")])
1444 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_mixed"
1445 [(set (reg:FPCMP FLAGS_REG)
1447 (match_operand:MODEF 0 "register_operand" "f,x")
1448 (match_operand:MODEF 1 "nonimmediate_operand" "f,xm")))]
1449 "TARGET_MIX_SSE_I387
1450 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1451 "* return output_fp_compare (insn, operands, true,
1452 <FPCMP:MODE>mode == CCFPUmode);"
1453 [(set_attr "type" "fcmp,ssecomi")
1454 (set_attr "prefix" "orig,maybe_vex")
1455 (set_attr "mode" "<MODEF:MODE>")
1456 (set (attr "prefix_rep")
1457 (if_then_else (eq_attr "type" "ssecomi")
1459 (const_string "*")))
1460 (set (attr "prefix_data16")
1461 (cond [(eq_attr "type" "fcmp")
1463 (eq_attr "mode" "DF")
1466 (const_string "0")))
1467 (set_attr "athlon_decode" "vector")
1468 (set_attr "amdfam10_decode" "direct")
1469 (set_attr "bdver1_decode" "double")])
1471 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_sse"
1472 [(set (reg:FPCMP FLAGS_REG)
1474 (match_operand:MODEF 0 "register_operand" "x")
1475 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
1477 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1478 "* return output_fp_compare (insn, operands, true,
1479 <FPCMP:MODE>mode == CCFPUmode);"
1480 [(set_attr "type" "ssecomi")
1481 (set_attr "prefix" "maybe_vex")
1482 (set_attr "mode" "<MODEF:MODE>")
1483 (set_attr "prefix_rep" "0")
1484 (set (attr "prefix_data16")
1485 (if_then_else (eq_attr "mode" "DF")
1487 (const_string "0")))
1488 (set_attr "athlon_decode" "vector")
1489 (set_attr "amdfam10_decode" "direct")
1490 (set_attr "bdver1_decode" "double")])
1492 (define_insn "*cmpi<FPCMP:unord><X87MODEF:mode>_i387"
1493 [(set (reg:FPCMP FLAGS_REG)
1495 (match_operand:X87MODEF 0 "register_operand" "f")
1496 (match_operand:X87MODEF 1 "register_operand" "f")))]
1497 "TARGET_80387 && TARGET_CMOVE
1498 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
1499 "* return output_fp_compare (insn, operands, true,
1500 <FPCMP:MODE>mode == CCFPUmode);"
1501 [(set_attr "type" "fcmp")
1502 (set_attr "mode" "<X87MODEF:MODE>")
1503 (set_attr "athlon_decode" "vector")
1504 (set_attr "amdfam10_decode" "direct")
1505 (set_attr "bdver1_decode" "double")])
1507 ;; Push/pop instructions.
1509 (define_insn "*push<mode>2"
1510 [(set (match_operand:DWI 0 "push_operand" "=<")
1511 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1514 [(set_attr "type" "multi")
1515 (set_attr "mode" "<MODE>")])
1518 [(set (match_operand:TI 0 "push_operand")
1519 (match_operand:TI 1 "general_operand"))]
1520 "TARGET_64BIT && reload_completed
1521 && !SSE_REG_P (operands[1])"
1523 "ix86_split_long_move (operands); DONE;")
1525 (define_insn "*pushdi2_rex64"
1526 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1527 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1532 [(set_attr "type" "push,multi")
1533 (set_attr "mode" "DI")])
1535 ;; Convert impossible pushes of immediate to existing instructions.
1536 ;; First try to get scratch register and go through it. In case this
1537 ;; fails, push sign extended lower part first and then overwrite
1538 ;; upper part by 32bit move.
1540 [(match_scratch:DI 2 "r")
1541 (set (match_operand:DI 0 "push_operand")
1542 (match_operand:DI 1 "immediate_operand"))]
1543 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1544 && !x86_64_immediate_operand (operands[1], DImode)"
1545 [(set (match_dup 2) (match_dup 1))
1546 (set (match_dup 0) (match_dup 2))])
1548 ;; We need to define this as both peepholer and splitter for case
1549 ;; peephole2 pass is not run.
1550 ;; "&& 1" is needed to keep it from matching the previous pattern.
1552 [(set (match_operand:DI 0 "push_operand")
1553 (match_operand:DI 1 "immediate_operand"))]
1554 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1555 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1556 [(set (match_dup 0) (match_dup 1))
1557 (set (match_dup 2) (match_dup 3))]
1559 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1561 operands[1] = gen_lowpart (DImode, operands[2]);
1562 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1567 [(set (match_operand:DI 0 "push_operand")
1568 (match_operand:DI 1 "immediate_operand"))]
1569 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1570 ? epilogue_completed : reload_completed)
1571 && !symbolic_operand (operands[1], DImode)
1572 && !x86_64_immediate_operand (operands[1], DImode)"
1573 [(set (match_dup 0) (match_dup 1))
1574 (set (match_dup 2) (match_dup 3))]
1576 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1578 operands[1] = gen_lowpart (DImode, operands[2]);
1579 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1584 [(set (match_operand:DI 0 "push_operand")
1585 (match_operand:DI 1 "general_operand"))]
1586 "!TARGET_64BIT && reload_completed
1587 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1589 "ix86_split_long_move (operands); DONE;")
1591 (define_insn "*pushsi2"
1592 [(set (match_operand:SI 0 "push_operand" "=<")
1593 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1596 [(set_attr "type" "push")
1597 (set_attr "mode" "SI")])
1599 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1600 ;; "push a byte/word". But actually we use pushl, which has the effect
1601 ;; of rounding the amount pushed up to a word.
1603 ;; For TARGET_64BIT we always round up to 8 bytes.
1604 (define_insn "*push<mode>2_rex64"
1605 [(set (match_operand:SWI124 0 "push_operand" "=X")
1606 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1609 [(set_attr "type" "push")
1610 (set_attr "mode" "DI")])
1612 (define_insn "*push<mode>2"
1613 [(set (match_operand:SWI12 0 "push_operand" "=X")
1614 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1617 [(set_attr "type" "push")
1618 (set_attr "mode" "SI")])
1620 (define_insn "*push<mode>2_prologue"
1621 [(set (match_operand:W 0 "push_operand" "=<")
1622 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1623 (clobber (mem:BLK (scratch)))]
1625 "push{<imodesuffix>}\t%1"
1626 [(set_attr "type" "push")
1627 (set_attr "mode" "<MODE>")])
1629 (define_insn "*pop<mode>1"
1630 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1631 (match_operand:W 1 "pop_operand" ">"))]
1633 "pop{<imodesuffix>}\t%0"
1634 [(set_attr "type" "pop")
1635 (set_attr "mode" "<MODE>")])
1637 (define_insn "*pop<mode>1_epilogue"
1638 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1639 (match_operand:W 1 "pop_operand" ">"))
1640 (clobber (mem:BLK (scratch)))]
1642 "pop{<imodesuffix>}\t%0"
1643 [(set_attr "type" "pop")
1644 (set_attr "mode" "<MODE>")])
1646 ;; Move instructions.
1648 ;; Reload patterns to support multi-word load/store
1649 ;; with non-offsetable address.
1650 (define_expand "reload_noff_store"
1651 [(parallel [(match_operand 0 "memory_operand" "=m")
1652 (match_operand 1 "register_operand" "r")
1653 (match_operand:DI 2 "register_operand" "=&r")])]
1656 rtx mem = operands[0];
1657 rtx addr = XEXP (mem, 0);
1659 emit_move_insn (operands[2], addr);
1660 mem = replace_equiv_address_nv (mem, operands[2]);
1662 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
1666 (define_expand "reload_noff_load"
1667 [(parallel [(match_operand 0 "register_operand" "=r")
1668 (match_operand 1 "memory_operand" "m")
1669 (match_operand:DI 2 "register_operand" "=r")])]
1672 rtx mem = operands[1];
1673 rtx addr = XEXP (mem, 0);
1675 emit_move_insn (operands[2], addr);
1676 mem = replace_equiv_address_nv (mem, operands[2]);
1678 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
1682 (define_expand "movoi"
1683 [(set (match_operand:OI 0 "nonimmediate_operand")
1684 (match_operand:OI 1 "general_operand"))]
1686 "ix86_expand_move (OImode, operands); DONE;")
1688 (define_expand "movti"
1689 [(set (match_operand:TI 0 "nonimmediate_operand")
1690 (match_operand:TI 1 "nonimmediate_operand"))]
1691 "TARGET_64BIT || TARGET_SSE"
1694 ix86_expand_move (TImode, operands);
1695 else if (push_operand (operands[0], TImode))
1696 ix86_expand_push (TImode, operands[1]);
1698 ix86_expand_vector_move (TImode, operands);
1702 ;; This expands to what emit_move_complex would generate if we didn't
1703 ;; have a movti pattern. Having this avoids problems with reload on
1704 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1705 ;; to have around all the time.
1706 (define_expand "movcdi"
1707 [(set (match_operand:CDI 0 "nonimmediate_operand")
1708 (match_operand:CDI 1 "general_operand"))]
1711 if (push_operand (operands[0], CDImode))
1712 emit_move_complex_push (CDImode, operands[0], operands[1]);
1714 emit_move_complex_parts (operands[0], operands[1]);
1718 (define_expand "mov<mode>"
1719 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1720 (match_operand:SWI1248x 1 "general_operand"))]
1722 "ix86_expand_move (<MODE>mode, operands); DONE;")
1724 (define_insn "*mov<mode>_xor"
1725 [(set (match_operand:SWI48 0 "register_operand" "=r")
1726 (match_operand:SWI48 1 "const0_operand"))
1727 (clobber (reg:CC FLAGS_REG))]
1730 [(set_attr "type" "alu1")
1731 (set_attr "mode" "SI")
1732 (set_attr "length_immediate" "0")])
1734 (define_insn "*mov<mode>_or"
1735 [(set (match_operand:SWI48 0 "register_operand" "=r")
1736 (match_operand:SWI48 1 "const_int_operand"))
1737 (clobber (reg:CC FLAGS_REG))]
1739 && operands[1] == constm1_rtx"
1740 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1741 [(set_attr "type" "alu1")
1742 (set_attr "mode" "<MODE>")
1743 (set_attr "length_immediate" "1")])
1745 (define_insn "*movoi_internal_avx"
1746 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x ,m")
1747 (match_operand:OI 1 "vector_move_operand" "C ,xm,x"))]
1748 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1750 switch (get_attr_type (insn))
1753 return standard_sse_constant_opcode (insn, operands[1]);
1756 if (misaligned_operand (operands[0], OImode)
1757 || misaligned_operand (operands[1], OImode))
1759 if (get_attr_mode (insn) == MODE_V8SF)
1760 return "vmovups\t{%1, %0|%0, %1}";
1762 return "vmovdqu\t{%1, %0|%0, %1}";
1766 if (get_attr_mode (insn) == MODE_V8SF)
1767 return "vmovaps\t{%1, %0|%0, %1}";
1769 return "vmovdqa\t{%1, %0|%0, %1}";
1776 [(set_attr "type" "sselog1,ssemov,ssemov")
1777 (set_attr "prefix" "vex")
1779 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1780 (const_string "V8SF")
1781 (and (eq_attr "alternative" "2")
1782 (match_test "TARGET_SSE_TYPELESS_STORES"))
1783 (const_string "V8SF")
1785 (const_string "OI")))])
1787 (define_insn "*movti_internal"
1788 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,x,x ,m")
1789 (match_operand:TI 1 "general_operand" "riFo,re,C,xm,x"))]
1790 "(TARGET_64BIT || TARGET_SSE)
1791 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1793 switch (get_attr_type (insn))
1799 return standard_sse_constant_opcode (insn, operands[1]);
1802 /* TDmode values are passed as TImode on the stack. Moving them
1803 to stack may result in unaligned memory access. */
1804 if (misaligned_operand (operands[0], TImode)
1805 || misaligned_operand (operands[1], TImode))
1807 if (get_attr_mode (insn) == MODE_V4SF)
1808 return "%vmovups\t{%1, %0|%0, %1}";
1810 return "%vmovdqu\t{%1, %0|%0, %1}";
1814 if (get_attr_mode (insn) == MODE_V4SF)
1815 return "%vmovaps\t{%1, %0|%0, %1}";
1817 return "%vmovdqa\t{%1, %0|%0, %1}";
1824 [(set_attr "isa" "x64,x64,*,*,*")
1825 (set_attr "type" "multi,multi,sselog1,ssemov,ssemov")
1826 (set (attr "prefix")
1827 (if_then_else (eq_attr "type" "sselog1,ssemov")
1828 (const_string "maybe_vex")
1829 (const_string "orig")))
1831 (cond [(eq_attr "alternative" "0,1")
1833 (ior (not (match_test "TARGET_SSE2"))
1834 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
1835 (const_string "V4SF")
1836 (and (eq_attr "alternative" "4")
1837 (match_test "TARGET_SSE_TYPELESS_STORES"))
1838 (const_string "V4SF")
1839 (match_test "TARGET_AVX")
1841 (match_test "optimize_function_for_size_p (cfun)")
1842 (const_string "V4SF")
1844 (const_string "TI")))])
1847 [(set (match_operand:TI 0 "nonimmediate_operand")
1848 (match_operand:TI 1 "general_operand"))]
1850 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1852 "ix86_split_long_move (operands); DONE;")
1854 (define_insn "*movdi_internal"
1855 [(set (match_operand:DI 0 "nonimmediate_operand"
1856 "=r ,o ,r,r ,r,m ,*y,*y,?*y,?m,?r ,?*Ym,*x,*x,*x,m ,?r ,?r,?*Yi,?*Ym,?*Yi")
1857 (match_operand:DI 1 "general_operand"
1858 "riFo,riF,Z,rem,i,re,C ,*y,m ,*y,*Yn,r ,C ,*x,m ,*x,*Yj,*x,r ,*Yj ,*Yn"))]
1859 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1861 switch (get_attr_type (insn))
1867 return "pxor\t%0, %0";
1870 #ifndef HAVE_AS_IX86_INTERUNIT_MOVQ
1871 /* Handle broken assemblers that require movd instead of movq. */
1872 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1873 return "movd\t{%1, %0|%0, %1}";
1875 return "movq\t{%1, %0|%0, %1}";
1878 if (GENERAL_REG_P (operands[0]))
1879 return "%vpextrq\t{$0, %1, %0|%0, %1, 0}";
1881 return standard_sse_constant_opcode (insn, operands[1]);
1884 switch (get_attr_mode (insn))
1887 #ifndef HAVE_AS_IX86_INTERUNIT_MOVQ
1888 /* Handle broken assemblers that require movd instead of movq. */
1889 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1890 return "%vmovd\t{%1, %0|%0, %1}";
1892 return "%vmovq\t{%1, %0|%0, %1}";
1894 return "%vmovdqa\t{%1, %0|%0, %1}";
1897 gcc_assert (!TARGET_AVX);
1898 return "movlps\t{%1, %0|%0, %1}";
1900 return "%vmovaps\t{%1, %0|%0, %1}";
1907 if (SSE_REG_P (operands[0]))
1908 return "movq2dq\t{%1, %0|%0, %1}";
1910 return "movdq2q\t{%1, %0|%0, %1}";
1913 return "lea{q}\t{%E1, %0|%0, %E1}";
1916 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1917 if (get_attr_mode (insn) == MODE_SI)
1918 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1919 else if (which_alternative == 4)
1920 return "movabs{q}\t{%1, %0|%0, %1}";
1921 else if (ix86_use_lea_for_mov (insn, operands))
1922 return "lea{q}\t{%E1, %0|%0, %E1}";
1924 return "mov{q}\t{%1, %0|%0, %1}";
1931 (cond [(eq_attr "alternative" "0,1")
1932 (const_string "nox64")
1933 (eq_attr "alternative" "2,3,4,5,10,11,16,18")
1934 (const_string "x64")
1935 (eq_attr "alternative" "17")
1936 (const_string "x64_sse4")
1938 (const_string "*")))
1940 (cond [(eq_attr "alternative" "0,1")
1941 (const_string "multi")
1942 (eq_attr "alternative" "6")
1943 (const_string "mmx")
1944 (eq_attr "alternative" "7,8,9,10,11")
1945 (const_string "mmxmov")
1946 (eq_attr "alternative" "12,17")
1947 (const_string "sselog1")
1948 (eq_attr "alternative" "13,14,15,16,18")
1949 (const_string "ssemov")
1950 (eq_attr "alternative" "19,20")
1951 (const_string "ssecvt")
1952 (match_operand 1 "pic_32bit_operand")
1953 (const_string "lea")
1955 (const_string "imov")))
1958 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
1960 (const_string "*")))
1961 (set (attr "length_immediate")
1962 (cond [(and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
1964 (eq_attr "alternative" "17")
1967 (const_string "*")))
1968 (set (attr "prefix_rex")
1969 (if_then_else (eq_attr "alternative" "10,11,16,17,18")
1971 (const_string "*")))
1972 (set (attr "prefix_extra")
1973 (if_then_else (eq_attr "alternative" "17")
1975 (const_string "*")))
1976 (set (attr "prefix")
1977 (if_then_else (eq_attr "type" "sselog1,ssemov")
1978 (const_string "maybe_vex")
1979 (const_string "orig")))
1980 (set (attr "prefix_data16")
1981 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
1983 (const_string "*")))
1985 (cond [(eq_attr "alternative" "2")
1987 (eq_attr "alternative" "12,13")
1988 (cond [(ior (not (match_test "TARGET_SSE2"))
1989 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
1990 (const_string "V4SF")
1991 (match_test "TARGET_AVX")
1993 (match_test "optimize_function_for_size_p (cfun)")
1994 (const_string "V4SF")
1996 (const_string "TI"))
1998 (and (eq_attr "alternative" "14,15")
1999 (not (match_test "TARGET_SSE2")))
2000 (const_string "V2SF")
2001 (eq_attr "alternative" "17")
2004 (const_string "DI")))])
2007 [(set (match_operand:DI 0 "nonimmediate_operand")
2008 (match_operand:DI 1 "general_operand"))]
2009 "!TARGET_64BIT && reload_completed
2010 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2011 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2013 "ix86_split_long_move (operands); DONE;")
2015 (define_insn "*movsi_internal"
2016 [(set (match_operand:SI 0 "nonimmediate_operand"
2017 "=r,m ,*y,*y,?rm,?*y,*x,*x,*x,m ,?r ,?r,?*Yi")
2018 (match_operand:SI 1 "general_operand"
2019 "g ,re,C ,*y,*y ,rm ,C ,*x,m ,*x,*Yj,*x,r"))]
2020 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2022 switch (get_attr_type (insn))
2025 if (GENERAL_REG_P (operands[0]))
2026 return "%vpextrd\t{$0, %1, %0|%0, %1, 0}";
2028 return standard_sse_constant_opcode (insn, operands[1]);
2031 switch (get_attr_mode (insn))
2034 return "%vmovd\t{%1, %0|%0, %1}";
2036 return "%vmovdqa\t{%1, %0|%0, %1}";
2039 return "%vmovaps\t{%1, %0|%0, %1}";
2042 gcc_assert (!TARGET_AVX);
2043 return "movss\t{%1, %0|%0, %1}";
2050 return "pxor\t%0, %0";
2053 switch (get_attr_mode (insn))
2056 return "movq\t{%1, %0|%0, %1}";
2058 return "movd\t{%1, %0|%0, %1}";
2065 return "lea{l}\t{%E1, %0|%0, %E1}";
2068 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2069 if (ix86_use_lea_for_mov (insn, operands))
2070 return "lea{l}\t{%E1, %0|%0, %E1}";
2072 return "mov{l}\t{%1, %0|%0, %1}";
2079 (if_then_else (eq_attr "alternative" "11")
2080 (const_string "sse4")
2081 (const_string "*")))
2083 (cond [(eq_attr "alternative" "2")
2084 (const_string "mmx")
2085 (eq_attr "alternative" "3,4,5")
2086 (const_string "mmxmov")
2087 (eq_attr "alternative" "6,11")
2088 (const_string "sselog1")
2089 (eq_attr "alternative" "7,8,9,10,12")
2090 (const_string "ssemov")
2091 (match_operand 1 "pic_32bit_operand")
2092 (const_string "lea")
2094 (const_string "imov")))
2095 (set (attr "length_immediate")
2096 (if_then_else (eq_attr "alternative" "11")
2098 (const_string "*")))
2099 (set (attr "prefix_extra")
2100 (if_then_else (eq_attr "alternative" "11")
2102 (const_string "*")))
2103 (set (attr "prefix")
2104 (if_then_else (eq_attr "type" "sselog1,ssemov")
2105 (const_string "maybe_vex")
2106 (const_string "orig")))
2107 (set (attr "prefix_data16")
2108 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2110 (const_string "*")))
2112 (cond [(eq_attr "alternative" "2,3")
2114 (eq_attr "alternative" "6,7")
2115 (cond [(ior (not (match_test "TARGET_SSE2"))
2116 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2117 (const_string "V4SF")
2118 (match_test "TARGET_AVX")
2120 (match_test "optimize_function_for_size_p (cfun)")
2121 (const_string "V4SF")
2123 (const_string "TI"))
2125 (and (eq_attr "alternative" "8,9")
2126 (not (match_test "TARGET_SSE2")))
2128 (eq_attr "alternative" "11")
2131 (const_string "SI")))])
2133 (define_insn "*movhi_internal"
2134 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m")
2135 (match_operand:HI 1 "general_operand" "r ,rn,rm,rn"))]
2136 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2138 switch (get_attr_type (insn))
2141 /* movzwl is faster than movw on p2 due to partial word stalls,
2142 though not as fast as an aligned movl. */
2143 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2145 if (get_attr_mode (insn) == MODE_SI)
2146 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2148 return "mov{w}\t{%1, %0|%0, %1}";
2152 (cond [(match_test "optimize_function_for_size_p (cfun)")
2153 (const_string "imov")
2154 (and (eq_attr "alternative" "0")
2155 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2156 (not (match_test "TARGET_HIMODE_MATH"))))
2157 (const_string "imov")
2158 (and (eq_attr "alternative" "1,2")
2159 (match_operand:HI 1 "aligned_operand"))
2160 (const_string "imov")
2161 (and (match_test "TARGET_MOVX")
2162 (eq_attr "alternative" "0,2"))
2163 (const_string "imovx")
2165 (const_string "imov")))
2167 (cond [(eq_attr "type" "imovx")
2169 (and (eq_attr "alternative" "1,2")
2170 (match_operand:HI 1 "aligned_operand"))
2172 (and (eq_attr "alternative" "0")
2173 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2174 (not (match_test "TARGET_HIMODE_MATH"))))
2177 (const_string "HI")))])
2179 ;; Situation is quite tricky about when to choose full sized (SImode) move
2180 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2181 ;; partial register dependency machines (such as AMD Athlon), where QImode
2182 ;; moves issue extra dependency and for partial register stalls machines
2183 ;; that don't use QImode patterns (and QImode move cause stall on the next
2186 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2187 ;; register stall machines with, where we use QImode instructions, since
2188 ;; partial register stall can be caused there. Then we use movzx.
2189 (define_insn "*movqi_internal"
2190 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2191 (match_operand:QI 1 "general_operand" "q ,qn,qm,q,rn,qm,qn"))]
2192 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2194 switch (get_attr_type (insn))
2197 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2198 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2200 if (get_attr_mode (insn) == MODE_SI)
2201 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2203 return "mov{b}\t{%1, %0|%0, %1}";
2207 (cond [(and (eq_attr "alternative" "5")
2208 (not (match_operand:QI 1 "aligned_operand")))
2209 (const_string "imovx")
2210 (match_test "optimize_function_for_size_p (cfun)")
2211 (const_string "imov")
2212 (and (eq_attr "alternative" "3")
2213 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2214 (not (match_test "TARGET_QIMODE_MATH"))))
2215 (const_string "imov")
2216 (eq_attr "alternative" "3,5")
2217 (const_string "imovx")
2218 (and (match_test "TARGET_MOVX")
2219 (eq_attr "alternative" "2"))
2220 (const_string "imovx")
2222 (const_string "imov")))
2224 (cond [(eq_attr "alternative" "3,4,5")
2226 (eq_attr "alternative" "6")
2228 (eq_attr "type" "imovx")
2230 (and (eq_attr "type" "imov")
2231 (and (eq_attr "alternative" "0,1")
2232 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2233 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2234 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2236 ;; Avoid partial register stalls when not using QImode arithmetic
2237 (and (eq_attr "type" "imov")
2238 (and (eq_attr "alternative" "0,1")
2239 (and (match_test "TARGET_PARTIAL_REG_STALL")
2240 (not (match_test "TARGET_QIMODE_MATH")))))
2243 (const_string "QI")))])
2245 ;; Stores and loads of ax to arbitrary constant address.
2246 ;; We fake an second form of instruction to force reload to load address
2247 ;; into register when rax is not available
2248 (define_insn "*movabs<mode>_1"
2249 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2250 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2251 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2253 movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1}
2254 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2255 [(set_attr "type" "imov")
2256 (set_attr "modrm" "0,*")
2257 (set_attr "length_address" "8,0")
2258 (set_attr "length_immediate" "0,*")
2259 (set_attr "memory" "store")
2260 (set_attr "mode" "<MODE>")])
2262 (define_insn "*movabs<mode>_2"
2263 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2264 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2265 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2267 movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]}
2268 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2269 [(set_attr "type" "imov")
2270 (set_attr "modrm" "0,*")
2271 (set_attr "length_address" "8,0")
2272 (set_attr "length_immediate" "0")
2273 (set_attr "memory" "load")
2274 (set_attr "mode" "<MODE>")])
2276 (define_insn "swap<mode>"
2277 [(set (match_operand:SWI48 0 "register_operand" "+r")
2278 (match_operand:SWI48 1 "register_operand" "+r"))
2282 "xchg{<imodesuffix>}\t%1, %0"
2283 [(set_attr "type" "imov")
2284 (set_attr "mode" "<MODE>")
2285 (set_attr "pent_pair" "np")
2286 (set_attr "athlon_decode" "vector")
2287 (set_attr "amdfam10_decode" "double")
2288 (set_attr "bdver1_decode" "double")])
2290 (define_insn "*swap<mode>_1"
2291 [(set (match_operand:SWI12 0 "register_operand" "+r")
2292 (match_operand:SWI12 1 "register_operand" "+r"))
2295 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2297 [(set_attr "type" "imov")
2298 (set_attr "mode" "SI")
2299 (set_attr "pent_pair" "np")
2300 (set_attr "athlon_decode" "vector")
2301 (set_attr "amdfam10_decode" "double")
2302 (set_attr "bdver1_decode" "double")])
2304 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2305 ;; is disabled for AMDFAM10
2306 (define_insn "*swap<mode>_2"
2307 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2308 (match_operand:SWI12 1 "register_operand" "+<r>"))
2311 "TARGET_PARTIAL_REG_STALL"
2312 "xchg{<imodesuffix>}\t%1, %0"
2313 [(set_attr "type" "imov")
2314 (set_attr "mode" "<MODE>")
2315 (set_attr "pent_pair" "np")
2316 (set_attr "athlon_decode" "vector")])
2318 (define_expand "movstrict<mode>"
2319 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2320 (match_operand:SWI12 1 "general_operand"))]
2323 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2325 if (GET_CODE (operands[0]) == SUBREG
2326 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2328 /* Don't generate memory->memory moves, go through a register */
2329 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2330 operands[1] = force_reg (<MODE>mode, operands[1]);
2333 (define_insn "*movstrict<mode>_1"
2334 [(set (strict_low_part
2335 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2336 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2337 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2338 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2339 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2340 [(set_attr "type" "imov")
2341 (set_attr "mode" "<MODE>")])
2343 (define_insn "*movstrict<mode>_xor"
2344 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2345 (match_operand:SWI12 1 "const0_operand"))
2346 (clobber (reg:CC FLAGS_REG))]
2348 "xor{<imodesuffix>}\t%0, %0"
2349 [(set_attr "type" "alu1")
2350 (set_attr "mode" "<MODE>")
2351 (set_attr "length_immediate" "0")])
2353 (define_insn "*mov<mode>_extv_1"
2354 [(set (match_operand:SWI24 0 "register_operand" "=R")
2355 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2359 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2360 [(set_attr "type" "imovx")
2361 (set_attr "mode" "SI")])
2363 (define_insn "*movqi_extv_1"
2364 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2365 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2370 switch (get_attr_type (insn))
2373 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2375 return "mov{b}\t{%h1, %0|%0, %h1}";
2378 [(set_attr "isa" "*,*,nox64")
2380 (if_then_else (and (match_operand:QI 0 "register_operand")
2381 (ior (not (match_operand:QI 0 "QIreg_operand"))
2382 (match_test "TARGET_MOVX")))
2383 (const_string "imovx")
2384 (const_string "imov")))
2386 (if_then_else (eq_attr "type" "imovx")
2388 (const_string "QI")))])
2390 (define_insn "*mov<mode>_extzv_1"
2391 [(set (match_operand:SWI48 0 "register_operand" "=R")
2392 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2396 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2397 [(set_attr "type" "imovx")
2398 (set_attr "mode" "SI")])
2400 (define_insn "*movqi_extzv_2"
2401 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2403 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2408 switch (get_attr_type (insn))
2411 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2413 return "mov{b}\t{%h1, %0|%0, %h1}";
2416 [(set_attr "isa" "*,*,nox64")
2418 (if_then_else (and (match_operand:QI 0 "register_operand")
2419 (ior (not (match_operand:QI 0 "QIreg_operand"))
2420 (match_test "TARGET_MOVX")))
2421 (const_string "imovx")
2422 (const_string "imov")))
2424 (if_then_else (eq_attr "type" "imovx")
2426 (const_string "QI")))])
2428 (define_insn "mov<mode>_insv_1"
2429 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "+Q,Q")
2432 (match_operand:SWI48 1 "general_x64nomem_operand" "Qn,m"))]
2435 if (CONST_INT_P (operands[1]))
2436 operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2437 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2439 [(set_attr "isa" "*,nox64")
2440 (set_attr "type" "imov")
2441 (set_attr "mode" "QI")])
2443 (define_insn "*movqi_insv_2"
2444 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2447 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2450 "mov{b}\t{%h1, %h0|%h0, %h1}"
2451 [(set_attr "type" "imov")
2452 (set_attr "mode" "QI")])
2454 ;; Floating point push instructions.
2456 (define_insn "*pushtf"
2457 [(set (match_operand:TF 0 "push_operand" "=<,<")
2458 (match_operand:TF 1 "general_no_elim_operand" "x,*roF"))]
2459 "TARGET_64BIT || TARGET_SSE"
2461 /* This insn should be already split before reg-stack. */
2464 [(set_attr "isa" "*,x64")
2465 (set_attr "type" "multi")
2466 (set_attr "unit" "sse,*")
2467 (set_attr "mode" "TF,DI")])
2469 ;; %%% Kill this when call knows how to work this out.
2471 [(set (match_operand:TF 0 "push_operand")
2472 (match_operand:TF 1 "sse_reg_operand"))]
2473 "TARGET_SSE && reload_completed"
2474 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2475 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2477 (define_insn "*pushxf"
2478 [(set (match_operand:XF 0 "push_operand" "=<,<")
2479 (match_operand:XF 1 "general_no_elim_operand" "f,Yx*roF"))]
2482 /* This insn should be already split before reg-stack. */
2485 [(set_attr "type" "multi")
2486 (set_attr "unit" "i387,*")
2488 (cond [(eq_attr "alternative" "1")
2489 (if_then_else (match_test "TARGET_64BIT")
2491 (const_string "SI"))
2493 (const_string "XF")))])
2495 ;; %%% Kill this when call knows how to work this out.
2497 [(set (match_operand:XF 0 "push_operand")
2498 (match_operand:XF 1 "fp_register_operand"))]
2500 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2501 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2502 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2504 (define_insn "*pushdf"
2505 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2506 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*roF,rmF,x"))]
2509 /* This insn should be already split before reg-stack. */
2512 [(set_attr "isa" "*,nox64,x64,sse2")
2513 (set_attr "type" "multi")
2514 (set_attr "unit" "i387,*,*,sse")
2515 (set_attr "mode" "DF,SI,DI,DF")])
2517 ;; %%% Kill this when call knows how to work this out.
2519 [(set (match_operand:DF 0 "push_operand")
2520 (match_operand:DF 1 "any_fp_register_operand"))]
2522 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2523 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2525 (define_insn "*pushsf_rex64"
2526 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2527 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2530 /* Anything else should be already split before reg-stack. */
2531 gcc_assert (which_alternative == 1);
2532 return "push{q}\t%q1";
2534 [(set_attr "type" "multi,push,multi")
2535 (set_attr "unit" "i387,*,*")
2536 (set_attr "mode" "SF,DI,SF")])
2538 (define_insn "*pushsf"
2539 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2540 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
2543 /* Anything else should be already split before reg-stack. */
2544 gcc_assert (which_alternative == 1);
2545 return "push{l}\t%1";
2547 [(set_attr "type" "multi,push,multi")
2548 (set_attr "unit" "i387,*,*")
2549 (set_attr "mode" "SF,SI,SF")])
2551 ;; %%% Kill this when call knows how to work this out.
2553 [(set (match_operand:SF 0 "push_operand")
2554 (match_operand:SF 1 "any_fp_register_operand"))]
2556 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2557 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2558 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2561 [(set (match_operand:SF 0 "push_operand")
2562 (match_operand:SF 1 "memory_operand"))]
2564 && (operands[2] = find_constant_src (insn))"
2565 [(set (match_dup 0) (match_dup 2))])
2568 [(set (match_operand 0 "push_operand")
2569 (match_operand 1 "general_operand"))]
2571 && (GET_MODE (operands[0]) == TFmode
2572 || GET_MODE (operands[0]) == XFmode
2573 || GET_MODE (operands[0]) == DFmode)
2574 && !ANY_FP_REG_P (operands[1])"
2576 "ix86_split_long_move (operands); DONE;")
2578 ;; Floating point move instructions.
2580 (define_expand "movtf"
2581 [(set (match_operand:TF 0 "nonimmediate_operand")
2582 (match_operand:TF 1 "nonimmediate_operand"))]
2583 "TARGET_64BIT || TARGET_SSE"
2584 "ix86_expand_move (TFmode, operands); DONE;")
2586 (define_expand "mov<mode>"
2587 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2588 (match_operand:X87MODEF 1 "general_operand"))]
2590 "ix86_expand_move (<MODE>mode, operands); DONE;")
2592 (define_insn "*movtf_internal"
2593 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
2594 (match_operand:TF 1 "general_operand" "C ,xm,x,*roF,*rC"))]
2595 "(TARGET_64BIT || TARGET_SSE)
2596 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2597 && (!can_create_pseudo_p ()
2598 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2599 || GET_CODE (operands[1]) != CONST_DOUBLE
2600 || (optimize_function_for_size_p (cfun)
2601 && standard_sse_constant_p (operands[1])
2602 && !memory_operand (operands[0], TFmode))
2603 || (!TARGET_MEMORY_MISMATCH_STALL
2604 && memory_operand (operands[0], TFmode)))"
2606 switch (get_attr_type (insn))
2609 return standard_sse_constant_opcode (insn, operands[1]);
2612 /* Handle misaligned load/store since we
2613 don't have movmisaligntf pattern. */
2614 if (misaligned_operand (operands[0], TFmode)
2615 || misaligned_operand (operands[1], TFmode))
2617 if (get_attr_mode (insn) == MODE_V4SF)
2618 return "%vmovups\t{%1, %0|%0, %1}";
2620 return "%vmovdqu\t{%1, %0|%0, %1}";
2624 if (get_attr_mode (insn) == MODE_V4SF)
2625 return "%vmovaps\t{%1, %0|%0, %1}";
2627 return "%vmovdqa\t{%1, %0|%0, %1}";
2637 [(set_attr "isa" "*,*,*,x64,x64")
2638 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
2639 (set (attr "prefix")
2640 (if_then_else (eq_attr "type" "sselog1,ssemov")
2641 (const_string "maybe_vex")
2642 (const_string "orig")))
2644 (cond [(eq_attr "alternative" "3,4")
2646 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2647 (const_string "V4SF")
2648 (and (eq_attr "alternative" "2")
2649 (match_test "TARGET_SSE_TYPELESS_STORES"))
2650 (const_string "V4SF")
2651 (match_test "TARGET_AVX")
2653 (ior (not (match_test "TARGET_SSE2"))
2654 (match_test "optimize_function_for_size_p (cfun)"))
2655 (const_string "V4SF")
2657 (const_string "TI")))])
2659 ;; Possible store forwarding (partial memory) stall in alternatives 4 and 5.
2660 (define_insn "*movxf_internal"
2661 [(set (match_operand:XF 0 "nonimmediate_operand"
2662 "=f,m,f,?Yx*r ,!o ,!o")
2663 (match_operand:XF 1 "general_operand"
2664 "fm,f,G,Yx*roF,Yx*rF,Yx*rC"))]
2665 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2666 && (!can_create_pseudo_p ()
2667 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2668 || GET_CODE (operands[1]) != CONST_DOUBLE
2669 || (optimize_function_for_size_p (cfun)
2670 && standard_80387_constant_p (operands[1]) > 0
2671 && !memory_operand (operands[0], XFmode))
2672 || (!TARGET_MEMORY_MISMATCH_STALL
2673 && memory_operand (operands[0], XFmode)))"
2675 switch (get_attr_type (insn))
2678 if (which_alternative == 2)
2679 return standard_80387_constant_opcode (operands[1]);
2680 return output_387_reg_move (insn, operands);
2689 [(set_attr "isa" "*,*,*,*,nox64,x64")
2690 (set_attr "type" "fmov,fmov,fmov,multi,multi,multi")
2692 (cond [(eq_attr "alternative" "3,4,5")
2693 (if_then_else (match_test "TARGET_64BIT")
2695 (const_string "SI"))
2697 (const_string "XF")))])
2699 ;; Possible store forwarding (partial memory) stall in alternative 4.
2700 (define_insn "*movdf_internal"
2701 [(set (match_operand:DF 0 "nonimmediate_operand"
2702 "=Yf*f,m ,Yf*f,?Yd*r ,!o ,?r,?m,?r,?r,x,x,x,m,*x,*x,*x,m ,r ,Yi")
2703 (match_operand:DF 1 "general_operand"
2704 "Yf*fm,Yf*f,G ,Yd*roF,Yd*rF,rm,rC,C ,F ,C,x,m,x,C ,*x,m ,*x,Yj,r"))]
2705 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2706 && (!can_create_pseudo_p ()
2707 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2708 || GET_CODE (operands[1]) != CONST_DOUBLE
2709 || (optimize_function_for_size_p (cfun)
2710 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2711 && standard_80387_constant_p (operands[1]) > 0)
2712 || (TARGET_SSE2 && TARGET_SSE_MATH
2713 && standard_sse_constant_p (operands[1])))
2714 && !memory_operand (operands[0], DFmode))
2715 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
2716 && memory_operand (operands[0], DFmode)))"
2718 switch (get_attr_type (insn))
2721 if (which_alternative == 2)
2722 return standard_80387_constant_opcode (operands[1]);
2723 return output_387_reg_move (insn, operands);
2729 if (get_attr_mode (insn) == MODE_SI)
2730 return "mov{l}\t{%1, %k0|%k0, %1}";
2731 else if (which_alternative == 8)
2732 return "movabs{q}\t{%1, %0|%0, %1}";
2734 return "mov{q}\t{%1, %0|%0, %1}";
2737 return standard_sse_constant_opcode (insn, operands[1]);
2740 switch (get_attr_mode (insn))
2743 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2744 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2745 return "%vmovsd\t{%1, %0|%0, %1}";
2748 return "%vmovaps\t{%1, %0|%0, %1}";
2750 return "%vmovapd\t{%1, %0|%0, %1}";
2753 gcc_assert (!TARGET_AVX);
2754 return "movlps\t{%1, %0|%0, %1}";
2756 gcc_assert (!TARGET_AVX);
2757 return "movlpd\t{%1, %0|%0, %1}";
2760 #ifndef HAVE_AS_IX86_INTERUNIT_MOVQ
2761 /* Handle broken assemblers that require movd instead of movq. */
2762 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2763 return "%vmovd\t{%1, %0|%0, %1}";
2765 return "%vmovq\t{%1, %0|%0, %1}";
2776 (cond [(eq_attr "alternative" "3,4")
2777 (const_string "nox64")
2778 (eq_attr "alternative" "5,6,7,8,17,18")
2779 (const_string "x64")
2780 (eq_attr "alternative" "9,10,11,12")
2781 (const_string "sse2")
2783 (const_string "*")))
2785 (cond [(eq_attr "alternative" "0,1,2")
2786 (const_string "fmov")
2787 (eq_attr "alternative" "3,4")
2788 (const_string "multi")
2789 (eq_attr "alternative" "5,6,7,8")
2790 (const_string "imov")
2791 (eq_attr "alternative" "9,13")
2792 (const_string "sselog1")
2794 (const_string "ssemov")))
2796 (if_then_else (eq_attr "alternative" "8")
2798 (const_string "*")))
2799 (set (attr "length_immediate")
2800 (if_then_else (eq_attr "alternative" "8")
2802 (const_string "*")))
2803 (set (attr "prefix")
2804 (if_then_else (eq_attr "type" "sselog1,ssemov")
2805 (const_string "maybe_vex")
2806 (const_string "orig")))
2807 (set (attr "prefix_data16")
2809 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2810 (eq_attr "mode" "V1DF"))
2812 (const_string "*")))
2814 (cond [(eq_attr "alternative" "3,4,7")
2816 (eq_attr "alternative" "5,6,8,17,18")
2819 /* xorps is one byte shorter for non-AVX targets. */
2820 (eq_attr "alternative" "9,13")
2821 (cond [(not (match_test "TARGET_SSE2"))
2822 (const_string "V4SF")
2823 (match_test "TARGET_AVX")
2824 (const_string "V2DF")
2825 (match_test "optimize_function_for_size_p (cfun)")
2826 (const_string "V4SF")
2827 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
2830 (const_string "V2DF"))
2832 /* For architectures resolving dependencies on
2833 whole SSE registers use movapd to break dependency
2834 chains, otherwise use short move to avoid extra work. */
2836 /* movaps is one byte shorter for non-AVX targets. */
2837 (eq_attr "alternative" "10,14")
2838 (cond [(ior (not (match_test "TARGET_SSE2"))
2839 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2840 (const_string "V4SF")
2841 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2842 (const_string "V2DF")
2843 (match_test "TARGET_AVX")
2845 (match_test "optimize_function_for_size_p (cfun)")
2846 (const_string "V4SF")
2848 (const_string "DF"))
2850 /* For architectures resolving dependencies on register
2851 parts we may avoid extra work to zero out upper part
2853 (eq_attr "alternative" "11,15")
2854 (cond [(not (match_test "TARGET_SSE2"))
2855 (const_string "V2SF")
2856 (match_test "TARGET_AVX")
2858 (match_test "TARGET_SSE_SPLIT_REGS")
2859 (const_string "V1DF")
2861 (const_string "DF"))
2863 (and (eq_attr "alternative" "12,16")
2864 (not (match_test "TARGET_SSE2")))
2865 (const_string "V2SF")
2867 (const_string "DF")))])
2869 (define_insn "*movsf_internal"
2870 [(set (match_operand:SF 0 "nonimmediate_operand"
2871 "=Yf*f,m ,Yf*f,?r ,?m,x,x,x,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym")
2872 (match_operand:SF 1 "general_operand"
2873 "Yf*fm,Yf*f,G ,rmF,rF,C,x,m,x,Yj,r ,*y ,m ,*y,*Yn,r"))]
2874 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2875 && (!can_create_pseudo_p ()
2876 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2877 || GET_CODE (operands[1]) != CONST_DOUBLE
2878 || (optimize_function_for_size_p (cfun)
2879 && ((!TARGET_SSE_MATH
2880 && standard_80387_constant_p (operands[1]) > 0)
2882 && standard_sse_constant_p (operands[1]))))
2883 || memory_operand (operands[0], SFmode))"
2885 switch (get_attr_type (insn))
2888 if (which_alternative == 2)
2889 return standard_80387_constant_opcode (operands[1]);
2890 return output_387_reg_move (insn, operands);
2893 return "mov{l}\t{%1, %0|%0, %1}";
2896 return standard_sse_constant_opcode (insn, operands[1]);
2899 switch (get_attr_mode (insn))
2902 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2903 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
2904 return "%vmovss\t{%1, %0|%0, %1}";
2907 return "%vmovaps\t{%1, %0|%0, %1}";
2910 return "%vmovd\t{%1, %0|%0, %1}";
2917 switch (get_attr_mode (insn))
2920 return "movq\t{%1, %0|%0, %1}";
2922 return "movd\t{%1, %0|%0, %1}";
2933 (cond [(eq_attr "alternative" "0,1,2")
2934 (const_string "fmov")
2935 (eq_attr "alternative" "3,4")
2936 (const_string "imov")
2937 (eq_attr "alternative" "5")
2938 (const_string "sselog1")
2939 (eq_attr "alternative" "11,12,13,14,15")
2940 (const_string "mmxmov")
2942 (const_string "ssemov")))
2943 (set (attr "prefix")
2944 (if_then_else (eq_attr "type" "sselog1,ssemov")
2945 (const_string "maybe_vex")
2946 (const_string "orig")))
2947 (set (attr "prefix_data16")
2948 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2950 (const_string "*")))
2952 (cond [(eq_attr "alternative" "3,4,9,10,14,15")
2954 (eq_attr "alternative" "11")
2956 (eq_attr "alternative" "5")
2957 (cond [(not (match_test "TARGET_SSE2"))
2958 (const_string "V4SF")
2959 (match_test "TARGET_AVX")
2960 (const_string "V4SF")
2961 (match_test "optimize_function_for_size_p (cfun)")
2962 (const_string "V4SF")
2963 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
2966 (const_string "V4SF"))
2968 /* For architectures resolving dependencies on
2969 whole SSE registers use APS move to break dependency
2970 chains, otherwise use short move to avoid extra work.
2972 Do the same for architectures resolving dependencies on
2973 the parts. While in DF mode it is better to always handle
2974 just register parts, the SF mode is different due to lack
2975 of instructions to load just part of the register. It is
2976 better to maintain the whole registers in single format
2977 to avoid problems on using packed logical operations. */
2978 (and (eq_attr "alternative" "6")
2979 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2980 (match_test "TARGET_SSE_SPLIT_REGS")))
2981 (const_string "V4SF")
2983 (const_string "SF")))])
2986 [(set (match_operand 0 "any_fp_register_operand")
2987 (match_operand 1 "memory_operand"))]
2989 && (GET_MODE (operands[0]) == TFmode
2990 || GET_MODE (operands[0]) == XFmode
2991 || GET_MODE (operands[0]) == DFmode
2992 || GET_MODE (operands[0]) == SFmode)
2993 && (operands[2] = find_constant_src (insn))"
2994 [(set (match_dup 0) (match_dup 2))]
2996 rtx c = operands[2];
2997 int r = REGNO (operands[0]);
2999 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3000 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3005 [(set (match_operand 0 "any_fp_register_operand")
3006 (float_extend (match_operand 1 "memory_operand")))]
3008 && (GET_MODE (operands[0]) == TFmode
3009 || GET_MODE (operands[0]) == XFmode
3010 || GET_MODE (operands[0]) == DFmode)
3011 && (operands[2] = find_constant_src (insn))"
3012 [(set (match_dup 0) (match_dup 2))]
3014 rtx c = operands[2];
3015 int r = REGNO (operands[0]);
3017 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3018 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3022 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3024 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3025 (match_operand:X87MODEF 1 "immediate_operand"))]
3027 && (standard_80387_constant_p (operands[1]) == 8
3028 || standard_80387_constant_p (operands[1]) == 9)"
3029 [(set (match_dup 0)(match_dup 1))
3031 (neg:X87MODEF (match_dup 0)))]
3035 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3036 if (real_isnegzero (&r))
3037 operands[1] = CONST0_RTX (<MODE>mode);
3039 operands[1] = CONST1_RTX (<MODE>mode);
3043 [(set (match_operand 0 "nonimmediate_operand")
3044 (match_operand 1 "general_operand"))]
3046 && (GET_MODE (operands[0]) == TFmode
3047 || GET_MODE (operands[0]) == XFmode
3048 || GET_MODE (operands[0]) == DFmode)
3049 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3051 "ix86_split_long_move (operands); DONE;")
3053 (define_insn "swapxf"
3054 [(set (match_operand:XF 0 "register_operand" "+f")
3055 (match_operand:XF 1 "register_operand" "+f"))
3060 if (STACK_TOP_P (operands[0]))
3065 [(set_attr "type" "fxch")
3066 (set_attr "mode" "XF")])
3068 (define_insn "*swap<mode>"
3069 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3070 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3073 "TARGET_80387 || reload_completed"
3075 if (STACK_TOP_P (operands[0]))
3080 [(set_attr "type" "fxch")
3081 (set_attr "mode" "<MODE>")])
3083 ;; Zero extension instructions
3085 (define_expand "zero_extendsidi2"
3086 [(set (match_operand:DI 0 "nonimmediate_operand")
3087 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3089 (define_insn "*zero_extendsidi2"
3090 [(set (match_operand:DI 0 "nonimmediate_operand"
3091 "=r,?r,?o,r ,o,?*Ym,?!*y,?r ,?*Yi,?*x")
3093 (match_operand:SI 1 "x86_64_zext_operand"
3094 "0 ,rm,r ,rmWz,0,r ,m ,*Yj,r ,m")))]
3097 switch (get_attr_type (insn))
3100 if (ix86_use_lea_for_mov (insn, operands))
3101 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3103 return "mov{l}\t{%1, %k0|%k0, %1}";
3109 return "movd\t{%1, %0|%0, %1}";
3112 if (GENERAL_REG_P (operands[0]))
3113 return "%vmovd\t{%1, %k0|%k0, %1}";
3115 return "%vmovd\t{%1, %0|%0, %1}";
3122 (cond [(eq_attr "alternative" "0,1,2")
3123 (const_string "nox64")
3124 (eq_attr "alternative" "3,7")
3125 (const_string "x64")
3126 (eq_attr "alternative" "9")
3127 (const_string "sse2")
3129 (const_string "*")))
3131 (cond [(eq_attr "alternative" "0,1,2,4")
3132 (const_string "multi")
3133 (eq_attr "alternative" "5,6")
3134 (const_string "mmxmov")
3135 (eq_attr "alternative" "7,8,9")
3136 (const_string "ssemov")
3138 (const_string "imovx")))
3139 (set (attr "prefix")
3140 (if_then_else (eq_attr "type" "ssemov")
3141 (const_string "maybe_vex")
3142 (const_string "orig")))
3143 (set (attr "prefix_0f")
3144 (if_then_else (eq_attr "type" "imovx")
3146 (const_string "*")))
3148 (cond [(eq_attr "alternative" "5,6")
3150 (eq_attr "alternative" "7,8,9")
3153 (const_string "SI")))])
3156 [(set (match_operand:DI 0 "memory_operand")
3157 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3159 [(set (match_dup 4) (const_int 0))]
3160 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3163 [(set (match_operand:DI 0 "register_operand")
3164 (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3165 "!TARGET_64BIT && reload_completed
3166 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3167 && true_regnum (operands[0]) == true_regnum (operands[1])"
3168 [(set (match_dup 4) (const_int 0))]
3169 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3172 [(set (match_operand:DI 0 "nonimmediate_operand")
3173 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3174 "!TARGET_64BIT && reload_completed
3175 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3176 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3177 [(set (match_dup 3) (match_dup 1))
3178 (set (match_dup 4) (const_int 0))]
3179 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3181 (define_insn "zero_extend<mode>di2"
3182 [(set (match_operand:DI 0 "register_operand" "=r")
3184 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3186 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3187 [(set_attr "type" "imovx")
3188 (set_attr "mode" "SI")])
3190 (define_expand "zero_extend<mode>si2"
3191 [(set (match_operand:SI 0 "register_operand")
3192 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3195 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3197 operands[1] = force_reg (<MODE>mode, operands[1]);
3198 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3203 (define_insn_and_split "zero_extend<mode>si2_and"
3204 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3206 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3207 (clobber (reg:CC FLAGS_REG))]
3208 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3210 "&& reload_completed"
3211 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3212 (clobber (reg:CC FLAGS_REG))])]
3214 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3216 ix86_expand_clear (operands[0]);
3218 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3219 emit_insn (gen_movstrict<mode>
3220 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3224 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3226 [(set_attr "type" "alu1")
3227 (set_attr "mode" "SI")])
3229 (define_insn "*zero_extend<mode>si2"
3230 [(set (match_operand:SI 0 "register_operand" "=r")
3232 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3233 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3234 "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3235 [(set_attr "type" "imovx")
3236 (set_attr "mode" "SI")])
3238 (define_expand "zero_extendqihi2"
3239 [(set (match_operand:HI 0 "register_operand")
3240 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3243 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3245 operands[1] = force_reg (QImode, operands[1]);
3246 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3251 (define_insn_and_split "zero_extendqihi2_and"
3252 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3253 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3254 (clobber (reg:CC FLAGS_REG))]
3255 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3257 "&& reload_completed"
3258 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3259 (clobber (reg:CC FLAGS_REG))])]
3261 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3263 ix86_expand_clear (operands[0]);
3265 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3266 emit_insn (gen_movstrictqi
3267 (gen_lowpart (QImode, operands[0]), operands[1]));
3271 operands[0] = gen_lowpart (SImode, operands[0]);
3273 [(set_attr "type" "alu1")
3274 (set_attr "mode" "SI")])
3276 ; zero extend to SImode to avoid partial register stalls
3277 (define_insn "*zero_extendqihi2"
3278 [(set (match_operand:HI 0 "register_operand" "=r")
3279 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3280 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3281 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3282 [(set_attr "type" "imovx")
3283 (set_attr "mode" "SI")])
3285 ;; Sign extension instructions
3287 (define_expand "extendsidi2"
3288 [(set (match_operand:DI 0 "register_operand")
3289 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3294 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3299 (define_insn "*extendsidi2_rex64"
3300 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3301 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3305 movs{lq|x}\t{%1, %0|%0, %1}"
3306 [(set_attr "type" "imovx")
3307 (set_attr "mode" "DI")
3308 (set_attr "prefix_0f" "0")
3309 (set_attr "modrm" "0,1")])
3311 (define_insn "extendsidi2_1"
3312 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3313 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3314 (clobber (reg:CC FLAGS_REG))
3315 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3319 ;; Extend to memory case when source register does die.
3321 [(set (match_operand:DI 0 "memory_operand")
3322 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3323 (clobber (reg:CC FLAGS_REG))
3324 (clobber (match_operand:SI 2 "register_operand"))]
3326 && dead_or_set_p (insn, operands[1])
3327 && !reg_mentioned_p (operands[1], operands[0]))"
3328 [(set (match_dup 3) (match_dup 1))
3329 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3330 (clobber (reg:CC FLAGS_REG))])
3331 (set (match_dup 4) (match_dup 1))]
3332 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3334 ;; Extend to memory case when source register does not die.
3336 [(set (match_operand:DI 0 "memory_operand")
3337 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3338 (clobber (reg:CC FLAGS_REG))
3339 (clobber (match_operand:SI 2 "register_operand"))]
3343 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3345 emit_move_insn (operands[3], operands[1]);
3347 /* Generate a cltd if possible and doing so it profitable. */
3348 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3349 && true_regnum (operands[1]) == AX_REG
3350 && true_regnum (operands[2]) == DX_REG)
3352 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3356 emit_move_insn (operands[2], operands[1]);
3357 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3359 emit_move_insn (operands[4], operands[2]);
3363 ;; Extend to register case. Optimize case where source and destination
3364 ;; registers match and cases where we can use cltd.
3366 [(set (match_operand:DI 0 "register_operand")
3367 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3368 (clobber (reg:CC FLAGS_REG))
3369 (clobber (match_scratch:SI 2))]
3373 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3375 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3376 emit_move_insn (operands[3], operands[1]);
3378 /* Generate a cltd if possible and doing so it profitable. */
3379 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3380 && true_regnum (operands[3]) == AX_REG
3381 && true_regnum (operands[4]) == DX_REG)
3383 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3387 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3388 emit_move_insn (operands[4], operands[1]);
3390 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3394 (define_insn "extend<mode>di2"
3395 [(set (match_operand:DI 0 "register_operand" "=r")
3397 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3399 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3400 [(set_attr "type" "imovx")
3401 (set_attr "mode" "DI")])
3403 (define_insn "extendhisi2"
3404 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3405 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3408 switch (get_attr_prefix_0f (insn))
3411 return "{cwtl|cwde}";
3413 return "movs{wl|x}\t{%1, %0|%0, %1}";
3416 [(set_attr "type" "imovx")
3417 (set_attr "mode" "SI")
3418 (set (attr "prefix_0f")
3419 ;; movsx is short decodable while cwtl is vector decoded.
3420 (if_then_else (and (eq_attr "cpu" "!k6")
3421 (eq_attr "alternative" "0"))
3423 (const_string "1")))
3425 (if_then_else (eq_attr "prefix_0f" "0")
3427 (const_string "1")))])
3429 (define_insn "*extendhisi2_zext"
3430 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3433 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3436 switch (get_attr_prefix_0f (insn))
3439 return "{cwtl|cwde}";
3441 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3444 [(set_attr "type" "imovx")
3445 (set_attr "mode" "SI")
3446 (set (attr "prefix_0f")
3447 ;; movsx is short decodable while cwtl is vector decoded.
3448 (if_then_else (and (eq_attr "cpu" "!k6")
3449 (eq_attr "alternative" "0"))
3451 (const_string "1")))
3453 (if_then_else (eq_attr "prefix_0f" "0")
3455 (const_string "1")))])
3457 (define_insn "extendqisi2"
3458 [(set (match_operand:SI 0 "register_operand" "=r")
3459 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3461 "movs{bl|x}\t{%1, %0|%0, %1}"
3462 [(set_attr "type" "imovx")
3463 (set_attr "mode" "SI")])
3465 (define_insn "*extendqisi2_zext"
3466 [(set (match_operand:DI 0 "register_operand" "=r")
3468 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3470 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3471 [(set_attr "type" "imovx")
3472 (set_attr "mode" "SI")])
3474 (define_insn "extendqihi2"
3475 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3476 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3479 switch (get_attr_prefix_0f (insn))
3482 return "{cbtw|cbw}";
3484 return "movs{bw|x}\t{%1, %0|%0, %1}";
3487 [(set_attr "type" "imovx")
3488 (set_attr "mode" "HI")
3489 (set (attr "prefix_0f")
3490 ;; movsx is short decodable while cwtl is vector decoded.
3491 (if_then_else (and (eq_attr "cpu" "!k6")
3492 (eq_attr "alternative" "0"))
3494 (const_string "1")))
3496 (if_then_else (eq_attr "prefix_0f" "0")
3498 (const_string "1")))])
3500 ;; Conversions between float and double.
3502 ;; These are all no-ops in the model used for the 80387.
3503 ;; So just emit moves.
3505 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3507 [(set (match_operand:DF 0 "push_operand")
3508 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3510 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3511 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3514 [(set (match_operand:XF 0 "push_operand")
3515 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3517 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3518 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3519 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3521 (define_expand "extendsfdf2"
3522 [(set (match_operand:DF 0 "nonimmediate_operand")
3523 (float_extend:DF (match_operand:SF 1 "general_operand")))]
3524 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3526 /* ??? Needed for compress_float_constant since all fp constants
3527 are TARGET_LEGITIMATE_CONSTANT_P. */
3528 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3530 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3531 && standard_80387_constant_p (operands[1]) > 0)
3533 operands[1] = simplify_const_unary_operation
3534 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3535 emit_move_insn_1 (operands[0], operands[1]);
3538 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3542 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3544 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3546 We do the conversion post reload to avoid producing of 128bit spills
3547 that might lead to ICE on 32bit target. The sequence unlikely combine
3550 [(set (match_operand:DF 0 "register_operand")
3552 (match_operand:SF 1 "nonimmediate_operand")))]
3553 "TARGET_USE_VECTOR_FP_CONVERTS
3554 && optimize_insn_for_speed_p ()
3555 && reload_completed && SSE_REG_P (operands[0])"
3560 (parallel [(const_int 0) (const_int 1)]))))]
3562 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3563 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3564 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3565 Try to avoid move when unpacking can be done in source. */
3566 if (REG_P (operands[1]))
3568 /* If it is unsafe to overwrite upper half of source, we need
3569 to move to destination and unpack there. */
3570 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3571 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3572 && true_regnum (operands[0]) != true_regnum (operands[1]))
3574 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3575 emit_move_insn (tmp, operands[1]);
3578 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3579 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3583 emit_insn (gen_vec_setv4sf_0 (operands[3],
3584 CONST0_RTX (V4SFmode), operands[1]));
3587 (define_insn "*extendsfdf2_mixed"
3588 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3590 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3591 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3593 switch (which_alternative)
3597 return output_387_reg_move (insn, operands);
3600 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3606 [(set_attr "type" "fmov,fmov,ssecvt")
3607 (set_attr "prefix" "orig,orig,maybe_vex")
3608 (set_attr "mode" "SF,XF,DF")])
3610 (define_insn "*extendsfdf2_sse"
3611 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3612 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3613 "TARGET_SSE2 && TARGET_SSE_MATH"
3614 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3615 [(set_attr "type" "ssecvt")
3616 (set_attr "prefix" "maybe_vex")
3617 (set_attr "mode" "DF")])
3619 (define_insn "*extendsfdf2_i387"
3620 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3621 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3623 "* return output_387_reg_move (insn, operands);"
3624 [(set_attr "type" "fmov")
3625 (set_attr "mode" "SF,XF")])
3627 (define_expand "extend<mode>xf2"
3628 [(set (match_operand:XF 0 "nonimmediate_operand")
3629 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
3632 /* ??? Needed for compress_float_constant since all fp constants
3633 are TARGET_LEGITIMATE_CONSTANT_P. */
3634 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3636 if (standard_80387_constant_p (operands[1]) > 0)
3638 operands[1] = simplify_const_unary_operation
3639 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3640 emit_move_insn_1 (operands[0], operands[1]);
3643 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3647 (define_insn "*extend<mode>xf2_i387"
3648 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3650 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3652 "* return output_387_reg_move (insn, operands);"
3653 [(set_attr "type" "fmov")
3654 (set_attr "mode" "<MODE>,XF")])
3656 ;; %%% This seems bad bad news.
3657 ;; This cannot output into an f-reg because there is no way to be sure
3658 ;; of truncating in that case. Otherwise this is just like a simple move
3659 ;; insn. So we pretend we can output to a reg in order to get better
3660 ;; register preferencing, but we really use a stack slot.
3662 ;; Conversion from DFmode to SFmode.
3664 (define_expand "truncdfsf2"
3665 [(set (match_operand:SF 0 "nonimmediate_operand")
3667 (match_operand:DF 1 "nonimmediate_operand")))]
3668 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3670 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3672 else if (flag_unsafe_math_optimizations)
3676 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3677 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3682 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
3684 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3686 We do the conversion post reload to avoid producing of 128bit spills
3687 that might lead to ICE on 32bit target. The sequence unlikely combine
3690 [(set (match_operand:SF 0 "register_operand")
3692 (match_operand:DF 1 "nonimmediate_operand")))]
3693 "TARGET_USE_VECTOR_FP_CONVERTS
3694 && optimize_insn_for_speed_p ()
3695 && reload_completed && SSE_REG_P (operands[0])"
3698 (float_truncate:V2SF
3702 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3703 operands[3] = CONST0_RTX (V2SFmode);
3704 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
3705 /* Use movsd for loading from memory, unpcklpd for registers.
3706 Try to avoid move when unpacking can be done in source, or SSE3
3707 movddup is available. */
3708 if (REG_P (operands[1]))
3711 && true_regnum (operands[0]) != true_regnum (operands[1])
3712 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3713 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
3715 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
3716 emit_move_insn (tmp, operands[1]);
3719 else if (!TARGET_SSE3)
3720 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3721 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
3724 emit_insn (gen_sse2_loadlpd (operands[4],
3725 CONST0_RTX (V2DFmode), operands[1]));
3728 (define_expand "truncdfsf2_with_temp"
3729 [(parallel [(set (match_operand:SF 0)
3730 (float_truncate:SF (match_operand:DF 1)))
3731 (clobber (match_operand:SF 2))])])
3733 (define_insn "*truncdfsf_fast_mixed"
3734 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
3736 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
3737 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3739 switch (which_alternative)
3742 return output_387_reg_move (insn, operands);
3744 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
3749 [(set_attr "type" "fmov,ssecvt")
3750 (set_attr "prefix" "orig,maybe_vex")
3751 (set_attr "mode" "SF")])
3753 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3754 ;; because nothing we do here is unsafe.
3755 (define_insn "*truncdfsf_fast_sse"
3756 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
3758 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
3759 "TARGET_SSE2 && TARGET_SSE_MATH"
3760 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
3761 [(set_attr "type" "ssecvt")
3762 (set_attr "prefix" "maybe_vex")
3763 (set_attr "mode" "SF")])
3765 (define_insn "*truncdfsf_fast_i387"
3766 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
3768 (match_operand:DF 1 "nonimmediate_operand" "f")))]
3769 "TARGET_80387 && flag_unsafe_math_optimizations"
3770 "* return output_387_reg_move (insn, operands);"
3771 [(set_attr "type" "fmov")
3772 (set_attr "mode" "SF")])
3774 (define_insn "*truncdfsf_mixed"
3775 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
3777 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
3778 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
3779 "TARGET_MIX_SSE_I387"
3781 switch (which_alternative)
3784 return output_387_reg_move (insn, operands);
3786 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
3792 [(set_attr "isa" "*,sse2,*,*,*")
3793 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
3794 (set_attr "unit" "*,*,i387,i387,i387")
3795 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
3796 (set_attr "mode" "SF")])
3798 (define_insn "*truncdfsf_i387"
3799 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
3801 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
3802 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
3805 switch (which_alternative)
3808 return output_387_reg_move (insn, operands);
3814 [(set_attr "type" "fmov,multi,multi,multi")
3815 (set_attr "unit" "*,i387,i387,i387")
3816 (set_attr "mode" "SF")])
3818 (define_insn "*truncdfsf2_i387_1"
3819 [(set (match_operand:SF 0 "memory_operand" "=m")
3821 (match_operand:DF 1 "register_operand" "f")))]
3823 && !(TARGET_SSE2 && TARGET_SSE_MATH)
3824 && !TARGET_MIX_SSE_I387"
3825 "* return output_387_reg_move (insn, operands);"
3826 [(set_attr "type" "fmov")
3827 (set_attr "mode" "SF")])
3830 [(set (match_operand:SF 0 "register_operand")
3832 (match_operand:DF 1 "fp_register_operand")))
3833 (clobber (match_operand 2))]
3835 [(set (match_dup 2) (match_dup 1))
3836 (set (match_dup 0) (match_dup 2))]
3837 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
3839 ;; Conversion from XFmode to {SF,DF}mode
3841 (define_expand "truncxf<mode>2"
3842 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
3843 (float_truncate:MODEF
3844 (match_operand:XF 1 "register_operand")))
3845 (clobber (match_dup 2))])]
3848 if (flag_unsafe_math_optimizations)
3850 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
3851 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
3852 if (reg != operands[0])
3853 emit_move_insn (operands[0], reg);
3857 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
3860 (define_insn "*truncxfsf2_mixed"
3861 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
3863 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
3864 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
3867 gcc_assert (!which_alternative);
3868 return output_387_reg_move (insn, operands);
3870 [(set_attr "type" "fmov,multi,multi,multi")
3871 (set_attr "unit" "*,i387,i387,i387")
3872 (set_attr "mode" "SF")])
3874 (define_insn "*truncxfdf2_mixed"
3875 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
3877 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
3878 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
3881 gcc_assert (!which_alternative);
3882 return output_387_reg_move (insn, operands);
3884 [(set_attr "isa" "*,*,sse2,*")
3885 (set_attr "type" "fmov,multi,multi,multi")
3886 (set_attr "unit" "*,i387,i387,i387")
3887 (set_attr "mode" "DF")])
3889 (define_insn "truncxf<mode>2_i387_noop"
3890 [(set (match_operand:MODEF 0 "register_operand" "=f")
3891 (float_truncate:MODEF
3892 (match_operand:XF 1 "register_operand" "f")))]
3893 "TARGET_80387 && flag_unsafe_math_optimizations"
3894 "* return output_387_reg_move (insn, operands);"
3895 [(set_attr "type" "fmov")
3896 (set_attr "mode" "<MODE>")])
3898 (define_insn "*truncxf<mode>2_i387"
3899 [(set (match_operand:MODEF 0 "memory_operand" "=m")
3900 (float_truncate:MODEF
3901 (match_operand:XF 1 "register_operand" "f")))]
3903 "* return output_387_reg_move (insn, operands);"
3904 [(set_attr "type" "fmov")
3905 (set_attr "mode" "<MODE>")])
3908 [(set (match_operand:MODEF 0 "register_operand")
3909 (float_truncate:MODEF
3910 (match_operand:XF 1 "register_operand")))
3911 (clobber (match_operand:MODEF 2 "memory_operand"))]
3912 "TARGET_80387 && reload_completed"
3913 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
3914 (set (match_dup 0) (match_dup 2))])
3917 [(set (match_operand:MODEF 0 "memory_operand")
3918 (float_truncate:MODEF
3919 (match_operand:XF 1 "register_operand")))
3920 (clobber (match_operand:MODEF 2 "memory_operand"))]
3922 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
3924 ;; Signed conversion to DImode.
3926 (define_expand "fix_truncxfdi2"
3927 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
3928 (fix:DI (match_operand:XF 1 "register_operand")))
3929 (clobber (reg:CC FLAGS_REG))])]
3934 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
3939 (define_expand "fix_trunc<mode>di2"
3940 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
3941 (fix:DI (match_operand:MODEF 1 "register_operand")))
3942 (clobber (reg:CC FLAGS_REG))])]
3943 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
3946 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
3948 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
3951 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
3953 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
3954 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
3955 if (out != operands[0])
3956 emit_move_insn (operands[0], out);
3961 ;; Signed conversion to SImode.
3963 (define_expand "fix_truncxfsi2"
3964 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
3965 (fix:SI (match_operand:XF 1 "register_operand")))
3966 (clobber (reg:CC FLAGS_REG))])]
3971 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
3976 (define_expand "fix_trunc<mode>si2"
3977 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
3978 (fix:SI (match_operand:MODEF 1 "register_operand")))
3979 (clobber (reg:CC FLAGS_REG))])]
3980 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
3983 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
3985 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
3988 if (SSE_FLOAT_MODE_P (<MODE>mode))
3990 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
3991 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
3992 if (out != operands[0])
3993 emit_move_insn (operands[0], out);
3998 ;; Signed conversion to HImode.
4000 (define_expand "fix_trunc<mode>hi2"
4001 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4002 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4003 (clobber (reg:CC FLAGS_REG))])]
4005 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4009 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4014 ;; Unsigned conversion to SImode.
4016 (define_expand "fixuns_trunc<mode>si2"
4018 [(set (match_operand:SI 0 "register_operand")
4020 (match_operand:MODEF 1 "nonimmediate_operand")))
4022 (clobber (match_scratch:<ssevecmode> 3))
4023 (clobber (match_scratch:<ssevecmode> 4))])]
4024 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4026 enum machine_mode mode = <MODE>mode;
4027 enum machine_mode vecmode = <ssevecmode>mode;
4028 REAL_VALUE_TYPE TWO31r;
4031 if (optimize_insn_for_size_p ())
4034 real_ldexp (&TWO31r, &dconst1, 31);
4035 two31 = const_double_from_real_value (TWO31r, mode);
4036 two31 = ix86_build_const_vector (vecmode, true, two31);
4037 operands[2] = force_reg (vecmode, two31);
4040 (define_insn_and_split "*fixuns_trunc<mode>_1"
4041 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4043 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4044 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4045 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4046 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4047 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4048 && optimize_function_for_speed_p (cfun)"
4050 "&& reload_completed"
4053 ix86_split_convert_uns_si_sse (operands);
4057 ;; Unsigned conversion to HImode.
4058 ;; Without these patterns, we'll try the unsigned SI conversion which
4059 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4061 (define_expand "fixuns_trunc<mode>hi2"
4063 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4064 (set (match_operand:HI 0 "nonimmediate_operand")
4065 (subreg:HI (match_dup 2) 0))]
4066 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4067 "operands[2] = gen_reg_rtx (SImode);")
4069 ;; When SSE is available, it is always faster to use it!
4070 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4071 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4072 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4073 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4074 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4075 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4076 [(set_attr "type" "sseicvt")
4077 (set_attr "prefix" "maybe_vex")
4078 (set (attr "prefix_rex")
4080 (match_test "<SWI48:MODE>mode == DImode")
4082 (const_string "*")))
4083 (set_attr "mode" "<MODEF:MODE>")
4084 (set_attr "athlon_decode" "double,vector")
4085 (set_attr "amdfam10_decode" "double,double")
4086 (set_attr "bdver1_decode" "double,double")])
4088 ;; Avoid vector decoded forms of the instruction.
4090 [(match_scratch:MODEF 2 "x")
4091 (set (match_operand:SWI48 0 "register_operand")
4092 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4093 "TARGET_AVOID_VECTOR_DECODE
4094 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4095 && optimize_insn_for_speed_p ()"
4096 [(set (match_dup 2) (match_dup 1))
4097 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4099 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4100 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4101 (fix:SWI248x (match_operand 1 "register_operand")))]
4102 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4104 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4105 && (TARGET_64BIT || <MODE>mode != DImode))
4107 && can_create_pseudo_p ()"
4112 if (memory_operand (operands[0], VOIDmode))
4113 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4116 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4117 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4123 [(set_attr "type" "fisttp")
4124 (set_attr "mode" "<MODE>")])
4126 (define_insn "fix_trunc<mode>_i387_fisttp"
4127 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4128 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4129 (clobber (match_scratch:XF 2 "=&1f"))]
4130 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4132 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4133 && (TARGET_64BIT || <MODE>mode != DImode))
4134 && TARGET_SSE_MATH)"
4135 "* return output_fix_trunc (insn, operands, true);"
4136 [(set_attr "type" "fisttp")
4137 (set_attr "mode" "<MODE>")])
4139 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4140 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4141 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4142 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4143 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4144 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4146 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4147 && (TARGET_64BIT || <MODE>mode != DImode))
4148 && TARGET_SSE_MATH)"
4150 [(set_attr "type" "fisttp")
4151 (set_attr "mode" "<MODE>")])
4154 [(set (match_operand:SWI248x 0 "register_operand")
4155 (fix:SWI248x (match_operand 1 "register_operand")))
4156 (clobber (match_operand:SWI248x 2 "memory_operand"))
4157 (clobber (match_scratch 3))]
4159 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4160 (clobber (match_dup 3))])
4161 (set (match_dup 0) (match_dup 2))])
4164 [(set (match_operand:SWI248x 0 "memory_operand")
4165 (fix:SWI248x (match_operand 1 "register_operand")))
4166 (clobber (match_operand:SWI248x 2 "memory_operand"))
4167 (clobber (match_scratch 3))]
4169 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4170 (clobber (match_dup 3))])])
4172 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4173 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4174 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4175 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4176 ;; function in i386.c.
4177 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4178 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4179 (fix:SWI248x (match_operand 1 "register_operand")))
4180 (clobber (reg:CC FLAGS_REG))]
4181 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4183 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4184 && (TARGET_64BIT || <MODE>mode != DImode))
4185 && can_create_pseudo_p ()"
4190 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4192 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4193 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4194 if (memory_operand (operands[0], VOIDmode))
4195 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4196 operands[2], operands[3]));
4199 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4200 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4201 operands[2], operands[3],
4206 [(set_attr "type" "fistp")
4207 (set_attr "i387_cw" "trunc")
4208 (set_attr "mode" "<MODE>")])
4210 (define_insn "fix_truncdi_i387"
4211 [(set (match_operand:DI 0 "memory_operand" "=m")
4212 (fix:DI (match_operand 1 "register_operand" "f")))
4213 (use (match_operand:HI 2 "memory_operand" "m"))
4214 (use (match_operand:HI 3 "memory_operand" "m"))
4215 (clobber (match_scratch:XF 4 "=&1f"))]
4216 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4218 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4219 "* return output_fix_trunc (insn, operands, false);"
4220 [(set_attr "type" "fistp")
4221 (set_attr "i387_cw" "trunc")
4222 (set_attr "mode" "DI")])
4224 (define_insn "fix_truncdi_i387_with_temp"
4225 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4226 (fix:DI (match_operand 1 "register_operand" "f,f")))
4227 (use (match_operand:HI 2 "memory_operand" "m,m"))
4228 (use (match_operand:HI 3 "memory_operand" "m,m"))
4229 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4230 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4231 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4233 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4235 [(set_attr "type" "fistp")
4236 (set_attr "i387_cw" "trunc")
4237 (set_attr "mode" "DI")])
4240 [(set (match_operand:DI 0 "register_operand")
4241 (fix:DI (match_operand 1 "register_operand")))
4242 (use (match_operand:HI 2 "memory_operand"))
4243 (use (match_operand:HI 3 "memory_operand"))
4244 (clobber (match_operand:DI 4 "memory_operand"))
4245 (clobber (match_scratch 5))]
4247 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4250 (clobber (match_dup 5))])
4251 (set (match_dup 0) (match_dup 4))])
4254 [(set (match_operand:DI 0 "memory_operand")
4255 (fix:DI (match_operand 1 "register_operand")))
4256 (use (match_operand:HI 2 "memory_operand"))
4257 (use (match_operand:HI 3 "memory_operand"))
4258 (clobber (match_operand:DI 4 "memory_operand"))
4259 (clobber (match_scratch 5))]
4261 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4264 (clobber (match_dup 5))])])
4266 (define_insn "fix_trunc<mode>_i387"
4267 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4268 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4269 (use (match_operand:HI 2 "memory_operand" "m"))
4270 (use (match_operand:HI 3 "memory_operand" "m"))]
4271 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4273 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4274 "* return output_fix_trunc (insn, operands, false);"
4275 [(set_attr "type" "fistp")
4276 (set_attr "i387_cw" "trunc")
4277 (set_attr "mode" "<MODE>")])
4279 (define_insn "fix_trunc<mode>_i387_with_temp"
4280 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4281 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4282 (use (match_operand:HI 2 "memory_operand" "m,m"))
4283 (use (match_operand:HI 3 "memory_operand" "m,m"))
4284 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4285 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4287 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4289 [(set_attr "type" "fistp")
4290 (set_attr "i387_cw" "trunc")
4291 (set_attr "mode" "<MODE>")])
4294 [(set (match_operand:SWI24 0 "register_operand")
4295 (fix:SWI24 (match_operand 1 "register_operand")))
4296 (use (match_operand:HI 2 "memory_operand"))
4297 (use (match_operand:HI 3 "memory_operand"))
4298 (clobber (match_operand:SWI24 4 "memory_operand"))]
4300 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4302 (use (match_dup 3))])
4303 (set (match_dup 0) (match_dup 4))])
4306 [(set (match_operand:SWI24 0 "memory_operand")
4307 (fix:SWI24 (match_operand 1 "register_operand")))
4308 (use (match_operand:HI 2 "memory_operand"))
4309 (use (match_operand:HI 3 "memory_operand"))
4310 (clobber (match_operand:SWI24 4 "memory_operand"))]
4312 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4314 (use (match_dup 3))])])
4316 (define_insn "x86_fnstcw_1"
4317 [(set (match_operand:HI 0 "memory_operand" "=m")
4318 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4321 [(set (attr "length")
4322 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4323 (set_attr "mode" "HI")
4324 (set_attr "unit" "i387")
4325 (set_attr "bdver1_decode" "vector")])
4327 (define_insn "x86_fldcw_1"
4328 [(set (reg:HI FPCR_REG)
4329 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4332 [(set (attr "length")
4333 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4334 (set_attr "mode" "HI")
4335 (set_attr "unit" "i387")
4336 (set_attr "athlon_decode" "vector")
4337 (set_attr "amdfam10_decode" "vector")
4338 (set_attr "bdver1_decode" "vector")])
4340 ;; Conversion between fixed point and floating point.
4342 ;; Even though we only accept memory inputs, the backend _really_
4343 ;; wants to be able to do this between registers.
4345 (define_expand "floathi<mode>2"
4346 [(set (match_operand:X87MODEF 0 "register_operand")
4347 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand")))]
4349 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4350 || TARGET_MIX_SSE_I387)")
4352 ;; Pre-reload splitter to add memory clobber to the pattern.
4353 (define_insn_and_split "*floathi<mode>2_1"
4354 [(set (match_operand:X87MODEF 0 "register_operand")
4355 (float:X87MODEF (match_operand:HI 1 "register_operand")))]
4357 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4358 || TARGET_MIX_SSE_I387)
4359 && can_create_pseudo_p ()"
4362 [(parallel [(set (match_dup 0)
4363 (float:X87MODEF (match_dup 1)))
4364 (clobber (match_dup 2))])]
4365 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4367 (define_insn "*floathi<mode>2_i387_with_temp"
4368 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4369 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4370 (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4372 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4373 || TARGET_MIX_SSE_I387)"
4375 [(set_attr "type" "fmov,multi")
4376 (set_attr "mode" "<MODE>")
4377 (set_attr "unit" "*,i387")
4378 (set_attr "fp_int_src" "true")])
4380 (define_insn "*floathi<mode>2_i387"
4381 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4382 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4384 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4385 || TARGET_MIX_SSE_I387)"
4387 [(set_attr "type" "fmov")
4388 (set_attr "mode" "<MODE>")
4389 (set_attr "fp_int_src" "true")])
4392 [(set (match_operand:X87MODEF 0 "register_operand")
4393 (float:X87MODEF (match_operand:HI 1 "register_operand")))
4394 (clobber (match_operand:HI 2 "memory_operand"))]
4396 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4397 || TARGET_MIX_SSE_I387)
4398 && reload_completed"
4399 [(set (match_dup 2) (match_dup 1))
4400 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4403 [(set (match_operand:X87MODEF 0 "register_operand")
4404 (float:X87MODEF (match_operand:HI 1 "memory_operand")))
4405 (clobber (match_operand:HI 2 "memory_operand"))]
4407 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4408 || TARGET_MIX_SSE_I387)
4409 && reload_completed"
4410 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4412 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4413 [(set (match_operand:X87MODEF 0 "register_operand")
4415 (match_operand:SWI48x 1 "nonimmediate_operand")))]
4417 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4418 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4420 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4421 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4422 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4424 rtx reg = gen_reg_rtx (XFmode);
4425 rtx (*insn)(rtx, rtx);
4427 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4429 if (<X87MODEF:MODE>mode == SFmode)
4430 insn = gen_truncxfsf2;
4431 else if (<X87MODEF:MODE>mode == DFmode)
4432 insn = gen_truncxfdf2;
4436 emit_insn (insn (operands[0], reg));
4441 ;; Pre-reload splitter to add memory clobber to the pattern.
4442 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4443 [(set (match_operand:X87MODEF 0 "register_operand")
4444 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))]
4446 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4447 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4448 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4449 || TARGET_MIX_SSE_I387))
4450 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4451 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4452 && ((<SWI48x:MODE>mode == SImode
4453 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4454 && optimize_function_for_speed_p (cfun)
4455 && flag_trapping_math)
4456 || !(TARGET_INTER_UNIT_CONVERSIONS
4457 || optimize_function_for_size_p (cfun)))))
4458 && can_create_pseudo_p ()"
4461 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4462 (clobber (match_dup 2))])]
4464 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4466 /* Avoid store forwarding (partial memory) stall penalty
4467 by passing DImode value through XMM registers. */
4468 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4469 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4470 && optimize_function_for_speed_p (cfun))
4472 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4479 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4480 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4482 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4483 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4484 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4485 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4487 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4488 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4489 (set_attr "unit" "*,i387,*,*,*")
4490 (set_attr "athlon_decode" "*,*,double,direct,double")
4491 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4492 (set_attr "bdver1_decode" "*,*,double,direct,double")
4493 (set_attr "fp_int_src" "true")])
4495 (define_insn "*floatsi<mode>2_vector_mixed"
4496 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4497 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4498 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4499 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4503 [(set_attr "type" "fmov,sseicvt")
4504 (set_attr "mode" "<MODE>,<ssevecmode>")
4505 (set_attr "unit" "i387,*")
4506 (set_attr "athlon_decode" "*,direct")
4507 (set_attr "amdfam10_decode" "*,double")
4508 (set_attr "bdver1_decode" "*,direct")
4509 (set_attr "fp_int_src" "true")])
4511 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_with_temp"
4512 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4514 (match_operand:SWI48 1 "nonimmediate_operand" "m,?r,r,m")))
4515 (clobber (match_operand:SWI48 2 "memory_operand" "=X,m,m,X"))]
4516 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4518 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4519 (set_attr "mode" "<MODEF:MODE>")
4520 (set_attr "unit" "*,i387,*,*")
4521 (set_attr "athlon_decode" "*,*,double,direct")
4522 (set_attr "amdfam10_decode" "*,*,vector,double")
4523 (set_attr "bdver1_decode" "*,*,double,direct")
4524 (set_attr "fp_int_src" "true")])
4527 [(set (match_operand:MODEF 0 "register_operand")
4528 (float:MODEF (match_operand:SWI48 1 "register_operand")))
4529 (clobber (match_operand:SWI48 2 "memory_operand"))]
4530 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4531 && TARGET_INTER_UNIT_CONVERSIONS
4533 && (SSE_REG_P (operands[0])
4534 || (GET_CODE (operands[0]) == SUBREG
4535 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4536 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4539 [(set (match_operand:MODEF 0 "register_operand")
4540 (float:MODEF (match_operand:SWI48 1 "register_operand")))
4541 (clobber (match_operand:SWI48 2 "memory_operand"))]
4542 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4543 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4545 && (SSE_REG_P (operands[0])
4546 || (GET_CODE (operands[0]) == SUBREG
4547 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4548 [(set (match_dup 2) (match_dup 1))
4549 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4551 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_interunit"
4552 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4554 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
4555 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4556 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4559 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
4560 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4561 [(set_attr "type" "fmov,sseicvt,sseicvt")
4562 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4563 (set_attr "mode" "<MODEF:MODE>")
4564 (set (attr "prefix_rex")
4566 (and (eq_attr "prefix" "maybe_vex")
4567 (match_test "<SWI48:MODE>mode == DImode"))
4569 (const_string "*")))
4570 (set_attr "unit" "i387,*,*")
4571 (set_attr "athlon_decode" "*,double,direct")
4572 (set_attr "amdfam10_decode" "*,vector,double")
4573 (set_attr "bdver1_decode" "*,double,direct")
4574 (set_attr "fp_int_src" "true")])
4576 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_nointerunit"
4577 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4579 (match_operand:SWI48 1 "memory_operand" "m,m")))]
4580 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4581 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4584 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4585 [(set_attr "type" "fmov,sseicvt")
4586 (set_attr "prefix" "orig,maybe_vex")
4587 (set_attr "mode" "<MODEF:MODE>")
4588 (set (attr "prefix_rex")
4590 (and (eq_attr "prefix" "maybe_vex")
4591 (match_test "<SWI48:MODE>mode == DImode"))
4593 (const_string "*")))
4594 (set_attr "athlon_decode" "*,direct")
4595 (set_attr "amdfam10_decode" "*,double")
4596 (set_attr "bdver1_decode" "*,direct")
4597 (set_attr "fp_int_src" "true")])
4599 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4600 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4602 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4603 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4604 "TARGET_SSE2 && TARGET_SSE_MATH
4605 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4607 [(set_attr "type" "sseicvt")
4608 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4609 (set_attr "athlon_decode" "double,direct,double")
4610 (set_attr "amdfam10_decode" "vector,double,double")
4611 (set_attr "bdver1_decode" "double,direct,double")
4612 (set_attr "fp_int_src" "true")])
4614 (define_insn "*floatsi<mode>2_vector_sse"
4615 [(set (match_operand:MODEF 0 "register_operand" "=x")
4616 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4617 "TARGET_SSE2 && TARGET_SSE_MATH
4618 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4620 [(set_attr "type" "sseicvt")
4621 (set_attr "mode" "<MODE>")
4622 (set_attr "athlon_decode" "direct")
4623 (set_attr "amdfam10_decode" "double")
4624 (set_attr "bdver1_decode" "direct")
4625 (set_attr "fp_int_src" "true")])
4628 [(set (match_operand:MODEF 0 "register_operand")
4629 (float:MODEF (match_operand:SI 1 "register_operand")))
4630 (clobber (match_operand:SI 2 "memory_operand"))]
4631 "TARGET_SSE2 && TARGET_SSE_MATH
4632 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4634 && (SSE_REG_P (operands[0])
4635 || (GET_CODE (operands[0]) == SUBREG
4636 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4639 rtx op1 = operands[1];
4641 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4643 if (GET_CODE (op1) == SUBREG)
4644 op1 = SUBREG_REG (op1);
4646 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES_TO_VEC)
4648 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4649 emit_insn (gen_sse2_loadld (operands[4],
4650 CONST0_RTX (V4SImode), operands[1]));
4652 /* We can ignore possible trapping value in the
4653 high part of SSE register for non-trapping math. */
4654 else if (SSE_REG_P (op1) && !flag_trapping_math)
4655 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4658 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4659 emit_move_insn (operands[2], operands[1]);
4660 emit_insn (gen_sse2_loadld (operands[4],
4661 CONST0_RTX (V4SImode), operands[2]));
4663 if (<ssevecmode>mode == V4SFmode)
4664 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4666 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4671 [(set (match_operand:MODEF 0 "register_operand")
4672 (float:MODEF (match_operand:SI 1 "memory_operand")))
4673 (clobber (match_operand:SI 2 "memory_operand"))]
4674 "TARGET_SSE2 && TARGET_SSE_MATH
4675 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4677 && (SSE_REG_P (operands[0])
4678 || (GET_CODE (operands[0]) == SUBREG
4679 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4682 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4684 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4686 emit_insn (gen_sse2_loadld (operands[4],
4687 CONST0_RTX (V4SImode), operands[1]));
4688 if (<ssevecmode>mode == V4SFmode)
4689 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4691 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4696 [(set (match_operand:MODEF 0 "register_operand")
4697 (float:MODEF (match_operand:SI 1 "register_operand")))]
4698 "TARGET_SSE2 && TARGET_SSE_MATH
4699 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4701 && (SSE_REG_P (operands[0])
4702 || (GET_CODE (operands[0]) == SUBREG
4703 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4706 rtx op1 = operands[1];
4708 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4710 if (GET_CODE (op1) == SUBREG)
4711 op1 = SUBREG_REG (op1);
4713 if (GENERAL_REG_P (op1))
4715 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4716 if (TARGET_INTER_UNIT_MOVES_TO_VEC)
4717 emit_insn (gen_sse2_loadld (operands[4],
4718 CONST0_RTX (V4SImode), operands[1]));
4721 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
4723 emit_insn (gen_sse2_loadld (operands[4],
4724 CONST0_RTX (V4SImode), operands[5]));
4725 ix86_free_from_memory (GET_MODE (operands[1]));
4728 /* We can ignore possible trapping value in the
4729 high part of SSE register for non-trapping math. */
4730 else if (SSE_REG_P (op1) && !flag_trapping_math)
4731 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4734 if (<ssevecmode>mode == V4SFmode)
4735 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4737 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4742 [(set (match_operand:MODEF 0 "register_operand")
4743 (float:MODEF (match_operand:SI 1 "memory_operand")))]
4744 "TARGET_SSE2 && TARGET_SSE_MATH
4745 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4747 && (SSE_REG_P (operands[0])
4748 || (GET_CODE (operands[0]) == SUBREG
4749 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4752 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4754 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4756 emit_insn (gen_sse2_loadld (operands[4],
4757 CONST0_RTX (V4SImode), operands[1]));
4758 if (<ssevecmode>mode == V4SFmode)
4759 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4761 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4765 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_with_temp"
4766 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
4768 (match_operand:SWI48 1 "nonimmediate_operand" "r,m")))
4769 (clobber (match_operand:SWI48 2 "memory_operand" "=m,X"))]
4770 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
4772 [(set_attr "type" "sseicvt")
4773 (set_attr "mode" "<MODEF:MODE>")
4774 (set_attr "athlon_decode" "double,direct")
4775 (set_attr "amdfam10_decode" "vector,double")
4776 (set_attr "bdver1_decode" "double,direct")
4777 (set_attr "btver2_decode" "double,double")
4778 (set_attr "fp_int_src" "true")])
4780 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_interunit"
4781 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
4783 (match_operand:SWI48 1 "nonimmediate_operand" "r,m")))]
4784 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
4785 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4786 "%vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4787 [(set_attr "type" "sseicvt")
4788 (set_attr "prefix" "maybe_vex")
4789 (set_attr "mode" "<MODEF:MODE>")
4790 (set (attr "prefix_rex")
4792 (and (eq_attr "prefix" "maybe_vex")
4793 (match_test "<SWI48:MODE>mode == DImode"))
4795 (const_string "*")))
4796 (set_attr "athlon_decode" "double,direct")
4797 (set_attr "amdfam10_decode" "vector,double")
4798 (set_attr "bdver1_decode" "double,direct")
4799 (set_attr "btver2_decode" "double,double")
4800 (set_attr "fp_int_src" "true")])
4803 [(set (match_operand:MODEF 0 "register_operand")
4804 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))
4805 (clobber (match_operand:SWI48 2 "memory_operand"))]
4806 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
4807 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4809 && (SSE_REG_P (operands[0])
4810 || (GET_CODE (operands[0]) == SUBREG
4811 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4812 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4814 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_nointerunit"
4815 [(set (match_operand:MODEF 0 "register_operand" "=x")
4817 (match_operand:SWI48 1 "memory_operand" "m")))]
4818 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
4819 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4820 "%vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4821 [(set_attr "type" "sseicvt")
4822 (set_attr "prefix" "maybe_vex")
4823 (set_attr "mode" "<MODEF:MODE>")
4824 (set (attr "prefix_rex")
4826 (and (eq_attr "prefix" "maybe_vex")
4827 (match_test "<SWI48:MODE>mode == DImode"))
4829 (const_string "*")))
4830 (set_attr "athlon_decode" "direct")
4831 (set_attr "amdfam10_decode" "double")
4832 (set_attr "bdver1_decode" "direct")
4833 (set_attr "fp_int_src" "true")])
4836 [(set (match_operand:MODEF 0 "register_operand")
4837 (float:MODEF (match_operand:SWI48 1 "register_operand")))
4838 (clobber (match_operand:SWI48 2 "memory_operand"))]
4839 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
4840 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4842 && (SSE_REG_P (operands[0])
4843 || (GET_CODE (operands[0]) == SUBREG
4844 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4845 [(set (match_dup 2) (match_dup 1))
4846 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4849 [(set (match_operand:MODEF 0 "register_operand")
4850 (float:MODEF (match_operand:SWI48 1 "memory_operand")))
4851 (clobber (match_operand:SWI48 2 "memory_operand"))]
4852 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
4854 && (SSE_REG_P (operands[0])
4855 || (GET_CODE (operands[0]) == SUBREG
4856 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4857 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4859 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
4860 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4862 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
4863 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
4865 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
4869 [(set_attr "type" "fmov,multi")
4870 (set_attr "mode" "<X87MODEF:MODE>")
4871 (set_attr "unit" "*,i387")
4872 (set_attr "fp_int_src" "true")])
4874 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
4875 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4877 (match_operand:SWI48x 1 "memory_operand" "m")))]
4879 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
4881 [(set_attr "type" "fmov")
4882 (set_attr "mode" "<X87MODEF:MODE>")
4883 (set_attr "fp_int_src" "true")])
4886 [(set (match_operand:X87MODEF 0 "fp_register_operand")
4887 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))
4888 (clobber (match_operand:SWI48x 2 "memory_operand"))]
4890 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4891 && reload_completed"
4892 [(set (match_dup 2) (match_dup 1))
4893 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4896 [(set (match_operand:X87MODEF 0 "fp_register_operand")
4897 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand")))
4898 (clobber (match_operand:SWI48x 2 "memory_operand"))]
4900 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4901 && reload_completed"
4902 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4904 ;; Avoid store forwarding (partial memory) stall penalty
4905 ;; by passing DImode value through XMM registers. */
4907 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
4908 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4910 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
4911 (clobber (match_scratch:V4SI 3 "=X,x"))
4912 (clobber (match_scratch:V4SI 4 "=X,x"))
4913 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
4914 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4915 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4916 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
4918 [(set_attr "type" "multi")
4919 (set_attr "mode" "<X87MODEF:MODE>")
4920 (set_attr "unit" "i387")
4921 (set_attr "fp_int_src" "true")])
4924 [(set (match_operand:X87MODEF 0 "fp_register_operand")
4925 (float:X87MODEF (match_operand:DI 1 "register_operand")))
4926 (clobber (match_scratch:V4SI 3))
4927 (clobber (match_scratch:V4SI 4))
4928 (clobber (match_operand:DI 2 "memory_operand"))]
4929 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4930 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4931 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
4932 && reload_completed"
4933 [(set (match_dup 2) (match_dup 3))
4934 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
4936 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
4937 Assemble the 64-bit DImode value in an xmm register. */
4938 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
4939 gen_rtx_SUBREG (SImode, operands[1], 0)));
4940 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
4941 gen_rtx_SUBREG (SImode, operands[1], 4)));
4942 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
4945 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
4949 [(set (match_operand:X87MODEF 0 "fp_register_operand")
4950 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
4951 (clobber (match_scratch:V4SI 3))
4952 (clobber (match_scratch:V4SI 4))
4953 (clobber (match_operand:DI 2 "memory_operand"))]
4954 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4955 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4956 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
4957 && reload_completed"
4958 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4960 ;; Avoid store forwarding (partial memory) stall penalty by extending
4961 ;; SImode value to DImode through XMM register instead of pushing two
4962 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES_TO_VEC
4963 ;; targets benefit from this optimization. Also note that fild
4964 ;; loads from memory only.
4966 (define_insn "*floatunssi<mode>2_1"
4967 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4968 (unsigned_float:X87MODEF
4969 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
4970 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
4971 (clobber (match_scratch:SI 3 "=X,x"))]
4973 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4976 [(set_attr "type" "multi")
4977 (set_attr "mode" "<MODE>")])
4980 [(set (match_operand:X87MODEF 0 "register_operand")
4981 (unsigned_float:X87MODEF
4982 (match_operand:SI 1 "register_operand")))
4983 (clobber (match_operand:DI 2 "memory_operand"))
4984 (clobber (match_scratch:SI 3))]
4986 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4988 && reload_completed"
4989 [(set (match_dup 2) (match_dup 1))
4991 (float:X87MODEF (match_dup 2)))]
4992 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
4995 [(set (match_operand:X87MODEF 0 "register_operand")
4996 (unsigned_float:X87MODEF
4997 (match_operand:SI 1 "memory_operand")))
4998 (clobber (match_operand:DI 2 "memory_operand"))
4999 (clobber (match_scratch:SI 3))]
5001 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5003 && reload_completed"
5004 [(set (match_dup 2) (match_dup 3))
5006 (float:X87MODEF (match_dup 2)))]
5008 emit_move_insn (operands[3], operands[1]);
5009 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5012 (define_expand "floatunssi<mode>2"
5014 [(set (match_operand:X87MODEF 0 "register_operand")
5015 (unsigned_float:X87MODEF
5016 (match_operand:SI 1 "nonimmediate_operand")))
5017 (clobber (match_dup 2))
5018 (clobber (match_scratch:SI 3))])]
5020 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5022 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5024 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5026 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5030 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5033 (define_expand "floatunsdisf2"
5034 [(use (match_operand:SF 0 "register_operand"))
5035 (use (match_operand:DI 1 "nonimmediate_operand"))]
5036 "TARGET_64BIT && TARGET_SSE_MATH"
5037 "x86_emit_floatuns (operands); DONE;")
5039 (define_expand "floatunsdidf2"
5040 [(use (match_operand:DF 0 "register_operand"))
5041 (use (match_operand:DI 1 "nonimmediate_operand"))]
5042 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5043 && TARGET_SSE2 && TARGET_SSE_MATH"
5046 x86_emit_floatuns (operands);
5048 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5052 ;; Load effective address instructions
5054 (define_insn_and_split "*lea<mode>"
5055 [(set (match_operand:SWI48 0 "register_operand" "=r")
5056 (match_operand:SWI48 1 "lea_address_operand" "p"))]
5059 if (SImode_address_operand (operands[1], VOIDmode))
5061 gcc_assert (TARGET_64BIT);
5062 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5065 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5067 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5070 enum machine_mode mode = <MODE>mode;
5073 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5074 change operands[] array behind our back. */
5075 pat = PATTERN (curr_insn);
5077 operands[0] = SET_DEST (pat);
5078 operands[1] = SET_SRC (pat);
5080 /* Emit all operations in SImode for zero-extended addresses. Recall
5081 that x86_64 inheretly zero-extends SImode operations to DImode. */
5082 if (SImode_address_operand (operands[1], VOIDmode))
5085 ix86_split_lea_for_addr (curr_insn, operands, mode);
5088 [(set_attr "type" "lea")
5091 (match_operand 1 "SImode_address_operand")
5093 (const_string "<MODE>")))])
5097 (define_expand "add<mode>3"
5098 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5099 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5100 (match_operand:SDWIM 2 "<general_operand>")))]
5102 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5104 (define_insn_and_split "*add<dwi>3_doubleword"
5105 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5107 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5108 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5109 (clobber (reg:CC FLAGS_REG))]
5110 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5113 [(parallel [(set (reg:CC FLAGS_REG)
5114 (unspec:CC [(match_dup 1) (match_dup 2)]
5117 (plus:DWIH (match_dup 1) (match_dup 2)))])
5118 (parallel [(set (match_dup 3)
5122 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5124 (clobber (reg:CC FLAGS_REG))])]
5125 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5127 (define_insn "*add<mode>3_cc"
5128 [(set (reg:CC FLAGS_REG)
5130 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5131 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5133 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5134 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5135 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5136 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5137 [(set_attr "type" "alu")
5138 (set_attr "mode" "<MODE>")])
5140 (define_insn "addqi3_cc"
5141 [(set (reg:CC FLAGS_REG)
5143 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5144 (match_operand:QI 2 "general_operand" "qn,qm")]
5146 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5147 (plus:QI (match_dup 1) (match_dup 2)))]
5148 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5149 "add{b}\t{%2, %0|%0, %2}"
5150 [(set_attr "type" "alu")
5151 (set_attr "mode" "QI")])
5153 (define_insn "*add<mode>_1"
5154 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5156 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5157 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5158 (clobber (reg:CC FLAGS_REG))]
5159 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5161 switch (get_attr_type (insn))
5167 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5168 if (operands[2] == const1_rtx)
5169 return "inc{<imodesuffix>}\t%0";
5172 gcc_assert (operands[2] == constm1_rtx);
5173 return "dec{<imodesuffix>}\t%0";
5177 /* For most processors, ADD is faster than LEA. This alternative
5178 was added to use ADD as much as possible. */
5179 if (which_alternative == 2)
5182 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5185 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5186 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5187 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5189 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5193 (cond [(eq_attr "alternative" "3")
5194 (const_string "lea")
5195 (match_operand:SWI48 2 "incdec_operand")
5196 (const_string "incdec")
5198 (const_string "alu")))
5199 (set (attr "length_immediate")
5201 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5203 (const_string "*")))
5204 (set_attr "mode" "<MODE>")])
5206 ;; It may seem that nonimmediate operand is proper one for operand 1.
5207 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5208 ;; we take care in ix86_binary_operator_ok to not allow two memory
5209 ;; operands so proper swapping will be done in reload. This allow
5210 ;; patterns constructed from addsi_1 to match.
5212 (define_insn "addsi_1_zext"
5213 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5215 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5216 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5217 (clobber (reg:CC FLAGS_REG))]
5218 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5220 switch (get_attr_type (insn))
5226 if (operands[2] == const1_rtx)
5227 return "inc{l}\t%k0";
5230 gcc_assert (operands[2] == constm1_rtx);
5231 return "dec{l}\t%k0";
5235 /* For most processors, ADD is faster than LEA. This alternative
5236 was added to use ADD as much as possible. */
5237 if (which_alternative == 1)
5240 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5243 if (x86_maybe_negate_const_int (&operands[2], SImode))
5244 return "sub{l}\t{%2, %k0|%k0, %2}";
5246 return "add{l}\t{%2, %k0|%k0, %2}";
5250 (cond [(eq_attr "alternative" "2")
5251 (const_string "lea")
5252 (match_operand:SI 2 "incdec_operand")
5253 (const_string "incdec")
5255 (const_string "alu")))
5256 (set (attr "length_immediate")
5258 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5260 (const_string "*")))
5261 (set_attr "mode" "SI")])
5263 (define_insn "*addhi_1"
5264 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5265 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5266 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5267 (clobber (reg:CC FLAGS_REG))]
5268 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5270 switch (get_attr_type (insn))
5276 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5277 if (operands[2] == const1_rtx)
5278 return "inc{w}\t%0";
5281 gcc_assert (operands[2] == constm1_rtx);
5282 return "dec{w}\t%0";
5286 /* For most processors, ADD is faster than LEA. This alternative
5287 was added to use ADD as much as possible. */
5288 if (which_alternative == 2)
5291 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5294 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5295 if (x86_maybe_negate_const_int (&operands[2], HImode))
5296 return "sub{w}\t{%2, %0|%0, %2}";
5298 return "add{w}\t{%2, %0|%0, %2}";
5302 (cond [(eq_attr "alternative" "3")
5303 (const_string "lea")
5304 (match_operand:HI 2 "incdec_operand")
5305 (const_string "incdec")
5307 (const_string "alu")))
5308 (set (attr "length_immediate")
5310 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5312 (const_string "*")))
5313 (set_attr "mode" "HI,HI,HI,SI")])
5315 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5316 (define_insn "*addqi_1"
5317 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5318 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5319 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5320 (clobber (reg:CC FLAGS_REG))]
5321 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5323 bool widen = (which_alternative == 3 || which_alternative == 4);
5325 switch (get_attr_type (insn))
5331 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5332 if (operands[2] == const1_rtx)
5333 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5336 gcc_assert (operands[2] == constm1_rtx);
5337 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5341 /* For most processors, ADD is faster than LEA. These alternatives
5342 were added to use ADD as much as possible. */
5343 if (which_alternative == 2 || which_alternative == 4)
5346 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5349 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5350 if (x86_maybe_negate_const_int (&operands[2], QImode))
5353 return "sub{l}\t{%2, %k0|%k0, %2}";
5355 return "sub{b}\t{%2, %0|%0, %2}";
5358 return "add{l}\t{%k2, %k0|%k0, %k2}";
5360 return "add{b}\t{%2, %0|%0, %2}";
5364 (cond [(eq_attr "alternative" "5")
5365 (const_string "lea")
5366 (match_operand:QI 2 "incdec_operand")
5367 (const_string "incdec")
5369 (const_string "alu")))
5370 (set (attr "length_immediate")
5372 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5374 (const_string "*")))
5375 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5377 (define_insn "*addqi_1_slp"
5378 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5379 (plus:QI (match_dup 0)
5380 (match_operand:QI 1 "general_operand" "qn,qm")))
5381 (clobber (reg:CC FLAGS_REG))]
5382 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5383 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5385 switch (get_attr_type (insn))
5388 if (operands[1] == const1_rtx)
5389 return "inc{b}\t%0";
5392 gcc_assert (operands[1] == constm1_rtx);
5393 return "dec{b}\t%0";
5397 if (x86_maybe_negate_const_int (&operands[1], QImode))
5398 return "sub{b}\t{%1, %0|%0, %1}";
5400 return "add{b}\t{%1, %0|%0, %1}";
5404 (if_then_else (match_operand:QI 1 "incdec_operand")
5405 (const_string "incdec")
5406 (const_string "alu1")))
5407 (set (attr "memory")
5408 (if_then_else (match_operand 1 "memory_operand")
5409 (const_string "load")
5410 (const_string "none")))
5411 (set_attr "mode" "QI")])
5413 ;; Split non destructive adds if we cannot use lea.
5415 [(set (match_operand:SWI48 0 "register_operand")
5416 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5417 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5418 (clobber (reg:CC FLAGS_REG))]
5419 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5420 [(set (match_dup 0) (match_dup 1))
5421 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5422 (clobber (reg:CC FLAGS_REG))])])
5424 ;; Convert add to the lea pattern to avoid flags dependency.
5426 [(set (match_operand:SWI 0 "register_operand")
5427 (plus:SWI (match_operand:SWI 1 "register_operand")
5428 (match_operand:SWI 2 "<nonmemory_operand>")))
5429 (clobber (reg:CC FLAGS_REG))]
5430 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5433 enum machine_mode mode = <MODE>mode;
5436 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5439 operands[0] = gen_lowpart (mode, operands[0]);
5440 operands[1] = gen_lowpart (mode, operands[1]);
5441 operands[2] = gen_lowpart (mode, operands[2]);
5444 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5446 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5450 ;; Split non destructive adds if we cannot use lea.
5452 [(set (match_operand:DI 0 "register_operand")
5454 (plus:SI (match_operand:SI 1 "register_operand")
5455 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5456 (clobber (reg:CC FLAGS_REG))]
5458 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5459 [(set (match_dup 3) (match_dup 1))
5460 (parallel [(set (match_dup 0)
5461 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5462 (clobber (reg:CC FLAGS_REG))])]
5463 "operands[3] = gen_lowpart (SImode, operands[0]);")
5465 ;; Convert add to the lea pattern to avoid flags dependency.
5467 [(set (match_operand:DI 0 "register_operand")
5469 (plus:SI (match_operand:SI 1 "register_operand")
5470 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5471 (clobber (reg:CC FLAGS_REG))]
5472 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5474 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5476 (define_insn "*add<mode>_2"
5477 [(set (reg FLAGS_REG)
5480 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5481 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5483 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5484 (plus:SWI (match_dup 1) (match_dup 2)))]
5485 "ix86_match_ccmode (insn, CCGOCmode)
5486 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5488 switch (get_attr_type (insn))
5491 if (operands[2] == const1_rtx)
5492 return "inc{<imodesuffix>}\t%0";
5495 gcc_assert (operands[2] == constm1_rtx);
5496 return "dec{<imodesuffix>}\t%0";
5500 if (which_alternative == 2)
5503 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5506 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5507 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5508 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5510 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5514 (if_then_else (match_operand:SWI 2 "incdec_operand")
5515 (const_string "incdec")
5516 (const_string "alu")))
5517 (set (attr "length_immediate")
5519 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5521 (const_string "*")))
5522 (set_attr "mode" "<MODE>")])
5524 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5525 (define_insn "*addsi_2_zext"
5526 [(set (reg FLAGS_REG)
5528 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5529 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5531 (set (match_operand:DI 0 "register_operand" "=r,r")
5532 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5533 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5534 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5536 switch (get_attr_type (insn))
5539 if (operands[2] == const1_rtx)
5540 return "inc{l}\t%k0";
5543 gcc_assert (operands[2] == constm1_rtx);
5544 return "dec{l}\t%k0";
5548 if (which_alternative == 1)
5551 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5554 if (x86_maybe_negate_const_int (&operands[2], SImode))
5555 return "sub{l}\t{%2, %k0|%k0, %2}";
5557 return "add{l}\t{%2, %k0|%k0, %2}";
5561 (if_then_else (match_operand:SI 2 "incdec_operand")
5562 (const_string "incdec")
5563 (const_string "alu")))
5564 (set (attr "length_immediate")
5566 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5568 (const_string "*")))
5569 (set_attr "mode" "SI")])
5571 (define_insn "*add<mode>_3"
5572 [(set (reg FLAGS_REG)
5574 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5575 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5576 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5577 "ix86_match_ccmode (insn, CCZmode)
5578 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5580 switch (get_attr_type (insn))
5583 if (operands[2] == const1_rtx)
5584 return "inc{<imodesuffix>}\t%0";
5587 gcc_assert (operands[2] == constm1_rtx);
5588 return "dec{<imodesuffix>}\t%0";
5592 if (which_alternative == 1)
5595 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5598 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5599 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5600 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5602 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5606 (if_then_else (match_operand:SWI 2 "incdec_operand")
5607 (const_string "incdec")
5608 (const_string "alu")))
5609 (set (attr "length_immediate")
5611 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5613 (const_string "*")))
5614 (set_attr "mode" "<MODE>")])
5616 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5617 (define_insn "*addsi_3_zext"
5618 [(set (reg FLAGS_REG)
5620 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5621 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5622 (set (match_operand:DI 0 "register_operand" "=r,r")
5623 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5624 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5625 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5627 switch (get_attr_type (insn))
5630 if (operands[2] == const1_rtx)
5631 return "inc{l}\t%k0";
5634 gcc_assert (operands[2] == constm1_rtx);
5635 return "dec{l}\t%k0";
5639 if (which_alternative == 1)
5642 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5645 if (x86_maybe_negate_const_int (&operands[2], SImode))
5646 return "sub{l}\t{%2, %k0|%k0, %2}";
5648 return "add{l}\t{%2, %k0|%k0, %2}";
5652 (if_then_else (match_operand:SI 2 "incdec_operand")
5653 (const_string "incdec")
5654 (const_string "alu")))
5655 (set (attr "length_immediate")
5657 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5659 (const_string "*")))
5660 (set_attr "mode" "SI")])
5662 ; For comparisons against 1, -1 and 128, we may generate better code
5663 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5664 ; is matched then. We can't accept general immediate, because for
5665 ; case of overflows, the result is messed up.
5666 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5667 ; only for comparisons not depending on it.
5669 (define_insn "*adddi_4"
5670 [(set (reg FLAGS_REG)
5672 (match_operand:DI 1 "nonimmediate_operand" "0")
5673 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5674 (clobber (match_scratch:DI 0 "=rm"))]
5676 && ix86_match_ccmode (insn, CCGCmode)"
5678 switch (get_attr_type (insn))
5681 if (operands[2] == constm1_rtx)
5682 return "inc{q}\t%0";
5685 gcc_assert (operands[2] == const1_rtx);
5686 return "dec{q}\t%0";
5690 if (x86_maybe_negate_const_int (&operands[2], DImode))
5691 return "add{q}\t{%2, %0|%0, %2}";
5693 return "sub{q}\t{%2, %0|%0, %2}";
5697 (if_then_else (match_operand:DI 2 "incdec_operand")
5698 (const_string "incdec")
5699 (const_string "alu")))
5700 (set (attr "length_immediate")
5702 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5704 (const_string "*")))
5705 (set_attr "mode" "DI")])
5707 ; For comparisons against 1, -1 and 128, we may generate better code
5708 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5709 ; is matched then. We can't accept general immediate, because for
5710 ; case of overflows, the result is messed up.
5711 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5712 ; only for comparisons not depending on it.
5714 (define_insn "*add<mode>_4"
5715 [(set (reg FLAGS_REG)
5717 (match_operand:SWI124 1 "nonimmediate_operand" "0")
5718 (match_operand:SWI124 2 "const_int_operand" "n")))
5719 (clobber (match_scratch:SWI124 0 "=<r>m"))]
5720 "ix86_match_ccmode (insn, CCGCmode)"
5722 switch (get_attr_type (insn))
5725 if (operands[2] == constm1_rtx)
5726 return "inc{<imodesuffix>}\t%0";
5729 gcc_assert (operands[2] == const1_rtx);
5730 return "dec{<imodesuffix>}\t%0";
5734 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5735 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5737 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5741 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
5742 (const_string "incdec")
5743 (const_string "alu")))
5744 (set (attr "length_immediate")
5746 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5748 (const_string "*")))
5749 (set_attr "mode" "<MODE>")])
5751 (define_insn "*add<mode>_5"
5752 [(set (reg FLAGS_REG)
5755 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
5756 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5758 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5759 "ix86_match_ccmode (insn, CCGOCmode)
5760 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5762 switch (get_attr_type (insn))
5765 if (operands[2] == const1_rtx)
5766 return "inc{<imodesuffix>}\t%0";
5769 gcc_assert (operands[2] == constm1_rtx);
5770 return "dec{<imodesuffix>}\t%0";
5774 if (which_alternative == 1)
5777 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5780 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5781 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5782 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5784 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5788 (if_then_else (match_operand:SWI 2 "incdec_operand")
5789 (const_string "incdec")
5790 (const_string "alu")))
5791 (set (attr "length_immediate")
5793 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5795 (const_string "*")))
5796 (set_attr "mode" "<MODE>")])
5798 (define_insn "addqi_ext_1"
5799 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
5804 (match_operand 1 "ext_register_operand" "0,0")
5807 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m")))
5808 (clobber (reg:CC FLAGS_REG))]
5811 switch (get_attr_type (insn))
5814 if (operands[2] == const1_rtx)
5815 return "inc{b}\t%h0";
5818 gcc_assert (operands[2] == constm1_rtx);
5819 return "dec{b}\t%h0";
5823 return "add{b}\t{%2, %h0|%h0, %2}";
5826 [(set_attr "isa" "*,nox64")
5828 (if_then_else (match_operand:QI 2 "incdec_operand")
5829 (const_string "incdec")
5830 (const_string "alu")))
5831 (set_attr "modrm" "1")
5832 (set_attr "mode" "QI")])
5834 (define_insn "*addqi_ext_2"
5835 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
5840 (match_operand 1 "ext_register_operand" "%0")
5844 (match_operand 2 "ext_register_operand" "Q")
5847 (clobber (reg:CC FLAGS_REG))]
5849 "add{b}\t{%h2, %h0|%h0, %h2}"
5850 [(set_attr "type" "alu")
5851 (set_attr "mode" "QI")])
5853 ;; The lea patterns for modes less than 32 bits need to be matched by
5854 ;; several insns converted to real lea by splitters.
5856 (define_insn_and_split "*lea_general_1"
5857 [(set (match_operand 0 "register_operand" "=r")
5858 (plus (plus (match_operand 1 "index_register_operand" "l")
5859 (match_operand 2 "register_operand" "r"))
5860 (match_operand 3 "immediate_operand" "i")))]
5861 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5862 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5863 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5864 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5865 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5866 || GET_MODE (operands[3]) == VOIDmode)"
5868 "&& reload_completed"
5871 enum machine_mode mode = SImode;
5874 operands[0] = gen_lowpart (mode, operands[0]);
5875 operands[1] = gen_lowpart (mode, operands[1]);
5876 operands[2] = gen_lowpart (mode, operands[2]);
5877 operands[3] = gen_lowpart (mode, operands[3]);
5879 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
5882 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5885 [(set_attr "type" "lea")
5886 (set_attr "mode" "SI")])
5888 (define_insn_and_split "*lea_general_2"
5889 [(set (match_operand 0 "register_operand" "=r")
5890 (plus (mult (match_operand 1 "index_register_operand" "l")
5891 (match_operand 2 "const248_operand" "n"))
5892 (match_operand 3 "nonmemory_operand" "ri")))]
5893 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5894 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5895 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5896 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5897 || GET_MODE (operands[3]) == VOIDmode)"
5899 "&& reload_completed"
5902 enum machine_mode mode = SImode;
5905 operands[0] = gen_lowpart (mode, operands[0]);
5906 operands[1] = gen_lowpart (mode, operands[1]);
5907 operands[3] = gen_lowpart (mode, operands[3]);
5909 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
5912 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5915 [(set_attr "type" "lea")
5916 (set_attr "mode" "SI")])
5918 (define_insn_and_split "*lea_general_3"
5919 [(set (match_operand 0 "register_operand" "=r")
5920 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5921 (match_operand 2 "const248_operand" "n"))
5922 (match_operand 3 "register_operand" "r"))
5923 (match_operand 4 "immediate_operand" "i")))]
5924 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5925 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5926 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5927 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5929 "&& reload_completed"
5932 enum machine_mode mode = SImode;
5935 operands[0] = gen_lowpart (mode, operands[0]);
5936 operands[1] = gen_lowpart (mode, operands[1]);
5937 operands[3] = gen_lowpart (mode, operands[3]);
5938 operands[4] = gen_lowpart (mode, operands[4]);
5940 pat = gen_rtx_PLUS (mode,
5942 gen_rtx_MULT (mode, operands[1],
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_4"
5954 [(set (match_operand 0 "register_operand" "=r")
5956 (match_operand 1 "index_register_operand" "l")
5957 (match_operand 2 "const_int_operand" "n"))
5958 (match_operand 3 "const_int_operand" "n")))]
5959 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5960 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
5961 || GET_MODE (operands[0]) == SImode
5962 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
5963 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5964 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
5965 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
5966 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
5968 "&& reload_completed"
5971 enum machine_mode mode = GET_MODE (operands[0]);
5974 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5977 operands[0] = gen_lowpart (mode, operands[0]);
5978 operands[1] = gen_lowpart (mode, operands[1]);
5981 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
5983 pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
5984 INTVAL (operands[3]));
5986 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5989 [(set_attr "type" "lea")
5991 (if_then_else (match_operand:DI 0)
5993 (const_string "SI")))])
5995 ;; Subtract instructions
5997 (define_expand "sub<mode>3"
5998 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5999 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6000 (match_operand:SDWIM 2 "<general_operand>")))]
6002 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6004 (define_insn_and_split "*sub<dwi>3_doubleword"
6005 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6007 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6008 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6009 (clobber (reg:CC FLAGS_REG))]
6010 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6013 [(parallel [(set (reg:CC FLAGS_REG)
6014 (compare:CC (match_dup 1) (match_dup 2)))
6016 (minus:DWIH (match_dup 1) (match_dup 2)))])
6017 (parallel [(set (match_dup 3)
6021 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6023 (clobber (reg:CC FLAGS_REG))])]
6024 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6026 (define_insn "*sub<mode>_1"
6027 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6029 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6030 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6031 (clobber (reg:CC FLAGS_REG))]
6032 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6033 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6034 [(set_attr "type" "alu")
6035 (set_attr "mode" "<MODE>")])
6037 (define_insn "*subsi_1_zext"
6038 [(set (match_operand:DI 0 "register_operand" "=r")
6040 (minus:SI (match_operand:SI 1 "register_operand" "0")
6041 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6042 (clobber (reg:CC FLAGS_REG))]
6043 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6044 "sub{l}\t{%2, %k0|%k0, %2}"
6045 [(set_attr "type" "alu")
6046 (set_attr "mode" "SI")])
6048 (define_insn "*subqi_1_slp"
6049 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6050 (minus:QI (match_dup 0)
6051 (match_operand:QI 1 "general_operand" "qn,qm")))
6052 (clobber (reg:CC FLAGS_REG))]
6053 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6054 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6055 "sub{b}\t{%1, %0|%0, %1}"
6056 [(set_attr "type" "alu1")
6057 (set_attr "mode" "QI")])
6059 (define_insn "*sub<mode>_2"
6060 [(set (reg FLAGS_REG)
6063 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6064 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6066 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6067 (minus:SWI (match_dup 1) (match_dup 2)))]
6068 "ix86_match_ccmode (insn, CCGOCmode)
6069 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6070 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6071 [(set_attr "type" "alu")
6072 (set_attr "mode" "<MODE>")])
6074 (define_insn "*subsi_2_zext"
6075 [(set (reg FLAGS_REG)
6077 (minus:SI (match_operand:SI 1 "register_operand" "0")
6078 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6080 (set (match_operand:DI 0 "register_operand" "=r")
6082 (minus:SI (match_dup 1)
6084 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6085 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6086 "sub{l}\t{%2, %k0|%k0, %2}"
6087 [(set_attr "type" "alu")
6088 (set_attr "mode" "SI")])
6090 (define_insn "*sub<mode>_3"
6091 [(set (reg FLAGS_REG)
6092 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6093 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6094 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6095 (minus:SWI (match_dup 1) (match_dup 2)))]
6096 "ix86_match_ccmode (insn, CCmode)
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_3_zext"
6103 [(set (reg FLAGS_REG)
6104 (compare (match_operand:SI 1 "register_operand" "0")
6105 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6106 (set (match_operand:DI 0 "register_operand" "=r")
6108 (minus:SI (match_dup 1)
6110 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6111 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6112 "sub{l}\t{%2, %1|%1, %2}"
6113 [(set_attr "type" "alu")
6114 (set_attr "mode" "SI")])
6116 ;; Add with carry and subtract with borrow
6118 (define_expand "<plusminus_insn><mode>3_carry"
6120 [(set (match_operand:SWI 0 "nonimmediate_operand")
6122 (match_operand:SWI 1 "nonimmediate_operand")
6123 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6124 [(match_operand 3 "flags_reg_operand")
6126 (match_operand:SWI 2 "<general_operand>"))))
6127 (clobber (reg:CC FLAGS_REG))])]
6128 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6130 (define_insn "*<plusminus_insn><mode>3_carry"
6131 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6133 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6135 (match_operator 3 "ix86_carry_flag_operator"
6136 [(reg FLAGS_REG) (const_int 0)])
6137 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6138 (clobber (reg:CC FLAGS_REG))]
6139 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6140 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6141 [(set_attr "type" "alu")
6142 (set_attr "use_carry" "1")
6143 (set_attr "pent_pair" "pu")
6144 (set_attr "mode" "<MODE>")])
6146 (define_insn "*addsi3_carry_zext"
6147 [(set (match_operand:DI 0 "register_operand" "=r")
6149 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6150 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6151 [(reg FLAGS_REG) (const_int 0)])
6152 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6153 (clobber (reg:CC FLAGS_REG))]
6154 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6155 "adc{l}\t{%2, %k0|%k0, %2}"
6156 [(set_attr "type" "alu")
6157 (set_attr "use_carry" "1")
6158 (set_attr "pent_pair" "pu")
6159 (set_attr "mode" "SI")])
6161 (define_insn "*subsi3_carry_zext"
6162 [(set (match_operand:DI 0 "register_operand" "=r")
6164 (minus:SI (match_operand:SI 1 "register_operand" "0")
6165 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6166 [(reg FLAGS_REG) (const_int 0)])
6167 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6168 (clobber (reg:CC FLAGS_REG))]
6169 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6170 "sbb{l}\t{%2, %k0|%k0, %2}"
6171 [(set_attr "type" "alu")
6172 (set_attr "pent_pair" "pu")
6173 (set_attr "mode" "SI")])
6177 (define_insn "adcx<mode>3"
6178 [(set (reg:CCC FLAGS_REG)
6181 (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6183 (match_operator 4 "ix86_carry_flag_operator"
6184 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6185 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6187 (set (match_operand:SWI48 0 "register_operand" "=r")
6188 (plus:SWI48 (match_dup 1)
6189 (plus:SWI48 (match_op_dup 4
6190 [(match_dup 3) (const_int 0)])
6192 "TARGET_ADX && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6193 "adcx\t{%2, %0|%0, %2}"
6194 [(set_attr "type" "alu")
6195 (set_attr "use_carry" "1")
6196 (set_attr "mode" "<MODE>")])
6198 ;; Overflow setting add and subtract instructions
6200 (define_insn "*add<mode>3_cconly_overflow"
6201 [(set (reg:CCC FLAGS_REG)
6204 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6205 (match_operand:SWI 2 "<general_operand>" "<g>"))
6207 (clobber (match_scratch:SWI 0 "=<r>"))]
6208 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6209 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6210 [(set_attr "type" "alu")
6211 (set_attr "mode" "<MODE>")])
6213 (define_insn "*sub<mode>3_cconly_overflow"
6214 [(set (reg:CCC FLAGS_REG)
6217 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6218 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6221 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6222 [(set_attr "type" "icmp")
6223 (set_attr "mode" "<MODE>")])
6225 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6226 [(set (reg:CCC FLAGS_REG)
6229 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6230 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6232 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6233 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6234 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6235 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6236 [(set_attr "type" "alu")
6237 (set_attr "mode" "<MODE>")])
6239 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6240 [(set (reg:CCC FLAGS_REG)
6243 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6244 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6246 (set (match_operand:DI 0 "register_operand" "=r")
6247 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6248 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6249 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6250 [(set_attr "type" "alu")
6251 (set_attr "mode" "SI")])
6253 ;; The patterns that match these are at the end of this file.
6255 (define_expand "<plusminus_insn>xf3"
6256 [(set (match_operand:XF 0 "register_operand")
6258 (match_operand:XF 1 "register_operand")
6259 (match_operand:XF 2 "register_operand")))]
6262 (define_expand "<plusminus_insn><mode>3"
6263 [(set (match_operand:MODEF 0 "register_operand")
6265 (match_operand:MODEF 1 "register_operand")
6266 (match_operand:MODEF 2 "nonimmediate_operand")))]
6267 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6268 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6270 ;; Multiply instructions
6272 (define_expand "mul<mode>3"
6273 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6275 (match_operand:SWIM248 1 "register_operand")
6276 (match_operand:SWIM248 2 "<general_operand>")))
6277 (clobber (reg:CC FLAGS_REG))])])
6279 (define_expand "mulqi3"
6280 [(parallel [(set (match_operand:QI 0 "register_operand")
6282 (match_operand:QI 1 "register_operand")
6283 (match_operand:QI 2 "nonimmediate_operand")))
6284 (clobber (reg:CC FLAGS_REG))])]
6285 "TARGET_QIMODE_MATH")
6288 ;; IMUL reg32/64, reg32/64, imm8 Direct
6289 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6290 ;; IMUL reg32/64, reg32/64, imm32 Direct
6291 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6292 ;; IMUL reg32/64, reg32/64 Direct
6293 ;; IMUL reg32/64, mem32/64 Direct
6295 ;; On BDVER1, all above IMULs use DirectPath
6297 (define_insn "*mul<mode>3_1"
6298 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6300 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6301 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6302 (clobber (reg:CC FLAGS_REG))]
6303 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6305 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6306 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6307 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6308 [(set_attr "type" "imul")
6309 (set_attr "prefix_0f" "0,0,1")
6310 (set (attr "athlon_decode")
6311 (cond [(eq_attr "cpu" "athlon")
6312 (const_string "vector")
6313 (eq_attr "alternative" "1")
6314 (const_string "vector")
6315 (and (eq_attr "alternative" "2")
6316 (match_operand 1 "memory_operand"))
6317 (const_string "vector")]
6318 (const_string "direct")))
6319 (set (attr "amdfam10_decode")
6320 (cond [(and (eq_attr "alternative" "0,1")
6321 (match_operand 1 "memory_operand"))
6322 (const_string "vector")]
6323 (const_string "direct")))
6324 (set_attr "bdver1_decode" "direct")
6325 (set_attr "mode" "<MODE>")])
6327 (define_insn "*mulsi3_1_zext"
6328 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6330 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6331 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6332 (clobber (reg:CC FLAGS_REG))]
6334 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6336 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6337 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6338 imul{l}\t{%2, %k0|%k0, %2}"
6339 [(set_attr "type" "imul")
6340 (set_attr "prefix_0f" "0,0,1")
6341 (set (attr "athlon_decode")
6342 (cond [(eq_attr "cpu" "athlon")
6343 (const_string "vector")
6344 (eq_attr "alternative" "1")
6345 (const_string "vector")
6346 (and (eq_attr "alternative" "2")
6347 (match_operand 1 "memory_operand"))
6348 (const_string "vector")]
6349 (const_string "direct")))
6350 (set (attr "amdfam10_decode")
6351 (cond [(and (eq_attr "alternative" "0,1")
6352 (match_operand 1 "memory_operand"))
6353 (const_string "vector")]
6354 (const_string "direct")))
6355 (set_attr "bdver1_decode" "direct")
6356 (set_attr "mode" "SI")])
6359 ;; IMUL reg16, reg16, imm8 VectorPath
6360 ;; IMUL reg16, mem16, imm8 VectorPath
6361 ;; IMUL reg16, reg16, imm16 VectorPath
6362 ;; IMUL reg16, mem16, imm16 VectorPath
6363 ;; IMUL reg16, reg16 Direct
6364 ;; IMUL reg16, mem16 Direct
6366 ;; On BDVER1, all HI MULs use DoublePath
6368 (define_insn "*mulhi3_1"
6369 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6370 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6371 (match_operand:HI 2 "general_operand" "K,n,mr")))
6372 (clobber (reg:CC FLAGS_REG))]
6374 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6376 imul{w}\t{%2, %1, %0|%0, %1, %2}
6377 imul{w}\t{%2, %1, %0|%0, %1, %2}
6378 imul{w}\t{%2, %0|%0, %2}"
6379 [(set_attr "type" "imul")
6380 (set_attr "prefix_0f" "0,0,1")
6381 (set (attr "athlon_decode")
6382 (cond [(eq_attr "cpu" "athlon")
6383 (const_string "vector")
6384 (eq_attr "alternative" "1,2")
6385 (const_string "vector")]
6386 (const_string "direct")))
6387 (set (attr "amdfam10_decode")
6388 (cond [(eq_attr "alternative" "0,1")
6389 (const_string "vector")]
6390 (const_string "direct")))
6391 (set_attr "bdver1_decode" "double")
6392 (set_attr "mode" "HI")])
6394 ;;On AMDFAM10 and BDVER1
6398 (define_insn "*mulqi3_1"
6399 [(set (match_operand:QI 0 "register_operand" "=a")
6400 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6401 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6402 (clobber (reg:CC FLAGS_REG))]
6404 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6406 [(set_attr "type" "imul")
6407 (set_attr "length_immediate" "0")
6408 (set (attr "athlon_decode")
6409 (if_then_else (eq_attr "cpu" "athlon")
6410 (const_string "vector")
6411 (const_string "direct")))
6412 (set_attr "amdfam10_decode" "direct")
6413 (set_attr "bdver1_decode" "direct")
6414 (set_attr "mode" "QI")])
6416 (define_expand "<u>mul<mode><dwi>3"
6417 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6420 (match_operand:DWIH 1 "nonimmediate_operand"))
6422 (match_operand:DWIH 2 "register_operand"))))
6423 (clobber (reg:CC FLAGS_REG))])])
6425 (define_expand "<u>mulqihi3"
6426 [(parallel [(set (match_operand:HI 0 "register_operand")
6429 (match_operand:QI 1 "nonimmediate_operand"))
6431 (match_operand:QI 2 "register_operand"))))
6432 (clobber (reg:CC FLAGS_REG))])]
6433 "TARGET_QIMODE_MATH")
6435 (define_insn "*bmi2_umulditi3_1"
6436 [(set (match_operand:DI 0 "register_operand" "=r")
6438 (match_operand:DI 2 "nonimmediate_operand" "%d")
6439 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6440 (set (match_operand:DI 1 "register_operand" "=r")
6443 (mult:TI (zero_extend:TI (match_dup 2))
6444 (zero_extend:TI (match_dup 3)))
6446 "TARGET_64BIT && TARGET_BMI2
6447 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6448 "mulx\t{%3, %0, %1|%1, %0, %3}"
6449 [(set_attr "type" "imulx")
6450 (set_attr "prefix" "vex")
6451 (set_attr "mode" "DI")])
6453 (define_insn "*bmi2_umulsidi3_1"
6454 [(set (match_operand:SI 0 "register_operand" "=r")
6456 (match_operand:SI 2 "nonimmediate_operand" "%d")
6457 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6458 (set (match_operand:SI 1 "register_operand" "=r")
6461 (mult:DI (zero_extend:DI (match_dup 2))
6462 (zero_extend:DI (match_dup 3)))
6464 "!TARGET_64BIT && TARGET_BMI2
6465 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6466 "mulx\t{%3, %0, %1|%1, %0, %3}"
6467 [(set_attr "type" "imulx")
6468 (set_attr "prefix" "vex")
6469 (set_attr "mode" "SI")])
6471 (define_insn "*umul<mode><dwi>3_1"
6472 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6475 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6477 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6478 (clobber (reg:CC FLAGS_REG))]
6479 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6482 mul{<imodesuffix>}\t%2"
6483 [(set_attr "isa" "bmi2,*")
6484 (set_attr "type" "imulx,imul")
6485 (set_attr "length_immediate" "*,0")
6486 (set (attr "athlon_decode")
6487 (cond [(eq_attr "alternative" "1")
6488 (if_then_else (eq_attr "cpu" "athlon")
6489 (const_string "vector")
6490 (const_string "double"))]
6491 (const_string "*")))
6492 (set_attr "amdfam10_decode" "*,double")
6493 (set_attr "bdver1_decode" "*,direct")
6494 (set_attr "prefix" "vex,orig")
6495 (set_attr "mode" "<MODE>")])
6497 ;; Convert mul to the mulx pattern to avoid flags dependency.
6499 [(set (match_operand:<DWI> 0 "register_operand")
6502 (match_operand:DWIH 1 "register_operand"))
6504 (match_operand:DWIH 2 "nonimmediate_operand"))))
6505 (clobber (reg:CC FLAGS_REG))]
6506 "TARGET_BMI2 && reload_completed
6507 && true_regnum (operands[1]) == DX_REG"
6508 [(parallel [(set (match_dup 3)
6509 (mult:DWIH (match_dup 1) (match_dup 2)))
6513 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6514 (zero_extend:<DWI> (match_dup 2)))
6517 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6519 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6522 (define_insn "*mul<mode><dwi>3_1"
6523 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6526 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6528 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6529 (clobber (reg:CC FLAGS_REG))]
6530 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6531 "imul{<imodesuffix>}\t%2"
6532 [(set_attr "type" "imul")
6533 (set_attr "length_immediate" "0")
6534 (set (attr "athlon_decode")
6535 (if_then_else (eq_attr "cpu" "athlon")
6536 (const_string "vector")
6537 (const_string "double")))
6538 (set_attr "amdfam10_decode" "double")
6539 (set_attr "bdver1_decode" "direct")
6540 (set_attr "mode" "<MODE>")])
6542 (define_insn "*<u>mulqihi3_1"
6543 [(set (match_operand:HI 0 "register_operand" "=a")
6546 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6548 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6549 (clobber (reg:CC FLAGS_REG))]
6551 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6552 "<sgnprefix>mul{b}\t%2"
6553 [(set_attr "type" "imul")
6554 (set_attr "length_immediate" "0")
6555 (set (attr "athlon_decode")
6556 (if_then_else (eq_attr "cpu" "athlon")
6557 (const_string "vector")
6558 (const_string "direct")))
6559 (set_attr "amdfam10_decode" "direct")
6560 (set_attr "bdver1_decode" "direct")
6561 (set_attr "mode" "QI")])
6563 (define_expand "<s>mul<mode>3_highpart"
6564 [(parallel [(set (match_operand:SWI48 0 "register_operand")
6569 (match_operand:SWI48 1 "nonimmediate_operand"))
6571 (match_operand:SWI48 2 "register_operand")))
6573 (clobber (match_scratch:SWI48 3))
6574 (clobber (reg:CC FLAGS_REG))])]
6576 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6578 (define_insn "*<s>muldi3_highpart_1"
6579 [(set (match_operand:DI 0 "register_operand" "=d")
6584 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6586 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6588 (clobber (match_scratch:DI 3 "=1"))
6589 (clobber (reg:CC FLAGS_REG))]
6591 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6592 "<sgnprefix>mul{q}\t%2"
6593 [(set_attr "type" "imul")
6594 (set_attr "length_immediate" "0")
6595 (set (attr "athlon_decode")
6596 (if_then_else (eq_attr "cpu" "athlon")
6597 (const_string "vector")
6598 (const_string "double")))
6599 (set_attr "amdfam10_decode" "double")
6600 (set_attr "bdver1_decode" "direct")
6601 (set_attr "mode" "DI")])
6603 (define_insn "*<s>mulsi3_highpart_1"
6604 [(set (match_operand:SI 0 "register_operand" "=d")
6609 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6611 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6613 (clobber (match_scratch:SI 3 "=1"))
6614 (clobber (reg:CC FLAGS_REG))]
6615 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6616 "<sgnprefix>mul{l}\t%2"
6617 [(set_attr "type" "imul")
6618 (set_attr "length_immediate" "0")
6619 (set (attr "athlon_decode")
6620 (if_then_else (eq_attr "cpu" "athlon")
6621 (const_string "vector")
6622 (const_string "double")))
6623 (set_attr "amdfam10_decode" "double")
6624 (set_attr "bdver1_decode" "direct")
6625 (set_attr "mode" "SI")])
6627 (define_insn "*<s>mulsi3_highpart_zext"
6628 [(set (match_operand:DI 0 "register_operand" "=d")
6629 (zero_extend:DI (truncate:SI
6631 (mult:DI (any_extend:DI
6632 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6634 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6636 (clobber (match_scratch:SI 3 "=1"))
6637 (clobber (reg:CC FLAGS_REG))]
6639 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6640 "<sgnprefix>mul{l}\t%2"
6641 [(set_attr "type" "imul")
6642 (set_attr "length_immediate" "0")
6643 (set (attr "athlon_decode")
6644 (if_then_else (eq_attr "cpu" "athlon")
6645 (const_string "vector")
6646 (const_string "double")))
6647 (set_attr "amdfam10_decode" "double")
6648 (set_attr "bdver1_decode" "direct")
6649 (set_attr "mode" "SI")])
6651 ;; The patterns that match these are at the end of this file.
6653 (define_expand "mulxf3"
6654 [(set (match_operand:XF 0 "register_operand")
6655 (mult:XF (match_operand:XF 1 "register_operand")
6656 (match_operand:XF 2 "register_operand")))]
6659 (define_expand "mul<mode>3"
6660 [(set (match_operand:MODEF 0 "register_operand")
6661 (mult:MODEF (match_operand:MODEF 1 "register_operand")
6662 (match_operand:MODEF 2 "nonimmediate_operand")))]
6663 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6664 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6666 ;; Divide instructions
6668 ;; The patterns that match these are at the end of this file.
6670 (define_expand "divxf3"
6671 [(set (match_operand:XF 0 "register_operand")
6672 (div:XF (match_operand:XF 1 "register_operand")
6673 (match_operand:XF 2 "register_operand")))]
6676 (define_expand "divdf3"
6677 [(set (match_operand:DF 0 "register_operand")
6678 (div:DF (match_operand:DF 1 "register_operand")
6679 (match_operand:DF 2 "nonimmediate_operand")))]
6680 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
6681 || (TARGET_SSE2 && TARGET_SSE_MATH)")
6683 (define_expand "divsf3"
6684 [(set (match_operand:SF 0 "register_operand")
6685 (div:SF (match_operand:SF 1 "register_operand")
6686 (match_operand:SF 2 "nonimmediate_operand")))]
6687 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
6692 && optimize_insn_for_speed_p ()
6693 && flag_finite_math_only && !flag_trapping_math
6694 && flag_unsafe_math_optimizations)
6696 ix86_emit_swdivsf (operands[0], operands[1],
6697 operands[2], SFmode);
6702 ;; Divmod instructions.
6704 (define_expand "divmod<mode>4"
6705 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6707 (match_operand:SWIM248 1 "register_operand")
6708 (match_operand:SWIM248 2 "nonimmediate_operand")))
6709 (set (match_operand:SWIM248 3 "register_operand")
6710 (mod:SWIM248 (match_dup 1) (match_dup 2)))
6711 (clobber (reg:CC FLAGS_REG))])])
6713 ;; Split with 8bit unsigned divide:
6714 ;; if (dividend an divisor are in [0-255])
6715 ;; use 8bit unsigned integer divide
6717 ;; use original integer divide
6719 [(set (match_operand:SWI48 0 "register_operand")
6720 (div:SWI48 (match_operand:SWI48 2 "register_operand")
6721 (match_operand:SWI48 3 "nonimmediate_operand")))
6722 (set (match_operand:SWI48 1 "register_operand")
6723 (mod:SWI48 (match_dup 2) (match_dup 3)))
6724 (clobber (reg:CC FLAGS_REG))]
6725 "TARGET_USE_8BIT_IDIV
6726 && TARGET_QIMODE_MATH
6727 && can_create_pseudo_p ()
6728 && !optimize_insn_for_size_p ()"
6730 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
6732 (define_insn_and_split "divmod<mode>4_1"
6733 [(set (match_operand:SWI48 0 "register_operand" "=a")
6734 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
6735 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
6736 (set (match_operand:SWI48 1 "register_operand" "=&d")
6737 (mod:SWI48 (match_dup 2) (match_dup 3)))
6738 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
6739 (clobber (reg:CC FLAGS_REG))]
6743 [(parallel [(set (match_dup 1)
6744 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
6745 (clobber (reg:CC FLAGS_REG))])
6746 (parallel [(set (match_dup 0)
6747 (div:SWI48 (match_dup 2) (match_dup 3)))
6749 (mod:SWI48 (match_dup 2) (match_dup 3)))
6751 (clobber (reg:CC FLAGS_REG))])]
6753 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
6755 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
6756 operands[4] = operands[2];
6759 /* Avoid use of cltd in favor of a mov+shift. */
6760 emit_move_insn (operands[1], operands[2]);
6761 operands[4] = operands[1];
6764 [(set_attr "type" "multi")
6765 (set_attr "mode" "<MODE>")])
6767 (define_insn_and_split "*divmod<mode>4"
6768 [(set (match_operand:SWIM248 0 "register_operand" "=a")
6769 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
6770 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
6771 (set (match_operand:SWIM248 1 "register_operand" "=&d")
6772 (mod:SWIM248 (match_dup 2) (match_dup 3)))
6773 (clobber (reg:CC FLAGS_REG))]
6777 [(parallel [(set (match_dup 1)
6778 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
6779 (clobber (reg:CC FLAGS_REG))])
6780 (parallel [(set (match_dup 0)
6781 (div:SWIM248 (match_dup 2) (match_dup 3)))
6783 (mod:SWIM248 (match_dup 2) (match_dup 3)))
6785 (clobber (reg:CC FLAGS_REG))])]
6787 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
6789 if (<MODE>mode != HImode
6790 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
6791 operands[4] = operands[2];
6794 /* Avoid use of cltd in favor of a mov+shift. */
6795 emit_move_insn (operands[1], operands[2]);
6796 operands[4] = operands[1];
6799 [(set_attr "type" "multi")
6800 (set_attr "mode" "<MODE>")])
6802 (define_insn "*divmod<mode>4_noext"
6803 [(set (match_operand:SWIM248 0 "register_operand" "=a")
6804 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
6805 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
6806 (set (match_operand:SWIM248 1 "register_operand" "=d")
6807 (mod:SWIM248 (match_dup 2) (match_dup 3)))
6808 (use (match_operand:SWIM248 4 "register_operand" "1"))
6809 (clobber (reg:CC FLAGS_REG))]
6811 "idiv{<imodesuffix>}\t%3"
6812 [(set_attr "type" "idiv")
6813 (set_attr "mode" "<MODE>")])
6815 (define_expand "divmodqi4"
6816 [(parallel [(set (match_operand:QI 0 "register_operand")
6818 (match_operand:QI 1 "register_operand")
6819 (match_operand:QI 2 "nonimmediate_operand")))
6820 (set (match_operand:QI 3 "register_operand")
6821 (mod:QI (match_dup 1) (match_dup 2)))
6822 (clobber (reg:CC FLAGS_REG))])]
6823 "TARGET_QIMODE_MATH"
6828 tmp0 = gen_reg_rtx (HImode);
6829 tmp1 = gen_reg_rtx (HImode);
6831 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
6833 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
6834 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
6836 /* Extract remainder from AH. */
6837 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
6838 insn = emit_move_insn (operands[3], tmp1);
6840 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
6841 set_unique_reg_note (insn, REG_EQUAL, mod);
6843 /* Extract quotient from AL. */
6844 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
6846 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
6847 set_unique_reg_note (insn, REG_EQUAL, div);
6852 ;; Divide AX by r/m8, with result stored in
6855 ;; Change div/mod to HImode and extend the second argument to HImode
6856 ;; so that mode of div/mod matches with mode of arguments. Otherwise
6857 ;; combine may fail.
6858 (define_insn "divmodhiqi3"
6859 [(set (match_operand:HI 0 "register_operand" "=a")
6864 (mod:HI (match_operand:HI 1 "register_operand" "0")
6866 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
6870 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
6871 (clobber (reg:CC FLAGS_REG))]
6872 "TARGET_QIMODE_MATH"
6874 [(set_attr "type" "idiv")
6875 (set_attr "mode" "QI")])
6877 (define_expand "udivmod<mode>4"
6878 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6880 (match_operand:SWIM248 1 "register_operand")
6881 (match_operand:SWIM248 2 "nonimmediate_operand")))
6882 (set (match_operand:SWIM248 3 "register_operand")
6883 (umod:SWIM248 (match_dup 1) (match_dup 2)))
6884 (clobber (reg:CC FLAGS_REG))])])
6886 ;; Split with 8bit unsigned divide:
6887 ;; if (dividend an divisor are in [0-255])
6888 ;; use 8bit unsigned integer divide
6890 ;; use original integer divide
6892 [(set (match_operand:SWI48 0 "register_operand")
6893 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
6894 (match_operand:SWI48 3 "nonimmediate_operand")))
6895 (set (match_operand:SWI48 1 "register_operand")
6896 (umod:SWI48 (match_dup 2) (match_dup 3)))
6897 (clobber (reg:CC FLAGS_REG))]
6898 "TARGET_USE_8BIT_IDIV
6899 && TARGET_QIMODE_MATH
6900 && can_create_pseudo_p ()
6901 && !optimize_insn_for_size_p ()"
6903 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
6905 (define_insn_and_split "udivmod<mode>4_1"
6906 [(set (match_operand:SWI48 0 "register_operand" "=a")
6907 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
6908 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
6909 (set (match_operand:SWI48 1 "register_operand" "=&d")
6910 (umod:SWI48 (match_dup 2) (match_dup 3)))
6911 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
6912 (clobber (reg:CC FLAGS_REG))]
6916 [(set (match_dup 1) (const_int 0))
6917 (parallel [(set (match_dup 0)
6918 (udiv:SWI48 (match_dup 2) (match_dup 3)))
6920 (umod:SWI48 (match_dup 2) (match_dup 3)))
6922 (clobber (reg:CC FLAGS_REG))])]
6924 [(set_attr "type" "multi")
6925 (set_attr "mode" "<MODE>")])
6927 (define_insn_and_split "*udivmod<mode>4"
6928 [(set (match_operand:SWIM248 0 "register_operand" "=a")
6929 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
6930 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
6931 (set (match_operand:SWIM248 1 "register_operand" "=&d")
6932 (umod:SWIM248 (match_dup 2) (match_dup 3)))
6933 (clobber (reg:CC FLAGS_REG))]
6937 [(set (match_dup 1) (const_int 0))
6938 (parallel [(set (match_dup 0)
6939 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
6941 (umod:SWIM248 (match_dup 2) (match_dup 3)))
6943 (clobber (reg:CC FLAGS_REG))])]
6945 [(set_attr "type" "multi")
6946 (set_attr "mode" "<MODE>")])
6948 (define_insn "*udivmod<mode>4_noext"
6949 [(set (match_operand:SWIM248 0 "register_operand" "=a")
6950 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
6951 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
6952 (set (match_operand:SWIM248 1 "register_operand" "=d")
6953 (umod:SWIM248 (match_dup 2) (match_dup 3)))
6954 (use (match_operand:SWIM248 4 "register_operand" "1"))
6955 (clobber (reg:CC FLAGS_REG))]
6957 "div{<imodesuffix>}\t%3"
6958 [(set_attr "type" "idiv")
6959 (set_attr "mode" "<MODE>")])
6961 (define_expand "udivmodqi4"
6962 [(parallel [(set (match_operand:QI 0 "register_operand")
6964 (match_operand:QI 1 "register_operand")
6965 (match_operand:QI 2 "nonimmediate_operand")))
6966 (set (match_operand:QI 3 "register_operand")
6967 (umod:QI (match_dup 1) (match_dup 2)))
6968 (clobber (reg:CC FLAGS_REG))])]
6969 "TARGET_QIMODE_MATH"
6974 tmp0 = gen_reg_rtx (HImode);
6975 tmp1 = gen_reg_rtx (HImode);
6977 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
6979 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
6980 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
6982 /* Extract remainder from AH. */
6983 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
6984 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
6985 insn = emit_move_insn (operands[3], tmp1);
6987 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
6988 set_unique_reg_note (insn, REG_EQUAL, mod);
6990 /* Extract quotient from AL. */
6991 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
6993 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
6994 set_unique_reg_note (insn, REG_EQUAL, div);
6999 (define_insn "udivmodhiqi3"
7000 [(set (match_operand:HI 0 "register_operand" "=a")
7005 (mod:HI (match_operand:HI 1 "register_operand" "0")
7007 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7011 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7012 (clobber (reg:CC FLAGS_REG))]
7013 "TARGET_QIMODE_MATH"
7015 [(set_attr "type" "idiv")
7016 (set_attr "mode" "QI")])
7018 ;; We cannot use div/idiv for double division, because it causes
7019 ;; "division by zero" on the overflow and that's not what we expect
7020 ;; from truncate. Because true (non truncating) double division is
7021 ;; never generated, we can't create this insn anyway.
7024 ; [(set (match_operand:SI 0 "register_operand" "=a")
7026 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7028 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7029 ; (set (match_operand:SI 3 "register_operand" "=d")
7031 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7032 ; (clobber (reg:CC FLAGS_REG))]
7034 ; "div{l}\t{%2, %0|%0, %2}"
7035 ; [(set_attr "type" "idiv")])
7037 ;;- Logical AND instructions
7039 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7040 ;; Note that this excludes ah.
7042 (define_expand "testsi_ccno_1"
7043 [(set (reg:CCNO FLAGS_REG)
7045 (and:SI (match_operand:SI 0 "nonimmediate_operand")
7046 (match_operand:SI 1 "x86_64_nonmemory_operand"))
7049 (define_expand "testqi_ccz_1"
7050 [(set (reg:CCZ FLAGS_REG)
7051 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7052 (match_operand:QI 1 "nonmemory_operand"))
7055 (define_expand "testdi_ccno_1"
7056 [(set (reg:CCNO FLAGS_REG)
7058 (and:DI (match_operand:DI 0 "nonimmediate_operand")
7059 (match_operand:DI 1 "x86_64_szext_general_operand"))
7061 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7063 (define_insn "*testdi_1"
7064 [(set (reg FLAGS_REG)
7067 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7068 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7070 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7071 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7073 test{l}\t{%k1, %k0|%k0, %k1}
7074 test{l}\t{%k1, %k0|%k0, %k1}
7075 test{q}\t{%1, %0|%0, %1}
7076 test{q}\t{%1, %0|%0, %1}
7077 test{q}\t{%1, %0|%0, %1}"
7078 [(set_attr "type" "test")
7079 (set_attr "modrm" "0,1,0,1,1")
7080 (set_attr "mode" "SI,SI,DI,DI,DI")])
7082 (define_insn "*testqi_1_maybe_si"
7083 [(set (reg FLAGS_REG)
7086 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7087 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7089 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7090 && ix86_match_ccmode (insn,
7091 CONST_INT_P (operands[1])
7092 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7094 if (which_alternative == 3)
7096 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7097 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7098 return "test{l}\t{%1, %k0|%k0, %1}";
7100 return "test{b}\t{%1, %0|%0, %1}";
7102 [(set_attr "type" "test")
7103 (set_attr "modrm" "0,1,1,1")
7104 (set_attr "mode" "QI,QI,QI,SI")
7105 (set_attr "pent_pair" "uv,np,uv,np")])
7107 (define_insn "*test<mode>_1"
7108 [(set (reg FLAGS_REG)
7111 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7112 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7114 "ix86_match_ccmode (insn, CCNOmode)
7115 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7116 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7117 [(set_attr "type" "test")
7118 (set_attr "modrm" "0,1,1")
7119 (set_attr "mode" "<MODE>")
7120 (set_attr "pent_pair" "uv,np,uv")])
7122 (define_expand "testqi_ext_ccno_0"
7123 [(set (reg:CCNO FLAGS_REG)
7127 (match_operand 0 "ext_register_operand")
7130 (match_operand 1 "const_int_operand"))
7133 (define_insn "*testqi_ext_0"
7134 [(set (reg FLAGS_REG)
7138 (match_operand 0 "ext_register_operand" "Q")
7141 (match_operand 1 "const_int_operand" "n"))
7143 "ix86_match_ccmode (insn, CCNOmode)"
7144 "test{b}\t{%1, %h0|%h0, %1}"
7145 [(set_attr "type" "test")
7146 (set_attr "mode" "QI")
7147 (set_attr "length_immediate" "1")
7148 (set_attr "modrm" "1")
7149 (set_attr "pent_pair" "np")])
7151 (define_insn "*testqi_ext_1"
7152 [(set (reg FLAGS_REG)
7156 (match_operand 0 "ext_register_operand" "Q,Q")
7160 (match_operand:QI 1 "nonimmediate_x64nomem_operand" "Q,m")))
7162 "ix86_match_ccmode (insn, CCNOmode)"
7163 "test{b}\t{%1, %h0|%h0, %1}"
7164 [(set_attr "isa" "*,nox64")
7165 (set_attr "type" "test")
7166 (set_attr "mode" "QI")])
7168 (define_insn "*testqi_ext_2"
7169 [(set (reg FLAGS_REG)
7173 (match_operand 0 "ext_register_operand" "Q")
7177 (match_operand 1 "ext_register_operand" "Q")
7181 "ix86_match_ccmode (insn, CCNOmode)"
7182 "test{b}\t{%h1, %h0|%h0, %h1}"
7183 [(set_attr "type" "test")
7184 (set_attr "mode" "QI")])
7186 ;; Combine likes to form bit extractions for some tests. Humor it.
7187 (define_insn "*testqi_ext_3"
7188 [(set (reg FLAGS_REG)
7189 (compare (zero_extract:SWI48
7190 (match_operand 0 "nonimmediate_operand" "rm")
7191 (match_operand:SWI48 1 "const_int_operand")
7192 (match_operand:SWI48 2 "const_int_operand"))
7194 "ix86_match_ccmode (insn, CCNOmode)
7195 && ((TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7196 || GET_MODE (operands[0]) == SImode
7197 || GET_MODE (operands[0]) == HImode
7198 || GET_MODE (operands[0]) == QImode)
7199 /* Ensure that resulting mask is zero or sign extended operand. */
7200 && INTVAL (operands[2]) >= 0
7201 && ((INTVAL (operands[1]) > 0
7202 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)
7203 || (<MODE>mode == DImode
7204 && INTVAL (operands[1]) > 32
7205 && INTVAL (operands[1]) + INTVAL (operands[2]) == 64))"
7209 [(set (match_operand 0 "flags_reg_operand")
7210 (match_operator 1 "compare_operator"
7212 (match_operand 2 "nonimmediate_operand")
7213 (match_operand 3 "const_int_operand")
7214 (match_operand 4 "const_int_operand"))
7216 "ix86_match_ccmode (insn, CCNOmode)"
7217 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7219 rtx val = operands[2];
7220 HOST_WIDE_INT len = INTVAL (operands[3]);
7221 HOST_WIDE_INT pos = INTVAL (operands[4]);
7223 enum machine_mode mode, submode;
7225 mode = GET_MODE (val);
7228 /* ??? Combine likes to put non-volatile mem extractions in QImode
7229 no matter the size of the test. So find a mode that works. */
7230 if (! MEM_VOLATILE_P (val))
7232 mode = smallest_mode_for_size (pos + len, MODE_INT);
7233 val = adjust_address (val, mode, 0);
7236 else if (GET_CODE (val) == SUBREG
7237 && (submode = GET_MODE (SUBREG_REG (val)),
7238 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7239 && pos + len <= GET_MODE_BITSIZE (submode)
7240 && GET_MODE_CLASS (submode) == MODE_INT)
7242 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7244 val = SUBREG_REG (val);
7246 else if (mode == HImode && pos + len <= 8)
7248 /* Small HImode tests can be converted to QImode. */
7250 val = gen_lowpart (QImode, val);
7253 if (len == HOST_BITS_PER_WIDE_INT)
7256 mask = ((HOST_WIDE_INT)1 << len) - 1;
7259 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7262 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7263 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7264 ;; this is relatively important trick.
7265 ;; Do the conversion only post-reload to avoid limiting of the register class
7268 [(set (match_operand 0 "flags_reg_operand")
7269 (match_operator 1 "compare_operator"
7270 [(and (match_operand 2 "register_operand")
7271 (match_operand 3 "const_int_operand"))
7274 && QI_REG_P (operands[2])
7275 && GET_MODE (operands[2]) != QImode
7276 && ((ix86_match_ccmode (insn, CCZmode)
7277 && !(INTVAL (operands[3]) & ~(255 << 8)))
7278 || (ix86_match_ccmode (insn, CCNOmode)
7279 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7282 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7286 operands[2] = gen_lowpart (SImode, operands[2]);
7287 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7291 [(set (match_operand 0 "flags_reg_operand")
7292 (match_operator 1 "compare_operator"
7293 [(and (match_operand 2 "nonimmediate_operand")
7294 (match_operand 3 "const_int_operand"))
7297 && GET_MODE (operands[2]) != QImode
7298 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7299 && ((ix86_match_ccmode (insn, CCZmode)
7300 && !(INTVAL (operands[3]) & ~255))
7301 || (ix86_match_ccmode (insn, CCNOmode)
7302 && !(INTVAL (operands[3]) & ~127)))"
7304 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7307 operands[2] = gen_lowpart (QImode, operands[2]);
7308 operands[3] = gen_lowpart (QImode, operands[3]);
7311 ;; %%% This used to optimize known byte-wide and operations to memory,
7312 ;; and sometimes to QImode registers. If this is considered useful,
7313 ;; it should be done with splitters.
7315 (define_expand "and<mode>3"
7316 [(set (match_operand:SWIM 0 "nonimmediate_operand")
7317 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7318 (match_operand:SWIM 2 "<general_szext_operand>")))]
7321 enum machine_mode mode = <MODE>mode;
7322 rtx (*insn) (rtx, rtx);
7324 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7326 HOST_WIDE_INT ival = INTVAL (operands[2]);
7328 if (ival == (HOST_WIDE_INT) 0xffffffff)
7330 else if (ival == 0xffff)
7332 else if (ival == 0xff)
7336 if (mode == <MODE>mode)
7338 ix86_expand_binary_operator (AND, <MODE>mode, operands);
7342 if (<MODE>mode == DImode)
7343 insn = (mode == SImode)
7344 ? gen_zero_extendsidi2
7346 ? gen_zero_extendhidi2
7347 : gen_zero_extendqidi2;
7348 else if (<MODE>mode == SImode)
7349 insn = (mode == HImode)
7350 ? gen_zero_extendhisi2
7351 : gen_zero_extendqisi2;
7352 else if (<MODE>mode == HImode)
7353 insn = gen_zero_extendqihi2;
7357 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7361 (define_insn "*anddi_1"
7362 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7364 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7365 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7366 (clobber (reg:CC FLAGS_REG))]
7367 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7369 switch (get_attr_type (insn))
7375 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7376 if (get_attr_mode (insn) == MODE_SI)
7377 return "and{l}\t{%k2, %k0|%k0, %k2}";
7379 return "and{q}\t{%2, %0|%0, %2}";
7382 [(set_attr "type" "alu,alu,alu,imovx")
7383 (set_attr "length_immediate" "*,*,*,0")
7384 (set (attr "prefix_rex")
7386 (and (eq_attr "type" "imovx")
7387 (and (match_test "INTVAL (operands[2]) == 0xff")
7388 (match_operand 1 "ext_QIreg_operand")))
7390 (const_string "*")))
7391 (set_attr "mode" "SI,DI,DI,SI")])
7393 (define_insn "*andsi_1"
7394 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya")
7395 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7396 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7397 (clobber (reg:CC FLAGS_REG))]
7398 "ix86_binary_operator_ok (AND, SImode, operands)"
7400 switch (get_attr_type (insn))
7406 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7407 return "and{l}\t{%2, %0|%0, %2}";
7410 [(set_attr "type" "alu,alu,imovx")
7411 (set (attr "prefix_rex")
7413 (and (eq_attr "type" "imovx")
7414 (and (match_test "INTVAL (operands[2]) == 0xff")
7415 (match_operand 1 "ext_QIreg_operand")))
7417 (const_string "*")))
7418 (set_attr "length_immediate" "*,*,0")
7419 (set_attr "mode" "SI")])
7421 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7422 (define_insn "*andsi_1_zext"
7423 [(set (match_operand:DI 0 "register_operand" "=r")
7425 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7426 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7427 (clobber (reg:CC FLAGS_REG))]
7428 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7429 "and{l}\t{%2, %k0|%k0, %2}"
7430 [(set_attr "type" "alu")
7431 (set_attr "mode" "SI")])
7433 (define_insn "*andhi_1"
7434 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya")
7435 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7436 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7437 (clobber (reg:CC FLAGS_REG))]
7438 "ix86_binary_operator_ok (AND, HImode, operands)"
7440 switch (get_attr_type (insn))
7446 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7447 return "and{w}\t{%2, %0|%0, %2}";
7450 [(set_attr "type" "alu,alu,imovx")
7451 (set_attr "length_immediate" "*,*,0")
7452 (set (attr "prefix_rex")
7454 (and (eq_attr "type" "imovx")
7455 (match_operand 1 "ext_QIreg_operand"))
7457 (const_string "*")))
7458 (set_attr "mode" "HI,HI,SI")])
7460 ;; %%% Potential partial reg stall on alternative 2. What to do?
7461 (define_insn "*andqi_1"
7462 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7463 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7464 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7465 (clobber (reg:CC FLAGS_REG))]
7466 "ix86_binary_operator_ok (AND, QImode, operands)"
7468 and{b}\t{%2, %0|%0, %2}
7469 and{b}\t{%2, %0|%0, %2}
7470 and{l}\t{%k2, %k0|%k0, %k2}"
7471 [(set_attr "type" "alu")
7472 (set_attr "mode" "QI,QI,SI")])
7474 (define_insn "*andqi_1_slp"
7475 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7476 (and:QI (match_dup 0)
7477 (match_operand:QI 1 "general_operand" "qn,qmn")))
7478 (clobber (reg:CC FLAGS_REG))]
7479 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7480 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7481 "and{b}\t{%1, %0|%0, %1}"
7482 [(set_attr "type" "alu1")
7483 (set_attr "mode" "QI")])
7485 ;; Turn *anddi_1 into *andsi_1_zext if possible.
7487 [(set (match_operand:DI 0 "register_operand")
7488 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
7489 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
7490 (clobber (reg:CC FLAGS_REG))]
7492 [(parallel [(set (match_dup 0)
7493 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
7494 (clobber (reg:CC FLAGS_REG))])]
7495 "operands[2] = gen_lowpart (SImode, operands[2]);")
7498 [(set (match_operand:SWI248 0 "register_operand")
7499 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
7500 (match_operand:SWI248 2 "const_int_operand")))
7501 (clobber (reg:CC FLAGS_REG))]
7503 && true_regnum (operands[0]) != true_regnum (operands[1])"
7506 HOST_WIDE_INT ival = INTVAL (operands[2]);
7507 enum machine_mode mode;
7508 rtx (*insn) (rtx, rtx);
7510 if (ival == (HOST_WIDE_INT) 0xffffffff)
7512 else if (ival == 0xffff)
7516 gcc_assert (ival == 0xff);
7520 if (<MODE>mode == DImode)
7521 insn = (mode == SImode)
7522 ? gen_zero_extendsidi2
7524 ? gen_zero_extendhidi2
7525 : gen_zero_extendqidi2;
7528 if (<MODE>mode != SImode)
7529 /* Zero extend to SImode to avoid partial register stalls. */
7530 operands[0] = gen_lowpart (SImode, operands[0]);
7532 insn = (mode == HImode)
7533 ? gen_zero_extendhisi2
7534 : gen_zero_extendqisi2;
7536 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7541 [(set (match_operand 0 "register_operand")
7543 (const_int -65536)))
7544 (clobber (reg:CC FLAGS_REG))]
7545 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7546 || optimize_function_for_size_p (cfun)"
7547 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7548 "operands[1] = gen_lowpart (HImode, operands[0]);")
7551 [(set (match_operand 0 "ext_register_operand")
7554 (clobber (reg:CC FLAGS_REG))]
7555 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7556 && reload_completed"
7557 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7558 "operands[1] = gen_lowpart (QImode, operands[0]);")
7561 [(set (match_operand 0 "ext_register_operand")
7563 (const_int -65281)))
7564 (clobber (reg:CC FLAGS_REG))]
7565 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7566 && reload_completed"
7567 [(parallel [(set (zero_extract:SI (match_dup 0)
7571 (zero_extract:SI (match_dup 0)
7574 (zero_extract:SI (match_dup 0)
7577 (clobber (reg:CC FLAGS_REG))])]
7578 "operands[0] = gen_lowpart (SImode, operands[0]);")
7580 (define_insn "*anddi_2"
7581 [(set (reg FLAGS_REG)
7584 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7585 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7587 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7588 (and:DI (match_dup 1) (match_dup 2)))]
7589 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7590 && ix86_binary_operator_ok (AND, DImode, operands)"
7592 and{l}\t{%k2, %k0|%k0, %k2}
7593 and{q}\t{%2, %0|%0, %2}
7594 and{q}\t{%2, %0|%0, %2}"
7595 [(set_attr "type" "alu")
7596 (set_attr "mode" "SI,DI,DI")])
7598 (define_insn "*andqi_2_maybe_si"
7599 [(set (reg FLAGS_REG)
7601 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7602 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7604 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7605 (and:QI (match_dup 1) (match_dup 2)))]
7606 "ix86_binary_operator_ok (AND, QImode, operands)
7607 && ix86_match_ccmode (insn,
7608 CONST_INT_P (operands[2])
7609 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7611 if (which_alternative == 2)
7613 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7614 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7615 return "and{l}\t{%2, %k0|%k0, %2}";
7617 return "and{b}\t{%2, %0|%0, %2}";
7619 [(set_attr "type" "alu")
7620 (set_attr "mode" "QI,QI,SI")])
7622 (define_insn "*and<mode>_2"
7623 [(set (reg FLAGS_REG)
7624 (compare (and:SWI124
7625 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7626 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7628 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7629 (and:SWI124 (match_dup 1) (match_dup 2)))]
7630 "ix86_match_ccmode (insn, CCNOmode)
7631 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7632 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7633 [(set_attr "type" "alu")
7634 (set_attr "mode" "<MODE>")])
7636 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7637 (define_insn "*andsi_2_zext"
7638 [(set (reg FLAGS_REG)
7640 (match_operand:SI 1 "nonimmediate_operand" "%0")
7641 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7643 (set (match_operand:DI 0 "register_operand" "=r")
7644 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7645 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7646 && ix86_binary_operator_ok (AND, SImode, operands)"
7647 "and{l}\t{%2, %k0|%k0, %2}"
7648 [(set_attr "type" "alu")
7649 (set_attr "mode" "SI")])
7651 (define_insn "*andqi_2_slp"
7652 [(set (reg FLAGS_REG)
7654 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7655 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
7657 (set (strict_low_part (match_dup 0))
7658 (and:QI (match_dup 0) (match_dup 1)))]
7659 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7660 && ix86_match_ccmode (insn, CCNOmode)
7661 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7662 "and{b}\t{%1, %0|%0, %1}"
7663 [(set_attr "type" "alu1")
7664 (set_attr "mode" "QI")])
7666 ;; ??? A bug in recog prevents it from recognizing a const_int as an
7667 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
7668 ;; for a QImode operand, which of course failed.
7669 (define_insn "andqi_ext_0"
7670 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7675 (match_operand 1 "ext_register_operand" "0")
7678 (match_operand 2 "const_int_operand" "n")))
7679 (clobber (reg:CC FLAGS_REG))]
7681 "and{b}\t{%2, %h0|%h0, %2}"
7682 [(set_attr "type" "alu")
7683 (set_attr "length_immediate" "1")
7684 (set_attr "modrm" "1")
7685 (set_attr "mode" "QI")])
7687 ;; Generated by peephole translating test to and. This shows up
7688 ;; often in fp comparisons.
7689 (define_insn "*andqi_ext_0_cc"
7690 [(set (reg FLAGS_REG)
7694 (match_operand 1 "ext_register_operand" "0")
7697 (match_operand 2 "const_int_operand" "n"))
7699 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7708 "ix86_match_ccmode (insn, CCNOmode)"
7709 "and{b}\t{%2, %h0|%h0, %2}"
7710 [(set_attr "type" "alu")
7711 (set_attr "length_immediate" "1")
7712 (set_attr "modrm" "1")
7713 (set_attr "mode" "QI")])
7715 (define_insn "*andqi_ext_1"
7716 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
7721 (match_operand 1 "ext_register_operand" "0,0")
7725 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
7726 (clobber (reg:CC FLAGS_REG))]
7728 "and{b}\t{%2, %h0|%h0, %2}"
7729 [(set_attr "isa" "*,nox64")
7730 (set_attr "type" "alu")
7731 (set_attr "length_immediate" "0")
7732 (set_attr "mode" "QI")])
7734 (define_insn "*andqi_ext_2"
7735 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7740 (match_operand 1 "ext_register_operand" "%0")
7744 (match_operand 2 "ext_register_operand" "Q")
7747 (clobber (reg:CC FLAGS_REG))]
7749 "and{b}\t{%h2, %h0|%h0, %h2}"
7750 [(set_attr "type" "alu")
7751 (set_attr "length_immediate" "0")
7752 (set_attr "mode" "QI")])
7754 ;; Convert wide AND instructions with immediate operand to shorter QImode
7755 ;; equivalents when possible.
7756 ;; Don't do the splitting with memory operands, since it introduces risk
7757 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
7758 ;; for size, but that can (should?) be handled by generic code instead.
7760 [(set (match_operand 0 "register_operand")
7761 (and (match_operand 1 "register_operand")
7762 (match_operand 2 "const_int_operand")))
7763 (clobber (reg:CC FLAGS_REG))]
7765 && QI_REG_P (operands[0])
7766 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7767 && !(~INTVAL (operands[2]) & ~(255 << 8))
7768 && GET_MODE (operands[0]) != QImode"
7769 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
7770 (and:SI (zero_extract:SI (match_dup 1)
7771 (const_int 8) (const_int 8))
7773 (clobber (reg:CC FLAGS_REG))])]
7775 operands[0] = gen_lowpart (SImode, operands[0]);
7776 operands[1] = gen_lowpart (SImode, operands[1]);
7777 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
7780 ;; Since AND can be encoded with sign extended immediate, this is only
7781 ;; profitable when 7th bit is not set.
7783 [(set (match_operand 0 "register_operand")
7784 (and (match_operand 1 "general_operand")
7785 (match_operand 2 "const_int_operand")))
7786 (clobber (reg:CC FLAGS_REG))]
7788 && ANY_QI_REG_P (operands[0])
7789 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7790 && !(~INTVAL (operands[2]) & ~255)
7791 && !(INTVAL (operands[2]) & 128)
7792 && GET_MODE (operands[0]) != QImode"
7793 [(parallel [(set (strict_low_part (match_dup 0))
7794 (and:QI (match_dup 1)
7796 (clobber (reg:CC FLAGS_REG))])]
7798 operands[0] = gen_lowpart (QImode, operands[0]);
7799 operands[1] = gen_lowpart (QImode, operands[1]);
7800 operands[2] = gen_lowpart (QImode, operands[2]);
7803 ;; Logical inclusive and exclusive OR instructions
7805 ;; %%% This used to optimize known byte-wide and operations to memory.
7806 ;; If this is considered useful, it should be done with splitters.
7808 (define_expand "<code><mode>3"
7809 [(set (match_operand:SWIM 0 "nonimmediate_operand")
7810 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7811 (match_operand:SWIM 2 "<general_operand>")))]
7813 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
7815 (define_insn "*<code><mode>_1"
7816 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
7818 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
7819 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
7820 (clobber (reg:CC FLAGS_REG))]
7821 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7822 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7823 [(set_attr "type" "alu")
7824 (set_attr "mode" "<MODE>")])
7826 ;; %%% Potential partial reg stall on alternative 2. What to do?
7827 (define_insn "*<code>qi_1"
7828 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
7829 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7830 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
7831 (clobber (reg:CC FLAGS_REG))]
7832 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
7834 <logic>{b}\t{%2, %0|%0, %2}
7835 <logic>{b}\t{%2, %0|%0, %2}
7836 <logic>{l}\t{%k2, %k0|%k0, %k2}"
7837 [(set_attr "type" "alu")
7838 (set_attr "mode" "QI,QI,SI")])
7840 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7841 (define_insn "*<code>si_1_zext"
7842 [(set (match_operand:DI 0 "register_operand" "=r")
7844 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7845 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7846 (clobber (reg:CC FLAGS_REG))]
7847 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7848 "<logic>{l}\t{%2, %k0|%k0, %2}"
7849 [(set_attr "type" "alu")
7850 (set_attr "mode" "SI")])
7852 (define_insn "*<code>si_1_zext_imm"
7853 [(set (match_operand:DI 0 "register_operand" "=r")
7855 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
7856 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
7857 (clobber (reg:CC FLAGS_REG))]
7858 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7859 "<logic>{l}\t{%2, %k0|%k0, %2}"
7860 [(set_attr "type" "alu")
7861 (set_attr "mode" "SI")])
7863 (define_insn "*<code>qi_1_slp"
7864 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
7865 (any_or:QI (match_dup 0)
7866 (match_operand:QI 1 "general_operand" "qmn,qn")))
7867 (clobber (reg:CC FLAGS_REG))]
7868 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7869 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7870 "<logic>{b}\t{%1, %0|%0, %1}"
7871 [(set_attr "type" "alu1")
7872 (set_attr "mode" "QI")])
7874 (define_insn "*<code><mode>_2"
7875 [(set (reg FLAGS_REG)
7876 (compare (any_or:SWI
7877 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
7878 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
7880 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
7881 (any_or:SWI (match_dup 1) (match_dup 2)))]
7882 "ix86_match_ccmode (insn, CCNOmode)
7883 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7884 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7885 [(set_attr "type" "alu")
7886 (set_attr "mode" "<MODE>")])
7888 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7889 ;; ??? Special case for immediate operand is missing - it is tricky.
7890 (define_insn "*<code>si_2_zext"
7891 [(set (reg FLAGS_REG)
7892 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7893 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7895 (set (match_operand:DI 0 "register_operand" "=r")
7896 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
7897 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7898 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7899 "<logic>{l}\t{%2, %k0|%k0, %2}"
7900 [(set_attr "type" "alu")
7901 (set_attr "mode" "SI")])
7903 (define_insn "*<code>si_2_zext_imm"
7904 [(set (reg FLAGS_REG)
7906 (match_operand:SI 1 "nonimmediate_operand" "%0")
7907 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
7909 (set (match_operand:DI 0 "register_operand" "=r")
7910 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
7911 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7912 && 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>qi_2_slp"
7918 [(set (reg FLAGS_REG)
7919 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7920 (match_operand:QI 1 "general_operand" "qmn,qn"))
7922 (set (strict_low_part (match_dup 0))
7923 (any_or:QI (match_dup 0) (match_dup 1)))]
7924 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7925 && ix86_match_ccmode (insn, CCNOmode)
7926 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7927 "<logic>{b}\t{%1, %0|%0, %1}"
7928 [(set_attr "type" "alu1")
7929 (set_attr "mode" "QI")])
7931 (define_insn "*<code><mode>_3"
7932 [(set (reg FLAGS_REG)
7933 (compare (any_or:SWI
7934 (match_operand:SWI 1 "nonimmediate_operand" "%0")
7935 (match_operand:SWI 2 "<general_operand>" "<g>"))
7937 (clobber (match_scratch:SWI 0 "=<r>"))]
7938 "ix86_match_ccmode (insn, CCNOmode)
7939 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7940 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7941 [(set_attr "type" "alu")
7942 (set_attr "mode" "<MODE>")])
7944 (define_insn "*<code>qi_ext_0"
7945 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7950 (match_operand 1 "ext_register_operand" "0")
7953 (match_operand 2 "const_int_operand" "n")))
7954 (clobber (reg:CC FLAGS_REG))]
7955 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7956 "<logic>{b}\t{%2, %h0|%h0, %2}"
7957 [(set_attr "type" "alu")
7958 (set_attr "length_immediate" "1")
7959 (set_attr "modrm" "1")
7960 (set_attr "mode" "QI")])
7962 (define_insn "*<code>qi_ext_1"
7963 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
7968 (match_operand 1 "ext_register_operand" "0,0")
7972 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
7973 (clobber (reg:CC FLAGS_REG))]
7974 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7975 "<logic>{b}\t{%2, %h0|%h0, %2}"
7976 [(set_attr "isa" "*,nox64")
7977 (set_attr "type" "alu")
7978 (set_attr "length_immediate" "0")
7979 (set_attr "mode" "QI")])
7981 (define_insn "*<code>qi_ext_2"
7982 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7986 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
7989 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
7992 (clobber (reg:CC FLAGS_REG))]
7993 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
7994 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
7995 [(set_attr "type" "alu")
7996 (set_attr "length_immediate" "0")
7997 (set_attr "mode" "QI")])
8000 [(set (match_operand 0 "register_operand")
8001 (any_or (match_operand 1 "register_operand")
8002 (match_operand 2 "const_int_operand")))
8003 (clobber (reg:CC FLAGS_REG))]
8005 && QI_REG_P (operands[0])
8006 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8007 && !(INTVAL (operands[2]) & ~(255 << 8))
8008 && GET_MODE (operands[0]) != QImode"
8009 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8010 (any_or:SI (zero_extract:SI (match_dup 1)
8011 (const_int 8) (const_int 8))
8013 (clobber (reg:CC FLAGS_REG))])]
8015 operands[0] = gen_lowpart (SImode, operands[0]);
8016 operands[1] = gen_lowpart (SImode, operands[1]);
8017 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8020 ;; Since OR can be encoded with sign extended immediate, this is only
8021 ;; profitable when 7th bit is set.
8023 [(set (match_operand 0 "register_operand")
8024 (any_or (match_operand 1 "general_operand")
8025 (match_operand 2 "const_int_operand")))
8026 (clobber (reg:CC FLAGS_REG))]
8028 && ANY_QI_REG_P (operands[0])
8029 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8030 && !(INTVAL (operands[2]) & ~255)
8031 && (INTVAL (operands[2]) & 128)
8032 && GET_MODE (operands[0]) != QImode"
8033 [(parallel [(set (strict_low_part (match_dup 0))
8034 (any_or:QI (match_dup 1)
8036 (clobber (reg:CC FLAGS_REG))])]
8038 operands[0] = gen_lowpart (QImode, operands[0]);
8039 operands[1] = gen_lowpart (QImode, operands[1]);
8040 operands[2] = gen_lowpart (QImode, operands[2]);
8043 (define_expand "xorqi_cc_ext_1"
8045 (set (reg:CCNO FLAGS_REG)
8049 (match_operand 1 "ext_register_operand")
8052 (match_operand:QI 2 "const_int_operand"))
8054 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8064 (define_insn "*xorqi_cc_ext_1"
8065 [(set (reg FLAGS_REG)
8069 (match_operand 1 "ext_register_operand" "0,0")
8072 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m"))
8074 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8083 "ix86_match_ccmode (insn, CCNOmode)"
8084 "xor{b}\t{%2, %h0|%h0, %2}"
8085 [(set_attr "isa" "*,nox64")
8086 (set_attr "type" "alu")
8087 (set_attr "modrm" "1")
8088 (set_attr "mode" "QI")])
8090 ;; Negation instructions
8092 (define_expand "neg<mode>2"
8093 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8094 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8096 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8098 (define_insn_and_split "*neg<dwi>2_doubleword"
8099 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8100 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8101 (clobber (reg:CC FLAGS_REG))]
8102 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8106 [(set (reg:CCZ FLAGS_REG)
8107 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8108 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8111 (plus:DWIH (match_dup 3)
8112 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8114 (clobber (reg:CC FLAGS_REG))])
8117 (neg:DWIH (match_dup 2)))
8118 (clobber (reg:CC FLAGS_REG))])]
8119 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8121 (define_insn "*neg<mode>2_1"
8122 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8123 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8124 (clobber (reg:CC FLAGS_REG))]
8125 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8126 "neg{<imodesuffix>}\t%0"
8127 [(set_attr "type" "negnot")
8128 (set_attr "mode" "<MODE>")])
8130 ;; Combine is quite creative about this pattern.
8131 (define_insn "*negsi2_1_zext"
8132 [(set (match_operand:DI 0 "register_operand" "=r")
8134 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8137 (clobber (reg:CC FLAGS_REG))]
8138 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8140 [(set_attr "type" "negnot")
8141 (set_attr "mode" "SI")])
8143 ;; The problem with neg is that it does not perform (compare x 0),
8144 ;; it really performs (compare 0 x), which leaves us with the zero
8145 ;; flag being the only useful item.
8147 (define_insn "*neg<mode>2_cmpz"
8148 [(set (reg:CCZ FLAGS_REG)
8150 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8152 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8153 (neg:SWI (match_dup 1)))]
8154 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8155 "neg{<imodesuffix>}\t%0"
8156 [(set_attr "type" "negnot")
8157 (set_attr "mode" "<MODE>")])
8159 (define_insn "*negsi2_cmpz_zext"
8160 [(set (reg:CCZ FLAGS_REG)
8164 (match_operand:DI 1 "register_operand" "0")
8168 (set (match_operand:DI 0 "register_operand" "=r")
8169 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8172 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8174 [(set_attr "type" "negnot")
8175 (set_attr "mode" "SI")])
8177 ;; Changing of sign for FP values is doable using integer unit too.
8179 (define_expand "<code><mode>2"
8180 [(set (match_operand:X87MODEF 0 "register_operand")
8181 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8182 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8183 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8185 (define_insn "*absneg<mode>2_mixed"
8186 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8187 (match_operator:MODEF 3 "absneg_operator"
8188 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8189 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8190 (clobber (reg:CC FLAGS_REG))]
8191 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8194 (define_insn "*absneg<mode>2_sse"
8195 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8196 (match_operator:MODEF 3 "absneg_operator"
8197 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8198 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8199 (clobber (reg:CC FLAGS_REG))]
8200 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8203 (define_insn "*absneg<mode>2_i387"
8204 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8205 (match_operator:X87MODEF 3 "absneg_operator"
8206 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8207 (use (match_operand 2))
8208 (clobber (reg:CC FLAGS_REG))]
8209 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8212 (define_expand "<code>tf2"
8213 [(set (match_operand:TF 0 "register_operand")
8214 (absneg:TF (match_operand:TF 1 "register_operand")))]
8216 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8218 (define_insn "*absnegtf2_sse"
8219 [(set (match_operand:TF 0 "register_operand" "=x,x")
8220 (match_operator:TF 3 "absneg_operator"
8221 [(match_operand:TF 1 "register_operand" "0,x")]))
8222 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8223 (clobber (reg:CC FLAGS_REG))]
8227 ;; Splitters for fp abs and neg.
8230 [(set (match_operand 0 "fp_register_operand")
8231 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8232 (use (match_operand 2))
8233 (clobber (reg:CC FLAGS_REG))]
8235 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8238 [(set (match_operand 0 "register_operand")
8239 (match_operator 3 "absneg_operator"
8240 [(match_operand 1 "register_operand")]))
8241 (use (match_operand 2 "nonimmediate_operand"))
8242 (clobber (reg:CC FLAGS_REG))]
8243 "reload_completed && SSE_REG_P (operands[0])"
8244 [(set (match_dup 0) (match_dup 3))]
8246 enum machine_mode mode = GET_MODE (operands[0]);
8247 enum machine_mode vmode = GET_MODE (operands[2]);
8250 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8251 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8252 if (operands_match_p (operands[0], operands[2]))
8255 operands[1] = operands[2];
8258 if (GET_CODE (operands[3]) == ABS)
8259 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8261 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8266 [(set (match_operand:SF 0 "register_operand")
8267 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8268 (use (match_operand:V4SF 2))
8269 (clobber (reg:CC FLAGS_REG))]
8271 [(parallel [(set (match_dup 0) (match_dup 1))
8272 (clobber (reg:CC FLAGS_REG))])]
8275 operands[0] = gen_lowpart (SImode, operands[0]);
8276 if (GET_CODE (operands[1]) == ABS)
8278 tmp = gen_int_mode (0x7fffffff, SImode);
8279 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8283 tmp = gen_int_mode (0x80000000, SImode);
8284 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8290 [(set (match_operand:DF 0 "register_operand")
8291 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8292 (use (match_operand 2))
8293 (clobber (reg:CC FLAGS_REG))]
8295 [(parallel [(set (match_dup 0) (match_dup 1))
8296 (clobber (reg:CC FLAGS_REG))])]
8301 tmp = gen_lowpart (DImode, operands[0]);
8302 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8305 if (GET_CODE (operands[1]) == ABS)
8308 tmp = gen_rtx_NOT (DImode, tmp);
8312 operands[0] = gen_highpart (SImode, operands[0]);
8313 if (GET_CODE (operands[1]) == ABS)
8315 tmp = gen_int_mode (0x7fffffff, SImode);
8316 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8320 tmp = gen_int_mode (0x80000000, SImode);
8321 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8328 [(set (match_operand:XF 0 "register_operand")
8329 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8330 (use (match_operand 2))
8331 (clobber (reg:CC FLAGS_REG))]
8333 [(parallel [(set (match_dup 0) (match_dup 1))
8334 (clobber (reg:CC FLAGS_REG))])]
8337 operands[0] = gen_rtx_REG (SImode,
8338 true_regnum (operands[0])
8339 + (TARGET_64BIT ? 1 : 2));
8340 if (GET_CODE (operands[1]) == ABS)
8342 tmp = GEN_INT (0x7fff);
8343 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8347 tmp = GEN_INT (0x8000);
8348 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8353 ;; Conditionalize these after reload. If they match before reload, we
8354 ;; lose the clobber and ability to use integer instructions.
8356 (define_insn "*<code><mode>2_1"
8357 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8358 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8360 && (reload_completed
8361 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8362 "f<absneg_mnemonic>"
8363 [(set_attr "type" "fsgn")
8364 (set_attr "mode" "<MODE>")])
8366 (define_insn "*<code>extendsfdf2"
8367 [(set (match_operand:DF 0 "register_operand" "=f")
8368 (absneg:DF (float_extend:DF
8369 (match_operand:SF 1 "register_operand" "0"))))]
8370 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8371 "f<absneg_mnemonic>"
8372 [(set_attr "type" "fsgn")
8373 (set_attr "mode" "DF")])
8375 (define_insn "*<code>extendsfxf2"
8376 [(set (match_operand:XF 0 "register_operand" "=f")
8377 (absneg:XF (float_extend:XF
8378 (match_operand:SF 1 "register_operand" "0"))))]
8380 "f<absneg_mnemonic>"
8381 [(set_attr "type" "fsgn")
8382 (set_attr "mode" "XF")])
8384 (define_insn "*<code>extenddfxf2"
8385 [(set (match_operand:XF 0 "register_operand" "=f")
8386 (absneg:XF (float_extend:XF
8387 (match_operand:DF 1 "register_operand" "0"))))]
8389 "f<absneg_mnemonic>"
8390 [(set_attr "type" "fsgn")
8391 (set_attr "mode" "XF")])
8393 ;; Copysign instructions
8395 (define_mode_iterator CSGNMODE [SF DF TF])
8396 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8398 (define_expand "copysign<mode>3"
8399 [(match_operand:CSGNMODE 0 "register_operand")
8400 (match_operand:CSGNMODE 1 "nonmemory_operand")
8401 (match_operand:CSGNMODE 2 "register_operand")]
8402 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8403 || (TARGET_SSE && (<MODE>mode == TFmode))"
8404 "ix86_expand_copysign (operands); DONE;")
8406 (define_insn_and_split "copysign<mode>3_const"
8407 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8409 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8410 (match_operand:CSGNMODE 2 "register_operand" "0")
8411 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8413 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8414 || (TARGET_SSE && (<MODE>mode == TFmode))"
8416 "&& reload_completed"
8418 "ix86_split_copysign_const (operands); DONE;")
8420 (define_insn "copysign<mode>3_var"
8421 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8423 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8424 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8425 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8426 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8428 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8429 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8430 || (TARGET_SSE && (<MODE>mode == TFmode))"
8434 [(set (match_operand:CSGNMODE 0 "register_operand")
8436 [(match_operand:CSGNMODE 2 "register_operand")
8437 (match_operand:CSGNMODE 3 "register_operand")
8438 (match_operand:<CSGNVMODE> 4)
8439 (match_operand:<CSGNVMODE> 5)]
8441 (clobber (match_scratch:<CSGNVMODE> 1))]
8442 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8443 || (TARGET_SSE && (<MODE>mode == TFmode)))
8444 && reload_completed"
8446 "ix86_split_copysign_var (operands); DONE;")
8448 ;; One complement instructions
8450 (define_expand "one_cmpl<mode>2"
8451 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8452 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
8454 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8456 (define_insn "*one_cmpl<mode>2_1"
8457 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8458 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8459 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8460 "not{<imodesuffix>}\t%0"
8461 [(set_attr "type" "negnot")
8462 (set_attr "mode" "<MODE>")])
8464 ;; %%% Potential partial reg stall on alternative 1. What to do?
8465 (define_insn "*one_cmplqi2_1"
8466 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8467 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8468 "ix86_unary_operator_ok (NOT, QImode, operands)"
8472 [(set_attr "type" "negnot")
8473 (set_attr "mode" "QI,SI")])
8475 ;; ??? Currently never generated - xor is used instead.
8476 (define_insn "*one_cmplsi2_1_zext"
8477 [(set (match_operand:DI 0 "register_operand" "=r")
8479 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8480 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8482 [(set_attr "type" "negnot")
8483 (set_attr "mode" "SI")])
8485 (define_insn "*one_cmpl<mode>2_2"
8486 [(set (reg FLAGS_REG)
8487 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8489 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8490 (not:SWI (match_dup 1)))]
8491 "ix86_match_ccmode (insn, CCNOmode)
8492 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8494 [(set_attr "type" "alu1")
8495 (set_attr "mode" "<MODE>")])
8498 [(set (match_operand 0 "flags_reg_operand")
8499 (match_operator 2 "compare_operator"
8500 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
8502 (set (match_operand:SWI 1 "nonimmediate_operand")
8503 (not:SWI (match_dup 3)))]
8504 "ix86_match_ccmode (insn, CCNOmode)"
8505 [(parallel [(set (match_dup 0)
8506 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8509 (xor:SWI (match_dup 3) (const_int -1)))])])
8511 ;; ??? Currently never generated - xor is used instead.
8512 (define_insn "*one_cmplsi2_2_zext"
8513 [(set (reg FLAGS_REG)
8514 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8516 (set (match_operand:DI 0 "register_operand" "=r")
8517 (zero_extend:DI (not:SI (match_dup 1))))]
8518 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8519 && ix86_unary_operator_ok (NOT, SImode, operands)"
8521 [(set_attr "type" "alu1")
8522 (set_attr "mode" "SI")])
8525 [(set (match_operand 0 "flags_reg_operand")
8526 (match_operator 2 "compare_operator"
8527 [(not:SI (match_operand:SI 3 "register_operand"))
8529 (set (match_operand:DI 1 "register_operand")
8530 (zero_extend:DI (not:SI (match_dup 3))))]
8531 "ix86_match_ccmode (insn, CCNOmode)"
8532 [(parallel [(set (match_dup 0)
8533 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8536 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8538 ;; Shift instructions
8540 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8541 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8542 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8543 ;; from the assembler input.
8545 ;; This instruction shifts the target reg/mem as usual, but instead of
8546 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8547 ;; is a left shift double, bits are taken from the high order bits of
8548 ;; reg, else if the insn is a shift right double, bits are taken from the
8549 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8550 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8552 ;; Since sh[lr]d does not change the `reg' operand, that is done
8553 ;; separately, making all shifts emit pairs of shift double and normal
8554 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8555 ;; support a 63 bit shift, each shift where the count is in a reg expands
8556 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8558 ;; If the shift count is a constant, we need never emit more than one
8559 ;; shift pair, instead using moves and sign extension for counts greater
8562 (define_expand "ashl<mode>3"
8563 [(set (match_operand:SDWIM 0 "<shift_operand>")
8564 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
8565 (match_operand:QI 2 "nonmemory_operand")))]
8567 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8569 (define_insn "*ashl<mode>3_doubleword"
8570 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8571 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8572 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8573 (clobber (reg:CC FLAGS_REG))]
8576 [(set_attr "type" "multi")])
8579 [(set (match_operand:DWI 0 "register_operand")
8580 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
8581 (match_operand:QI 2 "nonmemory_operand")))
8582 (clobber (reg:CC FLAGS_REG))]
8583 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8585 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8587 ;; By default we don't ask for a scratch register, because when DWImode
8588 ;; values are manipulated, registers are already at a premium. But if
8589 ;; we have one handy, we won't turn it away.
8592 [(match_scratch:DWIH 3 "r")
8593 (parallel [(set (match_operand:<DWI> 0 "register_operand")
8595 (match_operand:<DWI> 1 "nonmemory_operand")
8596 (match_operand:QI 2 "nonmemory_operand")))
8597 (clobber (reg:CC FLAGS_REG))])
8601 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
8603 (define_insn "x86_64_shld"
8604 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
8605 (ior:DI (ashift:DI (match_dup 0)
8606 (match_operand:QI 2 "nonmemory_operand" "Jc"))
8607 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8608 (minus:QI (const_int 64) (match_dup 2)))))
8609 (clobber (reg:CC FLAGS_REG))]
8611 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
8612 [(set_attr "type" "ishift")
8613 (set_attr "prefix_0f" "1")
8614 (set_attr "mode" "DI")
8615 (set_attr "athlon_decode" "vector")
8616 (set_attr "amdfam10_decode" "vector")
8617 (set_attr "bdver1_decode" "vector")])
8619 (define_insn "x86_shld"
8620 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
8621 (ior:SI (ashift:SI (match_dup 0)
8622 (match_operand:QI 2 "nonmemory_operand" "Ic"))
8623 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8624 (minus:QI (const_int 32) (match_dup 2)))))
8625 (clobber (reg:CC FLAGS_REG))]
8627 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
8628 [(set_attr "type" "ishift")
8629 (set_attr "prefix_0f" "1")
8630 (set_attr "mode" "SI")
8631 (set_attr "pent_pair" "np")
8632 (set_attr "athlon_decode" "vector")
8633 (set_attr "amdfam10_decode" "vector")
8634 (set_attr "bdver1_decode" "vector")])
8636 (define_expand "x86_shift<mode>_adj_1"
8637 [(set (reg:CCZ FLAGS_REG)
8638 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
8641 (set (match_operand:SWI48 0 "register_operand")
8642 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8643 (match_operand:SWI48 1 "register_operand")
8646 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8647 (match_operand:SWI48 3 "register_operand")
8650 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
8652 (define_expand "x86_shift<mode>_adj_2"
8653 [(use (match_operand:SWI48 0 "register_operand"))
8654 (use (match_operand:SWI48 1 "register_operand"))
8655 (use (match_operand:QI 2 "register_operand"))]
8658 rtx label = gen_label_rtx ();
8661 emit_insn (gen_testqi_ccz_1 (operands[2],
8662 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
8664 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
8665 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
8666 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
8667 gen_rtx_LABEL_REF (VOIDmode, label),
8669 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
8670 JUMP_LABEL (tmp) = label;
8672 emit_move_insn (operands[0], operands[1]);
8673 ix86_expand_clear (operands[1]);
8676 LABEL_NUSES (label) = 1;
8681 ;; Avoid useless masking of count operand.
8682 (define_insn "*ashl<mode>3_mask"
8683 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
8685 (match_operand:SWI48 1 "nonimmediate_operand" "0")
8688 (match_operand:SI 2 "register_operand" "c")
8689 (match_operand:SI 3 "const_int_operand" "n")) 0)))
8690 (clobber (reg:CC FLAGS_REG))]
8691 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
8692 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
8693 == GET_MODE_BITSIZE (<MODE>mode)-1"
8695 return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
8697 [(set_attr "type" "ishift")
8698 (set_attr "mode" "<MODE>")])
8700 (define_insn "*bmi2_ashl<mode>3_1"
8701 [(set (match_operand:SWI48 0 "register_operand" "=r")
8702 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
8703 (match_operand:SWI48 2 "register_operand" "r")))]
8705 "shlx\t{%2, %1, %0|%0, %1, %2}"
8706 [(set_attr "type" "ishiftx")
8707 (set_attr "mode" "<MODE>")])
8709 (define_insn "*ashl<mode>3_1"
8710 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
8711 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
8712 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
8713 (clobber (reg:CC FLAGS_REG))]
8714 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
8716 switch (get_attr_type (insn))
8723 gcc_assert (operands[2] == const1_rtx);
8724 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8725 return "add{<imodesuffix>}\t%0, %0";
8728 if (operands[2] == const1_rtx
8729 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
8730 return "sal{<imodesuffix>}\t%0";
8732 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
8735 [(set_attr "isa" "*,*,bmi2")
8737 (cond [(eq_attr "alternative" "1")
8738 (const_string "lea")
8739 (eq_attr "alternative" "2")
8740 (const_string "ishiftx")
8741 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
8742 (match_operand 0 "register_operand"))
8743 (match_operand 2 "const1_operand"))
8744 (const_string "alu")
8746 (const_string "ishift")))
8747 (set (attr "length_immediate")
8749 (ior (eq_attr "type" "alu")
8750 (and (eq_attr "type" "ishift")
8751 (and (match_operand 2 "const1_operand")
8752 (ior (match_test "TARGET_SHIFT1")
8753 (match_test "optimize_function_for_size_p (cfun)")))))
8755 (const_string "*")))
8756 (set_attr "mode" "<MODE>")])
8758 ;; Convert shift to the shiftx pattern to avoid flags dependency.
8760 [(set (match_operand:SWI48 0 "register_operand")
8761 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
8762 (match_operand:QI 2 "register_operand")))
8763 (clobber (reg:CC FLAGS_REG))]
8764 "TARGET_BMI2 && reload_completed"
8766 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
8767 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
8769 (define_insn "*bmi2_ashlsi3_1_zext"
8770 [(set (match_operand:DI 0 "register_operand" "=r")
8772 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
8773 (match_operand:SI 2 "register_operand" "r"))))]
8774 "TARGET_64BIT && TARGET_BMI2"
8775 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
8776 [(set_attr "type" "ishiftx")
8777 (set_attr "mode" "SI")])
8779 (define_insn "*ashlsi3_1_zext"
8780 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
8782 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
8783 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
8784 (clobber (reg:CC FLAGS_REG))]
8785 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
8787 switch (get_attr_type (insn))
8794 gcc_assert (operands[2] == const1_rtx);
8795 return "add{l}\t%k0, %k0";
8798 if (operands[2] == const1_rtx
8799 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
8800 return "sal{l}\t%k0";
8802 return "sal{l}\t{%2, %k0|%k0, %2}";
8805 [(set_attr "isa" "*,*,bmi2")
8807 (cond [(eq_attr "alternative" "1")
8808 (const_string "lea")
8809 (eq_attr "alternative" "2")
8810 (const_string "ishiftx")
8811 (and (match_test "TARGET_DOUBLE_WITH_ADD")
8812 (match_operand 2 "const1_operand"))
8813 (const_string "alu")
8815 (const_string "ishift")))
8816 (set (attr "length_immediate")
8818 (ior (eq_attr "type" "alu")
8819 (and (eq_attr "type" "ishift")
8820 (and (match_operand 2 "const1_operand")
8821 (ior (match_test "TARGET_SHIFT1")
8822 (match_test "optimize_function_for_size_p (cfun)")))))
8824 (const_string "*")))
8825 (set_attr "mode" "SI")])
8827 ;; Convert shift to the shiftx pattern to avoid flags dependency.
8829 [(set (match_operand:DI 0 "register_operand")
8831 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
8832 (match_operand:QI 2 "register_operand"))))
8833 (clobber (reg:CC FLAGS_REG))]
8834 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
8836 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
8837 "operands[2] = gen_lowpart (SImode, operands[2]);")
8839 (define_insn "*ashlhi3_1"
8840 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
8841 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
8842 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
8843 (clobber (reg:CC FLAGS_REG))]
8844 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
8846 switch (get_attr_type (insn))
8852 gcc_assert (operands[2] == const1_rtx);
8853 return "add{w}\t%0, %0";
8856 if (operands[2] == const1_rtx
8857 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
8858 return "sal{w}\t%0";
8860 return "sal{w}\t{%2, %0|%0, %2}";
8864 (cond [(eq_attr "alternative" "1")
8865 (const_string "lea")
8866 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
8867 (match_operand 0 "register_operand"))
8868 (match_operand 2 "const1_operand"))
8869 (const_string "alu")
8871 (const_string "ishift")))
8872 (set (attr "length_immediate")
8874 (ior (eq_attr "type" "alu")
8875 (and (eq_attr "type" "ishift")
8876 (and (match_operand 2 "const1_operand")
8877 (ior (match_test "TARGET_SHIFT1")
8878 (match_test "optimize_function_for_size_p (cfun)")))))
8880 (const_string "*")))
8881 (set_attr "mode" "HI,SI")])
8883 ;; %%% Potential partial reg stall on alternative 1. What to do?
8884 (define_insn "*ashlqi3_1"
8885 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
8886 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
8887 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
8888 (clobber (reg:CC FLAGS_REG))]
8889 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
8891 switch (get_attr_type (insn))
8897 gcc_assert (operands[2] == const1_rtx);
8898 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
8899 return "add{l}\t%k0, %k0";
8901 return "add{b}\t%0, %0";
8904 if (operands[2] == const1_rtx
8905 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
8907 if (get_attr_mode (insn) == MODE_SI)
8908 return "sal{l}\t%k0";
8910 return "sal{b}\t%0";
8914 if (get_attr_mode (insn) == MODE_SI)
8915 return "sal{l}\t{%2, %k0|%k0, %2}";
8917 return "sal{b}\t{%2, %0|%0, %2}";
8922 (cond [(eq_attr "alternative" "2")
8923 (const_string "lea")
8924 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
8925 (match_operand 0 "register_operand"))
8926 (match_operand 2 "const1_operand"))
8927 (const_string "alu")
8929 (const_string "ishift")))
8930 (set (attr "length_immediate")
8932 (ior (eq_attr "type" "alu")
8933 (and (eq_attr "type" "ishift")
8934 (and (match_operand 2 "const1_operand")
8935 (ior (match_test "TARGET_SHIFT1")
8936 (match_test "optimize_function_for_size_p (cfun)")))))
8938 (const_string "*")))
8939 (set_attr "mode" "QI,SI,SI")])
8941 (define_insn "*ashlqi3_1_slp"
8942 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
8943 (ashift:QI (match_dup 0)
8944 (match_operand:QI 1 "nonmemory_operand" "cI")))
8945 (clobber (reg:CC FLAGS_REG))]
8946 "(optimize_function_for_size_p (cfun)
8947 || !TARGET_PARTIAL_FLAG_REG_STALL
8948 || (operands[1] == const1_rtx
8950 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
8952 switch (get_attr_type (insn))
8955 gcc_assert (operands[1] == const1_rtx);
8956 return "add{b}\t%0, %0";
8959 if (operands[1] == const1_rtx
8960 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
8961 return "sal{b}\t%0";
8963 return "sal{b}\t{%1, %0|%0, %1}";
8967 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
8968 (match_operand 0 "register_operand"))
8969 (match_operand 1 "const1_operand"))
8970 (const_string "alu")
8972 (const_string "ishift1")))
8973 (set (attr "length_immediate")
8975 (ior (eq_attr "type" "alu")
8976 (and (eq_attr "type" "ishift1")
8977 (and (match_operand 1 "const1_operand")
8978 (ior (match_test "TARGET_SHIFT1")
8979 (match_test "optimize_function_for_size_p (cfun)")))))
8981 (const_string "*")))
8982 (set_attr "mode" "QI")])
8984 ;; Convert ashift to the lea pattern to avoid flags dependency.
8986 [(set (match_operand 0 "register_operand")
8987 (ashift (match_operand 1 "index_register_operand")
8988 (match_operand:QI 2 "const_int_operand")))
8989 (clobber (reg:CC FLAGS_REG))]
8990 "GET_MODE (operands[0]) == GET_MODE (operands[1])
8992 && true_regnum (operands[0]) != true_regnum (operands[1])"
8995 enum machine_mode mode = GET_MODE (operands[0]);
8998 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9001 operands[0] = gen_lowpart (mode, operands[0]);
9002 operands[1] = gen_lowpart (mode, operands[1]);
9005 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9007 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9009 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9013 ;; Convert ashift to the lea pattern to avoid flags dependency.
9015 [(set (match_operand:DI 0 "register_operand")
9017 (ashift:SI (match_operand:SI 1 "index_register_operand")
9018 (match_operand:QI 2 "const_int_operand"))))
9019 (clobber (reg:CC FLAGS_REG))]
9020 "TARGET_64BIT && reload_completed
9021 && true_regnum (operands[0]) != true_regnum (operands[1])"
9023 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
9025 operands[1] = gen_lowpart (SImode, operands[1]);
9026 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), SImode);
9029 ;; This pattern can't accept a variable shift count, since shifts by
9030 ;; zero don't affect the flags. We assume that shifts by constant
9031 ;; zero are optimized away.
9032 (define_insn "*ashl<mode>3_cmp"
9033 [(set (reg FLAGS_REG)
9035 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9036 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9038 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9039 (ashift:SWI (match_dup 1) (match_dup 2)))]
9040 "(optimize_function_for_size_p (cfun)
9041 || !TARGET_PARTIAL_FLAG_REG_STALL
9042 || (operands[2] == const1_rtx
9044 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9045 && ix86_match_ccmode (insn, CCGOCmode)
9046 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9048 switch (get_attr_type (insn))
9051 gcc_assert (operands[2] == const1_rtx);
9052 return "add{<imodesuffix>}\t%0, %0";
9055 if (operands[2] == const1_rtx
9056 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9057 return "sal{<imodesuffix>}\t%0";
9059 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9063 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9064 (match_operand 0 "register_operand"))
9065 (match_operand 2 "const1_operand"))
9066 (const_string "alu")
9068 (const_string "ishift")))
9069 (set (attr "length_immediate")
9071 (ior (eq_attr "type" "alu")
9072 (and (eq_attr "type" "ishift")
9073 (and (match_operand 2 "const1_operand")
9074 (ior (match_test "TARGET_SHIFT1")
9075 (match_test "optimize_function_for_size_p (cfun)")))))
9077 (const_string "*")))
9078 (set_attr "mode" "<MODE>")])
9080 (define_insn "*ashlsi3_cmp_zext"
9081 [(set (reg FLAGS_REG)
9083 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9084 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9086 (set (match_operand:DI 0 "register_operand" "=r")
9087 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9089 && (optimize_function_for_size_p (cfun)
9090 || !TARGET_PARTIAL_FLAG_REG_STALL
9091 || (operands[2] == const1_rtx
9093 || TARGET_DOUBLE_WITH_ADD)))
9094 && ix86_match_ccmode (insn, CCGOCmode)
9095 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9097 switch (get_attr_type (insn))
9100 gcc_assert (operands[2] == const1_rtx);
9101 return "add{l}\t%k0, %k0";
9104 if (operands[2] == const1_rtx
9105 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9106 return "sal{l}\t%k0";
9108 return "sal{l}\t{%2, %k0|%k0, %2}";
9112 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9113 (match_operand 2 "const1_operand"))
9114 (const_string "alu")
9116 (const_string "ishift")))
9117 (set (attr "length_immediate")
9119 (ior (eq_attr "type" "alu")
9120 (and (eq_attr "type" "ishift")
9121 (and (match_operand 2 "const1_operand")
9122 (ior (match_test "TARGET_SHIFT1")
9123 (match_test "optimize_function_for_size_p (cfun)")))))
9125 (const_string "*")))
9126 (set_attr "mode" "SI")])
9128 (define_insn "*ashl<mode>3_cconly"
9129 [(set (reg FLAGS_REG)
9131 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9132 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9134 (clobber (match_scratch:SWI 0 "=<r>"))]
9135 "(optimize_function_for_size_p (cfun)
9136 || !TARGET_PARTIAL_FLAG_REG_STALL
9137 || (operands[2] == const1_rtx
9139 || TARGET_DOUBLE_WITH_ADD)))
9140 && ix86_match_ccmode (insn, CCGOCmode)"
9142 switch (get_attr_type (insn))
9145 gcc_assert (operands[2] == const1_rtx);
9146 return "add{<imodesuffix>}\t%0, %0";
9149 if (operands[2] == const1_rtx
9150 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9151 return "sal{<imodesuffix>}\t%0";
9153 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9157 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9158 (match_operand 0 "register_operand"))
9159 (match_operand 2 "const1_operand"))
9160 (const_string "alu")
9162 (const_string "ishift")))
9163 (set (attr "length_immediate")
9165 (ior (eq_attr "type" "alu")
9166 (and (eq_attr "type" "ishift")
9167 (and (match_operand 2 "const1_operand")
9168 (ior (match_test "TARGET_SHIFT1")
9169 (match_test "optimize_function_for_size_p (cfun)")))))
9171 (const_string "*")))
9172 (set_attr "mode" "<MODE>")])
9174 ;; See comment above `ashl<mode>3' about how this works.
9176 (define_expand "<shift_insn><mode>3"
9177 [(set (match_operand:SDWIM 0 "<shift_operand>")
9178 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9179 (match_operand:QI 2 "nonmemory_operand")))]
9181 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9183 ;; Avoid useless masking of count operand.
9184 (define_insn "*<shift_insn><mode>3_mask"
9185 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9187 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9190 (match_operand:SI 2 "register_operand" "c")
9191 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9192 (clobber (reg:CC FLAGS_REG))]
9193 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9194 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9195 == GET_MODE_BITSIZE (<MODE>mode)-1"
9197 return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9199 [(set_attr "type" "ishift")
9200 (set_attr "mode" "<MODE>")])
9202 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9203 [(set (match_operand:DWI 0 "register_operand" "=r")
9204 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9205 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9206 (clobber (reg:CC FLAGS_REG))]
9209 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9211 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9212 [(set_attr "type" "multi")])
9214 ;; By default we don't ask for a scratch register, because when DWImode
9215 ;; values are manipulated, registers are already at a premium. But if
9216 ;; we have one handy, we won't turn it away.
9219 [(match_scratch:DWIH 3 "r")
9220 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9222 (match_operand:<DWI> 1 "register_operand")
9223 (match_operand:QI 2 "nonmemory_operand")))
9224 (clobber (reg:CC FLAGS_REG))])
9228 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9230 (define_insn "x86_64_shrd"
9231 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9232 (ior:DI (ashiftrt:DI (match_dup 0)
9233 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9234 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9235 (minus:QI (const_int 64) (match_dup 2)))))
9236 (clobber (reg:CC FLAGS_REG))]
9238 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9239 [(set_attr "type" "ishift")
9240 (set_attr "prefix_0f" "1")
9241 (set_attr "mode" "DI")
9242 (set_attr "athlon_decode" "vector")
9243 (set_attr "amdfam10_decode" "vector")
9244 (set_attr "bdver1_decode" "vector")])
9246 (define_insn "x86_shrd"
9247 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9248 (ior:SI (ashiftrt:SI (match_dup 0)
9249 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9250 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9251 (minus:QI (const_int 32) (match_dup 2)))))
9252 (clobber (reg:CC FLAGS_REG))]
9254 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9255 [(set_attr "type" "ishift")
9256 (set_attr "prefix_0f" "1")
9257 (set_attr "mode" "SI")
9258 (set_attr "pent_pair" "np")
9259 (set_attr "athlon_decode" "vector")
9260 (set_attr "amdfam10_decode" "vector")
9261 (set_attr "bdver1_decode" "vector")])
9263 (define_insn "ashrdi3_cvt"
9264 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9265 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9266 (match_operand:QI 2 "const_int_operand")))
9267 (clobber (reg:CC FLAGS_REG))]
9268 "TARGET_64BIT && INTVAL (operands[2]) == 63
9269 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9270 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9273 sar{q}\t{%2, %0|%0, %2}"
9274 [(set_attr "type" "imovx,ishift")
9275 (set_attr "prefix_0f" "0,*")
9276 (set_attr "length_immediate" "0,*")
9277 (set_attr "modrm" "0,1")
9278 (set_attr "mode" "DI")])
9280 (define_insn "ashrsi3_cvt"
9281 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9282 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9283 (match_operand:QI 2 "const_int_operand")))
9284 (clobber (reg:CC FLAGS_REG))]
9285 "INTVAL (operands[2]) == 31
9286 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9287 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9290 sar{l}\t{%2, %0|%0, %2}"
9291 [(set_attr "type" "imovx,ishift")
9292 (set_attr "prefix_0f" "0,*")
9293 (set_attr "length_immediate" "0,*")
9294 (set_attr "modrm" "0,1")
9295 (set_attr "mode" "SI")])
9297 (define_insn "*ashrsi3_cvt_zext"
9298 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9300 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9301 (match_operand:QI 2 "const_int_operand"))))
9302 (clobber (reg:CC FLAGS_REG))]
9303 "TARGET_64BIT && INTVAL (operands[2]) == 31
9304 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9305 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9308 sar{l}\t{%2, %k0|%k0, %2}"
9309 [(set_attr "type" "imovx,ishift")
9310 (set_attr "prefix_0f" "0,*")
9311 (set_attr "length_immediate" "0,*")
9312 (set_attr "modrm" "0,1")
9313 (set_attr "mode" "SI")])
9315 (define_expand "x86_shift<mode>_adj_3"
9316 [(use (match_operand:SWI48 0 "register_operand"))
9317 (use (match_operand:SWI48 1 "register_operand"))
9318 (use (match_operand:QI 2 "register_operand"))]
9321 rtx label = gen_label_rtx ();
9324 emit_insn (gen_testqi_ccz_1 (operands[2],
9325 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9327 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9328 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9329 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9330 gen_rtx_LABEL_REF (VOIDmode, label),
9332 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9333 JUMP_LABEL (tmp) = label;
9335 emit_move_insn (operands[0], operands[1]);
9336 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9337 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9339 LABEL_NUSES (label) = 1;
9344 (define_insn "*bmi2_<shift_insn><mode>3_1"
9345 [(set (match_operand:SWI48 0 "register_operand" "=r")
9346 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9347 (match_operand:SWI48 2 "register_operand" "r")))]
9349 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9350 [(set_attr "type" "ishiftx")
9351 (set_attr "mode" "<MODE>")])
9353 (define_insn "*<shift_insn><mode>3_1"
9354 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9356 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9357 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9358 (clobber (reg:CC FLAGS_REG))]
9359 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9361 switch (get_attr_type (insn))
9367 if (operands[2] == const1_rtx
9368 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9369 return "<shift>{<imodesuffix>}\t%0";
9371 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9374 [(set_attr "isa" "*,bmi2")
9375 (set_attr "type" "ishift,ishiftx")
9376 (set (attr "length_immediate")
9378 (and (match_operand 2 "const1_operand")
9379 (ior (match_test "TARGET_SHIFT1")
9380 (match_test "optimize_function_for_size_p (cfun)")))
9382 (const_string "*")))
9383 (set_attr "mode" "<MODE>")])
9385 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9387 [(set (match_operand:SWI48 0 "register_operand")
9388 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9389 (match_operand:QI 2 "register_operand")))
9390 (clobber (reg:CC FLAGS_REG))]
9391 "TARGET_BMI2 && reload_completed"
9393 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9394 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9396 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9397 [(set (match_operand:DI 0 "register_operand" "=r")
9399 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9400 (match_operand:SI 2 "register_operand" "r"))))]
9401 "TARGET_64BIT && TARGET_BMI2"
9402 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9403 [(set_attr "type" "ishiftx")
9404 (set_attr "mode" "SI")])
9406 (define_insn "*<shift_insn>si3_1_zext"
9407 [(set (match_operand:DI 0 "register_operand" "=r,r")
9409 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9410 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9411 (clobber (reg:CC FLAGS_REG))]
9412 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9414 switch (get_attr_type (insn))
9420 if (operands[2] == const1_rtx
9421 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9422 return "<shift>{l}\t%k0";
9424 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9427 [(set_attr "isa" "*,bmi2")
9428 (set_attr "type" "ishift,ishiftx")
9429 (set (attr "length_immediate")
9431 (and (match_operand 2 "const1_operand")
9432 (ior (match_test "TARGET_SHIFT1")
9433 (match_test "optimize_function_for_size_p (cfun)")))
9435 (const_string "*")))
9436 (set_attr "mode" "SI")])
9438 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9440 [(set (match_operand:DI 0 "register_operand")
9442 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
9443 (match_operand:QI 2 "register_operand"))))
9444 (clobber (reg:CC FLAGS_REG))]
9445 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9447 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9448 "operands[2] = gen_lowpart (SImode, operands[2]);")
9450 (define_insn "*<shift_insn><mode>3_1"
9451 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9453 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9454 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9455 (clobber (reg:CC FLAGS_REG))]
9456 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9458 if (operands[2] == const1_rtx
9459 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9460 return "<shift>{<imodesuffix>}\t%0";
9462 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9464 [(set_attr "type" "ishift")
9465 (set (attr "length_immediate")
9467 (and (match_operand 2 "const1_operand")
9468 (ior (match_test "TARGET_SHIFT1")
9469 (match_test "optimize_function_for_size_p (cfun)")))
9471 (const_string "*")))
9472 (set_attr "mode" "<MODE>")])
9474 (define_insn "*<shift_insn>qi3_1_slp"
9475 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9476 (any_shiftrt:QI (match_dup 0)
9477 (match_operand:QI 1 "nonmemory_operand" "cI")))
9478 (clobber (reg:CC FLAGS_REG))]
9479 "(optimize_function_for_size_p (cfun)
9480 || !TARGET_PARTIAL_REG_STALL
9481 || (operands[1] == const1_rtx
9484 if (operands[1] == const1_rtx
9485 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9486 return "<shift>{b}\t%0";
9488 return "<shift>{b}\t{%1, %0|%0, %1}";
9490 [(set_attr "type" "ishift1")
9491 (set (attr "length_immediate")
9493 (and (match_operand 1 "const1_operand")
9494 (ior (match_test "TARGET_SHIFT1")
9495 (match_test "optimize_function_for_size_p (cfun)")))
9497 (const_string "*")))
9498 (set_attr "mode" "QI")])
9500 ;; This pattern can't accept a variable shift count, since shifts by
9501 ;; zero don't affect the flags. We assume that shifts by constant
9502 ;; zero are optimized away.
9503 (define_insn "*<shift_insn><mode>3_cmp"
9504 [(set (reg FLAGS_REG)
9507 (match_operand:SWI 1 "nonimmediate_operand" "0")
9508 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9510 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9511 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9512 "(optimize_function_for_size_p (cfun)
9513 || !TARGET_PARTIAL_FLAG_REG_STALL
9514 || (operands[2] == const1_rtx
9516 && ix86_match_ccmode (insn, CCGOCmode)
9517 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9519 if (operands[2] == const1_rtx
9520 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9521 return "<shift>{<imodesuffix>}\t%0";
9523 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9525 [(set_attr "type" "ishift")
9526 (set (attr "length_immediate")
9528 (and (match_operand 2 "const1_operand")
9529 (ior (match_test "TARGET_SHIFT1")
9530 (match_test "optimize_function_for_size_p (cfun)")))
9532 (const_string "*")))
9533 (set_attr "mode" "<MODE>")])
9535 (define_insn "*<shift_insn>si3_cmp_zext"
9536 [(set (reg FLAGS_REG)
9538 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9539 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9541 (set (match_operand:DI 0 "register_operand" "=r")
9542 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9544 && (optimize_function_for_size_p (cfun)
9545 || !TARGET_PARTIAL_FLAG_REG_STALL
9546 || (operands[2] == const1_rtx
9548 && ix86_match_ccmode (insn, CCGOCmode)
9549 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9551 if (operands[2] == const1_rtx
9552 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9553 return "<shift>{l}\t%k0";
9555 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9557 [(set_attr "type" "ishift")
9558 (set (attr "length_immediate")
9560 (and (match_operand 2 "const1_operand")
9561 (ior (match_test "TARGET_SHIFT1")
9562 (match_test "optimize_function_for_size_p (cfun)")))
9564 (const_string "*")))
9565 (set_attr "mode" "SI")])
9567 (define_insn "*<shift_insn><mode>3_cconly"
9568 [(set (reg FLAGS_REG)
9571 (match_operand:SWI 1 "register_operand" "0")
9572 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9574 (clobber (match_scratch:SWI 0 "=<r>"))]
9575 "(optimize_function_for_size_p (cfun)
9576 || !TARGET_PARTIAL_FLAG_REG_STALL
9577 || (operands[2] == const1_rtx
9579 && ix86_match_ccmode (insn, CCGOCmode)"
9581 if (operands[2] == const1_rtx
9582 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9583 return "<shift>{<imodesuffix>}\t%0";
9585 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9587 [(set_attr "type" "ishift")
9588 (set (attr "length_immediate")
9590 (and (match_operand 2 "const1_operand")
9591 (ior (match_test "TARGET_SHIFT1")
9592 (match_test "optimize_function_for_size_p (cfun)")))
9594 (const_string "*")))
9595 (set_attr "mode" "<MODE>")])
9597 ;; Rotate instructions
9599 (define_expand "<rotate_insn>ti3"
9600 [(set (match_operand:TI 0 "register_operand")
9601 (any_rotate:TI (match_operand:TI 1 "register_operand")
9602 (match_operand:QI 2 "nonmemory_operand")))]
9605 if (const_1_to_63_operand (operands[2], VOIDmode))
9606 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
9607 (operands[0], operands[1], operands[2]));
9614 (define_expand "<rotate_insn>di3"
9615 [(set (match_operand:DI 0 "shiftdi_operand")
9616 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
9617 (match_operand:QI 2 "nonmemory_operand")))]
9621 ix86_expand_binary_operator (<CODE>, DImode, operands);
9622 else if (const_1_to_31_operand (operands[2], VOIDmode))
9623 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
9624 (operands[0], operands[1], operands[2]));
9631 (define_expand "<rotate_insn><mode>3"
9632 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
9633 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
9634 (match_operand:QI 2 "nonmemory_operand")))]
9636 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9638 ;; Avoid useless masking of count operand.
9639 (define_insn "*<rotate_insn><mode>3_mask"
9640 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9642 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9645 (match_operand:SI 2 "register_operand" "c")
9646 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9647 (clobber (reg:CC FLAGS_REG))]
9648 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9649 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9650 == GET_MODE_BITSIZE (<MODE>mode)-1"
9652 return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9654 [(set_attr "type" "rotate")
9655 (set_attr "mode" "<MODE>")])
9657 ;; Implement rotation using two double-precision
9658 ;; shift instructions and a scratch register.
9660 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
9661 [(set (match_operand:<DWI> 0 "register_operand" "=r")
9662 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
9663 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
9664 (clobber (reg:CC FLAGS_REG))
9665 (clobber (match_scratch:DWIH 3 "=&r"))]
9669 [(set (match_dup 3) (match_dup 4))
9672 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
9673 (lshiftrt:DWIH (match_dup 5)
9674 (minus:QI (match_dup 6) (match_dup 2)))))
9675 (clobber (reg:CC FLAGS_REG))])
9678 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
9679 (lshiftrt:DWIH (match_dup 3)
9680 (minus:QI (match_dup 6) (match_dup 2)))))
9681 (clobber (reg:CC FLAGS_REG))])]
9683 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
9685 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
9688 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
9689 [(set (match_operand:<DWI> 0 "register_operand" "=r")
9690 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
9691 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
9692 (clobber (reg:CC FLAGS_REG))
9693 (clobber (match_scratch:DWIH 3 "=&r"))]
9697 [(set (match_dup 3) (match_dup 4))
9700 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
9701 (ashift:DWIH (match_dup 5)
9702 (minus:QI (match_dup 6) (match_dup 2)))))
9703 (clobber (reg:CC FLAGS_REG))])
9706 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
9707 (ashift:DWIH (match_dup 3)
9708 (minus:QI (match_dup 6) (match_dup 2)))))
9709 (clobber (reg:CC FLAGS_REG))])]
9711 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
9713 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
9716 (define_insn "*bmi2_rorx<mode>3_1"
9717 [(set (match_operand:SWI48 0 "register_operand" "=r")
9718 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9719 (match_operand:QI 2 "immediate_operand" "<S>")))]
9721 "rorx\t{%2, %1, %0|%0, %1, %2}"
9722 [(set_attr "type" "rotatex")
9723 (set_attr "mode" "<MODE>")])
9725 (define_insn "*<rotate_insn><mode>3_1"
9726 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9728 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9729 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
9730 (clobber (reg:CC FLAGS_REG))]
9731 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9733 switch (get_attr_type (insn))
9739 if (operands[2] == const1_rtx
9740 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9741 return "<rotate>{<imodesuffix>}\t%0";
9743 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
9746 [(set_attr "isa" "*,bmi2")
9747 (set_attr "type" "rotate,rotatex")
9748 (set (attr "length_immediate")
9750 (and (eq_attr "type" "rotate")
9751 (and (match_operand 2 "const1_operand")
9752 (ior (match_test "TARGET_SHIFT1")
9753 (match_test "optimize_function_for_size_p (cfun)"))))
9755 (const_string "*")))
9756 (set_attr "mode" "<MODE>")])
9758 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
9760 [(set (match_operand:SWI48 0 "register_operand")
9761 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9762 (match_operand:QI 2 "immediate_operand")))
9763 (clobber (reg:CC FLAGS_REG))]
9764 "TARGET_BMI2 && reload_completed"
9766 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
9769 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
9773 [(set (match_operand:SWI48 0 "register_operand")
9774 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9775 (match_operand:QI 2 "immediate_operand")))
9776 (clobber (reg:CC FLAGS_REG))]
9777 "TARGET_BMI2 && reload_completed"
9779 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
9781 (define_insn "*bmi2_rorxsi3_1_zext"
9782 [(set (match_operand:DI 0 "register_operand" "=r")
9784 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9785 (match_operand:QI 2 "immediate_operand" "I"))))]
9786 "TARGET_64BIT && TARGET_BMI2"
9787 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
9788 [(set_attr "type" "rotatex")
9789 (set_attr "mode" "SI")])
9791 (define_insn "*<rotate_insn>si3_1_zext"
9792 [(set (match_operand:DI 0 "register_operand" "=r,r")
9794 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9795 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
9796 (clobber (reg:CC FLAGS_REG))]
9797 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9799 switch (get_attr_type (insn))
9805 if (operands[2] == const1_rtx
9806 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9807 return "<rotate>{l}\t%k0";
9809 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
9812 [(set_attr "isa" "*,bmi2")
9813 (set_attr "type" "rotate,rotatex")
9814 (set (attr "length_immediate")
9816 (and (eq_attr "type" "rotate")
9817 (and (match_operand 2 "const1_operand")
9818 (ior (match_test "TARGET_SHIFT1")
9819 (match_test "optimize_function_for_size_p (cfun)"))))
9821 (const_string "*")))
9822 (set_attr "mode" "SI")])
9824 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
9826 [(set (match_operand:DI 0 "register_operand")
9828 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
9829 (match_operand:QI 2 "immediate_operand"))))
9830 (clobber (reg:CC FLAGS_REG))]
9831 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9833 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
9836 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
9840 [(set (match_operand:DI 0 "register_operand")
9842 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
9843 (match_operand:QI 2 "immediate_operand"))))
9844 (clobber (reg:CC FLAGS_REG))]
9845 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9847 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
9849 (define_insn "*<rotate_insn><mode>3_1"
9850 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9851 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9852 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9853 (clobber (reg:CC FLAGS_REG))]
9854 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9856 if (operands[2] == const1_rtx
9857 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9858 return "<rotate>{<imodesuffix>}\t%0";
9860 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
9862 [(set_attr "type" "rotate")
9863 (set (attr "length_immediate")
9865 (and (match_operand 2 "const1_operand")
9866 (ior (match_test "TARGET_SHIFT1")
9867 (match_test "optimize_function_for_size_p (cfun)")))
9869 (const_string "*")))
9870 (set_attr "mode" "<MODE>")])
9872 (define_insn "*<rotate_insn>qi3_1_slp"
9873 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9874 (any_rotate:QI (match_dup 0)
9875 (match_operand:QI 1 "nonmemory_operand" "cI")))
9876 (clobber (reg:CC FLAGS_REG))]
9877 "(optimize_function_for_size_p (cfun)
9878 || !TARGET_PARTIAL_REG_STALL
9879 || (operands[1] == const1_rtx
9882 if (operands[1] == const1_rtx
9883 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9884 return "<rotate>{b}\t%0";
9886 return "<rotate>{b}\t{%1, %0|%0, %1}";
9888 [(set_attr "type" "rotate1")
9889 (set (attr "length_immediate")
9891 (and (match_operand 1 "const1_operand")
9892 (ior (match_test "TARGET_SHIFT1")
9893 (match_test "optimize_function_for_size_p (cfun)")))
9895 (const_string "*")))
9896 (set_attr "mode" "QI")])
9899 [(set (match_operand:HI 0 "register_operand")
9900 (any_rotate:HI (match_dup 0) (const_int 8)))
9901 (clobber (reg:CC FLAGS_REG))]
9903 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
9904 [(parallel [(set (strict_low_part (match_dup 0))
9905 (bswap:HI (match_dup 0)))
9906 (clobber (reg:CC FLAGS_REG))])])
9908 ;; Bit set / bit test instructions
9910 (define_expand "extv"
9911 [(set (match_operand:SI 0 "register_operand")
9912 (sign_extract:SI (match_operand:SI 1 "register_operand")
9913 (match_operand:SI 2 "const8_operand")
9914 (match_operand:SI 3 "const8_operand")))]
9917 /* Handle extractions from %ah et al. */
9918 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
9921 /* From mips.md: extract_bit_field doesn't verify that our source
9922 matches the predicate, so check it again here. */
9923 if (! ext_register_operand (operands[1], VOIDmode))
9927 (define_expand "extzv"
9928 [(set (match_operand:SI 0 "register_operand")
9929 (zero_extract:SI (match_operand 1 "ext_register_operand")
9930 (match_operand:SI 2 "const8_operand")
9931 (match_operand:SI 3 "const8_operand")))]
9934 /* Handle extractions from %ah et al. */
9935 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
9938 /* From mips.md: extract_bit_field doesn't verify that our source
9939 matches the predicate, so check it again here. */
9940 if (! ext_register_operand (operands[1], VOIDmode))
9944 (define_expand "insv"
9945 [(set (zero_extract (match_operand 0 "register_operand")
9946 (match_operand 1 "const_int_operand")
9947 (match_operand 2 "const_int_operand"))
9948 (match_operand 3 "register_operand"))]
9951 rtx (*gen_mov_insv_1) (rtx, rtx);
9953 if (ix86_expand_pinsr (operands))
9956 /* Handle insertions to %ah et al. */
9957 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
9960 /* From mips.md: insert_bit_field doesn't verify that our source
9961 matches the predicate, so check it again here. */
9962 if (! ext_register_operand (operands[0], VOIDmode))
9965 gen_mov_insv_1 = (TARGET_64BIT
9966 ? gen_movdi_insv_1 : gen_movsi_insv_1);
9968 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
9972 ;; %%% bts, btr, btc, bt.
9973 ;; In general these instructions are *slow* when applied to memory,
9974 ;; since they enforce atomic operation. When applied to registers,
9975 ;; it depends on the cpu implementation. They're never faster than
9976 ;; the corresponding and/ior/xor operations, so with 32-bit there's
9977 ;; no point. But in 64-bit, we can't hold the relevant immediates
9978 ;; within the instruction itself, so operating on bits in the high
9979 ;; 32-bits of a register becomes easier.
9981 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
9982 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
9983 ;; negdf respectively, so they can never be disabled entirely.
9985 (define_insn "*btsq"
9986 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
9988 (match_operand:DI 1 "const_0_to_63_operand"))
9990 (clobber (reg:CC FLAGS_REG))]
9991 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
9992 "bts{q}\t{%1, %0|%0, %1}"
9993 [(set_attr "type" "alu1")
9994 (set_attr "prefix_0f" "1")
9995 (set_attr "mode" "DI")])
9997 (define_insn "*btrq"
9998 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10000 (match_operand:DI 1 "const_0_to_63_operand"))
10002 (clobber (reg:CC FLAGS_REG))]
10003 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10004 "btr{q}\t{%1, %0|%0, %1}"
10005 [(set_attr "type" "alu1")
10006 (set_attr "prefix_0f" "1")
10007 (set_attr "mode" "DI")])
10009 (define_insn "*btcq"
10010 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10012 (match_operand:DI 1 "const_0_to_63_operand"))
10013 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10014 (clobber (reg:CC FLAGS_REG))]
10015 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10016 "btc{q}\t{%1, %0|%0, %1}"
10017 [(set_attr "type" "alu1")
10018 (set_attr "prefix_0f" "1")
10019 (set_attr "mode" "DI")])
10021 ;; Allow Nocona to avoid these instructions if a register is available.
10024 [(match_scratch:DI 2 "r")
10025 (parallel [(set (zero_extract:DI
10026 (match_operand:DI 0 "register_operand")
10028 (match_operand:DI 1 "const_0_to_63_operand"))
10030 (clobber (reg:CC FLAGS_REG))])]
10031 "TARGET_64BIT && !TARGET_USE_BT"
10034 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10037 if (HOST_BITS_PER_WIDE_INT >= 64)
10038 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10039 else if (i < HOST_BITS_PER_WIDE_INT)
10040 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10042 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10044 op1 = immed_double_const (lo, hi, DImode);
10047 emit_move_insn (operands[2], op1);
10051 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10056 [(match_scratch:DI 2 "r")
10057 (parallel [(set (zero_extract:DI
10058 (match_operand:DI 0 "register_operand")
10060 (match_operand:DI 1 "const_0_to_63_operand"))
10062 (clobber (reg:CC FLAGS_REG))])]
10063 "TARGET_64BIT && !TARGET_USE_BT"
10066 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10069 if (HOST_BITS_PER_WIDE_INT >= 64)
10070 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10071 else if (i < HOST_BITS_PER_WIDE_INT)
10072 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10074 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10076 op1 = immed_double_const (~lo, ~hi, DImode);
10079 emit_move_insn (operands[2], op1);
10083 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10088 [(match_scratch:DI 2 "r")
10089 (parallel [(set (zero_extract:DI
10090 (match_operand:DI 0 "register_operand")
10092 (match_operand:DI 1 "const_0_to_63_operand"))
10093 (not:DI (zero_extract:DI
10094 (match_dup 0) (const_int 1) (match_dup 1))))
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_xordi3 (operands[0], operands[0], op1));
10120 (define_insn "*bt<mode>"
10121 [(set (reg:CCC FLAGS_REG)
10123 (zero_extract:SWI48
10124 (match_operand:SWI48 0 "register_operand" "r")
10126 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10128 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10129 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10130 [(set_attr "type" "alu1")
10131 (set_attr "prefix_0f" "1")
10132 (set_attr "mode" "<MODE>")])
10134 ;; Store-flag instructions.
10136 ;; For all sCOND expanders, also expand the compare or test insn that
10137 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10139 (define_insn_and_split "*setcc_di_1"
10140 [(set (match_operand:DI 0 "register_operand" "=q")
10141 (match_operator:DI 1 "ix86_comparison_operator"
10142 [(reg FLAGS_REG) (const_int 0)]))]
10143 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10145 "&& reload_completed"
10146 [(set (match_dup 2) (match_dup 1))
10147 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10149 PUT_MODE (operands[1], QImode);
10150 operands[2] = gen_lowpart (QImode, operands[0]);
10153 (define_insn_and_split "*setcc_si_1_and"
10154 [(set (match_operand:SI 0 "register_operand" "=q")
10155 (match_operator:SI 1 "ix86_comparison_operator"
10156 [(reg FLAGS_REG) (const_int 0)]))
10157 (clobber (reg:CC FLAGS_REG))]
10158 "!TARGET_PARTIAL_REG_STALL
10159 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10161 "&& reload_completed"
10162 [(set (match_dup 2) (match_dup 1))
10163 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10164 (clobber (reg:CC FLAGS_REG))])]
10166 PUT_MODE (operands[1], QImode);
10167 operands[2] = gen_lowpart (QImode, operands[0]);
10170 (define_insn_and_split "*setcc_si_1_movzbl"
10171 [(set (match_operand:SI 0 "register_operand" "=q")
10172 (match_operator:SI 1 "ix86_comparison_operator"
10173 [(reg FLAGS_REG) (const_int 0)]))]
10174 "!TARGET_PARTIAL_REG_STALL
10175 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10177 "&& reload_completed"
10178 [(set (match_dup 2) (match_dup 1))
10179 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10181 PUT_MODE (operands[1], QImode);
10182 operands[2] = gen_lowpart (QImode, operands[0]);
10185 (define_insn "*setcc_qi"
10186 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10187 (match_operator:QI 1 "ix86_comparison_operator"
10188 [(reg FLAGS_REG) (const_int 0)]))]
10191 [(set_attr "type" "setcc")
10192 (set_attr "mode" "QI")])
10194 (define_insn "*setcc_qi_slp"
10195 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10196 (match_operator:QI 1 "ix86_comparison_operator"
10197 [(reg FLAGS_REG) (const_int 0)]))]
10200 [(set_attr "type" "setcc")
10201 (set_attr "mode" "QI")])
10203 ;; In general it is not safe to assume too much about CCmode registers,
10204 ;; so simplify-rtx stops when it sees a second one. Under certain
10205 ;; conditions this is safe on x86, so help combine not create
10212 [(set (match_operand:QI 0 "nonimmediate_operand")
10213 (ne:QI (match_operator 1 "ix86_comparison_operator"
10214 [(reg FLAGS_REG) (const_int 0)])
10217 [(set (match_dup 0) (match_dup 1))]
10218 "PUT_MODE (operands[1], QImode);")
10221 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10222 (ne:QI (match_operator 1 "ix86_comparison_operator"
10223 [(reg FLAGS_REG) (const_int 0)])
10226 [(set (match_dup 0) (match_dup 1))]
10227 "PUT_MODE (operands[1], QImode);")
10230 [(set (match_operand:QI 0 "nonimmediate_operand")
10231 (eq:QI (match_operator 1 "ix86_comparison_operator"
10232 [(reg FLAGS_REG) (const_int 0)])
10235 [(set (match_dup 0) (match_dup 1))]
10237 rtx new_op1 = copy_rtx (operands[1]);
10238 operands[1] = new_op1;
10239 PUT_MODE (new_op1, QImode);
10240 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10241 GET_MODE (XEXP (new_op1, 0))));
10243 /* Make sure that (a) the CCmode we have for the flags is strong
10244 enough for the reversed compare or (b) we have a valid FP compare. */
10245 if (! ix86_comparison_operator (new_op1, VOIDmode))
10250 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10251 (eq:QI (match_operator 1 "ix86_comparison_operator"
10252 [(reg FLAGS_REG) (const_int 0)])
10255 [(set (match_dup 0) (match_dup 1))]
10257 rtx new_op1 = copy_rtx (operands[1]);
10258 operands[1] = new_op1;
10259 PUT_MODE (new_op1, QImode);
10260 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10261 GET_MODE (XEXP (new_op1, 0))));
10263 /* Make sure that (a) the CCmode we have for the flags is strong
10264 enough for the reversed compare or (b) we have a valid FP compare. */
10265 if (! ix86_comparison_operator (new_op1, VOIDmode))
10269 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10270 ;; subsequent logical operations are used to imitate conditional moves.
10271 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10274 (define_insn "setcc_<mode>_sse"
10275 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10276 (match_operator:MODEF 3 "sse_comparison_operator"
10277 [(match_operand:MODEF 1 "register_operand" "0,x")
10278 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10279 "SSE_FLOAT_MODE_P (<MODE>mode)"
10281 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10282 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10283 [(set_attr "isa" "noavx,avx")
10284 (set_attr "type" "ssecmp")
10285 (set_attr "length_immediate" "1")
10286 (set_attr "prefix" "orig,vex")
10287 (set_attr "mode" "<MODE>")])
10289 ;; Basic conditional jump instructions.
10290 ;; We ignore the overflow flag for signed branch instructions.
10292 (define_insn "*jcc_1"
10294 (if_then_else (match_operator 1 "ix86_comparison_operator"
10295 [(reg FLAGS_REG) (const_int 0)])
10296 (label_ref (match_operand 0))
10300 [(set_attr "type" "ibr")
10301 (set_attr "modrm" "0")
10302 (set (attr "length")
10303 (if_then_else (and (ge (minus (match_dup 0) (pc))
10305 (lt (minus (match_dup 0) (pc))
10310 (define_insn "*jcc_2"
10312 (if_then_else (match_operator 1 "ix86_comparison_operator"
10313 [(reg FLAGS_REG) (const_int 0)])
10315 (label_ref (match_operand 0))))]
10318 [(set_attr "type" "ibr")
10319 (set_attr "modrm" "0")
10320 (set (attr "length")
10321 (if_then_else (and (ge (minus (match_dup 0) (pc))
10323 (lt (minus (match_dup 0) (pc))
10328 ;; In general it is not safe to assume too much about CCmode registers,
10329 ;; so simplify-rtx stops when it sees a second one. Under certain
10330 ;; conditions this is safe on x86, so help combine not create
10338 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10339 [(reg FLAGS_REG) (const_int 0)])
10341 (label_ref (match_operand 1))
10345 (if_then_else (match_dup 0)
10346 (label_ref (match_dup 1))
10348 "PUT_MODE (operands[0], VOIDmode);")
10352 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10353 [(reg FLAGS_REG) (const_int 0)])
10355 (label_ref (match_operand 1))
10359 (if_then_else (match_dup 0)
10360 (label_ref (match_dup 1))
10363 rtx new_op0 = copy_rtx (operands[0]);
10364 operands[0] = new_op0;
10365 PUT_MODE (new_op0, VOIDmode);
10366 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10367 GET_MODE (XEXP (new_op0, 0))));
10369 /* Make sure that (a) the CCmode we have for the flags is strong
10370 enough for the reversed compare or (b) we have a valid FP compare. */
10371 if (! ix86_comparison_operator (new_op0, VOIDmode))
10375 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10376 ;; pass generates from shift insn with QImode operand. Actually, the mode
10377 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10378 ;; appropriate modulo of the bit offset value.
10380 (define_insn_and_split "*jcc_bt<mode>"
10382 (if_then_else (match_operator 0 "bt_comparison_operator"
10383 [(zero_extract:SWI48
10384 (match_operand:SWI48 1 "register_operand" "r")
10387 (match_operand:QI 2 "register_operand" "r")))
10389 (label_ref (match_operand 3))
10391 (clobber (reg:CC FLAGS_REG))]
10392 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10395 [(set (reg:CCC FLAGS_REG)
10397 (zero_extract:SWI48
10403 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10404 (label_ref (match_dup 3))
10407 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10409 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10412 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10413 ;; also for DImode, this is what combine produces.
10414 (define_insn_and_split "*jcc_bt<mode>_mask"
10416 (if_then_else (match_operator 0 "bt_comparison_operator"
10417 [(zero_extract:SWI48
10418 (match_operand:SWI48 1 "register_operand" "r")
10421 (match_operand:SI 2 "register_operand" "r")
10422 (match_operand:SI 3 "const_int_operand" "n")))])
10423 (label_ref (match_operand 4))
10425 (clobber (reg:CC FLAGS_REG))]
10426 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10427 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10428 == GET_MODE_BITSIZE (<MODE>mode)-1"
10431 [(set (reg:CCC FLAGS_REG)
10433 (zero_extract:SWI48
10439 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10440 (label_ref (match_dup 4))
10443 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10445 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10448 (define_insn_and_split "*jcc_btsi_1"
10450 (if_then_else (match_operator 0 "bt_comparison_operator"
10453 (match_operand:SI 1 "register_operand" "r")
10454 (match_operand:QI 2 "register_operand" "r"))
10457 (label_ref (match_operand 3))
10459 (clobber (reg:CC FLAGS_REG))]
10460 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10463 [(set (reg:CCC FLAGS_REG)
10471 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10472 (label_ref (match_dup 3))
10475 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10477 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10480 ;; avoid useless masking of bit offset operand
10481 (define_insn_and_split "*jcc_btsi_mask_1"
10484 (match_operator 0 "bt_comparison_operator"
10487 (match_operand:SI 1 "register_operand" "r")
10490 (match_operand:SI 2 "register_operand" "r")
10491 (match_operand:SI 3 "const_int_operand" "n")) 0))
10494 (label_ref (match_operand 4))
10496 (clobber (reg:CC FLAGS_REG))]
10497 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10498 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10501 [(set (reg:CCC FLAGS_REG)
10509 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10510 (label_ref (match_dup 4))
10512 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10514 ;; Define combination compare-and-branch fp compare instructions to help
10517 (define_insn "*jcc<mode>_0_i387"
10519 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
10520 [(match_operand:X87MODEF 1 "register_operand" "f")
10521 (match_operand:X87MODEF 2 "const0_operand")])
10522 (label_ref (match_operand 3))
10524 (clobber (reg:CCFP FPSR_REG))
10525 (clobber (reg:CCFP FLAGS_REG))
10526 (clobber (match_scratch:HI 4 "=a"))]
10527 "TARGET_80387 && !TARGET_CMOVE"
10530 (define_insn "*jcc<mode>_0_r_i387"
10532 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
10533 [(match_operand:X87MODEF 1 "register_operand" "f")
10534 (match_operand:X87MODEF 2 "const0_operand")])
10536 (label_ref (match_operand 3))))
10537 (clobber (reg:CCFP FPSR_REG))
10538 (clobber (reg:CCFP FLAGS_REG))
10539 (clobber (match_scratch:HI 4 "=a"))]
10540 "TARGET_80387 && !TARGET_CMOVE"
10543 (define_insn "*jccxf_i387"
10545 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
10546 [(match_operand:XF 1 "register_operand" "f")
10547 (match_operand:XF 2 "register_operand" "f")])
10548 (label_ref (match_operand 3))
10550 (clobber (reg:CCFP FPSR_REG))
10551 (clobber (reg:CCFP FLAGS_REG))
10552 (clobber (match_scratch:HI 4 "=a"))]
10553 "TARGET_80387 && !TARGET_CMOVE"
10556 (define_insn "*jccxf_r_i387"
10558 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
10559 [(match_operand:XF 1 "register_operand" "f")
10560 (match_operand:XF 2 "register_operand" "f")])
10562 (label_ref (match_operand 3))))
10563 (clobber (reg:CCFP FPSR_REG))
10564 (clobber (reg:CCFP FLAGS_REG))
10565 (clobber (match_scratch:HI 4 "=a"))]
10566 "TARGET_80387 && !TARGET_CMOVE"
10569 (define_insn "*jcc<mode>_i387"
10571 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
10572 [(match_operand:MODEF 1 "register_operand" "f")
10573 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
10574 (label_ref (match_operand 3))
10576 (clobber (reg:CCFP FPSR_REG))
10577 (clobber (reg:CCFP FLAGS_REG))
10578 (clobber (match_scratch:HI 4 "=a"))]
10579 "TARGET_80387 && !TARGET_CMOVE"
10582 (define_insn "*jcc<mode>_r_i387"
10584 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
10585 [(match_operand:MODEF 1 "register_operand" "f")
10586 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
10588 (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 "*jccu<mode>_i387"
10597 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
10598 [(match_operand:X87MODEF 1 "register_operand" "f")
10599 (match_operand:X87MODEF 2 "register_operand" "f")])
10600 (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 "*jccu<mode>_r_i387"
10610 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
10611 [(match_operand:X87MODEF 1 "register_operand" "f")
10612 (match_operand:X87MODEF 2 "register_operand" "f")])
10614 (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"
10623 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10624 [(match_operand:X87MODEF 1 "register_operand")
10625 (match_operand:X87MODEF 2 "nonimmediate_operand")])
10627 (match_operand 4)))
10628 (clobber (reg:CCFP FPSR_REG))
10629 (clobber (reg:CCFP FLAGS_REG))]
10630 "TARGET_80387 && !TARGET_CMOVE
10631 && reload_completed"
10634 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10635 operands[3], operands[4], NULL_RTX, NULL_RTX);
10641 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10642 [(match_operand:X87MODEF 1 "register_operand")
10643 (match_operand:X87MODEF 2 "general_operand")])
10645 (match_operand 4)))
10646 (clobber (reg:CCFP FPSR_REG))
10647 (clobber (reg:CCFP FLAGS_REG))
10648 (clobber (match_scratch:HI 5))]
10649 "TARGET_80387 && !TARGET_CMOVE
10650 && reload_completed"
10653 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10654 operands[3], operands[4], operands[5], NULL_RTX);
10658 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
10659 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
10660 ;; with a precedence over other operators and is always put in the first
10661 ;; place. Swap condition and operands to match ficom instruction.
10663 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
10666 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
10667 [(match_operator:X87MODEF 1 "float_operator"
10668 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
10669 (match_operand:X87MODEF 3 "register_operand" "f,f")])
10670 (label_ref (match_operand 4))
10672 (clobber (reg:CCFP FPSR_REG))
10673 (clobber (reg:CCFP FLAGS_REG))
10674 (clobber (match_scratch:HI 5 "=a,a"))]
10675 "TARGET_80387 && !TARGET_CMOVE
10676 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
10677 || optimize_function_for_size_p (cfun))"
10680 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
10683 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
10684 [(match_operator:X87MODEF 1 "float_operator"
10685 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
10686 (match_operand:X87MODEF 3 "register_operand" "f,f")])
10688 (label_ref (match_operand 4))))
10689 (clobber (reg:CCFP FPSR_REG))
10690 (clobber (reg:CCFP FLAGS_REG))
10691 (clobber (match_scratch:HI 5 "=a,a"))]
10692 "TARGET_80387 && !TARGET_CMOVE
10693 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
10694 || optimize_function_for_size_p (cfun))"
10700 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
10701 [(match_operator:X87MODEF 1 "float_operator"
10702 [(match_operand:SWI24 2 "memory_operand")])
10703 (match_operand:X87MODEF 3 "register_operand")])
10705 (match_operand 5)))
10706 (clobber (reg:CCFP FPSR_REG))
10707 (clobber (reg:CCFP FLAGS_REG))
10708 (clobber (match_scratch:HI 6))]
10709 "TARGET_80387 && !TARGET_CMOVE
10710 && reload_completed"
10713 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
10714 gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
10715 operands[4], operands[5], operands[6], NULL_RTX);
10719 ;; %%% Kill this when reload knows how to do it.
10723 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
10724 [(match_operator:X87MODEF 1 "float_operator"
10725 [(match_operand:SWI24 2 "register_operand")])
10726 (match_operand:X87MODEF 3 "register_operand")])
10728 (match_operand 5)))
10729 (clobber (reg:CCFP FPSR_REG))
10730 (clobber (reg:CCFP FLAGS_REG))
10731 (clobber (match_scratch:HI 6))]
10732 "TARGET_80387 && !TARGET_CMOVE
10733 && reload_completed"
10736 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
10738 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
10739 gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]),
10740 operands[4], operands[5], operands[6], operands[2]);
10744 ;; Unconditional and other jump instructions
10746 (define_insn "jump"
10748 (label_ref (match_operand 0)))]
10751 [(set_attr "type" "ibr")
10752 (set (attr "length")
10753 (if_then_else (and (ge (minus (match_dup 0) (pc))
10755 (lt (minus (match_dup 0) (pc))
10759 (set_attr "modrm" "0")])
10761 (define_expand "indirect_jump"
10762 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
10766 operands[0] = convert_memory_address (word_mode, operands[0]);
10769 (define_insn "*indirect_jump"
10770 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))]
10773 [(set_attr "type" "ibr")
10774 (set_attr "length_immediate" "0")])
10776 (define_expand "tablejump"
10777 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
10778 (use (label_ref (match_operand 1)))])]
10781 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
10782 relative. Convert the relative address to an absolute address. */
10786 enum rtx_code code;
10788 /* We can't use @GOTOFF for text labels on VxWorks;
10789 see gotoff_operand. */
10790 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
10794 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
10796 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
10800 op1 = pic_offset_table_rtx;
10805 op0 = pic_offset_table_rtx;
10809 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
10814 operands[0] = convert_memory_address (word_mode, operands[0]);
10817 (define_insn "*tablejump_1"
10818 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))
10819 (use (label_ref (match_operand 1)))]
10822 [(set_attr "type" "ibr")
10823 (set_attr "length_immediate" "0")])
10825 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
10828 [(set (reg FLAGS_REG) (match_operand 0))
10829 (set (match_operand:QI 1 "register_operand")
10830 (match_operator:QI 2 "ix86_comparison_operator"
10831 [(reg FLAGS_REG) (const_int 0)]))
10832 (set (match_operand 3 "q_regs_operand")
10833 (zero_extend (match_dup 1)))]
10834 "(peep2_reg_dead_p (3, operands[1])
10835 || operands_match_p (operands[1], operands[3]))
10836 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
10837 [(set (match_dup 4) (match_dup 0))
10838 (set (strict_low_part (match_dup 5))
10841 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
10842 operands[5] = gen_lowpart (QImode, operands[3]);
10843 ix86_expand_clear (operands[3]);
10847 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
10848 (match_operand 4)])
10849 (set (match_operand:QI 1 "register_operand")
10850 (match_operator:QI 2 "ix86_comparison_operator"
10851 [(reg FLAGS_REG) (const_int 0)]))
10852 (set (match_operand 3 "q_regs_operand")
10853 (zero_extend (match_dup 1)))]
10854 "(peep2_reg_dead_p (3, operands[1])
10855 || operands_match_p (operands[1], operands[3]))
10856 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
10857 [(parallel [(set (match_dup 5) (match_dup 0))
10859 (set (strict_low_part (match_dup 6))
10862 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
10863 operands[6] = gen_lowpart (QImode, operands[3]);
10864 ix86_expand_clear (operands[3]);
10867 ;; Similar, but match zero extend with andsi3.
10870 [(set (reg FLAGS_REG) (match_operand 0))
10871 (set (match_operand:QI 1 "register_operand")
10872 (match_operator:QI 2 "ix86_comparison_operator"
10873 [(reg FLAGS_REG) (const_int 0)]))
10874 (parallel [(set (match_operand:SI 3 "q_regs_operand")
10875 (and:SI (match_dup 3) (const_int 255)))
10876 (clobber (reg:CC FLAGS_REG))])]
10877 "REGNO (operands[1]) == REGNO (operands[3])
10878 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
10879 [(set (match_dup 4) (match_dup 0))
10880 (set (strict_low_part (match_dup 5))
10883 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
10884 operands[5] = gen_lowpart (QImode, operands[3]);
10885 ix86_expand_clear (operands[3]);
10889 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
10890 (match_operand 4)])
10891 (set (match_operand:QI 1 "register_operand")
10892 (match_operator:QI 2 "ix86_comparison_operator"
10893 [(reg FLAGS_REG) (const_int 0)]))
10894 (parallel [(set (match_operand 3 "q_regs_operand")
10895 (zero_extend (match_dup 1)))
10896 (clobber (reg:CC FLAGS_REG))])]
10897 "(peep2_reg_dead_p (3, operands[1])
10898 || operands_match_p (operands[1], operands[3]))
10899 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
10900 [(parallel [(set (match_dup 5) (match_dup 0))
10902 (set (strict_low_part (match_dup 6))
10905 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
10906 operands[6] = gen_lowpart (QImode, operands[3]);
10907 ix86_expand_clear (operands[3]);
10910 ;; Call instructions.
10912 ;; The predicates normally associated with named expanders are not properly
10913 ;; checked for calls. This is a bug in the generic code, but it isn't that
10914 ;; easy to fix. Ignore it for now and be prepared to fix things up.
10916 ;; P6 processors will jump to the address after the decrement when %esp
10917 ;; is used as a call operand, so they will execute return address as a code.
10918 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
10920 ;; Register constraint for call instruction.
10921 (define_mode_attr c [(SI "l") (DI "r")])
10923 ;; Call subroutine returning no value.
10925 (define_expand "call"
10926 [(call (match_operand:QI 0)
10928 (use (match_operand 2))]
10931 ix86_expand_call (NULL, operands[0], operands[1],
10932 operands[2], NULL, false);
10936 (define_expand "sibcall"
10937 [(call (match_operand:QI 0)
10939 (use (match_operand 2))]
10942 ix86_expand_call (NULL, operands[0], operands[1],
10943 operands[2], NULL, true);
10947 (define_insn "*call"
10948 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
10949 (match_operand 1))]
10950 "!SIBLING_CALL_P (insn)"
10951 "* return ix86_output_call_insn (insn, operands[0]);"
10952 [(set_attr "type" "call")])
10954 (define_insn "*call_rex64_ms_sysv"
10955 [(match_parallel 2 "call_rex64_ms_sysv_operation"
10956 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
10958 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)])]
10959 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
10960 "* return ix86_output_call_insn (insn, operands[0]);"
10961 [(set_attr "type" "call")])
10963 (define_insn "*sibcall"
10964 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
10965 (match_operand 1))]
10966 "SIBLING_CALL_P (insn)"
10967 "* return ix86_output_call_insn (insn, operands[0]);"
10968 [(set_attr "type" "call")])
10970 (define_expand "call_pop"
10971 [(parallel [(call (match_operand:QI 0)
10972 (match_operand:SI 1))
10973 (set (reg:SI SP_REG)
10974 (plus:SI (reg:SI SP_REG)
10975 (match_operand:SI 3)))])]
10978 ix86_expand_call (NULL, operands[0], operands[1],
10979 operands[2], operands[3], false);
10983 (define_insn "*call_pop"
10984 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
10986 (set (reg:SI SP_REG)
10987 (plus:SI (reg:SI SP_REG)
10988 (match_operand:SI 2 "immediate_operand" "i")))]
10989 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
10990 "* return ix86_output_call_insn (insn, operands[0]);"
10991 [(set_attr "type" "call")])
10993 (define_insn "*sibcall_pop"
10994 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
10996 (set (reg:SI SP_REG)
10997 (plus:SI (reg:SI SP_REG)
10998 (match_operand:SI 2 "immediate_operand" "i")))]
10999 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11000 "* return ix86_output_call_insn (insn, operands[0]);"
11001 [(set_attr "type" "call")])
11003 ;; Call subroutine, returning value in operand 0
11005 (define_expand "call_value"
11006 [(set (match_operand 0)
11007 (call (match_operand:QI 1)
11008 (match_operand 2)))
11009 (use (match_operand 3))]
11012 ix86_expand_call (operands[0], operands[1], operands[2],
11013 operands[3], NULL, false);
11017 (define_expand "sibcall_value"
11018 [(set (match_operand 0)
11019 (call (match_operand:QI 1)
11020 (match_operand 2)))
11021 (use (match_operand 3))]
11024 ix86_expand_call (operands[0], operands[1], operands[2],
11025 operands[3], NULL, true);
11029 (define_insn "*call_value"
11030 [(set (match_operand 0)
11031 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11032 (match_operand 2)))]
11033 "!SIBLING_CALL_P (insn)"
11034 "* return ix86_output_call_insn (insn, operands[1]);"
11035 [(set_attr "type" "callv")])
11037 (define_insn "*sibcall_value"
11038 [(set (match_operand 0)
11039 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11040 (match_operand 2)))]
11041 "SIBLING_CALL_P (insn)"
11042 "* return ix86_output_call_insn (insn, operands[1]);"
11043 [(set_attr "type" "callv")])
11045 (define_insn "*call_value_rex64_ms_sysv"
11046 [(match_parallel 3 "call_rex64_ms_sysv_operation"
11047 [(set (match_operand 0)
11048 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11049 (match_operand 2)))
11050 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)])]
11051 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11052 "* return ix86_output_call_insn (insn, operands[1]);"
11053 [(set_attr "type" "callv")])
11055 (define_expand "call_value_pop"
11056 [(parallel [(set (match_operand 0)
11057 (call (match_operand:QI 1)
11058 (match_operand:SI 2)))
11059 (set (reg:SI SP_REG)
11060 (plus:SI (reg:SI SP_REG)
11061 (match_operand:SI 4)))])]
11064 ix86_expand_call (operands[0], operands[1], operands[2],
11065 operands[3], operands[4], false);
11069 (define_insn "*call_value_pop"
11070 [(set (match_operand 0)
11071 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11072 (match_operand 2)))
11073 (set (reg:SI SP_REG)
11074 (plus:SI (reg:SI SP_REG)
11075 (match_operand:SI 3 "immediate_operand" "i")))]
11076 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11077 "* return ix86_output_call_insn (insn, operands[1]);"
11078 [(set_attr "type" "callv")])
11080 (define_insn "*sibcall_value_pop"
11081 [(set (match_operand 0)
11082 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11083 (match_operand 2)))
11084 (set (reg:SI SP_REG)
11085 (plus:SI (reg:SI SP_REG)
11086 (match_operand:SI 3 "immediate_operand" "i")))]
11087 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11088 "* return ix86_output_call_insn (insn, operands[1]);"
11089 [(set_attr "type" "callv")])
11091 ;; Call subroutine returning any type.
11093 (define_expand "untyped_call"
11094 [(parallel [(call (match_operand 0)
11097 (match_operand 2)])]
11102 /* In order to give reg-stack an easier job in validating two
11103 coprocessor registers as containing a possible return value,
11104 simply pretend the untyped call returns a complex long double
11107 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11108 and should have the default ABI. */
11110 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11111 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11112 operands[0], const0_rtx,
11113 GEN_INT ((TARGET_64BIT
11114 ? (ix86_abi == SYSV_ABI
11115 ? X86_64_SSE_REGPARM_MAX
11116 : X86_64_MS_SSE_REGPARM_MAX)
11117 : X86_32_SSE_REGPARM_MAX)
11121 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11123 rtx set = XVECEXP (operands[2], 0, i);
11124 emit_move_insn (SET_DEST (set), SET_SRC (set));
11127 /* The optimizer does not know that the call sets the function value
11128 registers we stored in the result block. We avoid problems by
11129 claiming that all hard registers are used and clobbered at this
11131 emit_insn (gen_blockage ());
11136 ;; Prologue and epilogue instructions
11138 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11139 ;; all of memory. This blocks insns from being moved across this point.
11141 (define_insn "blockage"
11142 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11145 [(set_attr "length" "0")])
11147 ;; Do not schedule instructions accessing memory across this point.
11149 (define_expand "memory_blockage"
11150 [(set (match_dup 0)
11151 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11154 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11155 MEM_VOLATILE_P (operands[0]) = 1;
11158 (define_insn "*memory_blockage"
11159 [(set (match_operand:BLK 0)
11160 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11163 [(set_attr "length" "0")])
11165 ;; As USE insns aren't meaningful after reload, this is used instead
11166 ;; to prevent deleting instructions setting registers for PIC code
11167 (define_insn "prologue_use"
11168 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
11171 [(set_attr "length" "0")])
11173 ;; Insn emitted into the body of a function to return from a function.
11174 ;; This is only done if the function's epilogue is known to be simple.
11175 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11177 (define_expand "return"
11179 "ix86_can_use_return_insn_p ()"
11181 if (crtl->args.pops_args)
11183 rtx popc = GEN_INT (crtl->args.pops_args);
11184 emit_jump_insn (gen_simple_return_pop_internal (popc));
11189 ;; We need to disable this for TARGET_SEH, as otherwise
11190 ;; shrink-wrapped prologue gets enabled too. This might exceed
11191 ;; the maximum size of prologue in unwind information.
11193 (define_expand "simple_return"
11197 if (crtl->args.pops_args)
11199 rtx popc = GEN_INT (crtl->args.pops_args);
11200 emit_jump_insn (gen_simple_return_pop_internal (popc));
11205 (define_insn "simple_return_internal"
11209 [(set_attr "length" "1")
11210 (set_attr "atom_unit" "jeu")
11211 (set_attr "length_immediate" "0")
11212 (set_attr "modrm" "0")])
11214 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11215 ;; instruction Athlon and K8 have.
11217 (define_insn "simple_return_internal_long"
11219 (unspec [(const_int 0)] UNSPEC_REP)]
11222 [(set_attr "length" "2")
11223 (set_attr "atom_unit" "jeu")
11224 (set_attr "length_immediate" "0")
11225 (set_attr "prefix_rep" "1")
11226 (set_attr "modrm" "0")])
11228 (define_insn "simple_return_pop_internal"
11230 (use (match_operand:SI 0 "const_int_operand"))]
11233 [(set_attr "length" "3")
11234 (set_attr "atom_unit" "jeu")
11235 (set_attr "length_immediate" "2")
11236 (set_attr "modrm" "0")])
11238 (define_insn "simple_return_indirect_internal"
11240 (use (match_operand:SI 0 "register_operand" "r"))]
11243 [(set_attr "type" "ibr")
11244 (set_attr "length_immediate" "0")])
11250 [(set_attr "length" "1")
11251 (set_attr "length_immediate" "0")
11252 (set_attr "modrm" "0")])
11254 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11255 (define_insn "nops"
11256 [(unspec_volatile [(match_operand 0 "const_int_operand")]
11260 int num = INTVAL (operands[0]);
11262 gcc_assert (IN_RANGE (num, 1, 8));
11265 fputs ("\tnop\n", asm_out_file);
11269 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11270 (set_attr "length_immediate" "0")
11271 (set_attr "modrm" "0")])
11273 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11274 ;; branch prediction penalty for the third jump in a 16-byte
11278 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
11281 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11282 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11284 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11285 The align insn is used to avoid 3 jump instructions in the row to improve
11286 branch prediction and the benefits hardly outweigh the cost of extra 8
11287 nops on the average inserted by full alignment pseudo operation. */
11291 [(set_attr "length" "16")])
11293 (define_expand "prologue"
11296 "ix86_expand_prologue (); DONE;")
11298 (define_insn "set_got"
11299 [(set (match_operand:SI 0 "register_operand" "=r")
11300 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11301 (clobber (reg:CC FLAGS_REG))]
11303 "* return output_set_got (operands[0], NULL_RTX);"
11304 [(set_attr "type" "multi")
11305 (set_attr "length" "12")])
11307 (define_insn "set_got_labelled"
11308 [(set (match_operand:SI 0 "register_operand" "=r")
11309 (unspec:SI [(label_ref (match_operand 1))]
11311 (clobber (reg:CC FLAGS_REG))]
11313 "* return output_set_got (operands[0], operands[1]);"
11314 [(set_attr "type" "multi")
11315 (set_attr "length" "12")])
11317 (define_insn "set_got_rex64"
11318 [(set (match_operand:DI 0 "register_operand" "=r")
11319 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11321 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11322 [(set_attr "type" "lea")
11323 (set_attr "length_address" "4")
11324 (set_attr "mode" "DI")])
11326 (define_insn "set_rip_rex64"
11327 [(set (match_operand:DI 0 "register_operand" "=r")
11328 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
11330 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11331 [(set_attr "type" "lea")
11332 (set_attr "length_address" "4")
11333 (set_attr "mode" "DI")])
11335 (define_insn "set_got_offset_rex64"
11336 [(set (match_operand:DI 0 "register_operand" "=r")
11338 [(label_ref (match_operand 1))]
11339 UNSPEC_SET_GOT_OFFSET))]
11341 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11342 [(set_attr "type" "imov")
11343 (set_attr "length_immediate" "0")
11344 (set_attr "length_address" "8")
11345 (set_attr "mode" "DI")])
11347 (define_expand "epilogue"
11350 "ix86_expand_epilogue (1); DONE;")
11352 (define_expand "sibcall_epilogue"
11355 "ix86_expand_epilogue (0); DONE;")
11357 (define_expand "eh_return"
11358 [(use (match_operand 0 "register_operand"))]
11361 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11363 /* Tricky bit: we write the address of the handler to which we will
11364 be returning into someone else's stack frame, one word below the
11365 stack address we wish to restore. */
11366 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11367 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
11368 tmp = gen_rtx_MEM (Pmode, tmp);
11369 emit_move_insn (tmp, ra);
11371 emit_jump_insn (gen_eh_return_internal ());
11376 (define_insn_and_split "eh_return_internal"
11380 "epilogue_completed"
11382 "ix86_expand_epilogue (2); DONE;")
11384 (define_insn "leave"
11385 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11386 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11387 (clobber (mem:BLK (scratch)))]
11390 [(set_attr "type" "leave")])
11392 (define_insn "leave_rex64"
11393 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11394 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11395 (clobber (mem:BLK (scratch)))]
11398 [(set_attr "type" "leave")])
11400 ;; Handle -fsplit-stack.
11402 (define_expand "split_stack_prologue"
11406 ix86_expand_split_stack_prologue ();
11410 ;; In order to support the call/return predictor, we use a return
11411 ;; instruction which the middle-end doesn't see.
11412 (define_insn "split_stack_return"
11413 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
11414 UNSPECV_SPLIT_STACK_RETURN)]
11417 if (operands[0] == const0_rtx)
11422 [(set_attr "atom_unit" "jeu")
11423 (set_attr "modrm" "0")
11424 (set (attr "length")
11425 (if_then_else (match_operand:SI 0 "const0_operand")
11428 (set (attr "length_immediate")
11429 (if_then_else (match_operand:SI 0 "const0_operand")
11433 ;; If there are operand 0 bytes available on the stack, jump to
11436 (define_expand "split_stack_space_check"
11437 [(set (pc) (if_then_else
11438 (ltu (minus (reg SP_REG)
11439 (match_operand 0 "register_operand"))
11440 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11441 (label_ref (match_operand 1))
11445 rtx reg, size, limit;
11447 reg = gen_reg_rtx (Pmode);
11448 size = force_reg (Pmode, operands[0]);
11449 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11450 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11451 UNSPEC_STACK_CHECK);
11452 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11453 ix86_expand_branch (GEU, reg, limit, operands[1]);
11458 ;; Bit manipulation instructions.
11460 (define_expand "ffs<mode>2"
11461 [(set (match_dup 2) (const_int -1))
11462 (parallel [(set (match_dup 3) (match_dup 4))
11463 (set (match_operand:SWI48 0 "register_operand")
11465 (match_operand:SWI48 1 "nonimmediate_operand")))])
11466 (set (match_dup 0) (if_then_else:SWI48
11467 (eq (match_dup 3) (const_int 0))
11470 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11471 (clobber (reg:CC FLAGS_REG))])]
11474 enum machine_mode flags_mode;
11476 if (<MODE>mode == SImode && !TARGET_CMOVE)
11478 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11482 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
11484 operands[2] = gen_reg_rtx (<MODE>mode);
11485 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
11486 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
11489 (define_insn_and_split "ffssi2_no_cmove"
11490 [(set (match_operand:SI 0 "register_operand" "=r")
11491 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11492 (clobber (match_scratch:SI 2 "=&q"))
11493 (clobber (reg:CC FLAGS_REG))]
11496 "&& reload_completed"
11497 [(parallel [(set (match_dup 4) (match_dup 5))
11498 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11499 (set (strict_low_part (match_dup 3))
11500 (eq:QI (match_dup 4) (const_int 0)))
11501 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11502 (clobber (reg:CC FLAGS_REG))])
11503 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11504 (clobber (reg:CC FLAGS_REG))])
11505 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11506 (clobber (reg:CC FLAGS_REG))])]
11508 enum machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
11510 operands[3] = gen_lowpart (QImode, operands[2]);
11511 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
11512 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
11514 ix86_expand_clear (operands[2]);
11517 (define_insn "*tzcnt<mode>_1"
11518 [(set (reg:CCC FLAGS_REG)
11519 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11521 (set (match_operand:SWI48 0 "register_operand" "=r")
11522 (ctz:SWI48 (match_dup 1)))]
11524 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11525 [(set_attr "type" "alu1")
11526 (set_attr "prefix_0f" "1")
11527 (set_attr "prefix_rep" "1")
11528 (set_attr "btver2_decode" "double")
11529 (set_attr "mode" "<MODE>")])
11531 (define_insn "*bsf<mode>_1"
11532 [(set (reg:CCZ FLAGS_REG)
11533 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11535 (set (match_operand:SWI48 0 "register_operand" "=r")
11536 (ctz:SWI48 (match_dup 1)))]
11538 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11539 [(set_attr "type" "alu1")
11540 (set_attr "prefix_0f" "1")
11541 (set_attr "btver2_decode" "double")
11542 (set_attr "mode" "<MODE>")])
11544 (define_insn "ctz<mode>2"
11545 [(set (match_operand:SWI248 0 "register_operand" "=r")
11546 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11547 (clobber (reg:CC FLAGS_REG))]
11551 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11552 else if (optimize_function_for_size_p (cfun))
11554 else if (TARGET_GENERIC)
11555 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
11556 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
11558 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
11560 [(set_attr "type" "alu1")
11561 (set_attr "prefix_0f" "1")
11562 (set (attr "prefix_rep")
11564 (ior (match_test "TARGET_BMI")
11565 (and (not (match_test "optimize_function_for_size_p (cfun)"))
11566 (match_test "TARGET_GENERIC")))
11568 (const_string "0")))
11569 (set_attr "mode" "<MODE>")])
11571 (define_expand "clz<mode>2"
11573 [(set (match_operand:SWI248 0 "register_operand")
11576 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
11577 (clobber (reg:CC FLAGS_REG))])
11579 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
11580 (clobber (reg:CC FLAGS_REG))])]
11585 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
11588 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11591 (define_insn "clz<mode>2_lzcnt"
11592 [(set (match_operand:SWI248 0 "register_operand" "=r")
11593 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11594 (clobber (reg:CC FLAGS_REG))]
11596 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11597 [(set_attr "prefix_rep" "1")
11598 (set_attr "type" "bitmanip")
11599 (set_attr "mode" "<MODE>")])
11601 ;; BMI instructions.
11602 (define_insn "*bmi_andn_<mode>"
11603 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
11606 (match_operand:SWI48 1 "register_operand" "r,r"))
11607 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
11608 (clobber (reg:CC FLAGS_REG))]
11610 "andn\t{%2, %1, %0|%0, %1, %2}"
11611 [(set_attr "type" "bitmanip")
11612 (set_attr "btver2_decode" "direct, double")
11613 (set_attr "mode" "<MODE>")])
11615 (define_insn "bmi_bextr_<mode>"
11616 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
11617 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r,r")
11618 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")]
11620 (clobber (reg:CC FLAGS_REG))]
11622 "bextr\t{%2, %1, %0|%0, %1, %2}"
11623 [(set_attr "type" "bitmanip")
11624 (set_attr "btver2_decode" "direct, double")
11625 (set_attr "mode" "<MODE>")])
11627 (define_insn "*bmi_blsi_<mode>"
11628 [(set (match_operand:SWI48 0 "register_operand" "=r")
11631 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
11633 (clobber (reg:CC FLAGS_REG))]
11635 "blsi\t{%1, %0|%0, %1}"
11636 [(set_attr "type" "bitmanip")
11637 (set_attr "btver2_decode" "double")
11638 (set_attr "mode" "<MODE>")])
11640 (define_insn "*bmi_blsmsk_<mode>"
11641 [(set (match_operand:SWI48 0 "register_operand" "=r")
11644 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11647 (clobber (reg:CC FLAGS_REG))]
11649 "blsmsk\t{%1, %0|%0, %1}"
11650 [(set_attr "type" "bitmanip")
11651 (set_attr "btver2_decode" "double")
11652 (set_attr "mode" "<MODE>")])
11654 (define_insn "*bmi_blsr_<mode>"
11655 [(set (match_operand:SWI48 0 "register_operand" "=r")
11658 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11661 (clobber (reg:CC FLAGS_REG))]
11663 "blsr\t{%1, %0|%0, %1}"
11664 [(set_attr "type" "bitmanip")
11665 (set_attr "btver2_decode" "double")
11666 (set_attr "mode" "<MODE>")])
11668 ;; BMI2 instructions.
11669 (define_insn "bmi2_bzhi_<mode>3"
11670 [(set (match_operand:SWI48 0 "register_operand" "=r")
11671 (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
11672 (lshiftrt:SWI48 (const_int -1)
11673 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
11674 (clobber (reg:CC FLAGS_REG))]
11676 "bzhi\t{%2, %1, %0|%0, %1, %2}"
11677 [(set_attr "type" "bitmanip")
11678 (set_attr "prefix" "vex")
11679 (set_attr "mode" "<MODE>")])
11681 (define_insn "bmi2_pdep_<mode>3"
11682 [(set (match_operand:SWI48 0 "register_operand" "=r")
11683 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
11684 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
11687 "pdep\t{%2, %1, %0|%0, %1, %2}"
11688 [(set_attr "type" "bitmanip")
11689 (set_attr "prefix" "vex")
11690 (set_attr "mode" "<MODE>")])
11692 (define_insn "bmi2_pext_<mode>3"
11693 [(set (match_operand:SWI48 0 "register_operand" "=r")
11694 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
11695 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
11698 "pext\t{%2, %1, %0|%0, %1, %2}"
11699 [(set_attr "type" "bitmanip")
11700 (set_attr "prefix" "vex")
11701 (set_attr "mode" "<MODE>")])
11703 ;; TBM instructions.
11704 (define_insn "tbm_bextri_<mode>"
11705 [(set (match_operand:SWI48 0 "register_operand" "=r")
11706 (zero_extract:SWI48
11707 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11708 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
11709 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
11710 (clobber (reg:CC FLAGS_REG))]
11713 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
11714 return "bextr\t{%2, %1, %0|%0, %1, %2}";
11716 [(set_attr "type" "bitmanip")
11717 (set_attr "mode" "<MODE>")])
11719 (define_insn "*tbm_blcfill_<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 "blcfill\t{%1, %0|%0, %1}"
11729 [(set_attr "type" "bitmanip")
11730 (set_attr "mode" "<MODE>")])
11732 (define_insn "*tbm_blci_<mode>"
11733 [(set (match_operand:SWI48 0 "register_operand" "=r")
11737 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11740 (clobber (reg:CC FLAGS_REG))]
11742 "blci\t{%1, %0|%0, %1}"
11743 [(set_attr "type" "bitmanip")
11744 (set_attr "mode" "<MODE>")])
11746 (define_insn "*tbm_blcic_<mode>"
11747 [(set (match_operand:SWI48 0 "register_operand" "=r")
11750 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11754 (clobber (reg:CC FLAGS_REG))]
11756 "blcic\t{%1, %0|%0, %1}"
11757 [(set_attr "type" "bitmanip")
11758 (set_attr "mode" "<MODE>")])
11760 (define_insn "*tbm_blcmsk_<mode>"
11761 [(set (match_operand:SWI48 0 "register_operand" "=r")
11764 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11767 (clobber (reg:CC FLAGS_REG))]
11769 "blcmsk\t{%1, %0|%0, %1}"
11770 [(set_attr "type" "bitmanip")
11771 (set_attr "mode" "<MODE>")])
11773 (define_insn "*tbm_blcs_<mode>"
11774 [(set (match_operand:SWI48 0 "register_operand" "=r")
11777 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11780 (clobber (reg:CC FLAGS_REG))]
11782 "blcs\t{%1, %0|%0, %1}"
11783 [(set_attr "type" "bitmanip")
11784 (set_attr "mode" "<MODE>")])
11786 (define_insn "*tbm_blsfill_<mode>"
11787 [(set (match_operand:SWI48 0 "register_operand" "=r")
11790 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11793 (clobber (reg:CC FLAGS_REG))]
11795 "blsfill\t{%1, %0|%0, %1}"
11796 [(set_attr "type" "bitmanip")
11797 (set_attr "mode" "<MODE>")])
11799 (define_insn "*tbm_blsic_<mode>"
11800 [(set (match_operand:SWI48 0 "register_operand" "=r")
11803 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11807 (clobber (reg:CC FLAGS_REG))]
11809 "blsic\t{%1, %0|%0, %1}"
11810 [(set_attr "type" "bitmanip")
11811 (set_attr "mode" "<MODE>")])
11813 (define_insn "*tbm_t1mskc_<mode>"
11814 [(set (match_operand:SWI48 0 "register_operand" "=r")
11817 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11821 (clobber (reg:CC FLAGS_REG))]
11823 "t1mskc\t{%1, %0|%0, %1}"
11824 [(set_attr "type" "bitmanip")
11825 (set_attr "mode" "<MODE>")])
11827 (define_insn "*tbm_tzmsk_<mode>"
11828 [(set (match_operand:SWI48 0 "register_operand" "=r")
11831 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11835 (clobber (reg:CC FLAGS_REG))]
11837 "tzmsk\t{%1, %0|%0, %1}"
11838 [(set_attr "type" "bitmanip")
11839 (set_attr "mode" "<MODE>")])
11841 (define_insn "bsr_rex64"
11842 [(set (match_operand:DI 0 "register_operand" "=r")
11843 (minus:DI (const_int 63)
11844 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
11845 (clobber (reg:CC FLAGS_REG))]
11847 "bsr{q}\t{%1, %0|%0, %1}"
11848 [(set_attr "type" "alu1")
11849 (set_attr "prefix_0f" "1")
11850 (set_attr "mode" "DI")])
11853 [(set (match_operand:SI 0 "register_operand" "=r")
11854 (minus:SI (const_int 31)
11855 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
11856 (clobber (reg:CC FLAGS_REG))]
11858 "bsr{l}\t{%1, %0|%0, %1}"
11859 [(set_attr "type" "alu1")
11860 (set_attr "prefix_0f" "1")
11861 (set_attr "mode" "SI")])
11863 (define_insn "*bsrhi"
11864 [(set (match_operand:HI 0 "register_operand" "=r")
11865 (minus:HI (const_int 15)
11866 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
11867 (clobber (reg:CC FLAGS_REG))]
11869 "bsr{w}\t{%1, %0|%0, %1}"
11870 [(set_attr "type" "alu1")
11871 (set_attr "prefix_0f" "1")
11872 (set_attr "mode" "HI")])
11874 (define_insn "popcount<mode>2"
11875 [(set (match_operand:SWI248 0 "register_operand" "=r")
11877 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11878 (clobber (reg:CC FLAGS_REG))]
11882 return "popcnt\t{%1, %0|%0, %1}";
11884 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11887 [(set_attr "prefix_rep" "1")
11888 (set_attr "type" "bitmanip")
11889 (set_attr "mode" "<MODE>")])
11891 (define_insn "*popcount<mode>2_cmp"
11892 [(set (reg FLAGS_REG)
11895 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
11897 (set (match_operand:SWI248 0 "register_operand" "=r")
11898 (popcount:SWI248 (match_dup 1)))]
11899 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
11902 return "popcnt\t{%1, %0|%0, %1}";
11904 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11907 [(set_attr "prefix_rep" "1")
11908 (set_attr "type" "bitmanip")
11909 (set_attr "mode" "<MODE>")])
11911 (define_insn "*popcountsi2_cmp_zext"
11912 [(set (reg FLAGS_REG)
11914 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
11916 (set (match_operand:DI 0 "register_operand" "=r")
11917 (zero_extend:DI(popcount:SI (match_dup 1))))]
11918 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
11921 return "popcnt\t{%1, %0|%0, %1}";
11923 return "popcnt{l}\t{%1, %0|%0, %1}";
11926 [(set_attr "prefix_rep" "1")
11927 (set_attr "type" "bitmanip")
11928 (set_attr "mode" "SI")])
11930 (define_expand "bswapdi2"
11931 [(set (match_operand:DI 0 "register_operand")
11932 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
11936 operands[1] = force_reg (DImode, operands[1]);
11939 (define_expand "bswapsi2"
11940 [(set (match_operand:SI 0 "register_operand")
11941 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
11946 else if (TARGET_BSWAP)
11947 operands[1] = force_reg (SImode, operands[1]);
11950 rtx x = operands[0];
11952 emit_move_insn (x, operands[1]);
11953 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
11954 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
11955 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
11960 (define_insn "*bswap<mode>2_movbe"
11961 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
11962 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
11964 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11967 movbe\t{%1, %0|%0, %1}
11968 movbe\t{%1, %0|%0, %1}"
11969 [(set_attr "type" "bitmanip,imov,imov")
11970 (set_attr "modrm" "0,1,1")
11971 (set_attr "prefix_0f" "*,1,1")
11972 (set_attr "prefix_extra" "*,1,1")
11973 (set_attr "mode" "<MODE>")])
11975 (define_insn "*bswap<mode>2"
11976 [(set (match_operand:SWI48 0 "register_operand" "=r")
11977 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
11980 [(set_attr "type" "bitmanip")
11981 (set_attr "modrm" "0")
11982 (set_attr "mode" "<MODE>")])
11984 (define_insn "*bswaphi_lowpart_1"
11985 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
11986 (bswap:HI (match_dup 0)))
11987 (clobber (reg:CC FLAGS_REG))]
11988 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
11990 xchg{b}\t{%h0, %b0|%b0, %h0}
11991 rol{w}\t{$8, %0|%0, 8}"
11992 [(set_attr "length" "2,4")
11993 (set_attr "mode" "QI,HI")])
11995 (define_insn "bswaphi_lowpart"
11996 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
11997 (bswap:HI (match_dup 0)))
11998 (clobber (reg:CC FLAGS_REG))]
12000 "rol{w}\t{$8, %0|%0, 8}"
12001 [(set_attr "length" "4")
12002 (set_attr "mode" "HI")])
12004 (define_expand "paritydi2"
12005 [(set (match_operand:DI 0 "register_operand")
12006 (parity:DI (match_operand:DI 1 "register_operand")))]
12009 rtx scratch = gen_reg_rtx (QImode);
12012 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12013 NULL_RTX, operands[1]));
12015 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12016 gen_rtx_REG (CCmode, FLAGS_REG),
12018 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12021 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12024 rtx tmp = gen_reg_rtx (SImode);
12026 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12027 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12032 (define_expand "paritysi2"
12033 [(set (match_operand:SI 0 "register_operand")
12034 (parity:SI (match_operand:SI 1 "register_operand")))]
12037 rtx scratch = gen_reg_rtx (QImode);
12040 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12042 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12043 gen_rtx_REG (CCmode, FLAGS_REG),
12045 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12047 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12051 (define_insn_and_split "paritydi2_cmp"
12052 [(set (reg:CC FLAGS_REG)
12053 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12055 (clobber (match_scratch:DI 0 "=r"))
12056 (clobber (match_scratch:SI 1 "=&r"))
12057 (clobber (match_scratch:HI 2 "=Q"))]
12060 "&& reload_completed"
12062 [(set (match_dup 1)
12063 (xor:SI (match_dup 1) (match_dup 4)))
12064 (clobber (reg:CC FLAGS_REG))])
12066 [(set (reg:CC FLAGS_REG)
12067 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12068 (clobber (match_dup 1))
12069 (clobber (match_dup 2))])]
12071 operands[4] = gen_lowpart (SImode, operands[3]);
12075 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12076 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12079 operands[1] = gen_highpart (SImode, operands[3]);
12082 (define_insn_and_split "paritysi2_cmp"
12083 [(set (reg:CC FLAGS_REG)
12084 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12086 (clobber (match_scratch:SI 0 "=r"))
12087 (clobber (match_scratch:HI 1 "=&Q"))]
12090 "&& reload_completed"
12092 [(set (match_dup 1)
12093 (xor:HI (match_dup 1) (match_dup 3)))
12094 (clobber (reg:CC FLAGS_REG))])
12096 [(set (reg:CC FLAGS_REG)
12097 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12098 (clobber (match_dup 1))])]
12100 operands[3] = gen_lowpart (HImode, operands[2]);
12102 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12103 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12106 (define_insn "*parityhi2_cmp"
12107 [(set (reg:CC FLAGS_REG)
12108 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12110 (clobber (match_scratch:HI 0 "=Q"))]
12112 "xor{b}\t{%h0, %b0|%b0, %h0}"
12113 [(set_attr "length" "2")
12114 (set_attr "mode" "HI")])
12117 ;; Thread-local storage patterns for ELF.
12119 ;; Note that these code sequences must appear exactly as shown
12120 ;; in order to allow linker relaxation.
12122 (define_insn "*tls_global_dynamic_32_gnu"
12123 [(set (match_operand:SI 0 "register_operand" "=a")
12125 [(match_operand:SI 1 "register_operand" "b")
12126 (match_operand 2 "tls_symbolic_operand")
12127 (match_operand 3 "constant_call_address_operand" "z")]
12129 (clobber (match_scratch:SI 4 "=d"))
12130 (clobber (match_scratch:SI 5 "=c"))
12131 (clobber (reg:CC FLAGS_REG))]
12132 "!TARGET_64BIT && TARGET_GNU_TLS"
12135 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12136 if (TARGET_SUN_TLS)
12137 #ifdef HAVE_AS_IX86_TLSGDPLT
12138 return "call\t%a2@tlsgdplt";
12140 return "call\t%p3@plt";
12142 return "call\t%P3";
12144 [(set_attr "type" "multi")
12145 (set_attr "length" "12")])
12147 (define_expand "tls_global_dynamic_32"
12149 [(set (match_operand:SI 0 "register_operand")
12150 (unspec:SI [(match_operand:SI 2 "register_operand")
12151 (match_operand 1 "tls_symbolic_operand")
12152 (match_operand 3 "constant_call_address_operand")]
12154 (clobber (match_scratch:SI 4))
12155 (clobber (match_scratch:SI 5))
12156 (clobber (reg:CC FLAGS_REG))])])
12158 (define_insn "*tls_global_dynamic_64_<mode>"
12159 [(set (match_operand:P 0 "register_operand" "=a")
12161 (mem:QI (match_operand 2 "constant_call_address_operand" "z"))
12162 (match_operand 3)))
12163 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12168 fputs (ASM_BYTE "0x66\n", asm_out_file);
12170 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12171 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12172 fputs ("\trex64\n", asm_out_file);
12173 if (TARGET_SUN_TLS)
12174 return "call\t%p2@plt";
12175 return "call\t%P2";
12177 [(set_attr "type" "multi")
12178 (set (attr "length")
12179 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12181 (define_expand "tls_global_dynamic_64_<mode>"
12183 [(set (match_operand:P 0 "register_operand")
12185 (mem:QI (match_operand 2 "constant_call_address_operand"))
12187 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12191 (define_insn "*tls_local_dynamic_base_32_gnu"
12192 [(set (match_operand:SI 0 "register_operand" "=a")
12194 [(match_operand:SI 1 "register_operand" "b")
12195 (match_operand 2 "constant_call_address_operand" "z")]
12196 UNSPEC_TLS_LD_BASE))
12197 (clobber (match_scratch:SI 3 "=d"))
12198 (clobber (match_scratch:SI 4 "=c"))
12199 (clobber (reg:CC FLAGS_REG))]
12200 "!TARGET_64BIT && TARGET_GNU_TLS"
12203 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12204 if (TARGET_SUN_TLS)
12205 #ifdef HAVE_AS_IX86_TLSLDMPLT
12206 return "call\t%&@tlsldmplt";
12208 return "call\t%p2@plt";
12210 return "call\t%P2";
12212 [(set_attr "type" "multi")
12213 (set_attr "length" "11")])
12215 (define_expand "tls_local_dynamic_base_32"
12217 [(set (match_operand:SI 0 "register_operand")
12219 [(match_operand:SI 1 "register_operand")
12220 (match_operand 2 "constant_call_address_operand")]
12221 UNSPEC_TLS_LD_BASE))
12222 (clobber (match_scratch:SI 3))
12223 (clobber (match_scratch:SI 4))
12224 (clobber (reg:CC FLAGS_REG))])])
12226 (define_insn "*tls_local_dynamic_base_64_<mode>"
12227 [(set (match_operand:P 0 "register_operand" "=a")
12229 (mem:QI (match_operand 1 "constant_call_address_operand" "z"))
12230 (match_operand 2)))
12231 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12235 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12236 if (TARGET_SUN_TLS)
12237 return "call\t%p1@plt";
12238 return "call\t%P1";
12240 [(set_attr "type" "multi")
12241 (set_attr "length" "12")])
12243 (define_expand "tls_local_dynamic_base_64_<mode>"
12245 [(set (match_operand:P 0 "register_operand")
12247 (mem:QI (match_operand 1 "constant_call_address_operand"))
12249 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12252 ;; Local dynamic of a single variable is a lose. Show combine how
12253 ;; to convert that back to global dynamic.
12255 (define_insn_and_split "*tls_local_dynamic_32_once"
12256 [(set (match_operand:SI 0 "register_operand" "=a")
12258 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12259 (match_operand 2 "constant_call_address_operand" "z")]
12260 UNSPEC_TLS_LD_BASE)
12261 (const:SI (unspec:SI
12262 [(match_operand 3 "tls_symbolic_operand")]
12264 (clobber (match_scratch:SI 4 "=d"))
12265 (clobber (match_scratch:SI 5 "=c"))
12266 (clobber (reg:CC FLAGS_REG))]
12271 [(set (match_dup 0)
12272 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12274 (clobber (match_dup 4))
12275 (clobber (match_dup 5))
12276 (clobber (reg:CC FLAGS_REG))])])
12278 ;; Segment register for the thread base ptr load
12279 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12281 ;; Load and add the thread base pointer from %<tp_seg>:0.
12282 (define_insn "*load_tp_x32"
12283 [(set (match_operand:SI 0 "register_operand" "=r")
12284 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12286 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12287 [(set_attr "type" "imov")
12288 (set_attr "modrm" "0")
12289 (set_attr "length" "7")
12290 (set_attr "memory" "load")
12291 (set_attr "imm_disp" "false")])
12293 (define_insn "*load_tp_x32_zext"
12294 [(set (match_operand:DI 0 "register_operand" "=r")
12295 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12297 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12298 [(set_attr "type" "imov")
12299 (set_attr "modrm" "0")
12300 (set_attr "length" "7")
12301 (set_attr "memory" "load")
12302 (set_attr "imm_disp" "false")])
12304 (define_insn "*load_tp_<mode>"
12305 [(set (match_operand:P 0 "register_operand" "=r")
12306 (unspec:P [(const_int 0)] UNSPEC_TP))]
12308 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12309 [(set_attr "type" "imov")
12310 (set_attr "modrm" "0")
12311 (set_attr "length" "7")
12312 (set_attr "memory" "load")
12313 (set_attr "imm_disp" "false")])
12315 (define_insn "*add_tp_x32"
12316 [(set (match_operand:SI 0 "register_operand" "=r")
12317 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12318 (match_operand:SI 1 "register_operand" "0")))
12319 (clobber (reg:CC FLAGS_REG))]
12321 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12322 [(set_attr "type" "alu")
12323 (set_attr "modrm" "0")
12324 (set_attr "length" "7")
12325 (set_attr "memory" "load")
12326 (set_attr "imm_disp" "false")])
12328 (define_insn "*add_tp_x32_zext"
12329 [(set (match_operand:DI 0 "register_operand" "=r")
12331 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12332 (match_operand:SI 1 "register_operand" "0"))))
12333 (clobber (reg:CC FLAGS_REG))]
12335 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12336 [(set_attr "type" "alu")
12337 (set_attr "modrm" "0")
12338 (set_attr "length" "7")
12339 (set_attr "memory" "load")
12340 (set_attr "imm_disp" "false")])
12342 (define_insn "*add_tp_<mode>"
12343 [(set (match_operand:P 0 "register_operand" "=r")
12344 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12345 (match_operand:P 1 "register_operand" "0")))
12346 (clobber (reg:CC FLAGS_REG))]
12348 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12349 [(set_attr "type" "alu")
12350 (set_attr "modrm" "0")
12351 (set_attr "length" "7")
12352 (set_attr "memory" "load")
12353 (set_attr "imm_disp" "false")])
12355 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12356 ;; %rax as destination of the initial executable code sequence.
12357 (define_insn "tls_initial_exec_64_sun"
12358 [(set (match_operand:DI 0 "register_operand" "=a")
12360 [(match_operand 1 "tls_symbolic_operand")]
12361 UNSPEC_TLS_IE_SUN))
12362 (clobber (reg:CC FLAGS_REG))]
12363 "TARGET_64BIT && TARGET_SUN_TLS"
12366 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12367 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12369 [(set_attr "type" "multi")])
12371 ;; GNU2 TLS patterns can be split.
12373 (define_expand "tls_dynamic_gnu2_32"
12374 [(set (match_dup 3)
12375 (plus:SI (match_operand:SI 2 "register_operand")
12377 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
12380 [(set (match_operand:SI 0 "register_operand")
12381 (unspec:SI [(match_dup 1) (match_dup 3)
12382 (match_dup 2) (reg:SI SP_REG)]
12384 (clobber (reg:CC FLAGS_REG))])]
12385 "!TARGET_64BIT && TARGET_GNU2_TLS"
12387 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12388 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12391 (define_insn "*tls_dynamic_gnu2_lea_32"
12392 [(set (match_operand:SI 0 "register_operand" "=r")
12393 (plus:SI (match_operand:SI 1 "register_operand" "b")
12395 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
12396 UNSPEC_TLSDESC))))]
12397 "!TARGET_64BIT && TARGET_GNU2_TLS"
12398 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
12399 [(set_attr "type" "lea")
12400 (set_attr "mode" "SI")
12401 (set_attr "length" "6")
12402 (set_attr "length_address" "4")])
12404 (define_insn "*tls_dynamic_gnu2_call_32"
12405 [(set (match_operand:SI 0 "register_operand" "=a")
12406 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
12407 (match_operand:SI 2 "register_operand" "0")
12408 ;; we have to make sure %ebx still points to the GOT
12409 (match_operand:SI 3 "register_operand" "b")
12412 (clobber (reg:CC FLAGS_REG))]
12413 "!TARGET_64BIT && TARGET_GNU2_TLS"
12414 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12415 [(set_attr "type" "call")
12416 (set_attr "length" "2")
12417 (set_attr "length_address" "0")])
12419 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12420 [(set (match_operand:SI 0 "register_operand" "=&a")
12422 (unspec:SI [(match_operand 3 "tls_modbase_operand")
12423 (match_operand:SI 4)
12424 (match_operand:SI 2 "register_operand" "b")
12427 (const:SI (unspec:SI
12428 [(match_operand 1 "tls_symbolic_operand")]
12430 (clobber (reg:CC FLAGS_REG))]
12431 "!TARGET_64BIT && TARGET_GNU2_TLS"
12434 [(set (match_dup 0) (match_dup 5))]
12436 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12437 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12440 (define_expand "tls_dynamic_gnu2_64"
12441 [(set (match_dup 2)
12442 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
12445 [(set (match_operand:DI 0 "register_operand")
12446 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12448 (clobber (reg:CC FLAGS_REG))])]
12449 "TARGET_64BIT && TARGET_GNU2_TLS"
12451 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12452 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12455 (define_insn "*tls_dynamic_gnu2_lea_64"
12456 [(set (match_operand:DI 0 "register_operand" "=r")
12457 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
12459 "TARGET_64BIT && TARGET_GNU2_TLS"
12460 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
12461 [(set_attr "type" "lea")
12462 (set_attr "mode" "DI")
12463 (set_attr "length" "7")
12464 (set_attr "length_address" "4")])
12466 (define_insn "*tls_dynamic_gnu2_call_64"
12467 [(set (match_operand:DI 0 "register_operand" "=a")
12468 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
12469 (match_operand:DI 2 "register_operand" "0")
12472 (clobber (reg:CC FLAGS_REG))]
12473 "TARGET_64BIT && TARGET_GNU2_TLS"
12474 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12475 [(set_attr "type" "call")
12476 (set_attr "length" "2")
12477 (set_attr "length_address" "0")])
12479 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12480 [(set (match_operand:DI 0 "register_operand" "=&a")
12482 (unspec:DI [(match_operand 2 "tls_modbase_operand")
12483 (match_operand:DI 3)
12486 (const:DI (unspec:DI
12487 [(match_operand 1 "tls_symbolic_operand")]
12489 (clobber (reg:CC FLAGS_REG))]
12490 "TARGET_64BIT && TARGET_GNU2_TLS"
12493 [(set (match_dup 0) (match_dup 4))]
12495 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12496 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12499 ;; These patterns match the binary 387 instructions for addM3, subM3,
12500 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12501 ;; SFmode. The first is the normal insn, the second the same insn but
12502 ;; with one operand a conversion, and the third the same insn but with
12503 ;; the other operand a conversion. The conversion may be SFmode or
12504 ;; SImode if the target mode DFmode, but only SImode if the target mode
12507 ;; Gcc is slightly more smart about handling normal two address instructions
12508 ;; so use special patterns for add and mull.
12510 (define_insn "*fop_<mode>_comm_mixed"
12511 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12512 (match_operator:MODEF 3 "binary_fp_operator"
12513 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12514 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12515 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12516 && COMMUTATIVE_ARITH_P (operands[3])
12517 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12518 "* return output_387_binary_op (insn, operands);"
12519 [(set (attr "type")
12520 (if_then_else (eq_attr "alternative" "1,2")
12521 (if_then_else (match_operand:MODEF 3 "mult_operator")
12522 (const_string "ssemul")
12523 (const_string "sseadd"))
12524 (if_then_else (match_operand:MODEF 3 "mult_operator")
12525 (const_string "fmul")
12526 (const_string "fop"))))
12527 (set_attr "isa" "*,noavx,avx")
12528 (set_attr "prefix" "orig,orig,vex")
12529 (set_attr "mode" "<MODE>")])
12531 (define_insn "*fop_<mode>_comm_sse"
12532 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12533 (match_operator:MODEF 3 "binary_fp_operator"
12534 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12535 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12536 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12537 && COMMUTATIVE_ARITH_P (operands[3])
12538 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12539 "* return output_387_binary_op (insn, operands);"
12540 [(set (attr "type")
12541 (if_then_else (match_operand:MODEF 3 "mult_operator")
12542 (const_string "ssemul")
12543 (const_string "sseadd")))
12544 (set_attr "isa" "noavx,avx")
12545 (set_attr "prefix" "orig,vex")
12546 (set_attr "mode" "<MODE>")])
12548 (define_insn "*fop_<mode>_comm_i387"
12549 [(set (match_operand:MODEF 0 "register_operand" "=f")
12550 (match_operator:MODEF 3 "binary_fp_operator"
12551 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12552 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12553 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12554 && COMMUTATIVE_ARITH_P (operands[3])
12555 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12556 "* return output_387_binary_op (insn, operands);"
12557 [(set (attr "type")
12558 (if_then_else (match_operand:MODEF 3 "mult_operator")
12559 (const_string "fmul")
12560 (const_string "fop")))
12561 (set_attr "mode" "<MODE>")])
12563 (define_insn "*fop_<mode>_1_mixed"
12564 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
12565 (match_operator:MODEF 3 "binary_fp_operator"
12566 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
12567 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
12568 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12569 && !COMMUTATIVE_ARITH_P (operands[3])
12570 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12571 "* return output_387_binary_op (insn, operands);"
12572 [(set (attr "type")
12573 (cond [(and (eq_attr "alternative" "2,3")
12574 (match_operand:MODEF 3 "mult_operator"))
12575 (const_string "ssemul")
12576 (and (eq_attr "alternative" "2,3")
12577 (match_operand:MODEF 3 "div_operator"))
12578 (const_string "ssediv")
12579 (eq_attr "alternative" "2,3")
12580 (const_string "sseadd")
12581 (match_operand:MODEF 3 "mult_operator")
12582 (const_string "fmul")
12583 (match_operand:MODEF 3 "div_operator")
12584 (const_string "fdiv")
12586 (const_string "fop")))
12587 (set_attr "isa" "*,*,noavx,avx")
12588 (set_attr "prefix" "orig,orig,orig,vex")
12589 (set_attr "mode" "<MODE>")])
12591 (define_insn "*rcpsf2_sse"
12592 [(set (match_operand:SF 0 "register_operand" "=x")
12593 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12596 "%vrcpss\t{%1, %d0|%d0, %1}"
12597 [(set_attr "type" "sse")
12598 (set_attr "atom_sse_attr" "rcp")
12599 (set_attr "btver2_sse_attr" "rcp")
12600 (set_attr "prefix" "maybe_vex")
12601 (set_attr "mode" "SF")])
12603 (define_insn "*fop_<mode>_1_sse"
12604 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12605 (match_operator:MODEF 3 "binary_fp_operator"
12606 [(match_operand:MODEF 1 "register_operand" "0,x")
12607 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12608 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12609 && !COMMUTATIVE_ARITH_P (operands[3])"
12610 "* return output_387_binary_op (insn, operands);"
12611 [(set (attr "type")
12612 (cond [(match_operand:MODEF 3 "mult_operator")
12613 (const_string "ssemul")
12614 (match_operand:MODEF 3 "div_operator")
12615 (const_string "ssediv")
12617 (const_string "sseadd")))
12618 (set_attr "isa" "noavx,avx")
12619 (set_attr "prefix" "orig,vex")
12620 (set_attr "mode" "<MODE>")])
12622 ;; This pattern is not fully shadowed by the pattern above.
12623 (define_insn "*fop_<mode>_1_i387"
12624 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12625 (match_operator:MODEF 3 "binary_fp_operator"
12626 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12627 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12628 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12629 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12630 && !COMMUTATIVE_ARITH_P (operands[3])
12631 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12632 "* return output_387_binary_op (insn, operands);"
12633 [(set (attr "type")
12634 (cond [(match_operand:MODEF 3 "mult_operator")
12635 (const_string "fmul")
12636 (match_operand:MODEF 3 "div_operator")
12637 (const_string "fdiv")
12639 (const_string "fop")))
12640 (set_attr "mode" "<MODE>")])
12642 ;; ??? Add SSE splitters for these!
12643 (define_insn "*fop_<MODEF:mode>_2_i387"
12644 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12645 (match_operator:MODEF 3 "binary_fp_operator"
12647 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
12648 (match_operand:MODEF 2 "register_operand" "0,0")]))]
12649 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
12650 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12651 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12652 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12653 [(set (attr "type")
12654 (cond [(match_operand:MODEF 3 "mult_operator")
12655 (const_string "fmul")
12656 (match_operand:MODEF 3 "div_operator")
12657 (const_string "fdiv")
12659 (const_string "fop")))
12660 (set_attr "fp_int_src" "true")
12661 (set_attr "mode" "<SWI24:MODE>")])
12663 (define_insn "*fop_<MODEF:mode>_3_i387"
12664 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12665 (match_operator:MODEF 3 "binary_fp_operator"
12666 [(match_operand:MODEF 1 "register_operand" "0,0")
12668 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
12669 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
12670 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12671 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12672 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12673 [(set (attr "type")
12674 (cond [(match_operand:MODEF 3 "mult_operator")
12675 (const_string "fmul")
12676 (match_operand:MODEF 3 "div_operator")
12677 (const_string "fdiv")
12679 (const_string "fop")))
12680 (set_attr "fp_int_src" "true")
12681 (set_attr "mode" "<MODE>")])
12683 (define_insn "*fop_df_4_i387"
12684 [(set (match_operand:DF 0 "register_operand" "=f,f")
12685 (match_operator:DF 3 "binary_fp_operator"
12687 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12688 (match_operand:DF 2 "register_operand" "0,f")]))]
12689 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12690 && !(TARGET_SSE2 && TARGET_SSE_MATH)
12691 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12692 "* return output_387_binary_op (insn, operands);"
12693 [(set (attr "type")
12694 (cond [(match_operand:DF 3 "mult_operator")
12695 (const_string "fmul")
12696 (match_operand:DF 3 "div_operator")
12697 (const_string "fdiv")
12699 (const_string "fop")))
12700 (set_attr "mode" "SF")])
12702 (define_insn "*fop_df_5_i387"
12703 [(set (match_operand:DF 0 "register_operand" "=f,f")
12704 (match_operator:DF 3 "binary_fp_operator"
12705 [(match_operand:DF 1 "register_operand" "0,f")
12707 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12708 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12709 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12710 "* return output_387_binary_op (insn, operands);"
12711 [(set (attr "type")
12712 (cond [(match_operand:DF 3 "mult_operator")
12713 (const_string "fmul")
12714 (match_operand:DF 3 "div_operator")
12715 (const_string "fdiv")
12717 (const_string "fop")))
12718 (set_attr "mode" "SF")])
12720 (define_insn "*fop_df_6_i387"
12721 [(set (match_operand:DF 0 "register_operand" "=f,f")
12722 (match_operator:DF 3 "binary_fp_operator"
12724 (match_operand:SF 1 "register_operand" "0,f"))
12726 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12727 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12728 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12729 "* return output_387_binary_op (insn, operands);"
12730 [(set (attr "type")
12731 (cond [(match_operand:DF 3 "mult_operator")
12732 (const_string "fmul")
12733 (match_operand:DF 3 "div_operator")
12734 (const_string "fdiv")
12736 (const_string "fop")))
12737 (set_attr "mode" "SF")])
12739 (define_insn "*fop_xf_comm_i387"
12740 [(set (match_operand:XF 0 "register_operand" "=f")
12741 (match_operator:XF 3 "binary_fp_operator"
12742 [(match_operand:XF 1 "register_operand" "%0")
12743 (match_operand:XF 2 "register_operand" "f")]))]
12745 && COMMUTATIVE_ARITH_P (operands[3])"
12746 "* return output_387_binary_op (insn, operands);"
12747 [(set (attr "type")
12748 (if_then_else (match_operand:XF 3 "mult_operator")
12749 (const_string "fmul")
12750 (const_string "fop")))
12751 (set_attr "mode" "XF")])
12753 (define_insn "*fop_xf_1_i387"
12754 [(set (match_operand:XF 0 "register_operand" "=f,f")
12755 (match_operator:XF 3 "binary_fp_operator"
12756 [(match_operand:XF 1 "register_operand" "0,f")
12757 (match_operand:XF 2 "register_operand" "f,0")]))]
12759 && !COMMUTATIVE_ARITH_P (operands[3])"
12760 "* return output_387_binary_op (insn, operands);"
12761 [(set (attr "type")
12762 (cond [(match_operand:XF 3 "mult_operator")
12763 (const_string "fmul")
12764 (match_operand:XF 3 "div_operator")
12765 (const_string "fdiv")
12767 (const_string "fop")))
12768 (set_attr "mode" "XF")])
12770 (define_insn "*fop_xf_2_i387"
12771 [(set (match_operand:XF 0 "register_operand" "=f,f")
12772 (match_operator:XF 3 "binary_fp_operator"
12774 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
12775 (match_operand:XF 2 "register_operand" "0,0")]))]
12776 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12777 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12778 [(set (attr "type")
12779 (cond [(match_operand:XF 3 "mult_operator")
12780 (const_string "fmul")
12781 (match_operand:XF 3 "div_operator")
12782 (const_string "fdiv")
12784 (const_string "fop")))
12785 (set_attr "fp_int_src" "true")
12786 (set_attr "mode" "<MODE>")])
12788 (define_insn "*fop_xf_3_i387"
12789 [(set (match_operand:XF 0 "register_operand" "=f,f")
12790 (match_operator:XF 3 "binary_fp_operator"
12791 [(match_operand:XF 1 "register_operand" "0,0")
12793 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
12794 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12795 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12796 [(set (attr "type")
12797 (cond [(match_operand:XF 3 "mult_operator")
12798 (const_string "fmul")
12799 (match_operand:XF 3 "div_operator")
12800 (const_string "fdiv")
12802 (const_string "fop")))
12803 (set_attr "fp_int_src" "true")
12804 (set_attr "mode" "<MODE>")])
12806 (define_insn "*fop_xf_4_i387"
12807 [(set (match_operand:XF 0 "register_operand" "=f,f")
12808 (match_operator:XF 3 "binary_fp_operator"
12810 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
12811 (match_operand:XF 2 "register_operand" "0,f")]))]
12813 "* return output_387_binary_op (insn, operands);"
12814 [(set (attr "type")
12815 (cond [(match_operand:XF 3 "mult_operator")
12816 (const_string "fmul")
12817 (match_operand:XF 3 "div_operator")
12818 (const_string "fdiv")
12820 (const_string "fop")))
12821 (set_attr "mode" "<MODE>")])
12823 (define_insn "*fop_xf_5_i387"
12824 [(set (match_operand:XF 0 "register_operand" "=f,f")
12825 (match_operator:XF 3 "binary_fp_operator"
12826 [(match_operand:XF 1 "register_operand" "0,f")
12828 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12830 "* return output_387_binary_op (insn, operands);"
12831 [(set (attr "type")
12832 (cond [(match_operand:XF 3 "mult_operator")
12833 (const_string "fmul")
12834 (match_operand:XF 3 "div_operator")
12835 (const_string "fdiv")
12837 (const_string "fop")))
12838 (set_attr "mode" "<MODE>")])
12840 (define_insn "*fop_xf_6_i387"
12841 [(set (match_operand:XF 0 "register_operand" "=f,f")
12842 (match_operator:XF 3 "binary_fp_operator"
12844 (match_operand:MODEF 1 "register_operand" "0,f"))
12846 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12848 "* return output_387_binary_op (insn, operands);"
12849 [(set (attr "type")
12850 (cond [(match_operand:XF 3 "mult_operator")
12851 (const_string "fmul")
12852 (match_operand:XF 3 "div_operator")
12853 (const_string "fdiv")
12855 (const_string "fop")))
12856 (set_attr "mode" "<MODE>")])
12859 [(set (match_operand 0 "register_operand")
12860 (match_operator 3 "binary_fp_operator"
12861 [(float (match_operand:SWI24 1 "register_operand"))
12862 (match_operand 2 "register_operand")]))]
12864 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12865 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
12868 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
12869 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12870 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12871 gen_rtx_fmt_ee (GET_CODE (operands[3]),
12872 GET_MODE (operands[3]),
12875 ix86_free_from_memory (GET_MODE (operands[1]));
12880 [(set (match_operand 0 "register_operand")
12881 (match_operator 3 "binary_fp_operator"
12882 [(match_operand 1 "register_operand")
12883 (float (match_operand:SWI24 2 "register_operand"))]))]
12885 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12886 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
12889 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
12890 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12891 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12892 gen_rtx_fmt_ee (GET_CODE (operands[3]),
12893 GET_MODE (operands[3]),
12896 ix86_free_from_memory (GET_MODE (operands[2]));
12900 ;; FPU special functions.
12902 ;; This pattern implements a no-op XFmode truncation for
12903 ;; all fancy i386 XFmode math functions.
12905 (define_insn "truncxf<mode>2_i387_noop_unspec"
12906 [(set (match_operand:MODEF 0 "register_operand" "=f")
12907 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
12908 UNSPEC_TRUNC_NOOP))]
12909 "TARGET_USE_FANCY_MATH_387"
12910 "* return output_387_reg_move (insn, operands);"
12911 [(set_attr "type" "fmov")
12912 (set_attr "mode" "<MODE>")])
12914 (define_insn "sqrtxf2"
12915 [(set (match_operand:XF 0 "register_operand" "=f")
12916 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
12917 "TARGET_USE_FANCY_MATH_387"
12919 [(set_attr "type" "fpspc")
12920 (set_attr "mode" "XF")
12921 (set_attr "athlon_decode" "direct")
12922 (set_attr "amdfam10_decode" "direct")
12923 (set_attr "bdver1_decode" "direct")])
12925 (define_insn "sqrt_extend<mode>xf2_i387"
12926 [(set (match_operand:XF 0 "register_operand" "=f")
12929 (match_operand:MODEF 1 "register_operand" "0"))))]
12930 "TARGET_USE_FANCY_MATH_387"
12932 [(set_attr "type" "fpspc")
12933 (set_attr "mode" "XF")
12934 (set_attr "athlon_decode" "direct")
12935 (set_attr "amdfam10_decode" "direct")
12936 (set_attr "bdver1_decode" "direct")])
12938 (define_insn "*rsqrtsf2_sse"
12939 [(set (match_operand:SF 0 "register_operand" "=x")
12940 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12943 "%vrsqrtss\t{%1, %d0|%d0, %1}"
12944 [(set_attr "type" "sse")
12945 (set_attr "atom_sse_attr" "rcp")
12946 (set_attr "btver2_sse_attr" "rcp")
12947 (set_attr "prefix" "maybe_vex")
12948 (set_attr "mode" "SF")])
12950 (define_expand "rsqrtsf2"
12951 [(set (match_operand:SF 0 "register_operand")
12952 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
12956 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
12960 (define_insn "*sqrt<mode>2_sse"
12961 [(set (match_operand:MODEF 0 "register_operand" "=x")
12963 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
12964 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
12965 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
12966 [(set_attr "type" "sse")
12967 (set_attr "atom_sse_attr" "sqrt")
12968 (set_attr "btver2_sse_attr" "sqrt")
12969 (set_attr "prefix" "maybe_vex")
12970 (set_attr "mode" "<MODE>")
12971 (set_attr "athlon_decode" "*")
12972 (set_attr "amdfam10_decode" "*")
12973 (set_attr "bdver1_decode" "*")])
12975 (define_expand "sqrt<mode>2"
12976 [(set (match_operand:MODEF 0 "register_operand")
12978 (match_operand:MODEF 1 "nonimmediate_operand")))]
12979 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
12980 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
12982 if (<MODE>mode == SFmode
12984 && TARGET_RECIP_SQRT
12985 && !optimize_function_for_size_p (cfun)
12986 && flag_finite_math_only && !flag_trapping_math
12987 && flag_unsafe_math_optimizations)
12989 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
12993 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
12995 rtx op0 = gen_reg_rtx (XFmode);
12996 rtx op1 = force_reg (<MODE>mode, operands[1]);
12998 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
12999 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13004 (define_insn "fpremxf4_i387"
13005 [(set (match_operand:XF 0 "register_operand" "=f")
13006 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13007 (match_operand:XF 3 "register_operand" "1")]
13009 (set (match_operand:XF 1 "register_operand" "=u")
13010 (unspec:XF [(match_dup 2) (match_dup 3)]
13012 (set (reg:CCFP FPSR_REG)
13013 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13015 "TARGET_USE_FANCY_MATH_387"
13017 [(set_attr "type" "fpspc")
13018 (set_attr "mode" "XF")])
13020 (define_expand "fmodxf3"
13021 [(use (match_operand:XF 0 "register_operand"))
13022 (use (match_operand:XF 1 "general_operand"))
13023 (use (match_operand:XF 2 "general_operand"))]
13024 "TARGET_USE_FANCY_MATH_387"
13026 rtx label = gen_label_rtx ();
13028 rtx op1 = gen_reg_rtx (XFmode);
13029 rtx op2 = gen_reg_rtx (XFmode);
13031 emit_move_insn (op2, operands[2]);
13032 emit_move_insn (op1, operands[1]);
13034 emit_label (label);
13035 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13036 ix86_emit_fp_unordered_jump (label);
13037 LABEL_NUSES (label) = 1;
13039 emit_move_insn (operands[0], op1);
13043 (define_expand "fmod<mode>3"
13044 [(use (match_operand:MODEF 0 "register_operand"))
13045 (use (match_operand:MODEF 1 "general_operand"))
13046 (use (match_operand:MODEF 2 "general_operand"))]
13047 "TARGET_USE_FANCY_MATH_387"
13049 rtx (*gen_truncxf) (rtx, rtx);
13051 rtx label = gen_label_rtx ();
13053 rtx op1 = gen_reg_rtx (XFmode);
13054 rtx op2 = gen_reg_rtx (XFmode);
13056 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13057 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13059 emit_label (label);
13060 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13061 ix86_emit_fp_unordered_jump (label);
13062 LABEL_NUSES (label) = 1;
13064 /* Truncate the result properly for strict SSE math. */
13065 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13066 && !TARGET_MIX_SSE_I387)
13067 gen_truncxf = gen_truncxf<mode>2;
13069 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13071 emit_insn (gen_truncxf (operands[0], op1));
13075 (define_insn "fprem1xf4_i387"
13076 [(set (match_operand:XF 0 "register_operand" "=f")
13077 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13078 (match_operand:XF 3 "register_operand" "1")]
13080 (set (match_operand:XF 1 "register_operand" "=u")
13081 (unspec:XF [(match_dup 2) (match_dup 3)]
13083 (set (reg:CCFP FPSR_REG)
13084 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13086 "TARGET_USE_FANCY_MATH_387"
13088 [(set_attr "type" "fpspc")
13089 (set_attr "mode" "XF")])
13091 (define_expand "remainderxf3"
13092 [(use (match_operand:XF 0 "register_operand"))
13093 (use (match_operand:XF 1 "general_operand"))
13094 (use (match_operand:XF 2 "general_operand"))]
13095 "TARGET_USE_FANCY_MATH_387"
13097 rtx label = gen_label_rtx ();
13099 rtx op1 = gen_reg_rtx (XFmode);
13100 rtx op2 = gen_reg_rtx (XFmode);
13102 emit_move_insn (op2, operands[2]);
13103 emit_move_insn (op1, operands[1]);
13105 emit_label (label);
13106 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13107 ix86_emit_fp_unordered_jump (label);
13108 LABEL_NUSES (label) = 1;
13110 emit_move_insn (operands[0], op1);
13114 (define_expand "remainder<mode>3"
13115 [(use (match_operand:MODEF 0 "register_operand"))
13116 (use (match_operand:MODEF 1 "general_operand"))
13117 (use (match_operand:MODEF 2 "general_operand"))]
13118 "TARGET_USE_FANCY_MATH_387"
13120 rtx (*gen_truncxf) (rtx, rtx);
13122 rtx label = gen_label_rtx ();
13124 rtx op1 = gen_reg_rtx (XFmode);
13125 rtx op2 = gen_reg_rtx (XFmode);
13127 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13128 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13130 emit_label (label);
13132 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13133 ix86_emit_fp_unordered_jump (label);
13134 LABEL_NUSES (label) = 1;
13136 /* Truncate the result properly for strict SSE math. */
13137 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13138 && !TARGET_MIX_SSE_I387)
13139 gen_truncxf = gen_truncxf<mode>2;
13141 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13143 emit_insn (gen_truncxf (operands[0], op1));
13147 (define_int_iterator SINCOS
13151 (define_int_attr sincos
13152 [(UNSPEC_SIN "sin")
13153 (UNSPEC_COS "cos")])
13155 (define_insn "*<sincos>xf2_i387"
13156 [(set (match_operand:XF 0 "register_operand" "=f")
13157 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13159 "TARGET_USE_FANCY_MATH_387
13160 && flag_unsafe_math_optimizations"
13162 [(set_attr "type" "fpspc")
13163 (set_attr "mode" "XF")])
13165 (define_insn "*<sincos>_extend<mode>xf2_i387"
13166 [(set (match_operand:XF 0 "register_operand" "=f")
13167 (unspec:XF [(float_extend:XF
13168 (match_operand:MODEF 1 "register_operand" "0"))]
13170 "TARGET_USE_FANCY_MATH_387
13171 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13172 || TARGET_MIX_SSE_I387)
13173 && flag_unsafe_math_optimizations"
13175 [(set_attr "type" "fpspc")
13176 (set_attr "mode" "XF")])
13178 ;; When sincos pattern is defined, sin and cos builtin functions will be
13179 ;; expanded to sincos pattern with one of its outputs left unused.
13180 ;; CSE pass will figure out if two sincos patterns can be combined,
13181 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13182 ;; depending on the unused output.
13184 (define_insn "sincosxf3"
13185 [(set (match_operand:XF 0 "register_operand" "=f")
13186 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13187 UNSPEC_SINCOS_COS))
13188 (set (match_operand:XF 1 "register_operand" "=u")
13189 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13190 "TARGET_USE_FANCY_MATH_387
13191 && flag_unsafe_math_optimizations"
13193 [(set_attr "type" "fpspc")
13194 (set_attr "mode" "XF")])
13197 [(set (match_operand:XF 0 "register_operand")
13198 (unspec:XF [(match_operand:XF 2 "register_operand")]
13199 UNSPEC_SINCOS_COS))
13200 (set (match_operand:XF 1 "register_operand")
13201 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13202 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13203 && can_create_pseudo_p ()"
13204 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13207 [(set (match_operand:XF 0 "register_operand")
13208 (unspec:XF [(match_operand:XF 2 "register_operand")]
13209 UNSPEC_SINCOS_COS))
13210 (set (match_operand:XF 1 "register_operand")
13211 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13212 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13213 && can_create_pseudo_p ()"
13214 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13216 (define_insn "sincos_extend<mode>xf3_i387"
13217 [(set (match_operand:XF 0 "register_operand" "=f")
13218 (unspec:XF [(float_extend:XF
13219 (match_operand:MODEF 2 "register_operand" "0"))]
13220 UNSPEC_SINCOS_COS))
13221 (set (match_operand:XF 1 "register_operand" "=u")
13222 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13223 "TARGET_USE_FANCY_MATH_387
13224 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13225 || TARGET_MIX_SSE_I387)
13226 && flag_unsafe_math_optimizations"
13228 [(set_attr "type" "fpspc")
13229 (set_attr "mode" "XF")])
13232 [(set (match_operand:XF 0 "register_operand")
13233 (unspec:XF [(float_extend:XF
13234 (match_operand:MODEF 2 "register_operand"))]
13235 UNSPEC_SINCOS_COS))
13236 (set (match_operand:XF 1 "register_operand")
13237 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13238 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13239 && can_create_pseudo_p ()"
13240 [(set (match_dup 1)
13241 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13244 [(set (match_operand:XF 0 "register_operand")
13245 (unspec:XF [(float_extend:XF
13246 (match_operand:MODEF 2 "register_operand"))]
13247 UNSPEC_SINCOS_COS))
13248 (set (match_operand:XF 1 "register_operand")
13249 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13250 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13251 && can_create_pseudo_p ()"
13252 [(set (match_dup 0)
13253 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13255 (define_expand "sincos<mode>3"
13256 [(use (match_operand:MODEF 0 "register_operand"))
13257 (use (match_operand:MODEF 1 "register_operand"))
13258 (use (match_operand:MODEF 2 "register_operand"))]
13259 "TARGET_USE_FANCY_MATH_387
13260 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13261 || TARGET_MIX_SSE_I387)
13262 && flag_unsafe_math_optimizations"
13264 rtx op0 = gen_reg_rtx (XFmode);
13265 rtx op1 = gen_reg_rtx (XFmode);
13267 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13268 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13269 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13273 (define_insn "fptanxf4_i387"
13274 [(set (match_operand:XF 0 "register_operand" "=f")
13275 (match_operand:XF 3 "const_double_operand" "F"))
13276 (set (match_operand:XF 1 "register_operand" "=u")
13277 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13279 "TARGET_USE_FANCY_MATH_387
13280 && flag_unsafe_math_optimizations
13281 && standard_80387_constant_p (operands[3]) == 2"
13283 [(set_attr "type" "fpspc")
13284 (set_attr "mode" "XF")])
13286 (define_insn "fptan_extend<mode>xf4_i387"
13287 [(set (match_operand:MODEF 0 "register_operand" "=f")
13288 (match_operand:MODEF 3 "const_double_operand" "F"))
13289 (set (match_operand:XF 1 "register_operand" "=u")
13290 (unspec:XF [(float_extend:XF
13291 (match_operand:MODEF 2 "register_operand" "0"))]
13293 "TARGET_USE_FANCY_MATH_387
13294 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13295 || TARGET_MIX_SSE_I387)
13296 && flag_unsafe_math_optimizations
13297 && standard_80387_constant_p (operands[3]) == 2"
13299 [(set_attr "type" "fpspc")
13300 (set_attr "mode" "XF")])
13302 (define_expand "tanxf2"
13303 [(use (match_operand:XF 0 "register_operand"))
13304 (use (match_operand:XF 1 "register_operand"))]
13305 "TARGET_USE_FANCY_MATH_387
13306 && flag_unsafe_math_optimizations"
13308 rtx one = gen_reg_rtx (XFmode);
13309 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13311 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13315 (define_expand "tan<mode>2"
13316 [(use (match_operand:MODEF 0 "register_operand"))
13317 (use (match_operand:MODEF 1 "register_operand"))]
13318 "TARGET_USE_FANCY_MATH_387
13319 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13320 || TARGET_MIX_SSE_I387)
13321 && flag_unsafe_math_optimizations"
13323 rtx op0 = gen_reg_rtx (XFmode);
13325 rtx one = gen_reg_rtx (<MODE>mode);
13326 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13328 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13329 operands[1], op2));
13330 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13334 (define_insn "*fpatanxf3_i387"
13335 [(set (match_operand:XF 0 "register_operand" "=f")
13336 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13337 (match_operand:XF 2 "register_operand" "u")]
13339 (clobber (match_scratch:XF 3 "=2"))]
13340 "TARGET_USE_FANCY_MATH_387
13341 && flag_unsafe_math_optimizations"
13343 [(set_attr "type" "fpspc")
13344 (set_attr "mode" "XF")])
13346 (define_insn "fpatan_extend<mode>xf3_i387"
13347 [(set (match_operand:XF 0 "register_operand" "=f")
13348 (unspec:XF [(float_extend:XF
13349 (match_operand:MODEF 1 "register_operand" "0"))
13351 (match_operand:MODEF 2 "register_operand" "u"))]
13353 (clobber (match_scratch:XF 3 "=2"))]
13354 "TARGET_USE_FANCY_MATH_387
13355 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13356 || TARGET_MIX_SSE_I387)
13357 && flag_unsafe_math_optimizations"
13359 [(set_attr "type" "fpspc")
13360 (set_attr "mode" "XF")])
13362 (define_expand "atan2xf3"
13363 [(parallel [(set (match_operand:XF 0 "register_operand")
13364 (unspec:XF [(match_operand:XF 2 "register_operand")
13365 (match_operand:XF 1 "register_operand")]
13367 (clobber (match_scratch:XF 3))])]
13368 "TARGET_USE_FANCY_MATH_387
13369 && flag_unsafe_math_optimizations")
13371 (define_expand "atan2<mode>3"
13372 [(use (match_operand:MODEF 0 "register_operand"))
13373 (use (match_operand:MODEF 1 "register_operand"))
13374 (use (match_operand:MODEF 2 "register_operand"))]
13375 "TARGET_USE_FANCY_MATH_387
13376 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13377 || TARGET_MIX_SSE_I387)
13378 && flag_unsafe_math_optimizations"
13380 rtx op0 = gen_reg_rtx (XFmode);
13382 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13383 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13387 (define_expand "atanxf2"
13388 [(parallel [(set (match_operand:XF 0 "register_operand")
13389 (unspec:XF [(match_dup 2)
13390 (match_operand:XF 1 "register_operand")]
13392 (clobber (match_scratch:XF 3))])]
13393 "TARGET_USE_FANCY_MATH_387
13394 && flag_unsafe_math_optimizations"
13396 operands[2] = gen_reg_rtx (XFmode);
13397 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13400 (define_expand "atan<mode>2"
13401 [(use (match_operand:MODEF 0 "register_operand"))
13402 (use (match_operand:MODEF 1 "register_operand"))]
13403 "TARGET_USE_FANCY_MATH_387
13404 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13405 || TARGET_MIX_SSE_I387)
13406 && flag_unsafe_math_optimizations"
13408 rtx op0 = gen_reg_rtx (XFmode);
13410 rtx op2 = gen_reg_rtx (<MODE>mode);
13411 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13413 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13414 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13418 (define_expand "asinxf2"
13419 [(set (match_dup 2)
13420 (mult:XF (match_operand:XF 1 "register_operand")
13422 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13423 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13424 (parallel [(set (match_operand:XF 0 "register_operand")
13425 (unspec:XF [(match_dup 5) (match_dup 1)]
13427 (clobber (match_scratch:XF 6))])]
13428 "TARGET_USE_FANCY_MATH_387
13429 && flag_unsafe_math_optimizations"
13433 if (optimize_insn_for_size_p ())
13436 for (i = 2; i < 6; i++)
13437 operands[i] = gen_reg_rtx (XFmode);
13439 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13442 (define_expand "asin<mode>2"
13443 [(use (match_operand:MODEF 0 "register_operand"))
13444 (use (match_operand:MODEF 1 "general_operand"))]
13445 "TARGET_USE_FANCY_MATH_387
13446 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13447 || TARGET_MIX_SSE_I387)
13448 && flag_unsafe_math_optimizations"
13450 rtx op0 = gen_reg_rtx (XFmode);
13451 rtx op1 = gen_reg_rtx (XFmode);
13453 if (optimize_insn_for_size_p ())
13456 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13457 emit_insn (gen_asinxf2 (op0, op1));
13458 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13462 (define_expand "acosxf2"
13463 [(set (match_dup 2)
13464 (mult:XF (match_operand:XF 1 "register_operand")
13466 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13467 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13468 (parallel [(set (match_operand:XF 0 "register_operand")
13469 (unspec:XF [(match_dup 1) (match_dup 5)]
13471 (clobber (match_scratch:XF 6))])]
13472 "TARGET_USE_FANCY_MATH_387
13473 && flag_unsafe_math_optimizations"
13477 if (optimize_insn_for_size_p ())
13480 for (i = 2; i < 6; i++)
13481 operands[i] = gen_reg_rtx (XFmode);
13483 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13486 (define_expand "acos<mode>2"
13487 [(use (match_operand:MODEF 0 "register_operand"))
13488 (use (match_operand:MODEF 1 "general_operand"))]
13489 "TARGET_USE_FANCY_MATH_387
13490 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13491 || TARGET_MIX_SSE_I387)
13492 && flag_unsafe_math_optimizations"
13494 rtx op0 = gen_reg_rtx (XFmode);
13495 rtx op1 = gen_reg_rtx (XFmode);
13497 if (optimize_insn_for_size_p ())
13500 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13501 emit_insn (gen_acosxf2 (op0, op1));
13502 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13506 (define_insn "fyl2xxf3_i387"
13507 [(set (match_operand:XF 0 "register_operand" "=f")
13508 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13509 (match_operand:XF 2 "register_operand" "u")]
13511 (clobber (match_scratch:XF 3 "=2"))]
13512 "TARGET_USE_FANCY_MATH_387
13513 && flag_unsafe_math_optimizations"
13515 [(set_attr "type" "fpspc")
13516 (set_attr "mode" "XF")])
13518 (define_insn "fyl2x_extend<mode>xf3_i387"
13519 [(set (match_operand:XF 0 "register_operand" "=f")
13520 (unspec:XF [(float_extend:XF
13521 (match_operand:MODEF 1 "register_operand" "0"))
13522 (match_operand:XF 2 "register_operand" "u")]
13524 (clobber (match_scratch:XF 3 "=2"))]
13525 "TARGET_USE_FANCY_MATH_387
13526 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13527 || TARGET_MIX_SSE_I387)
13528 && flag_unsafe_math_optimizations"
13530 [(set_attr "type" "fpspc")
13531 (set_attr "mode" "XF")])
13533 (define_expand "logxf2"
13534 [(parallel [(set (match_operand:XF 0 "register_operand")
13535 (unspec:XF [(match_operand:XF 1 "register_operand")
13536 (match_dup 2)] UNSPEC_FYL2X))
13537 (clobber (match_scratch:XF 3))])]
13538 "TARGET_USE_FANCY_MATH_387
13539 && flag_unsafe_math_optimizations"
13541 operands[2] = gen_reg_rtx (XFmode);
13542 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13545 (define_expand "log<mode>2"
13546 [(use (match_operand:MODEF 0 "register_operand"))
13547 (use (match_operand:MODEF 1 "register_operand"))]
13548 "TARGET_USE_FANCY_MATH_387
13549 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13550 || TARGET_MIX_SSE_I387)
13551 && flag_unsafe_math_optimizations"
13553 rtx op0 = gen_reg_rtx (XFmode);
13555 rtx op2 = gen_reg_rtx (XFmode);
13556 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13558 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13559 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13563 (define_expand "log10xf2"
13564 [(parallel [(set (match_operand:XF 0 "register_operand")
13565 (unspec:XF [(match_operand:XF 1 "register_operand")
13566 (match_dup 2)] UNSPEC_FYL2X))
13567 (clobber (match_scratch:XF 3))])]
13568 "TARGET_USE_FANCY_MATH_387
13569 && flag_unsafe_math_optimizations"
13571 operands[2] = gen_reg_rtx (XFmode);
13572 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13575 (define_expand "log10<mode>2"
13576 [(use (match_operand:MODEF 0 "register_operand"))
13577 (use (match_operand:MODEF 1 "register_operand"))]
13578 "TARGET_USE_FANCY_MATH_387
13579 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13580 || TARGET_MIX_SSE_I387)
13581 && flag_unsafe_math_optimizations"
13583 rtx op0 = gen_reg_rtx (XFmode);
13585 rtx op2 = gen_reg_rtx (XFmode);
13586 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13588 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13589 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13593 (define_expand "log2xf2"
13594 [(parallel [(set (match_operand:XF 0 "register_operand")
13595 (unspec:XF [(match_operand:XF 1 "register_operand")
13596 (match_dup 2)] UNSPEC_FYL2X))
13597 (clobber (match_scratch:XF 3))])]
13598 "TARGET_USE_FANCY_MATH_387
13599 && flag_unsafe_math_optimizations"
13601 operands[2] = gen_reg_rtx (XFmode);
13602 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13605 (define_expand "log2<mode>2"
13606 [(use (match_operand:MODEF 0 "register_operand"))
13607 (use (match_operand:MODEF 1 "register_operand"))]
13608 "TARGET_USE_FANCY_MATH_387
13609 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13610 || TARGET_MIX_SSE_I387)
13611 && flag_unsafe_math_optimizations"
13613 rtx op0 = gen_reg_rtx (XFmode);
13615 rtx op2 = gen_reg_rtx (XFmode);
13616 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13618 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13619 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13623 (define_insn "fyl2xp1xf3_i387"
13624 [(set (match_operand:XF 0 "register_operand" "=f")
13625 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13626 (match_operand:XF 2 "register_operand" "u")]
13628 (clobber (match_scratch:XF 3 "=2"))]
13629 "TARGET_USE_FANCY_MATH_387
13630 && flag_unsafe_math_optimizations"
13632 [(set_attr "type" "fpspc")
13633 (set_attr "mode" "XF")])
13635 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13636 [(set (match_operand:XF 0 "register_operand" "=f")
13637 (unspec:XF [(float_extend:XF
13638 (match_operand:MODEF 1 "register_operand" "0"))
13639 (match_operand:XF 2 "register_operand" "u")]
13641 (clobber (match_scratch:XF 3 "=2"))]
13642 "TARGET_USE_FANCY_MATH_387
13643 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13644 || TARGET_MIX_SSE_I387)
13645 && flag_unsafe_math_optimizations"
13647 [(set_attr "type" "fpspc")
13648 (set_attr "mode" "XF")])
13650 (define_expand "log1pxf2"
13651 [(use (match_operand:XF 0 "register_operand"))
13652 (use (match_operand:XF 1 "register_operand"))]
13653 "TARGET_USE_FANCY_MATH_387
13654 && flag_unsafe_math_optimizations"
13656 if (optimize_insn_for_size_p ())
13659 ix86_emit_i387_log1p (operands[0], operands[1]);
13663 (define_expand "log1p<mode>2"
13664 [(use (match_operand:MODEF 0 "register_operand"))
13665 (use (match_operand:MODEF 1 "register_operand"))]
13666 "TARGET_USE_FANCY_MATH_387
13667 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13668 || TARGET_MIX_SSE_I387)
13669 && flag_unsafe_math_optimizations"
13673 if (optimize_insn_for_size_p ())
13676 op0 = gen_reg_rtx (XFmode);
13678 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13680 ix86_emit_i387_log1p (op0, operands[1]);
13681 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13685 (define_insn "fxtractxf3_i387"
13686 [(set (match_operand:XF 0 "register_operand" "=f")
13687 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13688 UNSPEC_XTRACT_FRACT))
13689 (set (match_operand:XF 1 "register_operand" "=u")
13690 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13691 "TARGET_USE_FANCY_MATH_387
13692 && flag_unsafe_math_optimizations"
13694 [(set_attr "type" "fpspc")
13695 (set_attr "mode" "XF")])
13697 (define_insn "fxtract_extend<mode>xf3_i387"
13698 [(set (match_operand:XF 0 "register_operand" "=f")
13699 (unspec:XF [(float_extend:XF
13700 (match_operand:MODEF 2 "register_operand" "0"))]
13701 UNSPEC_XTRACT_FRACT))
13702 (set (match_operand:XF 1 "register_operand" "=u")
13703 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13704 "TARGET_USE_FANCY_MATH_387
13705 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13706 || TARGET_MIX_SSE_I387)
13707 && flag_unsafe_math_optimizations"
13709 [(set_attr "type" "fpspc")
13710 (set_attr "mode" "XF")])
13712 (define_expand "logbxf2"
13713 [(parallel [(set (match_dup 2)
13714 (unspec:XF [(match_operand:XF 1 "register_operand")]
13715 UNSPEC_XTRACT_FRACT))
13716 (set (match_operand:XF 0 "register_operand")
13717 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13718 "TARGET_USE_FANCY_MATH_387
13719 && flag_unsafe_math_optimizations"
13720 "operands[2] = gen_reg_rtx (XFmode);")
13722 (define_expand "logb<mode>2"
13723 [(use (match_operand:MODEF 0 "register_operand"))
13724 (use (match_operand:MODEF 1 "register_operand"))]
13725 "TARGET_USE_FANCY_MATH_387
13726 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13727 || TARGET_MIX_SSE_I387)
13728 && flag_unsafe_math_optimizations"
13730 rtx op0 = gen_reg_rtx (XFmode);
13731 rtx op1 = gen_reg_rtx (XFmode);
13733 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13734 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13738 (define_expand "ilogbxf2"
13739 [(use (match_operand:SI 0 "register_operand"))
13740 (use (match_operand:XF 1 "register_operand"))]
13741 "TARGET_USE_FANCY_MATH_387
13742 && flag_unsafe_math_optimizations"
13746 if (optimize_insn_for_size_p ())
13749 op0 = gen_reg_rtx (XFmode);
13750 op1 = gen_reg_rtx (XFmode);
13752 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13753 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13757 (define_expand "ilogb<mode>2"
13758 [(use (match_operand:SI 0 "register_operand"))
13759 (use (match_operand:MODEF 1 "register_operand"))]
13760 "TARGET_USE_FANCY_MATH_387
13761 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13762 || TARGET_MIX_SSE_I387)
13763 && flag_unsafe_math_optimizations"
13767 if (optimize_insn_for_size_p ())
13770 op0 = gen_reg_rtx (XFmode);
13771 op1 = gen_reg_rtx (XFmode);
13773 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13774 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13778 (define_insn "*f2xm1xf2_i387"
13779 [(set (match_operand:XF 0 "register_operand" "=f")
13780 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13782 "TARGET_USE_FANCY_MATH_387
13783 && flag_unsafe_math_optimizations"
13785 [(set_attr "type" "fpspc")
13786 (set_attr "mode" "XF")])
13788 (define_insn "*fscalexf4_i387"
13789 [(set (match_operand:XF 0 "register_operand" "=f")
13790 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13791 (match_operand:XF 3 "register_operand" "1")]
13792 UNSPEC_FSCALE_FRACT))
13793 (set (match_operand:XF 1 "register_operand" "=u")
13794 (unspec:XF [(match_dup 2) (match_dup 3)]
13795 UNSPEC_FSCALE_EXP))]
13796 "TARGET_USE_FANCY_MATH_387
13797 && flag_unsafe_math_optimizations"
13799 [(set_attr "type" "fpspc")
13800 (set_attr "mode" "XF")])
13802 (define_expand "expNcorexf3"
13803 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
13804 (match_operand:XF 2 "register_operand")))
13805 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13806 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13807 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13808 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
13809 (parallel [(set (match_operand:XF 0 "register_operand")
13810 (unspec:XF [(match_dup 8) (match_dup 4)]
13811 UNSPEC_FSCALE_FRACT))
13813 (unspec:XF [(match_dup 8) (match_dup 4)]
13814 UNSPEC_FSCALE_EXP))])]
13815 "TARGET_USE_FANCY_MATH_387
13816 && flag_unsafe_math_optimizations"
13820 if (optimize_insn_for_size_p ())
13823 for (i = 3; i < 10; i++)
13824 operands[i] = gen_reg_rtx (XFmode);
13826 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
13829 (define_expand "expxf2"
13830 [(use (match_operand:XF 0 "register_operand"))
13831 (use (match_operand:XF 1 "register_operand"))]
13832 "TARGET_USE_FANCY_MATH_387
13833 && flag_unsafe_math_optimizations"
13837 if (optimize_insn_for_size_p ())
13840 op2 = gen_reg_rtx (XFmode);
13841 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
13843 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13847 (define_expand "exp<mode>2"
13848 [(use (match_operand:MODEF 0 "register_operand"))
13849 (use (match_operand:MODEF 1 "general_operand"))]
13850 "TARGET_USE_FANCY_MATH_387
13851 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13852 || TARGET_MIX_SSE_I387)
13853 && flag_unsafe_math_optimizations"
13857 if (optimize_insn_for_size_p ())
13860 op0 = gen_reg_rtx (XFmode);
13861 op1 = gen_reg_rtx (XFmode);
13863 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13864 emit_insn (gen_expxf2 (op0, op1));
13865 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13869 (define_expand "exp10xf2"
13870 [(use (match_operand:XF 0 "register_operand"))
13871 (use (match_operand:XF 1 "register_operand"))]
13872 "TARGET_USE_FANCY_MATH_387
13873 && flag_unsafe_math_optimizations"
13877 if (optimize_insn_for_size_p ())
13880 op2 = gen_reg_rtx (XFmode);
13881 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
13883 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13887 (define_expand "exp10<mode>2"
13888 [(use (match_operand:MODEF 0 "register_operand"))
13889 (use (match_operand:MODEF 1 "general_operand"))]
13890 "TARGET_USE_FANCY_MATH_387
13891 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13892 || TARGET_MIX_SSE_I387)
13893 && flag_unsafe_math_optimizations"
13897 if (optimize_insn_for_size_p ())
13900 op0 = gen_reg_rtx (XFmode);
13901 op1 = gen_reg_rtx (XFmode);
13903 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13904 emit_insn (gen_exp10xf2 (op0, op1));
13905 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13909 (define_expand "exp2xf2"
13910 [(use (match_operand:XF 0 "register_operand"))
13911 (use (match_operand:XF 1 "register_operand"))]
13912 "TARGET_USE_FANCY_MATH_387
13913 && flag_unsafe_math_optimizations"
13917 if (optimize_insn_for_size_p ())
13920 op2 = gen_reg_rtx (XFmode);
13921 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13923 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13927 (define_expand "exp2<mode>2"
13928 [(use (match_operand:MODEF 0 "register_operand"))
13929 (use (match_operand:MODEF 1 "general_operand"))]
13930 "TARGET_USE_FANCY_MATH_387
13931 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13932 || TARGET_MIX_SSE_I387)
13933 && flag_unsafe_math_optimizations"
13937 if (optimize_insn_for_size_p ())
13940 op0 = gen_reg_rtx (XFmode);
13941 op1 = gen_reg_rtx (XFmode);
13943 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13944 emit_insn (gen_exp2xf2 (op0, op1));
13945 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13949 (define_expand "expm1xf2"
13950 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
13952 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13953 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13954 (set (match_dup 9) (float_extend:XF (match_dup 13)))
13955 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13956 (parallel [(set (match_dup 7)
13957 (unspec:XF [(match_dup 6) (match_dup 4)]
13958 UNSPEC_FSCALE_FRACT))
13960 (unspec:XF [(match_dup 6) (match_dup 4)]
13961 UNSPEC_FSCALE_EXP))])
13962 (parallel [(set (match_dup 10)
13963 (unspec:XF [(match_dup 9) (match_dup 8)]
13964 UNSPEC_FSCALE_FRACT))
13965 (set (match_dup 11)
13966 (unspec:XF [(match_dup 9) (match_dup 8)]
13967 UNSPEC_FSCALE_EXP))])
13968 (set (match_dup 12) (minus:XF (match_dup 10)
13969 (float_extend:XF (match_dup 13))))
13970 (set (match_operand:XF 0 "register_operand")
13971 (plus:XF (match_dup 12) (match_dup 7)))]
13972 "TARGET_USE_FANCY_MATH_387
13973 && flag_unsafe_math_optimizations"
13977 if (optimize_insn_for_size_p ())
13980 for (i = 2; i < 13; i++)
13981 operands[i] = gen_reg_rtx (XFmode);
13984 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
13986 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
13989 (define_expand "expm1<mode>2"
13990 [(use (match_operand:MODEF 0 "register_operand"))
13991 (use (match_operand:MODEF 1 "general_operand"))]
13992 "TARGET_USE_FANCY_MATH_387
13993 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13994 || TARGET_MIX_SSE_I387)
13995 && flag_unsafe_math_optimizations"
13999 if (optimize_insn_for_size_p ())
14002 op0 = gen_reg_rtx (XFmode);
14003 op1 = gen_reg_rtx (XFmode);
14005 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14006 emit_insn (gen_expm1xf2 (op0, op1));
14007 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14011 (define_expand "ldexpxf3"
14012 [(set (match_dup 3)
14013 (float:XF (match_operand:SI 2 "register_operand")))
14014 (parallel [(set (match_operand:XF 0 " register_operand")
14015 (unspec:XF [(match_operand:XF 1 "register_operand")
14017 UNSPEC_FSCALE_FRACT))
14019 (unspec:XF [(match_dup 1) (match_dup 3)]
14020 UNSPEC_FSCALE_EXP))])]
14021 "TARGET_USE_FANCY_MATH_387
14022 && flag_unsafe_math_optimizations"
14024 if (optimize_insn_for_size_p ())
14027 operands[3] = gen_reg_rtx (XFmode);
14028 operands[4] = gen_reg_rtx (XFmode);
14031 (define_expand "ldexp<mode>3"
14032 [(use (match_operand:MODEF 0 "register_operand"))
14033 (use (match_operand:MODEF 1 "general_operand"))
14034 (use (match_operand:SI 2 "register_operand"))]
14035 "TARGET_USE_FANCY_MATH_387
14036 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14037 || TARGET_MIX_SSE_I387)
14038 && flag_unsafe_math_optimizations"
14042 if (optimize_insn_for_size_p ())
14045 op0 = gen_reg_rtx (XFmode);
14046 op1 = gen_reg_rtx (XFmode);
14048 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14049 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14050 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14054 (define_expand "scalbxf3"
14055 [(parallel [(set (match_operand:XF 0 " register_operand")
14056 (unspec:XF [(match_operand:XF 1 "register_operand")
14057 (match_operand:XF 2 "register_operand")]
14058 UNSPEC_FSCALE_FRACT))
14060 (unspec:XF [(match_dup 1) (match_dup 2)]
14061 UNSPEC_FSCALE_EXP))])]
14062 "TARGET_USE_FANCY_MATH_387
14063 && flag_unsafe_math_optimizations"
14065 if (optimize_insn_for_size_p ())
14068 operands[3] = gen_reg_rtx (XFmode);
14071 (define_expand "scalb<mode>3"
14072 [(use (match_operand:MODEF 0 "register_operand"))
14073 (use (match_operand:MODEF 1 "general_operand"))
14074 (use (match_operand:MODEF 2 "general_operand"))]
14075 "TARGET_USE_FANCY_MATH_387
14076 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14077 || TARGET_MIX_SSE_I387)
14078 && flag_unsafe_math_optimizations"
14082 if (optimize_insn_for_size_p ())
14085 op0 = gen_reg_rtx (XFmode);
14086 op1 = gen_reg_rtx (XFmode);
14087 op2 = gen_reg_rtx (XFmode);
14089 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14090 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14091 emit_insn (gen_scalbxf3 (op0, op1, op2));
14092 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14096 (define_expand "significandxf2"
14097 [(parallel [(set (match_operand:XF 0 "register_operand")
14098 (unspec:XF [(match_operand:XF 1 "register_operand")]
14099 UNSPEC_XTRACT_FRACT))
14101 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14102 "TARGET_USE_FANCY_MATH_387
14103 && flag_unsafe_math_optimizations"
14104 "operands[2] = gen_reg_rtx (XFmode);")
14106 (define_expand "significand<mode>2"
14107 [(use (match_operand:MODEF 0 "register_operand"))
14108 (use (match_operand:MODEF 1 "register_operand"))]
14109 "TARGET_USE_FANCY_MATH_387
14110 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14111 || TARGET_MIX_SSE_I387)
14112 && flag_unsafe_math_optimizations"
14114 rtx op0 = gen_reg_rtx (XFmode);
14115 rtx op1 = gen_reg_rtx (XFmode);
14117 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14118 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14123 (define_insn "sse4_1_round<mode>2"
14124 [(set (match_operand:MODEF 0 "register_operand" "=x")
14125 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14126 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14129 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14130 [(set_attr "type" "ssecvt")
14131 (set_attr "prefix_extra" "1")
14132 (set_attr "prefix" "maybe_vex")
14133 (set_attr "mode" "<MODE>")])
14135 (define_insn "rintxf2"
14136 [(set (match_operand:XF 0 "register_operand" "=f")
14137 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14139 "TARGET_USE_FANCY_MATH_387
14140 && flag_unsafe_math_optimizations"
14142 [(set_attr "type" "fpspc")
14143 (set_attr "mode" "XF")])
14145 (define_expand "rint<mode>2"
14146 [(use (match_operand:MODEF 0 "register_operand"))
14147 (use (match_operand:MODEF 1 "register_operand"))]
14148 "(TARGET_USE_FANCY_MATH_387
14149 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14150 || TARGET_MIX_SSE_I387)
14151 && flag_unsafe_math_optimizations)
14152 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14153 && !flag_trapping_math)"
14155 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14156 && !flag_trapping_math)
14159 emit_insn (gen_sse4_1_round<mode>2
14160 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14161 else if (optimize_insn_for_size_p ())
14164 ix86_expand_rint (operands[0], operands[1]);
14168 rtx op0 = gen_reg_rtx (XFmode);
14169 rtx op1 = gen_reg_rtx (XFmode);
14171 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14172 emit_insn (gen_rintxf2 (op0, op1));
14174 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14179 (define_expand "round<mode>2"
14180 [(match_operand:X87MODEF 0 "register_operand")
14181 (match_operand:X87MODEF 1 "nonimmediate_operand")]
14182 "(TARGET_USE_FANCY_MATH_387
14183 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14184 || TARGET_MIX_SSE_I387)
14185 && flag_unsafe_math_optimizations)
14186 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14187 && !flag_trapping_math && !flag_rounding_math)"
14189 if (optimize_insn_for_size_p ())
14192 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14193 && !flag_trapping_math && !flag_rounding_math)
14197 operands[1] = force_reg (<MODE>mode, operands[1]);
14198 ix86_expand_round_sse4 (operands[0], operands[1]);
14200 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14201 ix86_expand_round (operands[0], operands[1]);
14203 ix86_expand_rounddf_32 (operands[0], operands[1]);
14207 operands[1] = force_reg (<MODE>mode, operands[1]);
14208 ix86_emit_i387_round (operands[0], operands[1]);
14213 (define_insn_and_split "*fistdi2_1"
14214 [(set (match_operand:DI 0 "nonimmediate_operand")
14215 (unspec:DI [(match_operand:XF 1 "register_operand")]
14217 "TARGET_USE_FANCY_MATH_387
14218 && can_create_pseudo_p ()"
14223 if (memory_operand (operands[0], VOIDmode))
14224 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14227 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14228 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14233 [(set_attr "type" "fpspc")
14234 (set_attr "mode" "DI")])
14236 (define_insn "fistdi2"
14237 [(set (match_operand:DI 0 "memory_operand" "=m")
14238 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14240 (clobber (match_scratch:XF 2 "=&1f"))]
14241 "TARGET_USE_FANCY_MATH_387"
14242 "* return output_fix_trunc (insn, operands, false);"
14243 [(set_attr "type" "fpspc")
14244 (set_attr "mode" "DI")])
14246 (define_insn "fistdi2_with_temp"
14247 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14248 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14250 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14251 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14252 "TARGET_USE_FANCY_MATH_387"
14254 [(set_attr "type" "fpspc")
14255 (set_attr "mode" "DI")])
14258 [(set (match_operand:DI 0 "register_operand")
14259 (unspec:DI [(match_operand:XF 1 "register_operand")]
14261 (clobber (match_operand:DI 2 "memory_operand"))
14262 (clobber (match_scratch 3))]
14264 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14265 (clobber (match_dup 3))])
14266 (set (match_dup 0) (match_dup 2))])
14269 [(set (match_operand:DI 0 "memory_operand")
14270 (unspec:DI [(match_operand:XF 1 "register_operand")]
14272 (clobber (match_operand:DI 2 "memory_operand"))
14273 (clobber (match_scratch 3))]
14275 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14276 (clobber (match_dup 3))])])
14278 (define_insn_and_split "*fist<mode>2_1"
14279 [(set (match_operand:SWI24 0 "register_operand")
14280 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14282 "TARGET_USE_FANCY_MATH_387
14283 && can_create_pseudo_p ()"
14288 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14289 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14293 [(set_attr "type" "fpspc")
14294 (set_attr "mode" "<MODE>")])
14296 (define_insn "fist<mode>2"
14297 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14298 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14300 "TARGET_USE_FANCY_MATH_387"
14301 "* return output_fix_trunc (insn, operands, false);"
14302 [(set_attr "type" "fpspc")
14303 (set_attr "mode" "<MODE>")])
14305 (define_insn "fist<mode>2_with_temp"
14306 [(set (match_operand:SWI24 0 "register_operand" "=r")
14307 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14309 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14310 "TARGET_USE_FANCY_MATH_387"
14312 [(set_attr "type" "fpspc")
14313 (set_attr "mode" "<MODE>")])
14316 [(set (match_operand:SWI24 0 "register_operand")
14317 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14319 (clobber (match_operand:SWI24 2 "memory_operand"))]
14321 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14322 (set (match_dup 0) (match_dup 2))])
14325 [(set (match_operand:SWI24 0 "memory_operand")
14326 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14328 (clobber (match_operand:SWI24 2 "memory_operand"))]
14330 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14332 (define_expand "lrintxf<mode>2"
14333 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
14334 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
14336 "TARGET_USE_FANCY_MATH_387")
14338 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
14339 [(set (match_operand:SWI48 0 "nonimmediate_operand")
14340 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
14341 UNSPEC_FIX_NOTRUNC))]
14342 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
14344 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14345 [(match_operand:SWI248x 0 "nonimmediate_operand")
14346 (match_operand:X87MODEF 1 "register_operand")]
14347 "(TARGET_USE_FANCY_MATH_387
14348 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14349 || TARGET_MIX_SSE_I387)
14350 && flag_unsafe_math_optimizations)
14351 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14352 && <SWI248x:MODE>mode != HImode
14353 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14354 && !flag_trapping_math && !flag_rounding_math)"
14356 if (optimize_insn_for_size_p ())
14359 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14360 && <SWI248x:MODE>mode != HImode
14361 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14362 && !flag_trapping_math && !flag_rounding_math)
14363 ix86_expand_lround (operands[0], operands[1]);
14365 ix86_emit_i387_round (operands[0], operands[1]);
14369 (define_int_iterator FRNDINT_ROUNDING
14370 [UNSPEC_FRNDINT_FLOOR
14371 UNSPEC_FRNDINT_CEIL
14372 UNSPEC_FRNDINT_TRUNC])
14374 (define_int_iterator FIST_ROUNDING
14378 ;; Base name for define_insn
14379 (define_int_attr rounding_insn
14380 [(UNSPEC_FRNDINT_FLOOR "floor")
14381 (UNSPEC_FRNDINT_CEIL "ceil")
14382 (UNSPEC_FRNDINT_TRUNC "btrunc")
14383 (UNSPEC_FIST_FLOOR "floor")
14384 (UNSPEC_FIST_CEIL "ceil")])
14386 (define_int_attr rounding
14387 [(UNSPEC_FRNDINT_FLOOR "floor")
14388 (UNSPEC_FRNDINT_CEIL "ceil")
14389 (UNSPEC_FRNDINT_TRUNC "trunc")
14390 (UNSPEC_FIST_FLOOR "floor")
14391 (UNSPEC_FIST_CEIL "ceil")])
14393 (define_int_attr ROUNDING
14394 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
14395 (UNSPEC_FRNDINT_CEIL "CEIL")
14396 (UNSPEC_FRNDINT_TRUNC "TRUNC")
14397 (UNSPEC_FIST_FLOOR "FLOOR")
14398 (UNSPEC_FIST_CEIL "CEIL")])
14400 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14401 (define_insn_and_split "frndintxf2_<rounding>"
14402 [(set (match_operand:XF 0 "register_operand")
14403 (unspec:XF [(match_operand:XF 1 "register_operand")]
14405 (clobber (reg:CC FLAGS_REG))]
14406 "TARGET_USE_FANCY_MATH_387
14407 && flag_unsafe_math_optimizations
14408 && can_create_pseudo_p ()"
14413 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
14415 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14416 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
14418 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
14419 operands[2], operands[3]));
14422 [(set_attr "type" "frndint")
14423 (set_attr "i387_cw" "<rounding>")
14424 (set_attr "mode" "XF")])
14426 (define_insn "frndintxf2_<rounding>_i387"
14427 [(set (match_operand:XF 0 "register_operand" "=f")
14428 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14430 (use (match_operand:HI 2 "memory_operand" "m"))
14431 (use (match_operand:HI 3 "memory_operand" "m"))]
14432 "TARGET_USE_FANCY_MATH_387
14433 && flag_unsafe_math_optimizations"
14434 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14435 [(set_attr "type" "frndint")
14436 (set_attr "i387_cw" "<rounding>")
14437 (set_attr "mode" "XF")])
14439 (define_expand "<rounding_insn>xf2"
14440 [(parallel [(set (match_operand:XF 0 "register_operand")
14441 (unspec:XF [(match_operand:XF 1 "register_operand")]
14443 (clobber (reg:CC FLAGS_REG))])]
14444 "TARGET_USE_FANCY_MATH_387
14445 && flag_unsafe_math_optimizations
14446 && !optimize_insn_for_size_p ()")
14448 (define_expand "<rounding_insn><mode>2"
14449 [(parallel [(set (match_operand:MODEF 0 "register_operand")
14450 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
14452 (clobber (reg:CC FLAGS_REG))])]
14453 "(TARGET_USE_FANCY_MATH_387
14454 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14455 || TARGET_MIX_SSE_I387)
14456 && flag_unsafe_math_optimizations)
14457 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14458 && !flag_trapping_math)"
14460 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14461 && !flag_trapping_math)
14464 emit_insn (gen_sse4_1_round<mode>2
14465 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
14466 else if (optimize_insn_for_size_p ())
14468 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14470 if (ROUND_<ROUNDING> == ROUND_FLOOR)
14471 ix86_expand_floorceil (operands[0], operands[1], true);
14472 else if (ROUND_<ROUNDING> == ROUND_CEIL)
14473 ix86_expand_floorceil (operands[0], operands[1], false);
14474 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
14475 ix86_expand_trunc (operands[0], operands[1]);
14477 gcc_unreachable ();
14481 if (ROUND_<ROUNDING> == ROUND_FLOOR)
14482 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
14483 else if (ROUND_<ROUNDING> == ROUND_CEIL)
14484 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
14485 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
14486 ix86_expand_truncdf_32 (operands[0], operands[1]);
14488 gcc_unreachable ();
14495 if (optimize_insn_for_size_p ())
14498 op0 = gen_reg_rtx (XFmode);
14499 op1 = gen_reg_rtx (XFmode);
14500 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14501 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
14503 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14508 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14509 (define_insn_and_split "frndintxf2_mask_pm"
14510 [(set (match_operand:XF 0 "register_operand")
14511 (unspec:XF [(match_operand:XF 1 "register_operand")]
14512 UNSPEC_FRNDINT_MASK_PM))
14513 (clobber (reg:CC FLAGS_REG))]
14514 "TARGET_USE_FANCY_MATH_387
14515 && flag_unsafe_math_optimizations
14516 && can_create_pseudo_p ()"
14521 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
14523 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14524 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
14526 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
14527 operands[2], operands[3]));
14530 [(set_attr "type" "frndint")
14531 (set_attr "i387_cw" "mask_pm")
14532 (set_attr "mode" "XF")])
14534 (define_insn "frndintxf2_mask_pm_i387"
14535 [(set (match_operand:XF 0 "register_operand" "=f")
14536 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14537 UNSPEC_FRNDINT_MASK_PM))
14538 (use (match_operand:HI 2 "memory_operand" "m"))
14539 (use (match_operand:HI 3 "memory_operand" "m"))]
14540 "TARGET_USE_FANCY_MATH_387
14541 && flag_unsafe_math_optimizations"
14542 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
14543 [(set_attr "type" "frndint")
14544 (set_attr "i387_cw" "mask_pm")
14545 (set_attr "mode" "XF")])
14547 (define_expand "nearbyintxf2"
14548 [(parallel [(set (match_operand:XF 0 "register_operand")
14549 (unspec:XF [(match_operand:XF 1 "register_operand")]
14550 UNSPEC_FRNDINT_MASK_PM))
14551 (clobber (reg:CC FLAGS_REG))])]
14552 "TARGET_USE_FANCY_MATH_387
14553 && flag_unsafe_math_optimizations")
14555 (define_expand "nearbyint<mode>2"
14556 [(use (match_operand:MODEF 0 "register_operand"))
14557 (use (match_operand:MODEF 1 "register_operand"))]
14558 "TARGET_USE_FANCY_MATH_387
14559 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14560 || TARGET_MIX_SSE_I387)
14561 && flag_unsafe_math_optimizations"
14563 rtx op0 = gen_reg_rtx (XFmode);
14564 rtx op1 = gen_reg_rtx (XFmode);
14566 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14567 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
14569 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 "*fist<mode>2_<rounding>_1"
14575 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
14576 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
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_<ROUNDING>] = 1;
14588 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14589 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
14590 if (memory_operand (operands[0], VOIDmode))
14591 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
14592 operands[2], operands[3]));
14595 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14596 emit_insn (gen_fist<mode>2_<rounding>_with_temp
14597 (operands[0], operands[1], operands[2],
14598 operands[3], operands[4]));
14602 [(set_attr "type" "fistp")
14603 (set_attr "i387_cw" "<rounding>")
14604 (set_attr "mode" "<MODE>")])
14606 (define_insn "fistdi2_<rounding>"
14607 [(set (match_operand:DI 0 "memory_operand" "=m")
14608 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14610 (use (match_operand:HI 2 "memory_operand" "m"))
14611 (use (match_operand:HI 3 "memory_operand" "m"))
14612 (clobber (match_scratch:XF 4 "=&1f"))]
14613 "TARGET_USE_FANCY_MATH_387
14614 && flag_unsafe_math_optimizations"
14615 "* return output_fix_trunc (insn, operands, false);"
14616 [(set_attr "type" "fistp")
14617 (set_attr "i387_cw" "<rounding>")
14618 (set_attr "mode" "DI")])
14620 (define_insn "fistdi2_<rounding>_with_temp"
14621 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14622 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14624 (use (match_operand:HI 2 "memory_operand" "m,m"))
14625 (use (match_operand:HI 3 "memory_operand" "m,m"))
14626 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14627 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14628 "TARGET_USE_FANCY_MATH_387
14629 && flag_unsafe_math_optimizations"
14631 [(set_attr "type" "fistp")
14632 (set_attr "i387_cw" "<rounding>")
14633 (set_attr "mode" "DI")])
14636 [(set (match_operand:DI 0 "register_operand")
14637 (unspec:DI [(match_operand:XF 1 "register_operand")]
14639 (use (match_operand:HI 2 "memory_operand"))
14640 (use (match_operand:HI 3 "memory_operand"))
14641 (clobber (match_operand:DI 4 "memory_operand"))
14642 (clobber (match_scratch 5))]
14644 [(parallel [(set (match_dup 4)
14645 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
14646 (use (match_dup 2))
14647 (use (match_dup 3))
14648 (clobber (match_dup 5))])
14649 (set (match_dup 0) (match_dup 4))])
14652 [(set (match_operand:DI 0 "memory_operand")
14653 (unspec:DI [(match_operand:XF 1 "register_operand")]
14655 (use (match_operand:HI 2 "memory_operand"))
14656 (use (match_operand:HI 3 "memory_operand"))
14657 (clobber (match_operand:DI 4 "memory_operand"))
14658 (clobber (match_scratch 5))]
14660 [(parallel [(set (match_dup 0)
14661 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
14662 (use (match_dup 2))
14663 (use (match_dup 3))
14664 (clobber (match_dup 5))])])
14666 (define_insn "fist<mode>2_<rounding>"
14667 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14668 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14670 (use (match_operand:HI 2 "memory_operand" "m"))
14671 (use (match_operand:HI 3 "memory_operand" "m"))]
14672 "TARGET_USE_FANCY_MATH_387
14673 && flag_unsafe_math_optimizations"
14674 "* return output_fix_trunc (insn, operands, false);"
14675 [(set_attr "type" "fistp")
14676 (set_attr "i387_cw" "<rounding>")
14677 (set_attr "mode" "<MODE>")])
14679 (define_insn "fist<mode>2_<rounding>_with_temp"
14680 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
14681 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
14683 (use (match_operand:HI 2 "memory_operand" "m,m"))
14684 (use (match_operand:HI 3 "memory_operand" "m,m"))
14685 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
14686 "TARGET_USE_FANCY_MATH_387
14687 && flag_unsafe_math_optimizations"
14689 [(set_attr "type" "fistp")
14690 (set_attr "i387_cw" "<rounding>")
14691 (set_attr "mode" "<MODE>")])
14694 [(set (match_operand:SWI24 0 "register_operand")
14695 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14697 (use (match_operand:HI 2 "memory_operand"))
14698 (use (match_operand:HI 3 "memory_operand"))
14699 (clobber (match_operand:SWI24 4 "memory_operand"))]
14701 [(parallel [(set (match_dup 4)
14702 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
14703 (use (match_dup 2))
14704 (use (match_dup 3))])
14705 (set (match_dup 0) (match_dup 4))])
14708 [(set (match_operand:SWI24 0 "memory_operand")
14709 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14711 (use (match_operand:HI 2 "memory_operand"))
14712 (use (match_operand:HI 3 "memory_operand"))
14713 (clobber (match_operand:SWI24 4 "memory_operand"))]
14715 [(parallel [(set (match_dup 0)
14716 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
14717 (use (match_dup 2))
14718 (use (match_dup 3))])])
14720 (define_expand "l<rounding_insn>xf<mode>2"
14721 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
14722 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
14724 (clobber (reg:CC FLAGS_REG))])]
14725 "TARGET_USE_FANCY_MATH_387
14726 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14727 && flag_unsafe_math_optimizations")
14729 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
14730 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
14731 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
14733 (clobber (reg:CC FLAGS_REG))])]
14734 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14735 && !flag_trapping_math"
14737 if (TARGET_64BIT && optimize_insn_for_size_p ())
14740 if (ROUND_<ROUNDING> == ROUND_FLOOR)
14741 ix86_expand_lfloorceil (operands[0], operands[1], true);
14742 else if (ROUND_<ROUNDING> == ROUND_CEIL)
14743 ix86_expand_lfloorceil (operands[0], operands[1], false);
14745 gcc_unreachable ();
14750 (define_insn "fxam<mode>2_i387"
14751 [(set (match_operand:HI 0 "register_operand" "=a")
14753 [(match_operand:X87MODEF 1 "register_operand" "f")]
14755 "TARGET_USE_FANCY_MATH_387"
14756 "fxam\n\tfnstsw\t%0"
14757 [(set_attr "type" "multi")
14758 (set_attr "length" "4")
14759 (set_attr "unit" "i387")
14760 (set_attr "mode" "<MODE>")])
14762 (define_insn_and_split "fxam<mode>2_i387_with_temp"
14763 [(set (match_operand:HI 0 "register_operand")
14765 [(match_operand:MODEF 1 "memory_operand")]
14767 "TARGET_USE_FANCY_MATH_387
14768 && can_create_pseudo_p ()"
14771 [(set (match_dup 2)(match_dup 1))
14773 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
14775 operands[2] = gen_reg_rtx (<MODE>mode);
14777 MEM_VOLATILE_P (operands[1]) = 1;
14779 [(set_attr "type" "multi")
14780 (set_attr "unit" "i387")
14781 (set_attr "mode" "<MODE>")])
14783 (define_expand "isinfxf2"
14784 [(use (match_operand:SI 0 "register_operand"))
14785 (use (match_operand:XF 1 "register_operand"))]
14786 "TARGET_USE_FANCY_MATH_387
14787 && TARGET_C99_FUNCTIONS"
14789 rtx mask = GEN_INT (0x45);
14790 rtx val = GEN_INT (0x05);
14794 rtx scratch = gen_reg_rtx (HImode);
14795 rtx res = gen_reg_rtx (QImode);
14797 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
14799 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
14800 emit_insn (gen_cmpqi_ext_3 (scratch, val));
14801 cond = gen_rtx_fmt_ee (EQ, QImode,
14802 gen_rtx_REG (CCmode, FLAGS_REG),
14804 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
14805 emit_insn (gen_zero_extendqisi2 (operands[0], res));
14809 (define_expand "isinf<mode>2"
14810 [(use (match_operand:SI 0 "register_operand"))
14811 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
14812 "TARGET_USE_FANCY_MATH_387
14813 && TARGET_C99_FUNCTIONS
14814 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14816 rtx mask = GEN_INT (0x45);
14817 rtx val = GEN_INT (0x05);
14821 rtx scratch = gen_reg_rtx (HImode);
14822 rtx res = gen_reg_rtx (QImode);
14824 /* Remove excess precision by forcing value through memory. */
14825 if (memory_operand (operands[1], VOIDmode))
14826 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
14829 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14831 emit_move_insn (temp, operands[1]);
14832 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
14835 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
14836 emit_insn (gen_cmpqi_ext_3 (scratch, val));
14837 cond = gen_rtx_fmt_ee (EQ, QImode,
14838 gen_rtx_REG (CCmode, FLAGS_REG),
14840 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
14841 emit_insn (gen_zero_extendqisi2 (operands[0], res));
14845 (define_expand "signbitxf2"
14846 [(use (match_operand:SI 0 "register_operand"))
14847 (use (match_operand:XF 1 "register_operand"))]
14848 "TARGET_USE_FANCY_MATH_387"
14850 rtx scratch = gen_reg_rtx (HImode);
14852 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
14853 emit_insn (gen_andsi3 (operands[0],
14854 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
14858 (define_insn "movmsk_df"
14859 [(set (match_operand:SI 0 "register_operand" "=r")
14861 [(match_operand:DF 1 "register_operand" "x")]
14863 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
14864 "%vmovmskpd\t{%1, %0|%0, %1}"
14865 [(set_attr "type" "ssemov")
14866 (set_attr "prefix" "maybe_vex")
14867 (set_attr "mode" "DF")])
14869 ;; Use movmskpd in SSE mode to avoid store forwarding stall
14870 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
14871 (define_expand "signbitdf2"
14872 [(use (match_operand:SI 0 "register_operand"))
14873 (use (match_operand:DF 1 "register_operand"))]
14874 "TARGET_USE_FANCY_MATH_387
14875 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14877 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
14879 emit_insn (gen_movmsk_df (operands[0], operands[1]));
14880 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
14884 rtx scratch = gen_reg_rtx (HImode);
14886 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
14887 emit_insn (gen_andsi3 (operands[0],
14888 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
14893 (define_expand "signbitsf2"
14894 [(use (match_operand:SI 0 "register_operand"))
14895 (use (match_operand:SF 1 "register_operand"))]
14896 "TARGET_USE_FANCY_MATH_387
14897 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
14899 rtx scratch = gen_reg_rtx (HImode);
14901 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
14902 emit_insn (gen_andsi3 (operands[0],
14903 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
14907 ;; Block operation instructions
14910 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
14913 [(set_attr "length" "1")
14914 (set_attr "length_immediate" "0")
14915 (set_attr "modrm" "0")])
14917 (define_expand "movmem<mode>"
14918 [(use (match_operand:BLK 0 "memory_operand"))
14919 (use (match_operand:BLK 1 "memory_operand"))
14920 (use (match_operand:SWI48 2 "nonmemory_operand"))
14921 (use (match_operand:SWI48 3 "const_int_operand"))
14922 (use (match_operand:SI 4 "const_int_operand"))
14923 (use (match_operand:SI 5 "const_int_operand"))]
14926 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
14927 operands[4], operands[5]))
14933 ;; Most CPUs don't like single string operations
14934 ;; Handle this case here to simplify previous expander.
14936 (define_expand "strmov"
14937 [(set (match_dup 4) (match_operand 3 "memory_operand"))
14938 (set (match_operand 1 "memory_operand") (match_dup 4))
14939 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
14940 (clobber (reg:CC FLAGS_REG))])
14941 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
14942 (clobber (reg:CC FLAGS_REG))])]
14945 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
14947 /* If .md ever supports :P for Pmode, these can be directly
14948 in the pattern above. */
14949 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
14950 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
14952 /* Can't use this if the user has appropriated esi or edi. */
14953 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
14954 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
14956 emit_insn (gen_strmov_singleop (operands[0], operands[1],
14957 operands[2], operands[3],
14958 operands[5], operands[6]));
14962 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
14965 (define_expand "strmov_singleop"
14966 [(parallel [(set (match_operand 1 "memory_operand")
14967 (match_operand 3 "memory_operand"))
14968 (set (match_operand 0 "register_operand")
14970 (set (match_operand 2 "register_operand")
14971 (match_operand 5))])]
14973 "ix86_current_function_needs_cld = 1;")
14975 (define_insn "*strmovdi_rex_1"
14976 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
14977 (mem:DI (match_operand:P 3 "register_operand" "1")))
14978 (set (match_operand:P 0 "register_operand" "=D")
14979 (plus:P (match_dup 2)
14981 (set (match_operand:P 1 "register_operand" "=S")
14982 (plus:P (match_dup 3)
14985 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
14987 [(set_attr "type" "str")
14988 (set_attr "memory" "both")
14989 (set_attr "mode" "DI")])
14991 (define_insn "*strmovsi_1"
14992 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
14993 (mem:SI (match_operand:P 3 "register_operand" "1")))
14994 (set (match_operand:P 0 "register_operand" "=D")
14995 (plus:P (match_dup 2)
14997 (set (match_operand:P 1 "register_operand" "=S")
14998 (plus:P (match_dup 3)
15000 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15002 [(set_attr "type" "str")
15003 (set_attr "memory" "both")
15004 (set_attr "mode" "SI")])
15006 (define_insn "*strmovhi_1"
15007 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15008 (mem:HI (match_operand:P 3 "register_operand" "1")))
15009 (set (match_operand:P 0 "register_operand" "=D")
15010 (plus:P (match_dup 2)
15012 (set (match_operand:P 1 "register_operand" "=S")
15013 (plus:P (match_dup 3)
15015 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15017 [(set_attr "type" "str")
15018 (set_attr "memory" "both")
15019 (set_attr "mode" "HI")])
15021 (define_insn "*strmovqi_1"
15022 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15023 (mem:QI (match_operand:P 3 "register_operand" "1")))
15024 (set (match_operand:P 0 "register_operand" "=D")
15025 (plus:P (match_dup 2)
15027 (set (match_operand:P 1 "register_operand" "=S")
15028 (plus:P (match_dup 3)
15030 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15032 [(set_attr "type" "str")
15033 (set_attr "memory" "both")
15034 (set (attr "prefix_rex")
15036 (match_test "<P:MODE>mode == DImode")
15038 (const_string "*")))
15039 (set_attr "mode" "QI")])
15041 (define_expand "rep_mov"
15042 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
15043 (set (match_operand 0 "register_operand")
15045 (set (match_operand 2 "register_operand")
15047 (set (match_operand 1 "memory_operand")
15048 (match_operand 3 "memory_operand"))
15049 (use (match_dup 4))])]
15051 "ix86_current_function_needs_cld = 1;")
15053 (define_insn "*rep_movdi_rex64"
15054 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15055 (set (match_operand:P 0 "register_operand" "=D")
15056 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15058 (match_operand:P 3 "register_operand" "0")))
15059 (set (match_operand:P 1 "register_operand" "=S")
15060 (plus:P (ashift:P (match_dup 5) (const_int 3))
15061 (match_operand:P 4 "register_operand" "1")))
15062 (set (mem:BLK (match_dup 3))
15063 (mem:BLK (match_dup 4)))
15064 (use (match_dup 5))]
15066 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15068 [(set_attr "type" "str")
15069 (set_attr "prefix_rep" "1")
15070 (set_attr "memory" "both")
15071 (set_attr "mode" "DI")])
15073 (define_insn "*rep_movsi"
15074 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15075 (set (match_operand:P 0 "register_operand" "=D")
15076 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15078 (match_operand:P 3 "register_operand" "0")))
15079 (set (match_operand:P 1 "register_operand" "=S")
15080 (plus:P (ashift:P (match_dup 5) (const_int 2))
15081 (match_operand:P 4 "register_operand" "1")))
15082 (set (mem:BLK (match_dup 3))
15083 (mem:BLK (match_dup 4)))
15084 (use (match_dup 5))]
15085 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15086 "%^rep{%;} movs{l|d}"
15087 [(set_attr "type" "str")
15088 (set_attr "prefix_rep" "1")
15089 (set_attr "memory" "both")
15090 (set_attr "mode" "SI")])
15092 (define_insn "*rep_movqi"
15093 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15094 (set (match_operand:P 0 "register_operand" "=D")
15095 (plus:P (match_operand:P 3 "register_operand" "0")
15096 (match_operand:P 5 "register_operand" "2")))
15097 (set (match_operand:P 1 "register_operand" "=S")
15098 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15099 (set (mem:BLK (match_dup 3))
15100 (mem:BLK (match_dup 4)))
15101 (use (match_dup 5))]
15102 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15104 [(set_attr "type" "str")
15105 (set_attr "prefix_rep" "1")
15106 (set_attr "memory" "both")
15107 (set_attr "mode" "QI")])
15109 (define_expand "setmem<mode>"
15110 [(use (match_operand:BLK 0 "memory_operand"))
15111 (use (match_operand:SWI48 1 "nonmemory_operand"))
15112 (use (match_operand:QI 2 "nonmemory_operand"))
15113 (use (match_operand 3 "const_int_operand"))
15114 (use (match_operand:SI 4 "const_int_operand"))
15115 (use (match_operand:SI 5 "const_int_operand"))]
15118 if (ix86_expand_setmem (operands[0], operands[1],
15119 operands[2], operands[3],
15120 operands[4], operands[5]))
15126 ;; Most CPUs don't like single string operations
15127 ;; Handle this case here to simplify previous expander.
15129 (define_expand "strset"
15130 [(set (match_operand 1 "memory_operand")
15131 (match_operand 2 "register_operand"))
15132 (parallel [(set (match_operand 0 "register_operand")
15134 (clobber (reg:CC FLAGS_REG))])]
15137 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15138 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15140 /* If .md ever supports :P for Pmode, this can be directly
15141 in the pattern above. */
15142 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15143 GEN_INT (GET_MODE_SIZE (GET_MODE
15145 /* Can't use this if the user has appropriated eax or edi. */
15146 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15147 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15149 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15155 (define_expand "strset_singleop"
15156 [(parallel [(set (match_operand 1 "memory_operand")
15157 (match_operand 2 "register_operand"))
15158 (set (match_operand 0 "register_operand")
15160 (unspec [(const_int 0)] UNSPEC_STOS)])]
15162 "ix86_current_function_needs_cld = 1;")
15164 (define_insn "*strsetdi_rex_1"
15165 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
15166 (match_operand:DI 2 "register_operand" "a"))
15167 (set (match_operand:P 0 "register_operand" "=D")
15168 (plus:P (match_dup 1)
15170 (unspec [(const_int 0)] UNSPEC_STOS)]
15172 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15174 [(set_attr "type" "str")
15175 (set_attr "memory" "store")
15176 (set_attr "mode" "DI")])
15178 (define_insn "*strsetsi_1"
15179 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15180 (match_operand:SI 2 "register_operand" "a"))
15181 (set (match_operand:P 0 "register_operand" "=D")
15182 (plus:P (match_dup 1)
15184 (unspec [(const_int 0)] UNSPEC_STOS)]
15185 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15187 [(set_attr "type" "str")
15188 (set_attr "memory" "store")
15189 (set_attr "mode" "SI")])
15191 (define_insn "*strsethi_1"
15192 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15193 (match_operand:HI 2 "register_operand" "a"))
15194 (set (match_operand:P 0 "register_operand" "=D")
15195 (plus:P (match_dup 1)
15197 (unspec [(const_int 0)] UNSPEC_STOS)]
15198 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15200 [(set_attr "type" "str")
15201 (set_attr "memory" "store")
15202 (set_attr "mode" "HI")])
15204 (define_insn "*strsetqi_1"
15205 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15206 (match_operand:QI 2 "register_operand" "a"))
15207 (set (match_operand:P 0 "register_operand" "=D")
15208 (plus:P (match_dup 1)
15210 (unspec [(const_int 0)] UNSPEC_STOS)]
15211 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15213 [(set_attr "type" "str")
15214 (set_attr "memory" "store")
15215 (set (attr "prefix_rex")
15217 (match_test "<P:MODE>mode == DImode")
15219 (const_string "*")))
15220 (set_attr "mode" "QI")])
15222 (define_expand "rep_stos"
15223 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
15224 (set (match_operand 0 "register_operand")
15226 (set (match_operand 2 "memory_operand") (const_int 0))
15227 (use (match_operand 3 "register_operand"))
15228 (use (match_dup 1))])]
15230 "ix86_current_function_needs_cld = 1;")
15232 (define_insn "*rep_stosdi_rex64"
15233 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15234 (set (match_operand:P 0 "register_operand" "=D")
15235 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15237 (match_operand:P 3 "register_operand" "0")))
15238 (set (mem:BLK (match_dup 3))
15240 (use (match_operand:DI 2 "register_operand" "a"))
15241 (use (match_dup 4))]
15243 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15245 [(set_attr "type" "str")
15246 (set_attr "prefix_rep" "1")
15247 (set_attr "memory" "store")
15248 (set_attr "mode" "DI")])
15250 (define_insn "*rep_stossi"
15251 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15252 (set (match_operand:P 0 "register_operand" "=D")
15253 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15255 (match_operand:P 3 "register_operand" "0")))
15256 (set (mem:BLK (match_dup 3))
15258 (use (match_operand:SI 2 "register_operand" "a"))
15259 (use (match_dup 4))]
15260 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15261 "%^rep{%;} stos{l|d}"
15262 [(set_attr "type" "str")
15263 (set_attr "prefix_rep" "1")
15264 (set_attr "memory" "store")
15265 (set_attr "mode" "SI")])
15267 (define_insn "*rep_stosqi"
15268 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15269 (set (match_operand:P 0 "register_operand" "=D")
15270 (plus:P (match_operand:P 3 "register_operand" "0")
15271 (match_operand:P 4 "register_operand" "1")))
15272 (set (mem:BLK (match_dup 3))
15274 (use (match_operand:QI 2 "register_operand" "a"))
15275 (use (match_dup 4))]
15276 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15278 [(set_attr "type" "str")
15279 (set_attr "prefix_rep" "1")
15280 (set_attr "memory" "store")
15281 (set (attr "prefix_rex")
15283 (match_test "<P:MODE>mode == DImode")
15285 (const_string "*")))
15286 (set_attr "mode" "QI")])
15288 (define_expand "cmpstrnsi"
15289 [(set (match_operand:SI 0 "register_operand")
15290 (compare:SI (match_operand:BLK 1 "general_operand")
15291 (match_operand:BLK 2 "general_operand")))
15292 (use (match_operand 3 "general_operand"))
15293 (use (match_operand 4 "immediate_operand"))]
15296 rtx addr1, addr2, out, outlow, count, countreg, align;
15298 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15301 /* Can't use this if the user has appropriated ecx, esi or edi. */
15302 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
15307 out = gen_reg_rtx (SImode);
15309 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
15310 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
15311 if (addr1 != XEXP (operands[1], 0))
15312 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15313 if (addr2 != XEXP (operands[2], 0))
15314 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15316 count = operands[3];
15317 countreg = ix86_zero_extend_to_Pmode (count);
15319 /* %%% Iff we are testing strict equality, we can use known alignment
15320 to good advantage. This may be possible with combine, particularly
15321 once cc0 is dead. */
15322 align = operands[4];
15324 if (CONST_INT_P (count))
15326 if (INTVAL (count) == 0)
15328 emit_move_insn (operands[0], const0_rtx);
15331 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15332 operands[1], operands[2]));
15336 rtx (*gen_cmp) (rtx, rtx);
15338 gen_cmp = (TARGET_64BIT
15339 ? gen_cmpdi_1 : gen_cmpsi_1);
15341 emit_insn (gen_cmp (countreg, countreg));
15342 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15343 operands[1], operands[2]));
15346 outlow = gen_lowpart (QImode, out);
15347 emit_insn (gen_cmpintqi (outlow));
15348 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15350 if (operands[0] != out)
15351 emit_move_insn (operands[0], out);
15356 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15358 (define_expand "cmpintqi"
15359 [(set (match_dup 1)
15360 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15362 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15363 (parallel [(set (match_operand:QI 0 "register_operand")
15364 (minus:QI (match_dup 1)
15366 (clobber (reg:CC FLAGS_REG))])]
15369 operands[1] = gen_reg_rtx (QImode);
15370 operands[2] = gen_reg_rtx (QImode);
15373 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15374 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
15376 (define_expand "cmpstrnqi_nz_1"
15377 [(parallel [(set (reg:CC FLAGS_REG)
15378 (compare:CC (match_operand 4 "memory_operand")
15379 (match_operand 5 "memory_operand")))
15380 (use (match_operand 2 "register_operand"))
15381 (use (match_operand:SI 3 "immediate_operand"))
15382 (clobber (match_operand 0 "register_operand"))
15383 (clobber (match_operand 1 "register_operand"))
15384 (clobber (match_dup 2))])]
15386 "ix86_current_function_needs_cld = 1;")
15388 (define_insn "*cmpstrnqi_nz_1"
15389 [(set (reg:CC FLAGS_REG)
15390 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15391 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
15392 (use (match_operand:P 6 "register_operand" "2"))
15393 (use (match_operand:SI 3 "immediate_operand" "i"))
15394 (clobber (match_operand:P 0 "register_operand" "=S"))
15395 (clobber (match_operand:P 1 "register_operand" "=D"))
15396 (clobber (match_operand:P 2 "register_operand" "=c"))]
15397 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15399 [(set_attr "type" "str")
15400 (set_attr "mode" "QI")
15401 (set (attr "prefix_rex")
15403 (match_test "<P:MODE>mode == DImode")
15405 (const_string "*")))
15406 (set_attr "prefix_rep" "1")])
15408 ;; The same, but the count is not known to not be zero.
15410 (define_expand "cmpstrnqi_1"
15411 [(parallel [(set (reg:CC FLAGS_REG)
15412 (if_then_else:CC (ne (match_operand 2 "register_operand")
15414 (compare:CC (match_operand 4 "memory_operand")
15415 (match_operand 5 "memory_operand"))
15417 (use (match_operand:SI 3 "immediate_operand"))
15418 (use (reg:CC FLAGS_REG))
15419 (clobber (match_operand 0 "register_operand"))
15420 (clobber (match_operand 1 "register_operand"))
15421 (clobber (match_dup 2))])]
15423 "ix86_current_function_needs_cld = 1;")
15425 (define_insn "*cmpstrnqi_1"
15426 [(set (reg:CC FLAGS_REG)
15427 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
15429 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15430 (mem:BLK (match_operand:P 5 "register_operand" "1")))
15432 (use (match_operand:SI 3 "immediate_operand" "i"))
15433 (use (reg:CC FLAGS_REG))
15434 (clobber (match_operand:P 0 "register_operand" "=S"))
15435 (clobber (match_operand:P 1 "register_operand" "=D"))
15436 (clobber (match_operand:P 2 "register_operand" "=c"))]
15437 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15439 [(set_attr "type" "str")
15440 (set_attr "mode" "QI")
15441 (set (attr "prefix_rex")
15443 (match_test "<P:MODE>mode == DImode")
15445 (const_string "*")))
15446 (set_attr "prefix_rep" "1")])
15448 (define_expand "strlen<mode>"
15449 [(set (match_operand:P 0 "register_operand")
15450 (unspec:P [(match_operand:BLK 1 "general_operand")
15451 (match_operand:QI 2 "immediate_operand")
15452 (match_operand 3 "immediate_operand")]
15456 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15462 (define_expand "strlenqi_1"
15463 [(parallel [(set (match_operand 0 "register_operand")
15465 (clobber (match_operand 1 "register_operand"))
15466 (clobber (reg:CC FLAGS_REG))])]
15468 "ix86_current_function_needs_cld = 1;")
15470 (define_insn "*strlenqi_1"
15471 [(set (match_operand:P 0 "register_operand" "=&c")
15472 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
15473 (match_operand:QI 2 "register_operand" "a")
15474 (match_operand:P 3 "immediate_operand" "i")
15475 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
15476 (clobber (match_operand:P 1 "register_operand" "=D"))
15477 (clobber (reg:CC FLAGS_REG))]
15478 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15479 "%^repnz{%;} scasb"
15480 [(set_attr "type" "str")
15481 (set_attr "mode" "QI")
15482 (set (attr "prefix_rex")
15484 (match_test "<P:MODE>mode == DImode")
15486 (const_string "*")))
15487 (set_attr "prefix_rep" "1")])
15489 ;; Peephole optimizations to clean up after cmpstrn*. This should be
15490 ;; handled in combine, but it is not currently up to the task.
15491 ;; When used for their truth value, the cmpstrn* expanders generate
15500 ;; The intermediate three instructions are unnecessary.
15502 ;; This one handles cmpstrn*_nz_1...
15505 (set (reg:CC FLAGS_REG)
15506 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
15507 (mem:BLK (match_operand 5 "register_operand"))))
15508 (use (match_operand 6 "register_operand"))
15509 (use (match_operand:SI 3 "immediate_operand"))
15510 (clobber (match_operand 0 "register_operand"))
15511 (clobber (match_operand 1 "register_operand"))
15512 (clobber (match_operand 2 "register_operand"))])
15513 (set (match_operand:QI 7 "register_operand")
15514 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15515 (set (match_operand:QI 8 "register_operand")
15516 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15517 (set (reg FLAGS_REG)
15518 (compare (match_dup 7) (match_dup 8)))
15520 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15522 (set (reg:CC FLAGS_REG)
15523 (compare:CC (mem:BLK (match_dup 4))
15524 (mem:BLK (match_dup 5))))
15525 (use (match_dup 6))
15526 (use (match_dup 3))
15527 (clobber (match_dup 0))
15528 (clobber (match_dup 1))
15529 (clobber (match_dup 2))])])
15531 ;; ...and this one handles cmpstrn*_1.
15534 (set (reg:CC FLAGS_REG)
15535 (if_then_else:CC (ne (match_operand 6 "register_operand")
15537 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
15538 (mem:BLK (match_operand 5 "register_operand")))
15540 (use (match_operand:SI 3 "immediate_operand"))
15541 (use (reg:CC FLAGS_REG))
15542 (clobber (match_operand 0 "register_operand"))
15543 (clobber (match_operand 1 "register_operand"))
15544 (clobber (match_operand 2 "register_operand"))])
15545 (set (match_operand:QI 7 "register_operand")
15546 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15547 (set (match_operand:QI 8 "register_operand")
15548 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15549 (set (reg FLAGS_REG)
15550 (compare (match_dup 7) (match_dup 8)))
15552 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15554 (set (reg:CC FLAGS_REG)
15555 (if_then_else:CC (ne (match_dup 6)
15557 (compare:CC (mem:BLK (match_dup 4))
15558 (mem:BLK (match_dup 5)))
15560 (use (match_dup 3))
15561 (use (reg:CC FLAGS_REG))
15562 (clobber (match_dup 0))
15563 (clobber (match_dup 1))
15564 (clobber (match_dup 2))])])
15566 ;; Conditional move instructions.
15568 (define_expand "mov<mode>cc"
15569 [(set (match_operand:SWIM 0 "register_operand")
15570 (if_then_else:SWIM (match_operand 1 "comparison_operator")
15571 (match_operand:SWIM 2 "<general_operand>")
15572 (match_operand:SWIM 3 "<general_operand>")))]
15574 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
15576 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
15577 ;; the register first winds up with `sbbl $0,reg', which is also weird.
15578 ;; So just document what we're doing explicitly.
15580 (define_expand "x86_mov<mode>cc_0_m1"
15582 [(set (match_operand:SWI48 0 "register_operand")
15583 (if_then_else:SWI48
15584 (match_operator:SWI48 2 "ix86_carry_flag_operator"
15585 [(match_operand 1 "flags_reg_operand")
15589 (clobber (reg:CC FLAGS_REG))])])
15591 (define_insn "*x86_mov<mode>cc_0_m1"
15592 [(set (match_operand:SWI48 0 "register_operand" "=r")
15593 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15594 [(reg FLAGS_REG) (const_int 0)])
15597 (clobber (reg:CC FLAGS_REG))]
15599 "sbb{<imodesuffix>}\t%0, %0"
15600 ; Since we don't have the proper number of operands for an alu insn,
15601 ; fill in all the blanks.
15602 [(set_attr "type" "alu")
15603 (set_attr "use_carry" "1")
15604 (set_attr "pent_pair" "pu")
15605 (set_attr "memory" "none")
15606 (set_attr "imm_disp" "false")
15607 (set_attr "mode" "<MODE>")
15608 (set_attr "length_immediate" "0")])
15610 (define_insn "*x86_mov<mode>cc_0_m1_se"
15611 [(set (match_operand:SWI48 0 "register_operand" "=r")
15612 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15613 [(reg FLAGS_REG) (const_int 0)])
15616 (clobber (reg:CC FLAGS_REG))]
15618 "sbb{<imodesuffix>}\t%0, %0"
15619 [(set_attr "type" "alu")
15620 (set_attr "use_carry" "1")
15621 (set_attr "pent_pair" "pu")
15622 (set_attr "memory" "none")
15623 (set_attr "imm_disp" "false")
15624 (set_attr "mode" "<MODE>")
15625 (set_attr "length_immediate" "0")])
15627 (define_insn "*x86_mov<mode>cc_0_m1_neg"
15628 [(set (match_operand:SWI48 0 "register_operand" "=r")
15629 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15630 [(reg FLAGS_REG) (const_int 0)])))
15631 (clobber (reg:CC FLAGS_REG))]
15633 "sbb{<imodesuffix>}\t%0, %0"
15634 [(set_attr "type" "alu")
15635 (set_attr "use_carry" "1")
15636 (set_attr "pent_pair" "pu")
15637 (set_attr "memory" "none")
15638 (set_attr "imm_disp" "false")
15639 (set_attr "mode" "<MODE>")
15640 (set_attr "length_immediate" "0")])
15642 (define_insn "*mov<mode>cc_noc"
15643 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
15644 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
15645 [(reg FLAGS_REG) (const_int 0)])
15646 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
15647 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
15648 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
15650 cmov%O2%C1\t{%2, %0|%0, %2}
15651 cmov%O2%c1\t{%3, %0|%0, %3}"
15652 [(set_attr "type" "icmov")
15653 (set_attr "mode" "<MODE>")])
15655 ;; Don't do conditional moves with memory inputs. This splitter helps
15656 ;; register starved x86_32 by forcing inputs into registers before reload.
15658 [(set (match_operand:SWI248 0 "register_operand")
15659 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
15660 [(reg FLAGS_REG) (const_int 0)])
15661 (match_operand:SWI248 2 "nonimmediate_operand")
15662 (match_operand:SWI248 3 "nonimmediate_operand")))]
15663 "!TARGET_64BIT && TARGET_CMOVE
15664 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
15665 && (MEM_P (operands[2]) || MEM_P (operands[3]))
15666 && can_create_pseudo_p ()
15667 && optimize_insn_for_speed_p ()"
15668 [(set (match_dup 0)
15669 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
15671 if (MEM_P (operands[2]))
15672 operands[2] = force_reg (<MODE>mode, operands[2]);
15673 if (MEM_P (operands[3]))
15674 operands[3] = force_reg (<MODE>mode, operands[3]);
15677 (define_insn "*movqicc_noc"
15678 [(set (match_operand:QI 0 "register_operand" "=r,r")
15679 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
15680 [(reg FLAGS_REG) (const_int 0)])
15681 (match_operand:QI 2 "register_operand" "r,0")
15682 (match_operand:QI 3 "register_operand" "0,r")))]
15683 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
15685 [(set_attr "type" "icmov")
15686 (set_attr "mode" "QI")])
15689 [(set (match_operand:SWI12 0 "register_operand")
15690 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
15691 [(reg FLAGS_REG) (const_int 0)])
15692 (match_operand:SWI12 2 "register_operand")
15693 (match_operand:SWI12 3 "register_operand")))]
15694 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
15695 && reload_completed"
15696 [(set (match_dup 0)
15697 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
15699 operands[0] = gen_lowpart (SImode, operands[0]);
15700 operands[2] = gen_lowpart (SImode, operands[2]);
15701 operands[3] = gen_lowpart (SImode, operands[3]);
15704 ;; Don't do conditional moves with memory inputs
15706 [(match_scratch:SWI248 2 "r")
15707 (set (match_operand:SWI248 0 "register_operand")
15708 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
15709 [(reg FLAGS_REG) (const_int 0)])
15711 (match_operand:SWI248 3 "memory_operand")))]
15712 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
15713 && optimize_insn_for_speed_p ()"
15714 [(set (match_dup 2) (match_dup 3))
15716 (if_then_else:SWI248 (match_dup 1) (match_dup 0) (match_dup 2)))])
15719 [(match_scratch:SWI248 2 "r")
15720 (set (match_operand:SWI248 0 "register_operand")
15721 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
15722 [(reg FLAGS_REG) (const_int 0)])
15723 (match_operand:SWI248 3 "memory_operand")
15725 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
15726 && optimize_insn_for_speed_p ()"
15727 [(set (match_dup 2) (match_dup 3))
15729 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 0)))])
15731 (define_expand "mov<mode>cc"
15732 [(set (match_operand:X87MODEF 0 "register_operand")
15733 (if_then_else:X87MODEF
15734 (match_operand 1 "comparison_operator")
15735 (match_operand:X87MODEF 2 "register_operand")
15736 (match_operand:X87MODEF 3 "register_operand")))]
15737 "(TARGET_80387 && TARGET_CMOVE)
15738 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15739 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
15741 (define_insn "*movxfcc_1"
15742 [(set (match_operand:XF 0 "register_operand" "=f,f")
15743 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
15744 [(reg FLAGS_REG) (const_int 0)])
15745 (match_operand:XF 2 "register_operand" "f,0")
15746 (match_operand:XF 3 "register_operand" "0,f")))]
15747 "TARGET_80387 && TARGET_CMOVE"
15749 fcmov%F1\t{%2, %0|%0, %2}
15750 fcmov%f1\t{%3, %0|%0, %3}"
15751 [(set_attr "type" "fcmov")
15752 (set_attr "mode" "XF")])
15754 (define_insn "*movdfcc_1"
15755 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
15756 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
15757 [(reg FLAGS_REG) (const_int 0)])
15758 (match_operand:DF 2 "nonimmediate_operand"
15760 (match_operand:DF 3 "nonimmediate_operand"
15761 "0 ,f,0 ,rm,0, rm")))]
15762 "TARGET_80387 && TARGET_CMOVE
15763 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
15765 fcmov%F1\t{%2, %0|%0, %2}
15766 fcmov%f1\t{%3, %0|%0, %3}
15769 cmov%O2%C1\t{%2, %0|%0, %2}
15770 cmov%O2%c1\t{%3, %0|%0, %3}"
15771 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
15772 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
15773 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
15776 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
15777 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
15778 [(reg FLAGS_REG) (const_int 0)])
15779 (match_operand:DF 2 "nonimmediate_operand")
15780 (match_operand:DF 3 "nonimmediate_operand")))]
15781 "!TARGET_64BIT && reload_completed"
15782 [(set (match_dup 2)
15783 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
15785 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
15787 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
15788 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
15791 (define_insn "*movsfcc_1_387"
15792 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
15793 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
15794 [(reg FLAGS_REG) (const_int 0)])
15795 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
15796 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
15797 "TARGET_80387 && TARGET_CMOVE
15798 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
15800 fcmov%F1\t{%2, %0|%0, %2}
15801 fcmov%f1\t{%3, %0|%0, %3}
15802 cmov%O2%C1\t{%2, %0|%0, %2}
15803 cmov%O2%c1\t{%3, %0|%0, %3}"
15804 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
15805 (set_attr "mode" "SF,SF,SI,SI")])
15807 ;; Don't do conditional moves with memory inputs. This splitter helps
15808 ;; register starved x86_32 by forcing inputs into registers before reload.
15810 [(set (match_operand:MODEF 0 "register_operand")
15811 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
15812 [(reg FLAGS_REG) (const_int 0)])
15813 (match_operand:MODEF 2 "nonimmediate_operand")
15814 (match_operand:MODEF 3 "nonimmediate_operand")))]
15815 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
15816 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
15817 && (MEM_P (operands[2]) || MEM_P (operands[3]))
15818 && can_create_pseudo_p ()
15819 && optimize_insn_for_speed_p ()"
15820 [(set (match_dup 0)
15821 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
15823 if (MEM_P (operands[2]))
15824 operands[2] = force_reg (<MODE>mode, operands[2]);
15825 if (MEM_P (operands[3]))
15826 operands[3] = force_reg (<MODE>mode, operands[3]);
15829 ;; Don't do conditional moves with memory inputs
15831 [(match_scratch:MODEF 2 "r")
15832 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
15833 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
15834 [(reg FLAGS_REG) (const_int 0)])
15836 (match_operand:MODEF 3 "memory_operand")))]
15837 "(<MODE>mode != DFmode || TARGET_64BIT)
15838 && TARGET_80387 && TARGET_CMOVE
15839 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
15840 && optimize_insn_for_speed_p ()"
15841 [(set (match_dup 2) (match_dup 3))
15843 (if_then_else:MODEF (match_dup 1) (match_dup 0) (match_dup 2)))])
15846 [(match_scratch:MODEF 2 "r")
15847 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
15848 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
15849 [(reg FLAGS_REG) (const_int 0)])
15850 (match_operand:MODEF 3 "memory_operand")
15852 "(<MODE>mode != DFmode || TARGET_64BIT)
15853 && TARGET_80387 && TARGET_CMOVE
15854 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
15855 && optimize_insn_for_speed_p ()"
15856 [(set (match_dup 2) (match_dup 3))
15858 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 0)))])
15860 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
15861 ;; the scalar versions to have only XMM registers as operands.
15863 ;; XOP conditional move
15864 (define_insn "*xop_pcmov_<mode>"
15865 [(set (match_operand:MODEF 0 "register_operand" "=x")
15866 (if_then_else:MODEF
15867 (match_operand:MODEF 1 "register_operand" "x")
15868 (match_operand:MODEF 2 "register_operand" "x")
15869 (match_operand:MODEF 3 "register_operand" "x")))]
15871 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
15872 [(set_attr "type" "sse4arg")])
15874 ;; These versions of the min/max patterns are intentionally ignorant of
15875 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
15876 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
15877 ;; are undefined in this condition, we're certain this is correct.
15879 (define_insn "<code><mode>3"
15880 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
15882 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
15883 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
15884 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15886 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
15887 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
15888 [(set_attr "isa" "noavx,avx")
15889 (set_attr "prefix" "orig,vex")
15890 (set_attr "type" "sseadd")
15891 (set_attr "mode" "<MODE>")])
15893 ;; These versions of the min/max patterns implement exactly the operations
15894 ;; min = (op1 < op2 ? op1 : op2)
15895 ;; max = (!(op1 < op2) ? op1 : op2)
15896 ;; Their operands are not commutative, and thus they may be used in the
15897 ;; presence of -0.0 and NaN.
15899 (define_int_iterator IEEE_MAXMIN
15903 (define_int_attr ieee_maxmin
15904 [(UNSPEC_IEEE_MAX "max")
15905 (UNSPEC_IEEE_MIN "min")])
15907 (define_insn "*ieee_s<ieee_maxmin><mode>3"
15908 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
15910 [(match_operand:MODEF 1 "register_operand" "0,x")
15911 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
15913 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15915 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
15916 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
15917 [(set_attr "isa" "noavx,avx")
15918 (set_attr "prefix" "orig,vex")
15919 (set_attr "type" "sseadd")
15920 (set_attr "mode" "<MODE>")])
15922 ;; Make two stack loads independent:
15924 ;; fld %st(0) -> fld bb
15925 ;; fmul bb fmul %st(1), %st
15927 ;; Actually we only match the last two instructions for simplicity.
15929 [(set (match_operand 0 "fp_register_operand")
15930 (match_operand 1 "fp_register_operand"))
15932 (match_operator 2 "binary_fp_operator"
15934 (match_operand 3 "memory_operand")]))]
15935 "REGNO (operands[0]) != REGNO (operands[1])"
15936 [(set (match_dup 0) (match_dup 3))
15937 (set (match_dup 0) (match_dup 4))]
15939 ;; The % modifier is not operational anymore in peephole2's, so we have to
15940 ;; swap the operands manually in the case of addition and multiplication.
15944 if (COMMUTATIVE_ARITH_P (operands[2]))
15945 op0 = operands[0], op1 = operands[1];
15947 op0 = operands[1], op1 = operands[0];
15949 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
15950 GET_MODE (operands[2]),
15954 ;; Conditional addition patterns
15955 (define_expand "add<mode>cc"
15956 [(match_operand:SWI 0 "register_operand")
15957 (match_operand 1 "ordered_comparison_operator")
15958 (match_operand:SWI 2 "register_operand")
15959 (match_operand:SWI 3 "const_int_operand")]
15961 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
15963 ;; Misc patterns (?)
15965 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
15966 ;; Otherwise there will be nothing to keep
15968 ;; [(set (reg ebp) (reg esp))]
15969 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
15970 ;; (clobber (eflags)]
15971 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
15973 ;; in proper program order.
15975 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
15976 [(set (match_operand:P 0 "register_operand" "=r,r")
15977 (plus:P (match_operand:P 1 "register_operand" "0,r")
15978 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
15979 (clobber (reg:CC FLAGS_REG))
15980 (clobber (mem:BLK (scratch)))]
15983 switch (get_attr_type (insn))
15986 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
15989 gcc_assert (rtx_equal_p (operands[0], operands[1]));
15990 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
15991 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
15993 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
15996 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
15997 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16000 [(set (attr "type")
16001 (cond [(and (eq_attr "alternative" "0")
16002 (not (match_test "TARGET_OPT_AGU")))
16003 (const_string "alu")
16004 (match_operand:<MODE> 2 "const0_operand")
16005 (const_string "imov")
16007 (const_string "lea")))
16008 (set (attr "length_immediate")
16009 (cond [(eq_attr "type" "imov")
16011 (and (eq_attr "type" "alu")
16012 (match_operand 2 "const128_operand"))
16015 (const_string "*")))
16016 (set_attr "mode" "<MODE>")])
16018 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16019 [(set (match_operand:P 0 "register_operand" "=r")
16020 (minus:P (match_operand:P 1 "register_operand" "0")
16021 (match_operand:P 2 "register_operand" "r")))
16022 (clobber (reg:CC FLAGS_REG))
16023 (clobber (mem:BLK (scratch)))]
16025 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16026 [(set_attr "type" "alu")
16027 (set_attr "mode" "<MODE>")])
16029 (define_insn "allocate_stack_worker_probe_<mode>"
16030 [(set (match_operand:P 0 "register_operand" "=a")
16031 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16032 UNSPECV_STACK_PROBE))
16033 (clobber (reg:CC FLAGS_REG))]
16034 "ix86_target_stack_probe ()"
16035 "call\t___chkstk_ms"
16036 [(set_attr "type" "multi")
16037 (set_attr "length" "5")])
16039 (define_expand "allocate_stack"
16040 [(match_operand 0 "register_operand")
16041 (match_operand 1 "general_operand")]
16042 "ix86_target_stack_probe ()"
16046 #ifndef CHECK_STACK_LIMIT
16047 #define CHECK_STACK_LIMIT 0
16050 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16051 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16055 rtx (*insn) (rtx, rtx);
16057 x = copy_to_mode_reg (Pmode, operands[1]);
16059 insn = (TARGET_64BIT
16060 ? gen_allocate_stack_worker_probe_di
16061 : gen_allocate_stack_worker_probe_si);
16063 emit_insn (insn (x, x));
16066 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16067 stack_pointer_rtx, 0, OPTAB_DIRECT);
16069 if (x != stack_pointer_rtx)
16070 emit_move_insn (stack_pointer_rtx, x);
16072 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16076 ;; Use IOR for stack probes, this is shorter.
16077 (define_expand "probe_stack"
16078 [(match_operand 0 "memory_operand")]
16081 rtx (*gen_ior3) (rtx, rtx, rtx);
16083 gen_ior3 = (GET_MODE (operands[0]) == DImode
16084 ? gen_iordi3 : gen_iorsi3);
16086 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16090 (define_insn "adjust_stack_and_probe<mode>"
16091 [(set (match_operand:P 0 "register_operand" "=r")
16092 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16093 UNSPECV_PROBE_STACK_RANGE))
16094 (set (reg:P SP_REG)
16095 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16096 (clobber (reg:CC FLAGS_REG))
16097 (clobber (mem:BLK (scratch)))]
16099 "* return output_adjust_stack_and_probe (operands[0]);"
16100 [(set_attr "type" "multi")])
16102 (define_insn "probe_stack_range<mode>"
16103 [(set (match_operand:P 0 "register_operand" "=r")
16104 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16105 (match_operand:P 2 "const_int_operand" "n")]
16106 UNSPECV_PROBE_STACK_RANGE))
16107 (clobber (reg:CC FLAGS_REG))]
16109 "* return output_probe_stack_range (operands[0], operands[2]);"
16110 [(set_attr "type" "multi")])
16112 (define_expand "builtin_setjmp_receiver"
16113 [(label_ref (match_operand 0))]
16114 "!TARGET_64BIT && flag_pic"
16120 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16121 rtx label_rtx = gen_label_rtx ();
16122 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16123 xops[0] = xops[1] = picreg;
16124 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16125 ix86_expand_binary_operator (MINUS, SImode, xops);
16129 emit_insn (gen_set_got (pic_offset_table_rtx));
16133 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16136 [(set (match_operand 0 "register_operand")
16137 (match_operator 3 "promotable_binary_operator"
16138 [(match_operand 1 "register_operand")
16139 (match_operand 2 "aligned_operand")]))
16140 (clobber (reg:CC FLAGS_REG))]
16141 "! TARGET_PARTIAL_REG_STALL && reload_completed
16142 && ((GET_MODE (operands[0]) == HImode
16143 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16144 /* ??? next two lines just !satisfies_constraint_K (...) */
16145 || !CONST_INT_P (operands[2])
16146 || satisfies_constraint_K (operands[2])))
16147 || (GET_MODE (operands[0]) == QImode
16148 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16149 [(parallel [(set (match_dup 0)
16150 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16151 (clobber (reg:CC FLAGS_REG))])]
16153 operands[0] = gen_lowpart (SImode, operands[0]);
16154 operands[1] = gen_lowpart (SImode, operands[1]);
16155 if (GET_CODE (operands[3]) != ASHIFT)
16156 operands[2] = gen_lowpart (SImode, operands[2]);
16157 PUT_MODE (operands[3], SImode);
16160 ; Promote the QImode tests, as i386 has encoding of the AND
16161 ; instruction with 32-bit sign-extended immediate and thus the
16162 ; instruction size is unchanged, except in the %eax case for
16163 ; which it is increased by one byte, hence the ! optimize_size.
16165 [(set (match_operand 0 "flags_reg_operand")
16166 (match_operator 2 "compare_operator"
16167 [(and (match_operand 3 "aligned_operand")
16168 (match_operand 4 "const_int_operand"))
16170 (set (match_operand 1 "register_operand")
16171 (and (match_dup 3) (match_dup 4)))]
16172 "! TARGET_PARTIAL_REG_STALL && reload_completed
16173 && optimize_insn_for_speed_p ()
16174 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16175 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16176 /* Ensure that the operand will remain sign-extended immediate. */
16177 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16178 [(parallel [(set (match_dup 0)
16179 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16182 (and:SI (match_dup 3) (match_dup 4)))])]
16185 = gen_int_mode (INTVAL (operands[4])
16186 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16187 operands[1] = gen_lowpart (SImode, operands[1]);
16188 operands[3] = gen_lowpart (SImode, operands[3]);
16191 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16192 ; the TEST instruction with 32-bit sign-extended immediate and thus
16193 ; the instruction size would at least double, which is not what we
16194 ; want even with ! optimize_size.
16196 [(set (match_operand 0 "flags_reg_operand")
16197 (match_operator 1 "compare_operator"
16198 [(and (match_operand:HI 2 "aligned_operand")
16199 (match_operand:HI 3 "const_int_operand"))
16201 "! TARGET_PARTIAL_REG_STALL && reload_completed
16202 && ! TARGET_FAST_PREFIX
16203 && optimize_insn_for_speed_p ()
16204 /* Ensure that the operand will remain sign-extended immediate. */
16205 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16206 [(set (match_dup 0)
16207 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16211 = gen_int_mode (INTVAL (operands[3])
16212 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16213 operands[2] = gen_lowpart (SImode, operands[2]);
16217 [(set (match_operand 0 "register_operand")
16218 (neg (match_operand 1 "register_operand")))
16219 (clobber (reg:CC FLAGS_REG))]
16220 "! TARGET_PARTIAL_REG_STALL && reload_completed
16221 && (GET_MODE (operands[0]) == HImode
16222 || (GET_MODE (operands[0]) == QImode
16223 && (TARGET_PROMOTE_QImode
16224 || optimize_insn_for_size_p ())))"
16225 [(parallel [(set (match_dup 0)
16226 (neg:SI (match_dup 1)))
16227 (clobber (reg:CC FLAGS_REG))])]
16229 operands[0] = gen_lowpart (SImode, operands[0]);
16230 operands[1] = gen_lowpart (SImode, operands[1]);
16234 [(set (match_operand 0 "register_operand")
16235 (not (match_operand 1 "register_operand")))]
16236 "! TARGET_PARTIAL_REG_STALL && reload_completed
16237 && (GET_MODE (operands[0]) == HImode
16238 || (GET_MODE (operands[0]) == QImode
16239 && (TARGET_PROMOTE_QImode
16240 || optimize_insn_for_size_p ())))"
16241 [(set (match_dup 0)
16242 (not:SI (match_dup 1)))]
16244 operands[0] = gen_lowpart (SImode, operands[0]);
16245 operands[1] = gen_lowpart (SImode, operands[1]);
16248 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16249 ;; transform a complex memory operation into two memory to register operations.
16251 ;; Don't push memory operands
16253 [(set (match_operand:SWI 0 "push_operand")
16254 (match_operand:SWI 1 "memory_operand"))
16255 (match_scratch:SWI 2 "<r>")]
16256 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16257 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16258 [(set (match_dup 2) (match_dup 1))
16259 (set (match_dup 0) (match_dup 2))])
16261 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16264 [(set (match_operand:SF 0 "push_operand")
16265 (match_operand:SF 1 "memory_operand"))
16266 (match_scratch:SF 2 "r")]
16267 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16268 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16269 [(set (match_dup 2) (match_dup 1))
16270 (set (match_dup 0) (match_dup 2))])
16272 ;; Don't move an immediate directly to memory when the instruction
16273 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
16275 [(match_scratch:SWI124 1 "<r>")
16276 (set (match_operand:SWI124 0 "memory_operand")
16278 "optimize_insn_for_speed_p ()
16279 && ((<MODE>mode == HImode
16280 && TARGET_LCP_STALL)
16281 || (!TARGET_USE_MOV0
16282 && TARGET_SPLIT_LONG_MOVES
16283 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
16284 && peep2_regno_dead_p (0, FLAGS_REG)"
16285 [(parallel [(set (match_dup 2) (const_int 0))
16286 (clobber (reg:CC FLAGS_REG))])
16287 (set (match_dup 0) (match_dup 1))]
16288 "operands[2] = gen_lowpart (SImode, operands[1]);")
16291 [(match_scratch:SWI124 2 "<r>")
16292 (set (match_operand:SWI124 0 "memory_operand")
16293 (match_operand:SWI124 1 "immediate_operand"))]
16294 "optimize_insn_for_speed_p ()
16295 && ((<MODE>mode == HImode
16296 && TARGET_LCP_STALL)
16297 || (TARGET_SPLIT_LONG_MOVES
16298 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
16299 [(set (match_dup 2) (match_dup 1))
16300 (set (match_dup 0) (match_dup 2))])
16302 ;; Don't compare memory with zero, load and use a test instead.
16304 [(set (match_operand 0 "flags_reg_operand")
16305 (match_operator 1 "compare_operator"
16306 [(match_operand:SI 2 "memory_operand")
16308 (match_scratch:SI 3 "r")]
16309 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16310 [(set (match_dup 3) (match_dup 2))
16311 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16313 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16314 ;; Don't split NOTs with a displacement operand, because resulting XOR
16315 ;; will not be pairable anyway.
16317 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16318 ;; represented using a modRM byte. The XOR replacement is long decoded,
16319 ;; so this split helps here as well.
16321 ;; Note: Can't do this as a regular split because we can't get proper
16322 ;; lifetime information then.
16325 [(set (match_operand:SWI124 0 "nonimmediate_operand")
16326 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
16327 "optimize_insn_for_speed_p ()
16328 && ((TARGET_NOT_UNPAIRABLE
16329 && (!MEM_P (operands[0])
16330 || !memory_displacement_operand (operands[0], <MODE>mode)))
16331 || (TARGET_NOT_VECTORMODE
16332 && long_memory_operand (operands[0], <MODE>mode)))
16333 && peep2_regno_dead_p (0, FLAGS_REG)"
16334 [(parallel [(set (match_dup 0)
16335 (xor:SWI124 (match_dup 1) (const_int -1)))
16336 (clobber (reg:CC FLAGS_REG))])])
16338 ;; Non pairable "test imm, reg" instructions can be translated to
16339 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16340 ;; byte opcode instead of two, have a short form for byte operands),
16341 ;; so do it for other CPUs as well. Given that the value was dead,
16342 ;; this should not create any new dependencies. Pass on the sub-word
16343 ;; versions if we're concerned about partial register stalls.
16346 [(set (match_operand 0 "flags_reg_operand")
16347 (match_operator 1 "compare_operator"
16348 [(and:SI (match_operand:SI 2 "register_operand")
16349 (match_operand:SI 3 "immediate_operand"))
16351 "ix86_match_ccmode (insn, CCNOmode)
16352 && (true_regnum (operands[2]) != AX_REG
16353 || satisfies_constraint_K (operands[3]))
16354 && peep2_reg_dead_p (1, operands[2])"
16356 [(set (match_dup 0)
16357 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16360 (and:SI (match_dup 2) (match_dup 3)))])])
16362 ;; We don't need to handle HImode case, because it will be promoted to SImode
16363 ;; on ! TARGET_PARTIAL_REG_STALL
16366 [(set (match_operand 0 "flags_reg_operand")
16367 (match_operator 1 "compare_operator"
16368 [(and:QI (match_operand:QI 2 "register_operand")
16369 (match_operand:QI 3 "immediate_operand"))
16371 "! TARGET_PARTIAL_REG_STALL
16372 && ix86_match_ccmode (insn, CCNOmode)
16373 && true_regnum (operands[2]) != AX_REG
16374 && peep2_reg_dead_p (1, operands[2])"
16376 [(set (match_dup 0)
16377 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16380 (and:QI (match_dup 2) (match_dup 3)))])])
16383 [(set (match_operand 0 "flags_reg_operand")
16384 (match_operator 1 "compare_operator"
16387 (match_operand 2 "ext_register_operand")
16390 (match_operand 3 "const_int_operand"))
16392 "! TARGET_PARTIAL_REG_STALL
16393 && ix86_match_ccmode (insn, CCNOmode)
16394 && true_regnum (operands[2]) != AX_REG
16395 && peep2_reg_dead_p (1, operands[2])"
16396 [(parallel [(set (match_dup 0)
16405 (set (zero_extract:SI (match_dup 2)
16413 (match_dup 3)))])])
16415 ;; Don't do logical operations with memory inputs.
16417 [(match_scratch:SI 2 "r")
16418 (parallel [(set (match_operand:SI 0 "register_operand")
16419 (match_operator:SI 3 "arith_or_logical_operator"
16421 (match_operand:SI 1 "memory_operand")]))
16422 (clobber (reg:CC FLAGS_REG))])]
16423 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
16424 [(set (match_dup 2) (match_dup 1))
16425 (parallel [(set (match_dup 0)
16426 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16427 (clobber (reg:CC FLAGS_REG))])])
16430 [(match_scratch:SI 2 "r")
16431 (parallel [(set (match_operand:SI 0 "register_operand")
16432 (match_operator:SI 3 "arith_or_logical_operator"
16433 [(match_operand:SI 1 "memory_operand")
16435 (clobber (reg:CC FLAGS_REG))])]
16436 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
16437 [(set (match_dup 2) (match_dup 1))
16438 (parallel [(set (match_dup 0)
16439 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16440 (clobber (reg:CC FLAGS_REG))])])
16442 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
16443 ;; refers to the destination of the load!
16446 [(set (match_operand:SI 0 "register_operand")
16447 (match_operand:SI 1 "register_operand"))
16448 (parallel [(set (match_dup 0)
16449 (match_operator:SI 3 "commutative_operator"
16451 (match_operand:SI 2 "memory_operand")]))
16452 (clobber (reg:CC FLAGS_REG))])]
16453 "REGNO (operands[0]) != REGNO (operands[1])
16454 && GENERAL_REGNO_P (REGNO (operands[0]))
16455 && GENERAL_REGNO_P (REGNO (operands[1]))"
16456 [(set (match_dup 0) (match_dup 4))
16457 (parallel [(set (match_dup 0)
16458 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16459 (clobber (reg:CC FLAGS_REG))])]
16460 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
16463 [(set (match_operand 0 "register_operand")
16464 (match_operand 1 "register_operand"))
16466 (match_operator 3 "commutative_operator"
16468 (match_operand 2 "memory_operand")]))]
16469 "REGNO (operands[0]) != REGNO (operands[1])
16470 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
16471 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
16472 [(set (match_dup 0) (match_dup 2))
16474 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
16476 ; Don't do logical operations with memory outputs
16478 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16479 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
16480 ; the same decoder scheduling characteristics as the original.
16483 [(match_scratch:SI 2 "r")
16484 (parallel [(set (match_operand:SI 0 "memory_operand")
16485 (match_operator:SI 3 "arith_or_logical_operator"
16487 (match_operand:SI 1 "nonmemory_operand")]))
16488 (clobber (reg:CC FLAGS_REG))])]
16489 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16490 /* Do not split stack checking probes. */
16491 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16492 [(set (match_dup 2) (match_dup 0))
16493 (parallel [(set (match_dup 2)
16494 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16495 (clobber (reg:CC FLAGS_REG))])
16496 (set (match_dup 0) (match_dup 2))])
16499 [(match_scratch:SI 2 "r")
16500 (parallel [(set (match_operand:SI 0 "memory_operand")
16501 (match_operator:SI 3 "arith_or_logical_operator"
16502 [(match_operand:SI 1 "nonmemory_operand")
16504 (clobber (reg:CC FLAGS_REG))])]
16505 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16506 /* Do not split stack checking probes. */
16507 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16508 [(set (match_dup 2) (match_dup 0))
16509 (parallel [(set (match_dup 2)
16510 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16511 (clobber (reg:CC FLAGS_REG))])
16512 (set (match_dup 0) (match_dup 2))])
16514 ;; Attempt to use arith or logical operations with memory outputs with
16515 ;; setting of flags.
16517 [(set (match_operand:SWI 0 "register_operand")
16518 (match_operand:SWI 1 "memory_operand"))
16519 (parallel [(set (match_dup 0)
16520 (match_operator:SWI 3 "plusminuslogic_operator"
16522 (match_operand:SWI 2 "<nonmemory_operand>")]))
16523 (clobber (reg:CC FLAGS_REG))])
16524 (set (match_dup 1) (match_dup 0))
16525 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16526 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16527 && peep2_reg_dead_p (4, operands[0])
16528 && !reg_overlap_mentioned_p (operands[0], operands[1])
16529 && (<MODE>mode != QImode
16530 || immediate_operand (operands[2], QImode)
16531 || q_regs_operand (operands[2], QImode))
16532 && ix86_match_ccmode (peep2_next_insn (3),
16533 (GET_CODE (operands[3]) == PLUS
16534 || GET_CODE (operands[3]) == MINUS)
16535 ? CCGOCmode : CCNOmode)"
16536 [(parallel [(set (match_dup 4) (match_dup 5))
16537 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
16538 (match_dup 2)]))])]
16540 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
16541 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16542 copy_rtx (operands[1]),
16543 copy_rtx (operands[2]));
16544 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
16545 operands[5], const0_rtx);
16549 [(parallel [(set (match_operand:SWI 0 "register_operand")
16550 (match_operator:SWI 2 "plusminuslogic_operator"
16552 (match_operand:SWI 1 "memory_operand")]))
16553 (clobber (reg:CC FLAGS_REG))])
16554 (set (match_dup 1) (match_dup 0))
16555 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16556 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16557 && GET_CODE (operands[2]) != MINUS
16558 && peep2_reg_dead_p (3, operands[0])
16559 && !reg_overlap_mentioned_p (operands[0], operands[1])
16560 && ix86_match_ccmode (peep2_next_insn (2),
16561 GET_CODE (operands[2]) == PLUS
16562 ? CCGOCmode : CCNOmode)"
16563 [(parallel [(set (match_dup 3) (match_dup 4))
16564 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
16565 (match_dup 0)]))])]
16567 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
16568 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
16569 copy_rtx (operands[1]),
16570 copy_rtx (operands[0]));
16571 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
16572 operands[4], const0_rtx);
16576 [(set (match_operand:SWI12 0 "register_operand")
16577 (match_operand:SWI12 1 "memory_operand"))
16578 (parallel [(set (match_operand:SI 4 "register_operand")
16579 (match_operator:SI 3 "plusminuslogic_operator"
16581 (match_operand:SI 2 "nonmemory_operand")]))
16582 (clobber (reg:CC FLAGS_REG))])
16583 (set (match_dup 1) (match_dup 0))
16584 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16585 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16586 && REG_P (operands[0]) && REG_P (operands[4])
16587 && REGNO (operands[0]) == REGNO (operands[4])
16588 && peep2_reg_dead_p (4, operands[0])
16589 && (<MODE>mode != QImode
16590 || immediate_operand (operands[2], SImode)
16591 || q_regs_operand (operands[2], SImode))
16592 && !reg_overlap_mentioned_p (operands[0], operands[1])
16593 && ix86_match_ccmode (peep2_next_insn (3),
16594 (GET_CODE (operands[3]) == PLUS
16595 || GET_CODE (operands[3]) == MINUS)
16596 ? CCGOCmode : CCNOmode)"
16597 [(parallel [(set (match_dup 4) (match_dup 5))
16598 (set (match_dup 1) (match_dup 6))])]
16600 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
16601 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
16602 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16603 copy_rtx (operands[1]), operands[2]);
16604 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
16605 operands[5], const0_rtx);
16606 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16607 copy_rtx (operands[1]),
16608 copy_rtx (operands[2]));
16611 ;; Attempt to always use XOR for zeroing registers.
16613 [(set (match_operand 0 "register_operand")
16614 (match_operand 1 "const0_operand"))]
16615 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
16616 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16617 && GENERAL_REG_P (operands[0])
16618 && peep2_regno_dead_p (0, FLAGS_REG)"
16619 [(parallel [(set (match_dup 0) (const_int 0))
16620 (clobber (reg:CC FLAGS_REG))])]
16621 "operands[0] = gen_lowpart (word_mode, operands[0]);")
16624 [(set (strict_low_part (match_operand 0 "register_operand"))
16626 "(GET_MODE (operands[0]) == QImode
16627 || GET_MODE (operands[0]) == HImode)
16628 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16629 && peep2_regno_dead_p (0, FLAGS_REG)"
16630 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
16631 (clobber (reg:CC FLAGS_REG))])])
16633 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
16635 [(set (match_operand:SWI248 0 "register_operand")
16637 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
16638 && peep2_regno_dead_p (0, FLAGS_REG)"
16639 [(parallel [(set (match_dup 0) (const_int -1))
16640 (clobber (reg:CC FLAGS_REG))])]
16642 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
16643 operands[0] = gen_lowpart (SImode, operands[0]);
16646 ;; Attempt to convert simple lea to add/shift.
16647 ;; These can be created by move expanders.
16648 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
16649 ;; relevant lea instructions were already split.
16652 [(set (match_operand:SWI48 0 "register_operand")
16653 (plus:SWI48 (match_dup 0)
16654 (match_operand:SWI48 1 "<nonmemory_operand>")))]
16656 && peep2_regno_dead_p (0, FLAGS_REG)"
16657 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
16658 (clobber (reg:CC FLAGS_REG))])])
16661 [(set (match_operand:SWI48 0 "register_operand")
16662 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
16665 && peep2_regno_dead_p (0, FLAGS_REG)"
16666 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
16667 (clobber (reg:CC FLAGS_REG))])])
16670 [(set (match_operand:DI 0 "register_operand")
16672 (plus:SI (match_operand:SI 1 "register_operand")
16673 (match_operand:SI 2 "nonmemory_operand"))))]
16674 "TARGET_64BIT && !TARGET_OPT_AGU
16675 && REGNO (operands[0]) == REGNO (operands[1])
16676 && peep2_regno_dead_p (0, FLAGS_REG)"
16677 [(parallel [(set (match_dup 0)
16678 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
16679 (clobber (reg:CC FLAGS_REG))])])
16682 [(set (match_operand:DI 0 "register_operand")
16684 (plus:SI (match_operand:SI 1 "nonmemory_operand")
16685 (match_operand:SI 2 "register_operand"))))]
16686 "TARGET_64BIT && !TARGET_OPT_AGU
16687 && REGNO (operands[0]) == REGNO (operands[2])
16688 && peep2_regno_dead_p (0, FLAGS_REG)"
16689 [(parallel [(set (match_dup 0)
16690 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
16691 (clobber (reg:CC FLAGS_REG))])])
16694 [(set (match_operand:SWI48 0 "register_operand")
16695 (mult:SWI48 (match_dup 0)
16696 (match_operand:SWI48 1 "const_int_operand")))]
16697 "exact_log2 (INTVAL (operands[1])) >= 0
16698 && peep2_regno_dead_p (0, FLAGS_REG)"
16699 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
16700 (clobber (reg:CC FLAGS_REG))])]
16701 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
16704 [(set (match_operand:DI 0 "register_operand")
16706 (mult:SI (match_operand:SI 1 "register_operand")
16707 (match_operand:SI 2 "const_int_operand"))))]
16709 && exact_log2 (INTVAL (operands[2])) >= 0
16710 && REGNO (operands[0]) == REGNO (operands[1])
16711 && peep2_regno_dead_p (0, FLAGS_REG)"
16712 [(parallel [(set (match_dup 0)
16713 (zero_extend (ashift:SI (match_dup 1) (match_dup 2))))
16714 (clobber (reg:CC FLAGS_REG))])]
16715 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
16717 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
16718 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
16719 ;; On many CPUs it is also faster, since special hardware to avoid esp
16720 ;; dependencies is present.
16722 ;; While some of these conversions may be done using splitters, we use
16723 ;; peepholes in order to allow combine_stack_adjustments pass to see
16724 ;; nonobfuscated RTL.
16726 ;; Convert prologue esp subtractions to push.
16727 ;; We need register to push. In order to keep verify_flow_info happy we have
16729 ;; - use scratch and clobber it in order to avoid dependencies
16730 ;; - use already live register
16731 ;; We can't use the second way right now, since there is no reliable way how to
16732 ;; verify that given register is live. First choice will also most likely in
16733 ;; fewer dependencies. On the place of esp adjustments it is very likely that
16734 ;; call clobbered registers are dead. We may want to use base pointer as an
16735 ;; alternative when no register is available later.
16738 [(match_scratch:W 1 "r")
16739 (parallel [(set (reg:P SP_REG)
16740 (plus:P (reg:P SP_REG)
16741 (match_operand:P 0 "const_int_operand")))
16742 (clobber (reg:CC FLAGS_REG))
16743 (clobber (mem:BLK (scratch)))])]
16744 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16745 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
16746 [(clobber (match_dup 1))
16747 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16748 (clobber (mem:BLK (scratch)))])])
16751 [(match_scratch:W 1 "r")
16752 (parallel [(set (reg:P SP_REG)
16753 (plus:P (reg:P SP_REG)
16754 (match_operand:P 0 "const_int_operand")))
16755 (clobber (reg:CC FLAGS_REG))
16756 (clobber (mem:BLK (scratch)))])]
16757 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16758 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
16759 [(clobber (match_dup 1))
16760 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16761 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16762 (clobber (mem:BLK (scratch)))])])
16764 ;; Convert esp subtractions to push.
16766 [(match_scratch:W 1 "r")
16767 (parallel [(set (reg:P SP_REG)
16768 (plus:P (reg:P SP_REG)
16769 (match_operand:P 0 "const_int_operand")))
16770 (clobber (reg:CC FLAGS_REG))])]
16771 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16772 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
16773 [(clobber (match_dup 1))
16774 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
16777 [(match_scratch:W 1 "r")
16778 (parallel [(set (reg:P SP_REG)
16779 (plus:P (reg:P SP_REG)
16780 (match_operand:P 0 "const_int_operand")))
16781 (clobber (reg:CC FLAGS_REG))])]
16782 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16783 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
16784 [(clobber (match_dup 1))
16785 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16786 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
16788 ;; Convert epilogue deallocator to pop.
16790 [(match_scratch:W 1 "r")
16791 (parallel [(set (reg:P SP_REG)
16792 (plus:P (reg:P SP_REG)
16793 (match_operand:P 0 "const_int_operand")))
16794 (clobber (reg:CC FLAGS_REG))
16795 (clobber (mem:BLK (scratch)))])]
16796 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
16797 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
16798 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
16799 (clobber (mem:BLK (scratch)))])])
16801 ;; Two pops case is tricky, since pop causes dependency
16802 ;; on destination register. We use two registers if available.
16804 [(match_scratch:W 1 "r")
16805 (match_scratch:W 2 "r")
16806 (parallel [(set (reg:P SP_REG)
16807 (plus:P (reg:P SP_REG)
16808 (match_operand:P 0 "const_int_operand")))
16809 (clobber (reg:CC FLAGS_REG))
16810 (clobber (mem:BLK (scratch)))])]
16811 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
16812 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
16813 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
16814 (clobber (mem:BLK (scratch)))])
16815 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
16818 [(match_scratch:W 1 "r")
16819 (parallel [(set (reg:P SP_REG)
16820 (plus:P (reg:P SP_REG)
16821 (match_operand:P 0 "const_int_operand")))
16822 (clobber (reg:CC FLAGS_REG))
16823 (clobber (mem:BLK (scratch)))])]
16824 "optimize_insn_for_size_p ()
16825 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
16826 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
16827 (clobber (mem:BLK (scratch)))])
16828 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
16830 ;; Convert esp additions to pop.
16832 [(match_scratch:W 1 "r")
16833 (parallel [(set (reg:P SP_REG)
16834 (plus:P (reg:P SP_REG)
16835 (match_operand:P 0 "const_int_operand")))
16836 (clobber (reg:CC FLAGS_REG))])]
16837 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
16838 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
16840 ;; Two pops case is tricky, since pop causes dependency
16841 ;; on destination register. We use two registers if available.
16843 [(match_scratch:W 1 "r")
16844 (match_scratch:W 2 "r")
16845 (parallel [(set (reg:P SP_REG)
16846 (plus:P (reg:P SP_REG)
16847 (match_operand:P 0 "const_int_operand")))
16848 (clobber (reg:CC FLAGS_REG))])]
16849 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
16850 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
16851 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
16854 [(match_scratch:W 1 "r")
16855 (parallel [(set (reg:P SP_REG)
16856 (plus:P (reg:P SP_REG)
16857 (match_operand:P 0 "const_int_operand")))
16858 (clobber (reg:CC FLAGS_REG))])]
16859 "optimize_insn_for_size_p ()
16860 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
16861 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
16862 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
16864 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
16865 ;; required and register dies. Similarly for 128 to -128.
16867 [(set (match_operand 0 "flags_reg_operand")
16868 (match_operator 1 "compare_operator"
16869 [(match_operand 2 "register_operand")
16870 (match_operand 3 "const_int_operand")]))]
16871 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
16872 && incdec_operand (operands[3], GET_MODE (operands[3])))
16873 || (!TARGET_FUSE_CMP_AND_BRANCH
16874 && INTVAL (operands[3]) == 128))
16875 && ix86_match_ccmode (insn, CCGCmode)
16876 && peep2_reg_dead_p (1, operands[2])"
16877 [(parallel [(set (match_dup 0)
16878 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
16879 (clobber (match_dup 2))])])
16881 ;; Convert imul by three, five and nine into lea
16884 [(set (match_operand:SWI48 0 "register_operand")
16885 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
16886 (match_operand:SWI48 2 "const359_operand")))
16887 (clobber (reg:CC FLAGS_REG))])]
16888 "!TARGET_PARTIAL_REG_STALL
16889 || <MODE>mode == SImode
16890 || optimize_function_for_size_p (cfun)"
16891 [(set (match_dup 0)
16892 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
16894 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
16898 [(set (match_operand:SWI48 0 "register_operand")
16899 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
16900 (match_operand:SWI48 2 "const359_operand")))
16901 (clobber (reg:CC FLAGS_REG))])]
16902 "optimize_insn_for_speed_p ()
16903 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
16904 [(set (match_dup 0) (match_dup 1))
16906 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
16908 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
16910 ;; imul $32bit_imm, mem, reg is vector decoded, while
16911 ;; imul $32bit_imm, reg, reg is direct decoded.
16913 [(match_scratch:SWI48 3 "r")
16914 (parallel [(set (match_operand:SWI48 0 "register_operand")
16915 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
16916 (match_operand:SWI48 2 "immediate_operand")))
16917 (clobber (reg:CC FLAGS_REG))])]
16918 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
16919 && !satisfies_constraint_K (operands[2])"
16920 [(set (match_dup 3) (match_dup 1))
16921 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
16922 (clobber (reg:CC FLAGS_REG))])])
16925 [(match_scratch:SI 3 "r")
16926 (parallel [(set (match_operand:DI 0 "register_operand")
16928 (mult:SI (match_operand:SI 1 "memory_operand")
16929 (match_operand:SI 2 "immediate_operand"))))
16930 (clobber (reg:CC FLAGS_REG))])]
16932 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
16933 && !satisfies_constraint_K (operands[2])"
16934 [(set (match_dup 3) (match_dup 1))
16935 (parallel [(set (match_dup 0)
16936 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
16937 (clobber (reg:CC FLAGS_REG))])])
16939 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
16940 ;; Convert it into imul reg, reg
16941 ;; It would be better to force assembler to encode instruction using long
16942 ;; immediate, but there is apparently no way to do so.
16944 [(parallel [(set (match_operand:SWI248 0 "register_operand")
16946 (match_operand:SWI248 1 "nonimmediate_operand")
16947 (match_operand:SWI248 2 "const_int_operand")))
16948 (clobber (reg:CC FLAGS_REG))])
16949 (match_scratch:SWI248 3 "r")]
16950 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
16951 && satisfies_constraint_K (operands[2])"
16952 [(set (match_dup 3) (match_dup 2))
16953 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
16954 (clobber (reg:CC FLAGS_REG))])]
16956 if (!rtx_equal_p (operands[0], operands[1]))
16957 emit_move_insn (operands[0], operands[1]);
16960 ;; After splitting up read-modify operations, array accesses with memory
16961 ;; operands might end up in form:
16963 ;; movl 4(%esp), %edx
16965 ;; instead of pre-splitting:
16967 ;; addl 4(%esp), %eax
16969 ;; movl 4(%esp), %edx
16970 ;; leal (%edx,%eax,4), %eax
16973 [(match_scratch:W 5 "r")
16974 (parallel [(set (match_operand 0 "register_operand")
16975 (ashift (match_operand 1 "register_operand")
16976 (match_operand 2 "const_int_operand")))
16977 (clobber (reg:CC FLAGS_REG))])
16978 (parallel [(set (match_operand 3 "register_operand")
16979 (plus (match_dup 0)
16980 (match_operand 4 "x86_64_general_operand")))
16981 (clobber (reg:CC FLAGS_REG))])]
16982 "IN_RANGE (INTVAL (operands[2]), 1, 3)
16983 /* Validate MODE for lea. */
16984 && ((!TARGET_PARTIAL_REG_STALL
16985 && (GET_MODE (operands[0]) == QImode
16986 || GET_MODE (operands[0]) == HImode))
16987 || GET_MODE (operands[0]) == SImode
16988 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
16989 && (rtx_equal_p (operands[0], operands[3])
16990 || peep2_reg_dead_p (2, operands[0]))
16991 /* We reorder load and the shift. */
16992 && !reg_overlap_mentioned_p (operands[0], operands[4])"
16993 [(set (match_dup 5) (match_dup 4))
16994 (set (match_dup 0) (match_dup 1))]
16996 enum machine_mode op1mode = GET_MODE (operands[1]);
16997 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
16998 int scale = 1 << INTVAL (operands[2]);
16999 rtx index = gen_lowpart (word_mode, operands[1]);
17000 rtx base = gen_lowpart (word_mode, operands[5]);
17001 rtx dest = gen_lowpart (mode, operands[3]);
17003 operands[1] = gen_rtx_PLUS (word_mode, base,
17004 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
17005 operands[5] = base;
17006 if (mode != word_mode)
17007 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17008 if (op1mode != word_mode)
17009 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17010 operands[0] = dest;
17013 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17014 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17015 ;; caught for use by garbage collectors and the like. Using an insn that
17016 ;; maps to SIGILL makes it more likely the program will rightfully die.
17017 ;; Keeping with tradition, "6" is in honor of #UD.
17018 (define_insn "trap"
17019 [(trap_if (const_int 1) (const_int 6))]
17021 { return ASM_SHORT "0x0b0f"; }
17022 [(set_attr "length" "2")])
17024 (define_expand "prefetch"
17025 [(prefetch (match_operand 0 "address_operand")
17026 (match_operand:SI 1 "const_int_operand")
17027 (match_operand:SI 2 "const_int_operand"))]
17028 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17030 int rw = INTVAL (operands[1]);
17031 int locality = INTVAL (operands[2]);
17033 gcc_assert (rw == 0 || rw == 1);
17034 gcc_assert (IN_RANGE (locality, 0, 3));
17036 if (TARGET_PRFCHW && rw)
17037 operands[2] = GEN_INT (3);
17038 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17039 supported by SSE counterpart or the SSE prefetch is not available
17040 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17042 else if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17043 operands[2] = GEN_INT (3);
17045 operands[1] = const0_rtx;
17048 (define_insn "*prefetch_sse"
17049 [(prefetch (match_operand 0 "address_operand" "p")
17051 (match_operand:SI 1 "const_int_operand"))]
17052 "TARGET_PREFETCH_SSE"
17054 static const char * const patterns[4] = {
17055 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17058 int locality = INTVAL (operands[1]);
17059 gcc_assert (IN_RANGE (locality, 0, 3));
17061 return patterns[locality];
17063 [(set_attr "type" "sse")
17064 (set_attr "atom_sse_attr" "prefetch")
17065 (set (attr "length_address")
17066 (symbol_ref "memory_address_length (operands[0], false)"))
17067 (set_attr "memory" "none")])
17069 (define_insn "*prefetch_3dnow"
17070 [(prefetch (match_operand 0 "address_operand" "p")
17071 (match_operand:SI 1 "const_int_operand" "n")
17073 "TARGET_3DNOW || TARGET_PRFCHW"
17075 if (INTVAL (operands[1]) == 0)
17076 return "prefetch\t%a0";
17078 return "prefetchw\t%a0";
17080 [(set_attr "type" "mmx")
17081 (set (attr "length_address")
17082 (symbol_ref "memory_address_length (operands[0], false)"))
17083 (set_attr "memory" "none")])
17085 (define_expand "stack_protect_set"
17086 [(match_operand 0 "memory_operand")
17087 (match_operand 1 "memory_operand")]
17088 "TARGET_SSP_TLS_GUARD"
17090 rtx (*insn)(rtx, rtx);
17092 #ifdef TARGET_THREAD_SSP_OFFSET
17093 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17094 insn = (TARGET_LP64
17095 ? gen_stack_tls_protect_set_di
17096 : gen_stack_tls_protect_set_si);
17098 insn = (TARGET_LP64
17099 ? gen_stack_protect_set_di
17100 : gen_stack_protect_set_si);
17103 emit_insn (insn (operands[0], operands[1]));
17107 (define_insn "stack_protect_set_<mode>"
17108 [(set (match_operand:PTR 0 "memory_operand" "=m")
17109 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17111 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17112 (clobber (reg:CC FLAGS_REG))]
17113 "TARGET_SSP_TLS_GUARD"
17114 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17115 [(set_attr "type" "multi")])
17117 (define_insn "stack_tls_protect_set_<mode>"
17118 [(set (match_operand:PTR 0 "memory_operand" "=m")
17119 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17120 UNSPEC_SP_TLS_SET))
17121 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17122 (clobber (reg:CC FLAGS_REG))]
17124 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17125 [(set_attr "type" "multi")])
17127 (define_expand "stack_protect_test"
17128 [(match_operand 0 "memory_operand")
17129 (match_operand 1 "memory_operand")
17131 "TARGET_SSP_TLS_GUARD"
17133 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17135 rtx (*insn)(rtx, rtx, rtx);
17137 #ifdef TARGET_THREAD_SSP_OFFSET
17138 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17139 insn = (TARGET_LP64
17140 ? gen_stack_tls_protect_test_di
17141 : gen_stack_tls_protect_test_si);
17143 insn = (TARGET_LP64
17144 ? gen_stack_protect_test_di
17145 : gen_stack_protect_test_si);
17148 emit_insn (insn (flags, operands[0], operands[1]));
17150 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17151 flags, const0_rtx, operands[2]));
17155 (define_insn "stack_protect_test_<mode>"
17156 [(set (match_operand:CCZ 0 "flags_reg_operand")
17157 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17158 (match_operand:PTR 2 "memory_operand" "m")]
17160 (clobber (match_scratch:PTR 3 "=&r"))]
17161 "TARGET_SSP_TLS_GUARD"
17162 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17163 [(set_attr "type" "multi")])
17165 (define_insn "stack_tls_protect_test_<mode>"
17166 [(set (match_operand:CCZ 0 "flags_reg_operand")
17167 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17168 (match_operand:PTR 2 "const_int_operand" "i")]
17169 UNSPEC_SP_TLS_TEST))
17170 (clobber (match_scratch:PTR 3 "=r"))]
17172 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17173 [(set_attr "type" "multi")])
17175 (define_insn "sse4_2_crc32<mode>"
17176 [(set (match_operand:SI 0 "register_operand" "=r")
17178 [(match_operand:SI 1 "register_operand" "0")
17179 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17181 "TARGET_SSE4_2 || TARGET_CRC32"
17182 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17183 [(set_attr "type" "sselog1")
17184 (set_attr "prefix_rep" "1")
17185 (set_attr "prefix_extra" "1")
17186 (set (attr "prefix_data16")
17187 (if_then_else (match_operand:HI 2)
17189 (const_string "*")))
17190 (set (attr "prefix_rex")
17191 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
17193 (const_string "*")))
17194 (set_attr "mode" "SI")])
17196 (define_insn "sse4_2_crc32di"
17197 [(set (match_operand:DI 0 "register_operand" "=r")
17199 [(match_operand:DI 1 "register_operand" "0")
17200 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17202 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17203 "crc32{q}\t{%2, %0|%0, %2}"
17204 [(set_attr "type" "sselog1")
17205 (set_attr "prefix_rep" "1")
17206 (set_attr "prefix_extra" "1")
17207 (set_attr "mode" "DI")])
17209 (define_insn "rdpmc"
17210 [(set (match_operand:DI 0 "register_operand" "=A")
17211 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17215 [(set_attr "type" "other")
17216 (set_attr "length" "2")])
17218 (define_insn "rdpmc_rex64"
17219 [(set (match_operand:DI 0 "register_operand" "=a")
17220 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17222 (set (match_operand:DI 1 "register_operand" "=d")
17223 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
17226 [(set_attr "type" "other")
17227 (set_attr "length" "2")])
17229 (define_insn "rdtsc"
17230 [(set (match_operand:DI 0 "register_operand" "=A")
17231 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17234 [(set_attr "type" "other")
17235 (set_attr "length" "2")])
17237 (define_insn "rdtsc_rex64"
17238 [(set (match_operand:DI 0 "register_operand" "=a")
17239 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17240 (set (match_operand:DI 1 "register_operand" "=d")
17241 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17244 [(set_attr "type" "other")
17245 (set_attr "length" "2")])
17247 (define_insn "rdtscp"
17248 [(set (match_operand:DI 0 "register_operand" "=A")
17249 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17250 (set (match_operand:SI 1 "register_operand" "=c")
17251 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17254 [(set_attr "type" "other")
17255 (set_attr "length" "3")])
17257 (define_insn "rdtscp_rex64"
17258 [(set (match_operand:DI 0 "register_operand" "=a")
17259 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17260 (set (match_operand:DI 1 "register_operand" "=d")
17261 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17262 (set (match_operand:SI 2 "register_operand" "=c")
17263 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17266 [(set_attr "type" "other")
17267 (set_attr "length" "3")])
17269 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17271 ;; FXSR, XSAVE and XSAVEOPT instructions
17273 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17275 (define_insn "fxsave"
17276 [(set (match_operand:BLK 0 "memory_operand" "=m")
17277 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
17280 [(set_attr "type" "other")
17281 (set_attr "memory" "store")
17282 (set (attr "length")
17283 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17285 (define_insn "fxsave64"
17286 [(set (match_operand:BLK 0 "memory_operand" "=m")
17287 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
17288 "TARGET_64BIT && TARGET_FXSR"
17290 [(set_attr "type" "other")
17291 (set_attr "memory" "store")
17292 (set (attr "length")
17293 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17295 (define_insn "fxrstor"
17296 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
17300 [(set_attr "type" "other")
17301 (set_attr "memory" "load")
17302 (set (attr "length")
17303 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17305 (define_insn "fxrstor64"
17306 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
17307 UNSPECV_FXRSTOR64)]
17308 "TARGET_64BIT && TARGET_FXSR"
17310 [(set_attr "type" "other")
17311 (set_attr "memory" "load")
17312 (set (attr "length")
17313 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17315 (define_int_iterator ANY_XSAVE
17317 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")])
17319 (define_int_iterator ANY_XSAVE64
17321 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")])
17323 (define_int_attr xsave
17324 [(UNSPECV_XSAVE "xsave")
17325 (UNSPECV_XSAVE64 "xsave64")
17326 (UNSPECV_XSAVEOPT "xsaveopt")
17327 (UNSPECV_XSAVEOPT64 "xsaveopt64")])
17329 (define_insn "<xsave>"
17330 [(set (match_operand:BLK 0 "memory_operand" "=m")
17331 (unspec_volatile:BLK
17332 [(match_operand:DI 1 "register_operand" "A")]
17334 "!TARGET_64BIT && TARGET_XSAVE"
17336 [(set_attr "type" "other")
17337 (set_attr "memory" "store")
17338 (set (attr "length")
17339 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17341 (define_insn "<xsave>_rex64"
17342 [(set (match_operand:BLK 0 "memory_operand" "=m")
17343 (unspec_volatile:BLK
17344 [(match_operand:SI 1 "register_operand" "a")
17345 (match_operand:SI 2 "register_operand" "d")]
17347 "TARGET_64BIT && TARGET_XSAVE"
17349 [(set_attr "type" "other")
17350 (set_attr "memory" "store")
17351 (set (attr "length")
17352 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17354 (define_insn "<xsave>"
17355 [(set (match_operand:BLK 0 "memory_operand" "=m")
17356 (unspec_volatile:BLK
17357 [(match_operand:SI 1 "register_operand" "a")
17358 (match_operand:SI 2 "register_operand" "d")]
17360 "TARGET_64BIT && TARGET_XSAVE"
17362 [(set_attr "type" "other")
17363 (set_attr "memory" "store")
17364 (set (attr "length")
17365 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17367 (define_insn "xrstor"
17368 [(unspec_volatile:BLK
17369 [(match_operand:BLK 0 "memory_operand" "m")
17370 (match_operand:DI 1 "register_operand" "A")]
17372 "!TARGET_64BIT && TARGET_XSAVE"
17374 [(set_attr "type" "other")
17375 (set_attr "memory" "load")
17376 (set (attr "length")
17377 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17379 (define_insn "xrstor_rex64"
17380 [(unspec_volatile:BLK
17381 [(match_operand:BLK 0 "memory_operand" "m")
17382 (match_operand:SI 1 "register_operand" "a")
17383 (match_operand:SI 2 "register_operand" "d")]
17385 "TARGET_64BIT && TARGET_XSAVE"
17387 [(set_attr "type" "other")
17388 (set_attr "memory" "load")
17389 (set (attr "length")
17390 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17392 (define_insn "xrstor64"
17393 [(unspec_volatile:BLK
17394 [(match_operand:BLK 0 "memory_operand" "m")
17395 (match_operand:SI 1 "register_operand" "a")
17396 (match_operand:SI 2 "register_operand" "d")]
17398 "TARGET_64BIT && TARGET_XSAVE"
17400 [(set_attr "type" "other")
17401 (set_attr "memory" "load")
17402 (set (attr "length")
17403 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17405 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17407 ;; LWP instructions
17409 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17411 (define_expand "lwp_llwpcb"
17412 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17413 UNSPECV_LLWP_INTRINSIC)]
17416 (define_insn "*lwp_llwpcb<mode>1"
17417 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17418 UNSPECV_LLWP_INTRINSIC)]
17421 [(set_attr "type" "lwp")
17422 (set_attr "mode" "<MODE>")
17423 (set_attr "length" "5")])
17425 (define_expand "lwp_slwpcb"
17426 [(set (match_operand 0 "register_operand" "=r")
17427 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17432 insn = (Pmode == DImode
17434 : gen_lwp_slwpcbsi);
17436 emit_insn (insn (operands[0]));
17440 (define_insn "lwp_slwpcb<mode>"
17441 [(set (match_operand:P 0 "register_operand" "=r")
17442 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17445 [(set_attr "type" "lwp")
17446 (set_attr "mode" "<MODE>")
17447 (set_attr "length" "5")])
17449 (define_expand "lwp_lwpval<mode>3"
17450 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
17451 (match_operand:SI 2 "nonimmediate_operand" "rm")
17452 (match_operand:SI 3 "const_int_operand" "i")]
17453 UNSPECV_LWPVAL_INTRINSIC)]
17455 ;; Avoid unused variable warning.
17456 "(void) operands[0];")
17458 (define_insn "*lwp_lwpval<mode>3_1"
17459 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
17460 (match_operand:SI 1 "nonimmediate_operand" "rm")
17461 (match_operand:SI 2 "const_int_operand" "i")]
17462 UNSPECV_LWPVAL_INTRINSIC)]
17464 "lwpval\t{%2, %1, %0|%0, %1, %2}"
17465 [(set_attr "type" "lwp")
17466 (set_attr "mode" "<MODE>")
17467 (set (attr "length")
17468 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17470 (define_expand "lwp_lwpins<mode>3"
17471 [(set (reg:CCC FLAGS_REG)
17472 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
17473 (match_operand:SI 2 "nonimmediate_operand" "rm")
17474 (match_operand:SI 3 "const_int_operand" "i")]
17475 UNSPECV_LWPINS_INTRINSIC))
17476 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
17477 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
17480 (define_insn "*lwp_lwpins<mode>3_1"
17481 [(set (reg:CCC FLAGS_REG)
17482 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
17483 (match_operand:SI 1 "nonimmediate_operand" "rm")
17484 (match_operand:SI 2 "const_int_operand" "i")]
17485 UNSPECV_LWPINS_INTRINSIC))]
17487 "lwpins\t{%2, %1, %0|%0, %1, %2}"
17488 [(set_attr "type" "lwp")
17489 (set_attr "mode" "<MODE>")
17490 (set (attr "length")
17491 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17493 (define_int_iterator RDFSGSBASE
17497 (define_int_iterator WRFSGSBASE
17501 (define_int_attr fsgs
17502 [(UNSPECV_RDFSBASE "fs")
17503 (UNSPECV_RDGSBASE "gs")
17504 (UNSPECV_WRFSBASE "fs")
17505 (UNSPECV_WRGSBASE "gs")])
17507 (define_insn "rd<fsgs>base<mode>"
17508 [(set (match_operand:SWI48 0 "register_operand" "=r")
17509 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
17510 "TARGET_64BIT && TARGET_FSGSBASE"
17512 [(set_attr "type" "other")
17513 (set_attr "prefix_extra" "2")])
17515 (define_insn "wr<fsgs>base<mode>"
17516 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17518 "TARGET_64BIT && TARGET_FSGSBASE"
17520 [(set_attr "type" "other")
17521 (set_attr "prefix_extra" "2")])
17523 (define_insn "rdrand<mode>_1"
17524 [(set (match_operand:SWI248 0 "register_operand" "=r")
17525 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
17526 (set (reg:CCC FLAGS_REG)
17527 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
17530 [(set_attr "type" "other")
17531 (set_attr "prefix_extra" "1")])
17533 (define_insn "rdseed<mode>_1"
17534 [(set (match_operand:SWI248 0 "register_operand" "=r")
17535 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
17536 (set (reg:CCC FLAGS_REG)
17537 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
17540 [(set_attr "type" "other")
17541 (set_attr "prefix_extra" "1")])
17543 (define_expand "pause"
17544 [(set (match_dup 0)
17545 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
17548 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
17549 MEM_VOLATILE_P (operands[0]) = 1;
17552 ;; Use "rep; nop", instead of "pause", to support older assemblers.
17553 ;; They have the same encoding.
17554 (define_insn "*pause"
17555 [(set (match_operand:BLK 0)
17556 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
17559 [(set_attr "length" "2")
17560 (set_attr "memory" "unknown")])
17562 (define_expand "xbegin"
17563 [(set (match_operand:SI 0 "register_operand")
17564 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
17567 rtx label = gen_label_rtx ();
17569 /* xbegin is emitted as jump_insn, so reload won't be able
17570 to reload its operand. Force the value into AX hard register. */
17571 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
17572 emit_move_insn (ax_reg, constm1_rtx);
17574 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
17576 emit_label (label);
17577 LABEL_NUSES (label) = 1;
17579 emit_move_insn (operands[0], ax_reg);
17584 (define_insn "xbegin_1"
17586 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
17588 (label_ref (match_operand 1))
17590 (set (match_operand:SI 0 "register_operand" "+a")
17591 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
17594 [(set_attr "type" "other")
17595 (set_attr "length" "6")])
17597 (define_insn "xend"
17598 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
17601 [(set_attr "type" "other")
17602 (set_attr "length" "3")])
17604 (define_insn "xabort"
17605 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
17609 [(set_attr "type" "other")
17610 (set_attr "length" "3")])
17612 (define_expand "xtest"
17613 [(set (match_operand:QI 0 "register_operand")
17614 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
17617 emit_insn (gen_xtest_1 ());
17619 ix86_expand_setcc (operands[0], NE,
17620 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
17624 (define_insn "xtest_1"
17625 [(set (reg:CCZ FLAGS_REG)
17626 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
17629 [(set_attr "type" "other")
17630 (set_attr "length" "3")])
17634 (include "sync.md")