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,imul,imulx,idiv,
335 icmp,test,ibr,setcc,icmov,
336 push,pop,call,callv,leave,
338 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
339 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
340 sse,ssemov,sseadd,sseadd1,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
341 sseshuf,sseshuf1,ssediv,sseins,ssemuladd,sse4arg,lwp,
342 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
343 (const_string "other"))
345 ;; Main data type used by the insn
347 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
348 (const_string "unknown"))
350 ;; The CPU unit operations uses.
351 (define_attr "unit" "integer,i387,sse,mmx,unknown"
352 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
353 (const_string "i387")
354 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
355 sse,ssemov,sseadd,sseadd1,ssemul,ssecmp,ssecomi,ssecvt,
356 sseshuf,sseshuf1,ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
358 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
360 (eq_attr "type" "other")
361 (const_string "unknown")]
362 (const_string "integer")))
364 ;; The (bounding maximum) length of an instruction immediate.
365 (define_attr "length_immediate" ""
366 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
369 (eq_attr "unit" "i387,sse,mmx")
371 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
372 rotate,rotatex,rotate1,imul,icmp,push,pop")
373 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
374 (eq_attr "type" "imov,test")
375 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
376 (eq_attr "type" "call")
377 (if_then_else (match_operand 0 "constant_call_address_operand")
380 (eq_attr "type" "callv")
381 (if_then_else (match_operand 1 "constant_call_address_operand")
384 ;; We don't know the size before shorten_branches. Expect
385 ;; the instruction to fit for better scheduling.
386 (eq_attr "type" "ibr")
389 (symbol_ref "/* Update immediate_length and other attributes! */
390 gcc_unreachable (),1")))
392 ;; The (bounding maximum) length of an instruction address.
393 (define_attr "length_address" ""
394 (cond [(eq_attr "type" "str,other,multi,fxch")
396 (and (eq_attr "type" "call")
397 (match_operand 0 "constant_call_address_operand"))
399 (and (eq_attr "type" "callv")
400 (match_operand 1 "constant_call_address_operand"))
403 (symbol_ref "ix86_attr_length_address_default (insn)")))
405 ;; Set when length prefix is used.
406 (define_attr "prefix_data16" ""
407 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
409 (eq_attr "mode" "HI")
411 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
416 ;; Set when string REP prefix is used.
417 (define_attr "prefix_rep" ""
418 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
420 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
425 ;; Set when 0f opcode prefix is used.
426 (define_attr "prefix_0f" ""
428 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
429 (eq_attr "unit" "sse,mmx"))
433 ;; Set when REX opcode prefix is used.
434 (define_attr "prefix_rex" ""
435 (cond [(not (match_test "TARGET_64BIT"))
437 (and (eq_attr "mode" "DI")
438 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
439 (eq_attr "unit" "!mmx")))
441 (and (eq_attr "mode" "QI")
442 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
444 (match_test "x86_extended_reg_mentioned_p (insn)")
446 (and (eq_attr "type" "imovx")
447 (match_operand:QI 1 "ext_QIreg_operand"))
452 ;; There are also additional prefixes in 3DNOW, SSSE3.
453 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
454 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
455 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
456 (define_attr "prefix_extra" ""
457 (cond [(eq_attr "type" "ssemuladd,sse4arg")
459 (eq_attr "type" "sseiadd1,ssecvt1")
464 ;; Prefix used: original, VEX or maybe VEX.
465 (define_attr "prefix" "orig,vex,maybe_vex"
466 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
468 (const_string "orig")))
470 ;; VEX W bit is used.
471 (define_attr "prefix_vex_w" "" (const_int 0))
473 ;; The length of VEX prefix
474 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
475 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
476 ;; still prefix_0f 1, with prefix_extra 1.
477 (define_attr "length_vex" ""
478 (if_then_else (and (eq_attr "prefix_0f" "1")
479 (eq_attr "prefix_extra" "0"))
480 (if_then_else (eq_attr "prefix_vex_w" "1")
481 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
482 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
483 (if_then_else (eq_attr "prefix_vex_w" "1")
484 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
485 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
487 ;; Set when modrm byte is used.
488 (define_attr "modrm" ""
489 (cond [(eq_attr "type" "str,leave")
491 (eq_attr "unit" "i387")
493 (and (eq_attr "type" "incdec")
494 (and (not (match_test "TARGET_64BIT"))
495 (ior (match_operand:SI 1 "register_operand")
496 (match_operand:HI 1 "register_operand"))))
498 (and (eq_attr "type" "push")
499 (not (match_operand 1 "memory_operand")))
501 (and (eq_attr "type" "pop")
502 (not (match_operand 0 "memory_operand")))
504 (and (eq_attr "type" "imov")
505 (and (not (eq_attr "mode" "DI"))
506 (ior (and (match_operand 0 "register_operand")
507 (match_operand 1 "immediate_operand"))
508 (ior (and (match_operand 0 "ax_reg_operand")
509 (match_operand 1 "memory_displacement_only_operand"))
510 (and (match_operand 0 "memory_displacement_only_operand")
511 (match_operand 1 "ax_reg_operand"))))))
513 (and (eq_attr "type" "call")
514 (match_operand 0 "constant_call_address_operand"))
516 (and (eq_attr "type" "callv")
517 (match_operand 1 "constant_call_address_operand"))
519 (and (eq_attr "type" "alu,alu1,icmp,test")
520 (match_operand 0 "ax_reg_operand"))
521 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
525 ;; The (bounding maximum) length of an instruction in bytes.
526 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
527 ;; Later we may want to split them and compute proper length as for
529 (define_attr "length" ""
530 (cond [(eq_attr "type" "other,multi,fistp,frndint")
532 (eq_attr "type" "fcmp")
534 (eq_attr "unit" "i387")
536 (plus (attr "prefix_data16")
537 (attr "length_address")))
538 (ior (eq_attr "prefix" "vex")
539 (and (eq_attr "prefix" "maybe_vex")
540 (match_test "TARGET_AVX")))
541 (plus (attr "length_vex")
542 (plus (attr "length_immediate")
544 (attr "length_address"))))]
545 (plus (plus (attr "modrm")
546 (plus (attr "prefix_0f")
547 (plus (attr "prefix_rex")
548 (plus (attr "prefix_extra")
550 (plus (attr "prefix_rep")
551 (plus (attr "prefix_data16")
552 (plus (attr "length_immediate")
553 (attr "length_address")))))))
555 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
556 ;; `store' if there is a simple memory reference therein, or `unknown'
557 ;; if the instruction is complex.
559 (define_attr "memory" "none,load,store,both,unknown"
560 (cond [(eq_attr "type" "other,multi,str,lwp")
561 (const_string "unknown")
562 (eq_attr "type" "lea,fcmov,fpspc")
563 (const_string "none")
564 (eq_attr "type" "fistp,leave")
565 (const_string "both")
566 (eq_attr "type" "frndint")
567 (const_string "load")
568 (eq_attr "type" "push")
569 (if_then_else (match_operand 1 "memory_operand")
570 (const_string "both")
571 (const_string "store"))
572 (eq_attr "type" "pop")
573 (if_then_else (match_operand 0 "memory_operand")
574 (const_string "both")
575 (const_string "load"))
576 (eq_attr "type" "setcc")
577 (if_then_else (match_operand 0 "memory_operand")
578 (const_string "store")
579 (const_string "none"))
580 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
581 (if_then_else (ior (match_operand 0 "memory_operand")
582 (match_operand 1 "memory_operand"))
583 (const_string "load")
584 (const_string "none"))
585 (eq_attr "type" "ibr")
586 (if_then_else (match_operand 0 "memory_operand")
587 (const_string "load")
588 (const_string "none"))
589 (eq_attr "type" "call")
590 (if_then_else (match_operand 0 "constant_call_address_operand")
591 (const_string "none")
592 (const_string "load"))
593 (eq_attr "type" "callv")
594 (if_then_else (match_operand 1 "constant_call_address_operand")
595 (const_string "none")
596 (const_string "load"))
597 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1,sseshuf1")
598 (match_operand 1 "memory_operand"))
599 (const_string "both")
600 (and (match_operand 0 "memory_operand")
601 (match_operand 1 "memory_operand"))
602 (const_string "both")
603 (match_operand 0 "memory_operand")
604 (const_string "store")
605 (match_operand 1 "memory_operand")
606 (const_string "load")
608 "!alu1,negnot,ishift1,
609 imov,imovx,icmp,test,bitmanip,
611 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
612 sseshuf1,sseadd1,sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
613 (match_operand 2 "memory_operand"))
614 (const_string "load")
615 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
616 (match_operand 3 "memory_operand"))
617 (const_string "load")
619 (const_string "none")))
621 ;; Indicates if an instruction has both an immediate and a displacement.
623 (define_attr "imm_disp" "false,true,unknown"
624 (cond [(eq_attr "type" "other,multi")
625 (const_string "unknown")
626 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
627 (and (match_operand 0 "memory_displacement_operand")
628 (match_operand 1 "immediate_operand")))
629 (const_string "true")
630 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
631 (and (match_operand 0 "memory_displacement_operand")
632 (match_operand 2 "immediate_operand")))
633 (const_string "true")
635 (const_string "false")))
637 ;; Indicates if an FP operation has an integer source.
639 (define_attr "fp_int_src" "false,true"
640 (const_string "false"))
642 ;; Defines rounding mode of an FP operation.
644 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
645 (const_string "any"))
647 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
648 (define_attr "use_carry" "0,1" (const_string "0"))
650 ;; Define attribute to indicate unaligned ssemov insns
651 (define_attr "movu" "0,1" (const_string "0"))
653 ;; Used to control the "enabled" attribute on a per-instruction basis.
654 (define_attr "isa" "base,x64,nox64,sse2,sse2_noavx,sse3,sse4,sse4_noavx,
655 noavx,avx,avx2,noavx2,bmi2,fma4,fma"
656 (const_string "base"))
658 (define_attr "enabled" ""
659 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
660 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
661 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
662 (eq_attr "isa" "sse2_noavx")
663 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
664 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
665 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
666 (eq_attr "isa" "sse4_noavx")
667 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
668 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
669 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
670 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
671 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
672 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
673 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
674 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
678 ;; Describe a user's asm statement.
679 (define_asm_attributes
680 [(set_attr "length" "128")
681 (set_attr "type" "multi")])
683 (define_code_iterator plusminus [plus minus])
685 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
687 ;; Base name for define_insn
688 (define_code_attr plusminus_insn
689 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
690 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
692 ;; Base name for insn mnemonic.
693 (define_code_attr plusminus_mnemonic
694 [(plus "add") (ss_plus "adds") (us_plus "addus")
695 (minus "sub") (ss_minus "subs") (us_minus "subus")])
696 (define_code_attr plusminus_carry_mnemonic
697 [(plus "adc") (minus "sbb")])
699 ;; Mark commutative operators as such in constraints.
700 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
701 (minus "") (ss_minus "") (us_minus "")])
703 ;; Mapping of max and min
704 (define_code_iterator maxmin [smax smin umax umin])
706 ;; Mapping of signed max and min
707 (define_code_iterator smaxmin [smax smin])
709 ;; Mapping of unsigned max and min
710 (define_code_iterator umaxmin [umax umin])
712 ;; Base name for integer and FP insn mnemonic
713 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
714 (umax "maxu") (umin "minu")])
715 (define_code_attr maxmin_float [(smax "max") (smin "min")])
717 ;; Mapping of logic operators
718 (define_code_iterator any_logic [and ior xor])
719 (define_code_iterator any_or [ior xor])
721 ;; Base name for insn mnemonic.
722 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
724 ;; Mapping of logic-shift operators
725 (define_code_iterator any_lshift [ashift lshiftrt])
727 ;; Mapping of shift-right operators
728 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
730 ;; Mapping of all shift operators
731 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
733 ;; Base name for define_insn
734 (define_code_attr shift_insn
735 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
737 ;; Base name for insn mnemonic.
738 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
739 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
741 ;; Mapping of rotate operators
742 (define_code_iterator any_rotate [rotate rotatert])
744 ;; Base name for define_insn
745 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
747 ;; Base name for insn mnemonic.
748 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
750 ;; Mapping of abs neg operators
751 (define_code_iterator absneg [abs neg])
753 ;; Base name for x87 insn mnemonic.
754 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
756 ;; Used in signed and unsigned widening multiplications.
757 (define_code_iterator any_extend [sign_extend zero_extend])
759 ;; Prefix for insn menmonic.
760 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
762 ;; Prefix for define_insn
763 (define_code_attr u [(sign_extend "") (zero_extend "u")])
764 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
765 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
767 ;; All integer modes.
768 (define_mode_iterator SWI1248x [QI HI SI DI])
770 ;; All integer modes without QImode.
771 (define_mode_iterator SWI248x [HI SI DI])
773 ;; All integer modes without QImode and HImode.
774 (define_mode_iterator SWI48x [SI DI])
776 ;; All integer modes without SImode and DImode.
777 (define_mode_iterator SWI12 [QI HI])
779 ;; All integer modes without DImode.
780 (define_mode_iterator SWI124 [QI HI SI])
782 ;; All integer modes without QImode and DImode.
783 (define_mode_iterator SWI24 [HI SI])
785 ;; Single word integer modes.
786 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
788 ;; Single word integer modes without QImode.
789 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
791 ;; Single word integer modes without QImode and HImode.
792 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
794 ;; All math-dependant single and double word integer modes.
795 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
796 (HI "TARGET_HIMODE_MATH")
797 SI DI (TI "TARGET_64BIT")])
799 ;; Math-dependant single word integer modes.
800 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
801 (HI "TARGET_HIMODE_MATH")
802 SI (DI "TARGET_64BIT")])
804 ;; Math-dependant integer modes without DImode.
805 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
806 (HI "TARGET_HIMODE_MATH")
809 ;; Math-dependant single word integer modes without QImode.
810 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
811 SI (DI "TARGET_64BIT")])
813 ;; Double word integer modes.
814 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
815 (TI "TARGET_64BIT")])
817 ;; Double word integer modes as mode attribute.
818 (define_mode_attr DWI [(SI "DI") (DI "TI")])
819 (define_mode_attr dwi [(SI "di") (DI "ti")])
821 ;; Half mode for double word integer modes.
822 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
823 (DI "TARGET_64BIT")])
825 ;; Instruction suffix for integer modes.
826 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
828 ;; Pointer size prefix for integer modes (Intel asm dialect)
829 (define_mode_attr iptrsize [(QI "BYTE")
834 ;; Register class for integer modes.
835 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
837 ;; Immediate operand constraint for integer modes.
838 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
840 ;; General operand constraint for word modes.
841 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
843 ;; Immediate operand constraint for double integer modes.
844 (define_mode_attr di [(SI "nF") (DI "e")])
846 ;; Immediate operand constraint for shifts.
847 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
849 ;; General operand predicate for integer modes.
850 (define_mode_attr general_operand
851 [(QI "general_operand")
852 (HI "general_operand")
853 (SI "x86_64_general_operand")
854 (DI "x86_64_general_operand")
855 (TI "x86_64_general_operand")])
857 ;; General sign/zero extend operand predicate for integer modes.
858 (define_mode_attr general_szext_operand
859 [(QI "general_operand")
860 (HI "general_operand")
861 (SI "x86_64_szext_general_operand")
862 (DI "x86_64_szext_general_operand")])
864 ;; Immediate operand predicate for integer modes.
865 (define_mode_attr immediate_operand
866 [(QI "immediate_operand")
867 (HI "immediate_operand")
868 (SI "x86_64_immediate_operand")
869 (DI "x86_64_immediate_operand")])
871 ;; Nonmemory operand predicate for integer modes.
872 (define_mode_attr nonmemory_operand
873 [(QI "nonmemory_operand")
874 (HI "nonmemory_operand")
875 (SI "x86_64_nonmemory_operand")
876 (DI "x86_64_nonmemory_operand")])
878 ;; Operand predicate for shifts.
879 (define_mode_attr shift_operand
880 [(QI "nonimmediate_operand")
881 (HI "nonimmediate_operand")
882 (SI "nonimmediate_operand")
883 (DI "shiftdi_operand")
884 (TI "register_operand")])
886 ;; Operand predicate for shift argument.
887 (define_mode_attr shift_immediate_operand
888 [(QI "const_1_to_31_operand")
889 (HI "const_1_to_31_operand")
890 (SI "const_1_to_31_operand")
891 (DI "const_1_to_63_operand")])
893 ;; Input operand predicate for arithmetic left shifts.
894 (define_mode_attr ashl_input_operand
895 [(QI "nonimmediate_operand")
896 (HI "nonimmediate_operand")
897 (SI "nonimmediate_operand")
898 (DI "ashldi_input_operand")
899 (TI "reg_or_pm1_operand")])
901 ;; SSE and x87 SFmode and DFmode floating point modes
902 (define_mode_iterator MODEF [SF DF])
904 ;; All x87 floating point modes
905 (define_mode_iterator X87MODEF [SF DF XF])
907 ;; SSE instruction suffix for various modes
908 (define_mode_attr ssemodesuffix
910 (V8SF "ps") (V4DF "pd")
911 (V4SF "ps") (V2DF "pd")
912 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
913 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
915 ;; SSE vector suffix for floating point modes
916 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
918 ;; SSE vector mode corresponding to a scalar mode
919 (define_mode_attr ssevecmode
920 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
922 ;; Instruction suffix for REX 64bit operators.
923 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
925 ;; This mode iterator allows :P to be used for patterns that operate on
926 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
927 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
929 ;; This mode iterator allows :W to be used for patterns that operate on
930 ;; word_mode sized quantities.
931 (define_mode_iterator W
932 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
934 ;; This mode iterator allows :PTR to be used for patterns that operate on
935 ;; ptr_mode sized quantities.
936 (define_mode_iterator PTR
937 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
939 ;; Scheduling descriptions
941 (include "pentium.md")
944 (include "athlon.md")
945 (include "bdver1.md")
946 (include "bdver3.md")
947 (include "btver2.md")
953 ;; Operand and operator predicates and constraints
955 (include "predicates.md")
956 (include "constraints.md")
959 ;; Compare and branch/compare and store instructions.
961 (define_expand "cbranch<mode>4"
962 [(set (reg:CC FLAGS_REG)
963 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
964 (match_operand:SDWIM 2 "<general_operand>")))
965 (set (pc) (if_then_else
966 (match_operator 0 "ordered_comparison_operator"
967 [(reg:CC FLAGS_REG) (const_int 0)])
968 (label_ref (match_operand 3))
972 if (MEM_P (operands[1]) && MEM_P (operands[2]))
973 operands[1] = force_reg (<MODE>mode, operands[1]);
974 ix86_expand_branch (GET_CODE (operands[0]),
975 operands[1], operands[2], operands[3]);
979 (define_expand "cstore<mode>4"
980 [(set (reg:CC FLAGS_REG)
981 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
982 (match_operand:SWIM 3 "<general_operand>")))
983 (set (match_operand:QI 0 "register_operand")
984 (match_operator 1 "ordered_comparison_operator"
985 [(reg:CC FLAGS_REG) (const_int 0)]))]
988 if (MEM_P (operands[2]) && MEM_P (operands[3]))
989 operands[2] = force_reg (<MODE>mode, operands[2]);
990 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
991 operands[2], operands[3]);
995 (define_expand "cmp<mode>_1"
996 [(set (reg:CC FLAGS_REG)
997 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
998 (match_operand:SWI48 1 "<general_operand>")))])
1000 (define_insn "*cmp<mode>_ccno_1"
1001 [(set (reg FLAGS_REG)
1002 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1003 (match_operand:SWI 1 "const0_operand")))]
1004 "ix86_match_ccmode (insn, CCNOmode)"
1006 test{<imodesuffix>}\t%0, %0
1007 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1008 [(set_attr "type" "test,icmp")
1009 (set_attr "length_immediate" "0,1")
1010 (set_attr "mode" "<MODE>")])
1012 (define_insn "*cmp<mode>_1"
1013 [(set (reg FLAGS_REG)
1014 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1015 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1016 "ix86_match_ccmode (insn, CCmode)"
1017 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1018 [(set_attr "type" "icmp")
1019 (set_attr "mode" "<MODE>")])
1021 (define_insn "*cmp<mode>_minus_1"
1022 [(set (reg FLAGS_REG)
1024 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1025 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1027 "ix86_match_ccmode (insn, CCGOCmode)"
1028 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1029 [(set_attr "type" "icmp")
1030 (set_attr "mode" "<MODE>")])
1032 (define_insn "*cmpqi_ext_1"
1033 [(set (reg FLAGS_REG)
1035 (match_operand:QI 0 "general_operand" "Qm")
1038 (match_operand 1 "ext_register_operand" "Q")
1040 (const_int 8)) 0)))]
1041 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1042 "cmp{b}\t{%h1, %0|%0, %h1}"
1043 [(set_attr "type" "icmp")
1044 (set_attr "mode" "QI")])
1046 (define_insn "*cmpqi_ext_1_rex64"
1047 [(set (reg FLAGS_REG)
1049 (match_operand:QI 0 "register_operand" "Q")
1052 (match_operand 1 "ext_register_operand" "Q")
1054 (const_int 8)) 0)))]
1055 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1056 "cmp{b}\t{%h1, %0|%0, %h1}"
1057 [(set_attr "type" "icmp")
1058 (set_attr "mode" "QI")])
1060 (define_insn "*cmpqi_ext_2"
1061 [(set (reg FLAGS_REG)
1065 (match_operand 0 "ext_register_operand" "Q")
1068 (match_operand:QI 1 "const0_operand")))]
1069 "ix86_match_ccmode (insn, CCNOmode)"
1071 [(set_attr "type" "test")
1072 (set_attr "length_immediate" "0")
1073 (set_attr "mode" "QI")])
1075 (define_expand "cmpqi_ext_3"
1076 [(set (reg:CC FLAGS_REG)
1080 (match_operand 0 "ext_register_operand")
1083 (match_operand:QI 1 "immediate_operand")))])
1085 (define_insn "*cmpqi_ext_3_insn"
1086 [(set (reg FLAGS_REG)
1090 (match_operand 0 "ext_register_operand" "Q")
1093 (match_operand:QI 1 "general_operand" "Qmn")))]
1094 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1095 "cmp{b}\t{%1, %h0|%h0, %1}"
1096 [(set_attr "type" "icmp")
1097 (set_attr "modrm" "1")
1098 (set_attr "mode" "QI")])
1100 (define_insn "*cmpqi_ext_3_insn_rex64"
1101 [(set (reg FLAGS_REG)
1105 (match_operand 0 "ext_register_operand" "Q")
1108 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1109 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1110 "cmp{b}\t{%1, %h0|%h0, %1}"
1111 [(set_attr "type" "icmp")
1112 (set_attr "modrm" "1")
1113 (set_attr "mode" "QI")])
1115 (define_insn "*cmpqi_ext_4"
1116 [(set (reg FLAGS_REG)
1120 (match_operand 0 "ext_register_operand" "Q")
1125 (match_operand 1 "ext_register_operand" "Q")
1127 (const_int 8)) 0)))]
1128 "ix86_match_ccmode (insn, CCmode)"
1129 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1130 [(set_attr "type" "icmp")
1131 (set_attr "mode" "QI")])
1133 ;; These implement float point compares.
1134 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1135 ;; which would allow mix and match FP modes on the compares. Which is what
1136 ;; the old patterns did, but with many more of them.
1138 (define_expand "cbranchxf4"
1139 [(set (reg:CC FLAGS_REG)
1140 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1141 (match_operand:XF 2 "nonmemory_operand")))
1142 (set (pc) (if_then_else
1143 (match_operator 0 "ix86_fp_comparison_operator"
1146 (label_ref (match_operand 3))
1150 ix86_expand_branch (GET_CODE (operands[0]),
1151 operands[1], operands[2], operands[3]);
1155 (define_expand "cstorexf4"
1156 [(set (reg:CC FLAGS_REG)
1157 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1158 (match_operand:XF 3 "nonmemory_operand")))
1159 (set (match_operand:QI 0 "register_operand")
1160 (match_operator 1 "ix86_fp_comparison_operator"
1165 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1166 operands[2], operands[3]);
1170 (define_expand "cbranch<mode>4"
1171 [(set (reg:CC FLAGS_REG)
1172 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1173 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1174 (set (pc) (if_then_else
1175 (match_operator 0 "ix86_fp_comparison_operator"
1178 (label_ref (match_operand 3))
1180 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1182 ix86_expand_branch (GET_CODE (operands[0]),
1183 operands[1], operands[2], operands[3]);
1187 (define_expand "cstore<mode>4"
1188 [(set (reg:CC FLAGS_REG)
1189 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1190 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1191 (set (match_operand:QI 0 "register_operand")
1192 (match_operator 1 "ix86_fp_comparison_operator"
1195 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1197 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1198 operands[2], operands[3]);
1202 (define_expand "cbranchcc4"
1203 [(set (pc) (if_then_else
1204 (match_operator 0 "comparison_operator"
1205 [(match_operand 1 "flags_reg_operand")
1206 (match_operand 2 "const0_operand")])
1207 (label_ref (match_operand 3))
1211 ix86_expand_branch (GET_CODE (operands[0]),
1212 operands[1], operands[2], operands[3]);
1216 (define_expand "cstorecc4"
1217 [(set (match_operand:QI 0 "register_operand")
1218 (match_operator 1 "comparison_operator"
1219 [(match_operand 2 "flags_reg_operand")
1220 (match_operand 3 "const0_operand")]))]
1223 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1224 operands[2], operands[3]);
1229 ;; FP compares, step 1:
1230 ;; Set the FP condition codes.
1232 ;; CCFPmode compare with exceptions
1233 ;; CCFPUmode compare with no exceptions
1235 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1236 ;; used to manage the reg stack popping would not be preserved.
1238 (define_insn "*cmp<mode>_0_i387"
1239 [(set (match_operand:HI 0 "register_operand" "=a")
1242 (match_operand:X87MODEF 1 "register_operand" "f")
1243 (match_operand:X87MODEF 2 "const0_operand"))]
1246 "* return output_fp_compare (insn, operands, false, false);"
1247 [(set_attr "type" "multi")
1248 (set_attr "unit" "i387")
1249 (set_attr "mode" "<MODE>")])
1251 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1252 [(set (reg:CCFP FLAGS_REG)
1254 (match_operand:X87MODEF 1 "register_operand" "f")
1255 (match_operand:X87MODEF 2 "const0_operand")))
1256 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1257 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1259 "&& reload_completed"
1262 [(compare:CCFP (match_dup 1)(match_dup 2))]
1264 (set (reg:CC FLAGS_REG)
1265 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1267 [(set_attr "type" "multi")
1268 (set_attr "unit" "i387")
1269 (set_attr "mode" "<MODE>")])
1271 (define_insn "*cmpxf_i387"
1272 [(set (match_operand:HI 0 "register_operand" "=a")
1275 (match_operand:XF 1 "register_operand" "f")
1276 (match_operand:XF 2 "register_operand" "f"))]
1279 "* return output_fp_compare (insn, operands, false, false);"
1280 [(set_attr "type" "multi")
1281 (set_attr "unit" "i387")
1282 (set_attr "mode" "XF")])
1284 (define_insn_and_split "*cmpxf_cc_i387"
1285 [(set (reg:CCFP FLAGS_REG)
1287 (match_operand:XF 1 "register_operand" "f")
1288 (match_operand:XF 2 "register_operand" "f")))
1289 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1290 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1292 "&& reload_completed"
1295 [(compare:CCFP (match_dup 1)(match_dup 2))]
1297 (set (reg:CC FLAGS_REG)
1298 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1300 [(set_attr "type" "multi")
1301 (set_attr "unit" "i387")
1302 (set_attr "mode" "XF")])
1304 (define_insn "*cmp<mode>_i387"
1305 [(set (match_operand:HI 0 "register_operand" "=a")
1308 (match_operand:MODEF 1 "register_operand" "f")
1309 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1312 "* return output_fp_compare (insn, operands, false, false);"
1313 [(set_attr "type" "multi")
1314 (set_attr "unit" "i387")
1315 (set_attr "mode" "<MODE>")])
1317 (define_insn_and_split "*cmp<mode>_cc_i387"
1318 [(set (reg:CCFP FLAGS_REG)
1320 (match_operand:MODEF 1 "register_operand" "f")
1321 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1322 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1323 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1325 "&& reload_completed"
1328 [(compare:CCFP (match_dup 1)(match_dup 2))]
1330 (set (reg:CC FLAGS_REG)
1331 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1333 [(set_attr "type" "multi")
1334 (set_attr "unit" "i387")
1335 (set_attr "mode" "<MODE>")])
1337 (define_insn "*cmpu<mode>_i387"
1338 [(set (match_operand:HI 0 "register_operand" "=a")
1341 (match_operand:X87MODEF 1 "register_operand" "f")
1342 (match_operand:X87MODEF 2 "register_operand" "f"))]
1345 "* return output_fp_compare (insn, operands, false, true);"
1346 [(set_attr "type" "multi")
1347 (set_attr "unit" "i387")
1348 (set_attr "mode" "<MODE>")])
1350 (define_insn_and_split "*cmpu<mode>_cc_i387"
1351 [(set (reg:CCFPU FLAGS_REG)
1353 (match_operand:X87MODEF 1 "register_operand" "f")
1354 (match_operand:X87MODEF 2 "register_operand" "f")))
1355 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1356 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1358 "&& reload_completed"
1361 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1363 (set (reg:CC FLAGS_REG)
1364 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1366 [(set_attr "type" "multi")
1367 (set_attr "unit" "i387")
1368 (set_attr "mode" "<MODE>")])
1370 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1371 [(set (match_operand:HI 0 "register_operand" "=a")
1374 (match_operand:X87MODEF 1 "register_operand" "f")
1375 (match_operator:X87MODEF 3 "float_operator"
1376 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1379 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1380 || optimize_function_for_size_p (cfun))"
1381 "* return output_fp_compare (insn, operands, false, false);"
1382 [(set_attr "type" "multi")
1383 (set_attr "unit" "i387")
1384 (set_attr "fp_int_src" "true")
1385 (set_attr "mode" "<SWI24:MODE>")])
1387 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1388 [(set (reg:CCFP FLAGS_REG)
1390 (match_operand:X87MODEF 1 "register_operand" "f")
1391 (match_operator:X87MODEF 3 "float_operator"
1392 [(match_operand:SWI24 2 "memory_operand" "m")])))
1393 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1394 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1395 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1396 || optimize_function_for_size_p (cfun))"
1398 "&& reload_completed"
1403 (match_op_dup 3 [(match_dup 2)]))]
1405 (set (reg:CC FLAGS_REG)
1406 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1408 [(set_attr "type" "multi")
1409 (set_attr "unit" "i387")
1410 (set_attr "fp_int_src" "true")
1411 (set_attr "mode" "<SWI24:MODE>")])
1413 ;; FP compares, step 2
1414 ;; Move the fpsw to ax.
1416 (define_insn "x86_fnstsw_1"
1417 [(set (match_operand:HI 0 "register_operand" "=a")
1418 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1421 [(set (attr "length")
1422 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1423 (set_attr "mode" "SI")
1424 (set_attr "unit" "i387")])
1426 ;; FP compares, step 3
1427 ;; Get ax into flags, general case.
1429 (define_insn "x86_sahf_1"
1430 [(set (reg:CC FLAGS_REG)
1431 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1435 #ifndef HAVE_AS_IX86_SAHF
1437 return ASM_BYTE "0x9e";
1442 [(set_attr "length" "1")
1443 (set_attr "athlon_decode" "vector")
1444 (set_attr "amdfam10_decode" "direct")
1445 (set_attr "bdver1_decode" "direct")
1446 (set_attr "mode" "SI")])
1448 ;; Pentium Pro can do steps 1 through 3 in one go.
1449 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1450 ;; (these i387 instructions set flags directly)
1452 (define_mode_iterator FPCMP [CCFP CCFPU])
1453 (define_mode_attr unord [(CCFP "") (CCFPU "u")])
1455 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_mixed"
1456 [(set (reg:FPCMP FLAGS_REG)
1458 (match_operand:MODEF 0 "register_operand" "f,x")
1459 (match_operand:MODEF 1 "nonimmediate_operand" "f,xm")))]
1460 "TARGET_MIX_SSE_I387
1461 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1462 "* return output_fp_compare (insn, operands, true,
1463 <FPCMP:MODE>mode == CCFPUmode);"
1464 [(set_attr "type" "fcmp,ssecomi")
1465 (set_attr "prefix" "orig,maybe_vex")
1466 (set_attr "mode" "<MODEF:MODE>")
1467 (set (attr "prefix_rep")
1468 (if_then_else (eq_attr "type" "ssecomi")
1470 (const_string "*")))
1471 (set (attr "prefix_data16")
1472 (cond [(eq_attr "type" "fcmp")
1474 (eq_attr "mode" "DF")
1477 (const_string "0")))
1478 (set_attr "athlon_decode" "vector")
1479 (set_attr "amdfam10_decode" "direct")
1480 (set_attr "bdver1_decode" "double")])
1482 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_sse"
1483 [(set (reg:FPCMP FLAGS_REG)
1485 (match_operand:MODEF 0 "register_operand" "x")
1486 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
1488 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1489 "* return output_fp_compare (insn, operands, true,
1490 <FPCMP:MODE>mode == CCFPUmode);"
1491 [(set_attr "type" "ssecomi")
1492 (set_attr "prefix" "maybe_vex")
1493 (set_attr "mode" "<MODEF:MODE>")
1494 (set_attr "prefix_rep" "0")
1495 (set (attr "prefix_data16")
1496 (if_then_else (eq_attr "mode" "DF")
1498 (const_string "0")))
1499 (set_attr "athlon_decode" "vector")
1500 (set_attr "amdfam10_decode" "direct")
1501 (set_attr "bdver1_decode" "double")])
1503 (define_insn "*cmpi<FPCMP:unord><X87MODEF:mode>_i387"
1504 [(set (reg:FPCMP FLAGS_REG)
1506 (match_operand:X87MODEF 0 "register_operand" "f")
1507 (match_operand:X87MODEF 1 "register_operand" "f")))]
1508 "TARGET_80387 && TARGET_CMOVE
1509 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
1510 "* return output_fp_compare (insn, operands, true,
1511 <FPCMP:MODE>mode == CCFPUmode);"
1512 [(set_attr "type" "fcmp")
1513 (set_attr "mode" "<X87MODEF:MODE>")
1514 (set_attr "athlon_decode" "vector")
1515 (set_attr "amdfam10_decode" "direct")
1516 (set_attr "bdver1_decode" "double")])
1518 ;; Push/pop instructions.
1520 (define_insn "*push<mode>2"
1521 [(set (match_operand:DWI 0 "push_operand" "=<")
1522 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1525 [(set_attr "type" "multi")
1526 (set_attr "mode" "<MODE>")])
1529 [(set (match_operand:TI 0 "push_operand")
1530 (match_operand:TI 1 "general_operand"))]
1531 "TARGET_64BIT && reload_completed
1532 && !SSE_REG_P (operands[1])"
1534 "ix86_split_long_move (operands); DONE;")
1536 (define_insn "*pushdi2_rex64"
1537 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1538 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1543 [(set_attr "type" "push,multi")
1544 (set_attr "mode" "DI")])
1546 ;; Convert impossible pushes of immediate to existing instructions.
1547 ;; First try to get scratch register and go through it. In case this
1548 ;; fails, push sign extended lower part first and then overwrite
1549 ;; upper part by 32bit move.
1551 [(match_scratch:DI 2 "r")
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)"
1556 [(set (match_dup 2) (match_dup 1))
1557 (set (match_dup 0) (match_dup 2))])
1559 ;; We need to define this as both peepholer and splitter for case
1560 ;; peephole2 pass is not run.
1561 ;; "&& 1" is needed to keep it from matching the previous pattern.
1563 [(set (match_operand:DI 0 "push_operand")
1564 (match_operand:DI 1 "immediate_operand"))]
1565 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1566 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1567 [(set (match_dup 0) (match_dup 1))
1568 (set (match_dup 2) (match_dup 3))]
1570 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1572 operands[1] = gen_lowpart (DImode, operands[2]);
1573 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1578 [(set (match_operand:DI 0 "push_operand")
1579 (match_operand:DI 1 "immediate_operand"))]
1580 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1581 ? epilogue_completed : reload_completed)
1582 && !symbolic_operand (operands[1], DImode)
1583 && !x86_64_immediate_operand (operands[1], DImode)"
1584 [(set (match_dup 0) (match_dup 1))
1585 (set (match_dup 2) (match_dup 3))]
1587 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1589 operands[1] = gen_lowpart (DImode, operands[2]);
1590 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1595 [(set (match_operand:DI 0 "push_operand")
1596 (match_operand:DI 1 "general_operand"))]
1597 "!TARGET_64BIT && reload_completed
1598 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1600 "ix86_split_long_move (operands); DONE;")
1602 (define_insn "*pushsi2"
1603 [(set (match_operand:SI 0 "push_operand" "=<")
1604 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1607 [(set_attr "type" "push")
1608 (set_attr "mode" "SI")])
1610 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1611 ;; "push a byte/word". But actually we use pushl, which has the effect
1612 ;; of rounding the amount pushed up to a word.
1614 ;; For TARGET_64BIT we always round up to 8 bytes.
1615 (define_insn "*push<mode>2_rex64"
1616 [(set (match_operand:SWI124 0 "push_operand" "=X")
1617 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1620 [(set_attr "type" "push")
1621 (set_attr "mode" "DI")])
1623 (define_insn "*push<mode>2"
1624 [(set (match_operand:SWI12 0 "push_operand" "=X")
1625 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1628 [(set_attr "type" "push")
1629 (set_attr "mode" "SI")])
1631 (define_insn "*push<mode>2_prologue"
1632 [(set (match_operand:W 0 "push_operand" "=<")
1633 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1634 (clobber (mem:BLK (scratch)))]
1636 "push{<imodesuffix>}\t%1"
1637 [(set_attr "type" "push")
1638 (set_attr "mode" "<MODE>")])
1640 (define_insn "*pop<mode>1"
1641 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1642 (match_operand:W 1 "pop_operand" ">"))]
1644 "pop{<imodesuffix>}\t%0"
1645 [(set_attr "type" "pop")
1646 (set_attr "mode" "<MODE>")])
1648 (define_insn "*pop<mode>1_epilogue"
1649 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1650 (match_operand:W 1 "pop_operand" ">"))
1651 (clobber (mem:BLK (scratch)))]
1653 "pop{<imodesuffix>}\t%0"
1654 [(set_attr "type" "pop")
1655 (set_attr "mode" "<MODE>")])
1657 ;; Move instructions.
1659 ;; Reload patterns to support multi-word load/store
1660 ;; with non-offsetable address.
1661 (define_expand "reload_noff_store"
1662 [(parallel [(match_operand 0 "memory_operand" "=m")
1663 (match_operand 1 "register_operand" "r")
1664 (match_operand:DI 2 "register_operand" "=&r")])]
1667 rtx mem = operands[0];
1668 rtx addr = XEXP (mem, 0);
1670 emit_move_insn (operands[2], addr);
1671 mem = replace_equiv_address_nv (mem, operands[2]);
1673 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
1677 (define_expand "reload_noff_load"
1678 [(parallel [(match_operand 0 "register_operand" "=r")
1679 (match_operand 1 "memory_operand" "m")
1680 (match_operand:DI 2 "register_operand" "=r")])]
1683 rtx mem = operands[1];
1684 rtx addr = XEXP (mem, 0);
1686 emit_move_insn (operands[2], addr);
1687 mem = replace_equiv_address_nv (mem, operands[2]);
1689 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
1693 (define_expand "movoi"
1694 [(set (match_operand:OI 0 "nonimmediate_operand")
1695 (match_operand:OI 1 "general_operand"))]
1697 "ix86_expand_move (OImode, operands); DONE;")
1699 (define_expand "movti"
1700 [(set (match_operand:TI 0 "nonimmediate_operand")
1701 (match_operand:TI 1 "nonimmediate_operand"))]
1702 "TARGET_64BIT || TARGET_SSE"
1705 ix86_expand_move (TImode, operands);
1706 else if (push_operand (operands[0], TImode))
1707 ix86_expand_push (TImode, operands[1]);
1709 ix86_expand_vector_move (TImode, operands);
1713 ;; This expands to what emit_move_complex would generate if we didn't
1714 ;; have a movti pattern. Having this avoids problems with reload on
1715 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1716 ;; to have around all the time.
1717 (define_expand "movcdi"
1718 [(set (match_operand:CDI 0 "nonimmediate_operand")
1719 (match_operand:CDI 1 "general_operand"))]
1722 if (push_operand (operands[0], CDImode))
1723 emit_move_complex_push (CDImode, operands[0], operands[1]);
1725 emit_move_complex_parts (operands[0], operands[1]);
1729 (define_expand "mov<mode>"
1730 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1731 (match_operand:SWI1248x 1 "general_operand"))]
1733 "ix86_expand_move (<MODE>mode, operands); DONE;")
1735 (define_insn "*mov<mode>_xor"
1736 [(set (match_operand:SWI48 0 "register_operand" "=r")
1737 (match_operand:SWI48 1 "const0_operand"))
1738 (clobber (reg:CC FLAGS_REG))]
1741 [(set_attr "type" "alu1")
1742 (set_attr "mode" "SI")
1743 (set_attr "length_immediate" "0")])
1745 (define_insn "*mov<mode>_or"
1746 [(set (match_operand:SWI48 0 "register_operand" "=r")
1747 (match_operand:SWI48 1 "const_int_operand"))
1748 (clobber (reg:CC FLAGS_REG))]
1750 && operands[1] == constm1_rtx"
1751 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1752 [(set_attr "type" "alu1")
1753 (set_attr "mode" "<MODE>")
1754 (set_attr "length_immediate" "1")])
1756 (define_insn "*movoi_internal_avx"
1757 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x ,m")
1758 (match_operand:OI 1 "vector_move_operand" "C ,xm,x"))]
1759 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1761 switch (which_alternative)
1764 return standard_sse_constant_opcode (insn, operands[1]);
1767 if (misaligned_operand (operands[0], OImode)
1768 || misaligned_operand (operands[1], OImode))
1770 if (get_attr_mode (insn) == MODE_V8SF)
1771 return "vmovups\t{%1, %0|%0, %1}";
1773 return "vmovdqu\t{%1, %0|%0, %1}";
1777 if (get_attr_mode (insn) == MODE_V8SF)
1778 return "vmovaps\t{%1, %0|%0, %1}";
1780 return "vmovdqa\t{%1, %0|%0, %1}";
1786 [(set_attr "type" "sselog1,ssemov,ssemov")
1787 (set_attr "prefix" "vex")
1789 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1790 (const_string "V8SF")
1791 (and (eq_attr "alternative" "2")
1792 (match_test "TARGET_SSE_TYPELESS_STORES"))
1793 (const_string "V8SF")
1795 (const_string "OI")))])
1797 (define_insn "*movti_internal"
1798 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,x,x ,m")
1799 (match_operand:TI 1 "general_operand" "riFo,re,C,xm,x"))]
1800 "(TARGET_64BIT || TARGET_SSE)
1801 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1803 switch (which_alternative)
1809 return standard_sse_constant_opcode (insn, operands[1]);
1812 /* TDmode values are passed as TImode on the stack. Moving them
1813 to stack may result in unaligned memory access. */
1814 if (misaligned_operand (operands[0], TImode)
1815 || misaligned_operand (operands[1], TImode))
1817 if (get_attr_mode (insn) == MODE_V4SF)
1818 return "%vmovups\t{%1, %0|%0, %1}";
1820 return "%vmovdqu\t{%1, %0|%0, %1}";
1824 if (get_attr_mode (insn) == MODE_V4SF)
1825 return "%vmovaps\t{%1, %0|%0, %1}";
1827 return "%vmovdqa\t{%1, %0|%0, %1}";
1833 [(set_attr "isa" "x64,x64,*,*,*")
1834 (set_attr "type" "*,*,sselog1,ssemov,ssemov")
1835 (set (attr "prefix")
1836 (if_then_else (eq_attr "type" "sselog1,ssemov")
1837 (const_string "maybe_vex")
1838 (const_string "orig")))
1840 (cond [(eq_attr "alternative" "0,1")
1842 (ior (not (match_test "TARGET_SSE2"))
1843 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
1844 (const_string "V4SF")
1845 (and (eq_attr "alternative" "4")
1846 (match_test "TARGET_SSE_TYPELESS_STORES"))
1847 (const_string "V4SF")
1848 (match_test "TARGET_AVX")
1850 (match_test "optimize_function_for_size_p (cfun)")
1851 (const_string "V4SF")
1853 (const_string "TI")))])
1856 [(set (match_operand:TI 0 "nonimmediate_operand")
1857 (match_operand:TI 1 "general_operand"))]
1859 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1861 "ix86_split_long_move (operands); DONE;")
1863 (define_insn "*movdi_internal"
1864 [(set (match_operand:DI 0 "nonimmediate_operand"
1865 "=r ,o ,r,r ,r,m ,*y,m*y,*y,?*y,?r ,?*Ym,*x,*x,*x,m ,?r ,?*Yi,?*x,?*Ym")
1866 (match_operand:DI 1 "general_operand"
1867 "riFo,riF,Z,rem,i,re,C ,*y ,m ,m ,*Ym,r ,C ,*x,m ,*x,*Yi,r ,*Ym,*x"))]
1868 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1870 switch (get_attr_type (insn))
1876 return "pxor\t%0, %0";
1879 /* Handle broken assemblers that require movd instead of movq. */
1880 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1881 return "movd\t{%1, %0|%0, %1}";
1882 return "movq\t{%1, %0|%0, %1}";
1885 return standard_sse_constant_opcode (insn, operands[1]);
1888 switch (get_attr_mode (insn))
1891 /* Handle broken assemblers that require movd instead of movq. */
1892 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1893 return "%vmovd\t{%1, %0|%0, %1}";
1894 return "%vmovq\t{%1, %0|%0, %1}";
1896 return "%vmovdqa\t{%1, %0|%0, %1}";
1899 gcc_assert (!TARGET_AVX);
1900 return "movlps\t{%1, %0|%0, %1}";
1902 return "%vmovaps\t{%1, %0|%0, %1}";
1909 if (SSE_REG_P (operands[0]))
1910 return "movq2dq\t{%1, %0|%0, %1}";
1912 return "movdq2q\t{%1, %0|%0, %1}";
1915 return "lea{q}\t{%E1, %0|%0, %E1}";
1918 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1919 if (get_attr_mode (insn) == MODE_SI)
1920 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1921 else if (which_alternative == 4)
1922 return "movabs{q}\t{%1, %0|%0, %1}";
1923 else if (ix86_use_lea_for_mov (insn, operands))
1924 return "lea{q}\t{%E1, %0|%0, %E1}";
1926 return "mov{q}\t{%1, %0|%0, %1}";
1930 (cond [(eq_attr "alternative" "0,1,8")
1931 (const_string "nox64")
1932 (eq_attr "alternative" "2,3,4,5,9,10,11,16,17")
1933 (const_string "x64")
1934 (eq_attr "alternative" "18,19")
1935 (const_string "sse2")
1937 (const_string "*")))
1939 (cond [(eq_attr "alternative" "0,1")
1940 (const_string "multi")
1941 (eq_attr "alternative" "6")
1942 (const_string "mmx")
1943 (eq_attr "alternative" "7,8,9,10,11")
1944 (const_string "mmxmov")
1945 (eq_attr "alternative" "12")
1946 (const_string "sselog1")
1947 (eq_attr "alternative" "13,14,15,16,17")
1948 (const_string "ssemov")
1949 (eq_attr "alternative" "18,19")
1950 (const_string "ssecvt")
1951 (match_operand 1 "pic_32bit_operand")
1952 (const_string "lea")
1954 (const_string "imov")))
1957 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
1959 (const_string "*")))
1960 (set (attr "length_immediate")
1962 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
1964 (const_string "*")))
1965 (set (attr "prefix_rex")
1966 (if_then_else (eq_attr "alternative" "10,11")
1968 (const_string "*")))
1969 (set (attr "prefix")
1970 (if_then_else (eq_attr "type" "sselog1,ssemov")
1971 (const_string "maybe_vex")
1972 (const_string "orig")))
1973 (set (attr "prefix_data16")
1974 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
1976 (const_string "*")))
1978 (cond [(eq_attr "alternative" "2")
1980 (eq_attr "alternative" "12,13")
1981 (cond [(ior (not (match_test "TARGET_SSE2"))
1982 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
1983 (const_string "V4SF")
1984 (match_test "TARGET_AVX")
1986 (match_test "optimize_function_for_size_p (cfun)")
1987 (const_string "V4SF")
1989 (const_string "TI"))
1991 (and (eq_attr "alternative" "14,15")
1992 (not (match_test "TARGET_SSE2")))
1993 (const_string "V2SF")
1995 (const_string "DI")))])
1998 [(set (match_operand:DI 0 "nonimmediate_operand")
1999 (match_operand:DI 1 "general_operand"))]
2000 "!TARGET_64BIT && reload_completed
2001 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2002 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2004 "ix86_split_long_move (operands); DONE;")
2006 (define_insn "*movsi_internal"
2007 [(set (match_operand:SI 0 "nonimmediate_operand"
2008 "=r,m ,*y,*y,?rm,?*y,*x,*x,*x,m ,?r ,?*Yi")
2009 (match_operand:SI 1 "general_operand"
2010 "g ,re,C ,*y,*y ,rm ,C ,*x,m ,*x,*Yi,r"))]
2011 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2013 switch (get_attr_type (insn))
2016 return standard_sse_constant_opcode (insn, operands[1]);
2019 switch (get_attr_mode (insn))
2022 return "%vmovdqa\t{%1, %0|%0, %1}";
2024 return "%vmovaps\t{%1, %0|%0, %1}";
2026 return "%vmovd\t{%1, %0|%0, %1}";
2028 return "%vmovss\t{%1, %0|%0, %1}";
2034 return "pxor\t%0, %0";
2037 if (get_attr_mode (insn) == MODE_DI)
2038 return "movq\t{%1, %0|%0, %1}";
2039 return "movd\t{%1, %0|%0, %1}";
2042 return "lea{l}\t{%E1, %0|%0, %E1}";
2045 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2046 if (ix86_use_lea_for_mov (insn, operands))
2047 return "lea{l}\t{%E1, %0|%0, %E1}";
2049 return "mov{l}\t{%1, %0|%0, %1}";
2053 (cond [(eq_attr "alternative" "2")
2054 (const_string "mmx")
2055 (eq_attr "alternative" "3,4,5")
2056 (const_string "mmxmov")
2057 (eq_attr "alternative" "6")
2058 (const_string "sselog1")
2059 (eq_attr "alternative" "7,8,9,10,11")
2060 (const_string "ssemov")
2061 (match_operand 1 "pic_32bit_operand")
2062 (const_string "lea")
2064 (const_string "imov")))
2065 (set (attr "prefix")
2066 (if_then_else (eq_attr "type" "sselog1,ssemov")
2067 (const_string "maybe_vex")
2068 (const_string "orig")))
2069 (set (attr "prefix_data16")
2070 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2072 (const_string "*")))
2074 (cond [(eq_attr "alternative" "2,3")
2076 (eq_attr "alternative" "6,7")
2077 (cond [(ior (not (match_test "TARGET_SSE2"))
2078 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2079 (const_string "V4SF")
2080 (match_test "TARGET_AVX")
2082 (match_test "optimize_function_for_size_p (cfun)")
2083 (const_string "V4SF")
2085 (const_string "TI"))
2087 (and (eq_attr "alternative" "8,9")
2088 (not (match_test "TARGET_SSE2")))
2091 (const_string "SI")))])
2093 (define_insn "*movhi_internal"
2094 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m")
2095 (match_operand:HI 1 "general_operand" "r ,rn,rm,rn"))]
2096 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2098 switch (get_attr_type (insn))
2101 /* movzwl is faster than movw on p2 due to partial word stalls,
2102 though not as fast as an aligned movl. */
2103 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2105 if (get_attr_mode (insn) == MODE_SI)
2106 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2108 return "mov{w}\t{%1, %0|%0, %1}";
2112 (cond [(match_test "optimize_function_for_size_p (cfun)")
2113 (const_string "imov")
2114 (and (eq_attr "alternative" "0")
2115 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2116 (not (match_test "TARGET_HIMODE_MATH"))))
2117 (const_string "imov")
2118 (and (eq_attr "alternative" "1,2")
2119 (match_operand:HI 1 "aligned_operand"))
2120 (const_string "imov")
2121 (and (match_test "TARGET_MOVX")
2122 (eq_attr "alternative" "0,2"))
2123 (const_string "imovx")
2125 (const_string "imov")))
2127 (cond [(eq_attr "type" "imovx")
2129 (and (eq_attr "alternative" "1,2")
2130 (match_operand:HI 1 "aligned_operand"))
2132 (and (eq_attr "alternative" "0")
2133 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2134 (not (match_test "TARGET_HIMODE_MATH"))))
2137 (const_string "HI")))])
2139 ;; Situation is quite tricky about when to choose full sized (SImode) move
2140 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2141 ;; partial register dependency machines (such as AMD Athlon), where QImode
2142 ;; moves issue extra dependency and for partial register stalls machines
2143 ;; that don't use QImode patterns (and QImode move cause stall on the next
2146 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2147 ;; register stall machines with, where we use QImode instructions, since
2148 ;; partial register stall can be caused there. Then we use movzx.
2149 (define_insn "*movqi_internal"
2150 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2151 (match_operand:QI 1 "general_operand" "q ,qn,qm,q,rn,qm,qn"))]
2152 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2154 switch (get_attr_type (insn))
2157 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2158 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2160 if (get_attr_mode (insn) == MODE_SI)
2161 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2163 return "mov{b}\t{%1, %0|%0, %1}";
2167 (cond [(and (eq_attr "alternative" "5")
2168 (not (match_operand:QI 1 "aligned_operand")))
2169 (const_string "imovx")
2170 (match_test "optimize_function_for_size_p (cfun)")
2171 (const_string "imov")
2172 (and (eq_attr "alternative" "3")
2173 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2174 (not (match_test "TARGET_QIMODE_MATH"))))
2175 (const_string "imov")
2176 (eq_attr "alternative" "3,5")
2177 (const_string "imovx")
2178 (and (match_test "TARGET_MOVX")
2179 (eq_attr "alternative" "2"))
2180 (const_string "imovx")
2182 (const_string "imov")))
2184 (cond [(eq_attr "alternative" "3,4,5")
2186 (eq_attr "alternative" "6")
2188 (eq_attr "type" "imovx")
2190 (and (eq_attr "type" "imov")
2191 (and (eq_attr "alternative" "0,1")
2192 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2193 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2194 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2196 ;; Avoid partial register stalls when not using QImode arithmetic
2197 (and (eq_attr "type" "imov")
2198 (and (eq_attr "alternative" "0,1")
2199 (and (match_test "TARGET_PARTIAL_REG_STALL")
2200 (not (match_test "TARGET_QIMODE_MATH")))))
2203 (const_string "QI")))])
2205 ;; Stores and loads of ax to arbitrary constant address.
2206 ;; We fake an second form of instruction to force reload to load address
2207 ;; into register when rax is not available
2208 (define_insn "*movabs<mode>_1"
2209 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2210 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2211 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2213 movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1}
2214 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2215 [(set_attr "type" "imov")
2216 (set_attr "modrm" "0,*")
2217 (set_attr "length_address" "8,0")
2218 (set_attr "length_immediate" "0,*")
2219 (set_attr "memory" "store")
2220 (set_attr "mode" "<MODE>")])
2222 (define_insn "*movabs<mode>_2"
2223 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2224 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2225 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2227 movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]}
2228 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2229 [(set_attr "type" "imov")
2230 (set_attr "modrm" "0,*")
2231 (set_attr "length_address" "8,0")
2232 (set_attr "length_immediate" "0")
2233 (set_attr "memory" "load")
2234 (set_attr "mode" "<MODE>")])
2236 (define_insn "swap<mode>"
2237 [(set (match_operand:SWI48 0 "register_operand" "+r")
2238 (match_operand:SWI48 1 "register_operand" "+r"))
2242 "xchg{<imodesuffix>}\t%1, %0"
2243 [(set_attr "type" "imov")
2244 (set_attr "mode" "<MODE>")
2245 (set_attr "pent_pair" "np")
2246 (set_attr "athlon_decode" "vector")
2247 (set_attr "amdfam10_decode" "double")
2248 (set_attr "bdver1_decode" "double")])
2250 (define_insn "*swap<mode>_1"
2251 [(set (match_operand:SWI12 0 "register_operand" "+r")
2252 (match_operand:SWI12 1 "register_operand" "+r"))
2255 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2257 [(set_attr "type" "imov")
2258 (set_attr "mode" "SI")
2259 (set_attr "pent_pair" "np")
2260 (set_attr "athlon_decode" "vector")
2261 (set_attr "amdfam10_decode" "double")
2262 (set_attr "bdver1_decode" "double")])
2264 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2265 ;; is disabled for AMDFAM10
2266 (define_insn "*swap<mode>_2"
2267 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2268 (match_operand:SWI12 1 "register_operand" "+<r>"))
2271 "TARGET_PARTIAL_REG_STALL"
2272 "xchg{<imodesuffix>}\t%1, %0"
2273 [(set_attr "type" "imov")
2274 (set_attr "mode" "<MODE>")
2275 (set_attr "pent_pair" "np")
2276 (set_attr "athlon_decode" "vector")])
2278 (define_expand "movstrict<mode>"
2279 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2280 (match_operand:SWI12 1 "general_operand"))]
2283 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2285 if (GET_CODE (operands[0]) == SUBREG
2286 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2288 /* Don't generate memory->memory moves, go through a register */
2289 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2290 operands[1] = force_reg (<MODE>mode, operands[1]);
2293 (define_insn "*movstrict<mode>_1"
2294 [(set (strict_low_part
2295 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2296 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2297 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2298 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2299 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2300 [(set_attr "type" "imov")
2301 (set_attr "mode" "<MODE>")])
2303 (define_insn "*movstrict<mode>_xor"
2304 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2305 (match_operand:SWI12 1 "const0_operand"))
2306 (clobber (reg:CC FLAGS_REG))]
2308 "xor{<imodesuffix>}\t%0, %0"
2309 [(set_attr "type" "alu1")
2310 (set_attr "mode" "<MODE>")
2311 (set_attr "length_immediate" "0")])
2313 (define_insn "*mov<mode>_extv_1"
2314 [(set (match_operand:SWI24 0 "register_operand" "=R")
2315 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2319 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2320 [(set_attr "type" "imovx")
2321 (set_attr "mode" "SI")])
2323 (define_insn "*movqi_extv_1_rex64"
2324 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2325 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2330 switch (get_attr_type (insn))
2333 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2335 return "mov{b}\t{%h1, %0|%0, %h1}";
2339 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand"))
2340 (match_test "TARGET_MOVX"))
2341 (const_string "imovx")
2342 (const_string "imov")))
2344 (if_then_else (eq_attr "type" "imovx")
2346 (const_string "QI")))])
2348 (define_insn "*movqi_extv_1"
2349 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2350 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2355 switch (get_attr_type (insn))
2358 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2360 return "mov{b}\t{%h1, %0|%0, %h1}";
2364 (if_then_else (and (match_operand:QI 0 "register_operand")
2365 (ior (not (match_operand:QI 0 "QIreg_operand"))
2366 (match_test "TARGET_MOVX")))
2367 (const_string "imovx")
2368 (const_string "imov")))
2370 (if_then_else (eq_attr "type" "imovx")
2372 (const_string "QI")))])
2374 (define_insn "*mov<mode>_extzv_1"
2375 [(set (match_operand:SWI48 0 "register_operand" "=R")
2376 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2380 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2381 [(set_attr "type" "imovx")
2382 (set_attr "mode" "SI")])
2384 (define_insn "*movqi_extzv_2_rex64"
2385 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2387 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2392 switch (get_attr_type (insn))
2395 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2397 return "mov{b}\t{%h1, %0|%0, %h1}";
2401 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand"))
2402 (match_test "TARGET_MOVX"))
2403 (const_string "imovx")
2404 (const_string "imov")))
2406 (if_then_else (eq_attr "type" "imovx")
2408 (const_string "QI")))])
2410 (define_insn "*movqi_extzv_2"
2411 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2413 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2418 switch (get_attr_type (insn))
2421 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2423 return "mov{b}\t{%h1, %0|%0, %h1}";
2427 (if_then_else (and (match_operand:QI 0 "register_operand")
2428 (ior (not (match_operand:QI 0 "QIreg_operand"))
2429 (match_test "TARGET_MOVX")))
2430 (const_string "imovx")
2431 (const_string "imov")))
2433 (if_then_else (eq_attr "type" "imovx")
2435 (const_string "QI")))])
2437 (define_expand "mov<mode>_insv_1"
2438 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand")
2441 (match_operand:SWI48 1 "nonmemory_operand"))])
2443 (define_insn "*mov<mode>_insv_1_rex64"
2444 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2447 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2450 if (CONST_INT_P (operands[1]))
2451 operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2452 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2454 [(set_attr "type" "imov")
2455 (set_attr "mode" "QI")])
2457 (define_insn "*movsi_insv_1"
2458 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2461 (match_operand:SI 1 "general_operand" "Qmn"))]
2464 if (CONST_INT_P (operands[1]))
2465 operands[1] = simplify_gen_subreg (QImode, operands[1], SImode, 0);
2466 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2468 [(set_attr "type" "imov")
2469 (set_attr "mode" "QI")])
2471 (define_insn "*movqi_insv_2"
2472 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2475 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2478 "mov{b}\t{%h1, %h0|%h0, %h1}"
2479 [(set_attr "type" "imov")
2480 (set_attr "mode" "QI")])
2482 ;; Floating point push instructions.
2484 (define_insn "*pushtf"
2485 [(set (match_operand:TF 0 "push_operand" "=<,<")
2486 (match_operand:TF 1 "general_no_elim_operand" "x,*roF"))]
2487 "TARGET_64BIT || TARGET_SSE"
2489 /* This insn should be already split before reg-stack. */
2492 [(set_attr "isa" "*,x64")
2493 (set_attr "type" "multi")
2494 (set_attr "unit" "sse,*")
2495 (set_attr "mode" "TF,DI")])
2497 ;; %%% Kill this when call knows how to work this out.
2499 [(set (match_operand:TF 0 "push_operand")
2500 (match_operand:TF 1 "sse_reg_operand"))]
2501 "TARGET_SSE && reload_completed"
2502 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2503 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2505 (define_insn "*pushxf"
2506 [(set (match_operand:XF 0 "push_operand" "=<,<")
2507 (match_operand:XF 1 "general_no_elim_operand" "f,Yx*roF"))]
2510 /* This insn should be already split before reg-stack. */
2513 [(set_attr "type" "multi")
2514 (set_attr "unit" "i387,*")
2516 (cond [(eq_attr "alternative" "1")
2517 (if_then_else (match_test "TARGET_64BIT")
2519 (const_string "SI"))
2521 (const_string "XF")))])
2523 ;; %%% Kill this when call knows how to work this out.
2525 [(set (match_operand:XF 0 "push_operand")
2526 (match_operand:XF 1 "fp_register_operand"))]
2528 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2529 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2530 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2532 (define_insn "*pushdf"
2533 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2534 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*roF,rmF,x"))]
2537 /* This insn should be already split before reg-stack. */
2540 [(set_attr "isa" "*,nox64,x64,sse2")
2541 (set_attr "type" "multi")
2542 (set_attr "unit" "i387,*,*,sse")
2543 (set_attr "mode" "DF,SI,DI,DF")])
2545 ;; %%% Kill this when call knows how to work this out.
2547 [(set (match_operand:DF 0 "push_operand")
2548 (match_operand:DF 1 "any_fp_register_operand"))]
2550 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2551 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2553 (define_insn "*pushsf_rex64"
2554 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2555 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2558 /* Anything else should be already split before reg-stack. */
2559 gcc_assert (which_alternative == 1);
2560 return "push{q}\t%q1";
2562 [(set_attr "type" "multi,push,multi")
2563 (set_attr "unit" "i387,*,*")
2564 (set_attr "mode" "SF,DI,SF")])
2566 (define_insn "*pushsf"
2567 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2568 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
2571 /* Anything else should be already split before reg-stack. */
2572 gcc_assert (which_alternative == 1);
2573 return "push{l}\t%1";
2575 [(set_attr "type" "multi,push,multi")
2576 (set_attr "unit" "i387,*,*")
2577 (set_attr "mode" "SF,SI,SF")])
2579 ;; %%% Kill this when call knows how to work this out.
2581 [(set (match_operand:SF 0 "push_operand")
2582 (match_operand:SF 1 "any_fp_register_operand"))]
2584 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2585 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2586 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2589 [(set (match_operand:SF 0 "push_operand")
2590 (match_operand:SF 1 "memory_operand"))]
2592 && (operands[2] = find_constant_src (insn))"
2593 [(set (match_dup 0) (match_dup 2))])
2596 [(set (match_operand 0 "push_operand")
2597 (match_operand 1 "general_operand"))]
2599 && (GET_MODE (operands[0]) == TFmode
2600 || GET_MODE (operands[0]) == XFmode
2601 || GET_MODE (operands[0]) == DFmode)
2602 && !ANY_FP_REG_P (operands[1])"
2604 "ix86_split_long_move (operands); DONE;")
2606 ;; Floating point move instructions.
2608 (define_expand "movtf"
2609 [(set (match_operand:TF 0 "nonimmediate_operand")
2610 (match_operand:TF 1 "nonimmediate_operand"))]
2611 "TARGET_64BIT || TARGET_SSE"
2612 "ix86_expand_move (TFmode, operands); DONE;")
2614 (define_expand "mov<mode>"
2615 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2616 (match_operand:X87MODEF 1 "general_operand"))]
2618 "ix86_expand_move (<MODE>mode, operands); DONE;")
2620 (define_insn "*movtf_internal"
2621 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
2622 (match_operand:TF 1 "general_operand" "C ,xm,x,*roF,*rC"))]
2623 "(TARGET_64BIT || TARGET_SSE)
2624 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2625 && (!can_create_pseudo_p ()
2626 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2627 || GET_CODE (operands[1]) != CONST_DOUBLE
2628 || (optimize_function_for_size_p (cfun)
2629 && standard_sse_constant_p (operands[1])
2630 && !memory_operand (operands[0], TFmode))
2631 || (!TARGET_MEMORY_MISMATCH_STALL
2632 && memory_operand (operands[0], TFmode)))"
2634 switch (which_alternative)
2637 return standard_sse_constant_opcode (insn, operands[1]);
2640 /* Handle misaligned load/store since we
2641 don't have movmisaligntf pattern. */
2642 if (misaligned_operand (operands[0], TFmode)
2643 || misaligned_operand (operands[1], TFmode))
2645 if (get_attr_mode (insn) == MODE_V4SF)
2646 return "%vmovups\t{%1, %0|%0, %1}";
2648 return "%vmovdqu\t{%1, %0|%0, %1}";
2652 if (get_attr_mode (insn) == MODE_V4SF)
2653 return "%vmovaps\t{%1, %0|%0, %1}";
2655 return "%vmovdqa\t{%1, %0|%0, %1}";
2666 [(set_attr "isa" "*,*,*,x64,x64")
2667 (set_attr "type" "sselog1,ssemov,ssemov,*,*")
2668 (set (attr "prefix")
2669 (if_then_else (eq_attr "type" "sselog1,ssemov")
2670 (const_string "maybe_vex")
2671 (const_string "orig")))
2673 (cond [(eq_attr "alternative" "3,4")
2675 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2676 (const_string "V4SF")
2677 (and (eq_attr "alternative" "2")
2678 (match_test "TARGET_SSE_TYPELESS_STORES"))
2679 (const_string "V4SF")
2680 (match_test "TARGET_AVX")
2682 (ior (not (match_test "TARGET_SSE2"))
2683 (match_test "optimize_function_for_size_p (cfun)"))
2684 (const_string "V4SF")
2686 (const_string "TI")))])
2688 ;; Possible store forwarding (partial memory) stall in alternatives 4 and 5.
2689 (define_insn "*movxf_internal"
2690 [(set (match_operand:XF 0 "nonimmediate_operand"
2691 "=f,m,f,?Yx*r ,!o ,!o")
2692 (match_operand:XF 1 "general_operand"
2693 "fm,f,G,Yx*roF,Yx*rF,Yx*rC"))]
2694 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2695 && (!can_create_pseudo_p ()
2696 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2697 || GET_CODE (operands[1]) != CONST_DOUBLE
2698 || (optimize_function_for_size_p (cfun)
2699 && standard_80387_constant_p (operands[1]) > 0
2700 && !memory_operand (operands[0], XFmode))
2701 || (!TARGET_MEMORY_MISMATCH_STALL
2702 && memory_operand (operands[0], XFmode)))"
2704 switch (which_alternative)
2708 return output_387_reg_move (insn, operands);
2711 return standard_80387_constant_opcode (operands[1]);
2722 [(set_attr "isa" "*,*,*,*,nox64,x64")
2723 (set_attr "type" "fmov,fmov,fmov,multi,multi,multi")
2725 (cond [(eq_attr "alternative" "3,4,5")
2726 (if_then_else (match_test "TARGET_64BIT")
2728 (const_string "SI"))
2730 (const_string "XF")))])
2732 ;; Possible store forwarding (partial memory) stall in alternative 4.
2733 (define_insn "*movdf_internal"
2734 [(set (match_operand:DF 0 "nonimmediate_operand"
2735 "=Yf*f,m ,Yf*f,?Yd*r ,!o ,?r,?m,?r,?r,x,x,x,m,*x,*x,*x,m ,r ,Yi")
2736 (match_operand:DF 1 "general_operand"
2737 "Yf*fm,Yf*f,G ,Yd*roF,Yd*rF,rm,rC,C ,F ,C,x,m,x,C ,*x,m ,*x,Yi,r"))]
2738 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2739 && (!can_create_pseudo_p ()
2740 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2741 || GET_CODE (operands[1]) != CONST_DOUBLE
2742 || (optimize_function_for_size_p (cfun)
2743 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2744 && standard_80387_constant_p (operands[1]) > 0)
2745 || (TARGET_SSE2 && TARGET_SSE_MATH
2746 && standard_sse_constant_p (operands[1])))
2747 && !memory_operand (operands[0], DFmode))
2748 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
2749 && memory_operand (operands[0], DFmode)))"
2751 switch (which_alternative)
2755 return output_387_reg_move (insn, operands);
2758 return standard_80387_constant_opcode (operands[1]);
2766 return "mov{q}\t{%1, %0|%0, %1}";
2769 return "mov{l}\t{%1, %k0|%k0, %1}";
2772 return "movabs{q}\t{%1, %0|%0, %1}";
2776 return standard_sse_constant_opcode (insn, operands[1]);
2786 switch (get_attr_mode (insn))
2789 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2790 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2791 return "%vmovsd\t{%1, %0|%0, %1}";
2794 return "%vmovlpd\t{%1, %d0|%d0, %1}";
2796 return "%vmovapd\t{%1, %0|%0, %1}";
2798 gcc_assert (!TARGET_AVX);
2799 return "movlps\t{%1, %0|%0, %1}";
2801 return "%vmovaps\t{%1, %0|%0, %1}";
2804 /* Handle broken assemblers that require movd instead of movq. */
2805 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2806 return "%vmovd\t{%1, %0|%0, %1}";
2807 return "%vmovq\t{%1, %0|%0, %1}";
2818 (cond [(eq_attr "alternative" "3,4")
2819 (const_string "nox64")
2820 (eq_attr "alternative" "5,6,7,8,17,18")
2821 (const_string "x64")
2822 (eq_attr "alternative" "9,10,11,12")
2823 (const_string "sse2")
2825 (const_string "*")))
2827 (cond [(eq_attr "alternative" "0,1,2")
2828 (const_string "fmov")
2829 (eq_attr "alternative" "3,4")
2830 (const_string "multi")
2831 (eq_attr "alternative" "5,6,7,8")
2832 (const_string "imov")
2833 (eq_attr "alternative" "9,13")
2834 (const_string "sselog1")
2836 (const_string "ssemov")))
2838 (if_then_else (eq_attr "alternative" "8")
2840 (const_string "*")))
2841 (set (attr "length_immediate")
2842 (if_then_else (eq_attr "alternative" "8")
2844 (const_string "*")))
2845 (set (attr "prefix")
2846 (if_then_else (eq_attr "type" "sselog1,ssemov")
2847 (const_string "maybe_vex")
2848 (const_string "orig")))
2849 (set (attr "prefix_data16")
2851 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2852 (eq_attr "mode" "V1DF"))
2854 (const_string "*")))
2856 (cond [(eq_attr "alternative" "3,4,7")
2858 (eq_attr "alternative" "5,6,8,17,18")
2861 /* xorps is one byte shorter for !TARGET_AVX. */
2862 (eq_attr "alternative" "9,13")
2863 (cond [(not (match_test "TARGET_SSE2"))
2864 (const_string "V4SF")
2865 (match_test "TARGET_AVX")
2866 (const_string "V2DF")
2867 (match_test "optimize_function_for_size_p (cfun)")
2868 (const_string "V4SF")
2869 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
2872 (const_string "V2DF"))
2874 /* For architectures resolving dependencies on
2875 whole SSE registers use APD move to break dependency
2876 chains, otherwise use short move to avoid extra work.
2878 movaps encodes one byte shorter for !TARGET_AVX. */
2879 (eq_attr "alternative" "10,14")
2880 (cond [(ior (not (match_test "TARGET_SSE2"))
2881 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2882 (const_string "V4SF")
2883 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2884 (const_string "V2DF")
2885 (match_test "TARGET_AVX")
2887 (match_test "optimize_function_for_size_p (cfun)")
2888 (const_string "V4SF")
2890 (const_string "DF"))
2892 /* For architectures resolving dependencies on register
2893 parts we may avoid extra work to zero out upper part
2895 (eq_attr "alternative" "11,15")
2896 (cond [(not (match_test "TARGET_SSE2"))
2897 (const_string "V2SF")
2898 (match_test "TARGET_SSE_SPLIT_REGS")
2899 (const_string "V1DF")
2901 (const_string "DF"))
2903 (and (eq_attr "alternative" "12,16")
2904 (not (match_test "TARGET_SSE2")))
2905 (const_string "V2SF")
2907 (const_string "DF")))])
2909 (define_insn "*movsf_internal"
2910 [(set (match_operand:SF 0 "nonimmediate_operand"
2911 "=Yf*f,m ,Yf*f,?r ,?m,x,x,x,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym")
2912 (match_operand:SF 1 "general_operand"
2913 "Yf*fm,Yf*f,G ,rmF,rF,C,x,m,x,Yi,r ,*y ,m ,*y,*Ym,r"))]
2914 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2915 && (!can_create_pseudo_p ()
2916 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2917 || GET_CODE (operands[1]) != CONST_DOUBLE
2918 || (optimize_function_for_size_p (cfun)
2919 && ((!TARGET_SSE_MATH
2920 && standard_80387_constant_p (operands[1]) > 0)
2922 && standard_sse_constant_p (operands[1]))))
2923 || memory_operand (operands[0], SFmode))"
2925 switch (which_alternative)
2929 return output_387_reg_move (insn, operands);
2932 return standard_80387_constant_opcode (operands[1]);
2936 return "mov{l}\t{%1, %0|%0, %1}";
2939 return standard_sse_constant_opcode (insn, operands[1]);
2944 switch (get_attr_mode (insn))
2947 return "%vmovaps\t{%1, %0|%0, %1}";
2949 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2950 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
2951 return "%vmovss\t{%1, %0|%0, %1}";
2958 return "%vmovd\t{%1, %0|%0, %1}";
2965 if (get_attr_mode (insn) == MODE_DI)
2966 return "movq\t{%1, %0|%0, %1}";
2967 return "movd\t{%1, %0|%0, %1}";
2974 (cond [(eq_attr "alternative" "0,1,2")
2975 (const_string "fmov")
2976 (eq_attr "alternative" "3,4")
2977 (const_string "imov")
2978 (eq_attr "alternative" "5")
2979 (const_string "sselog1")
2980 (eq_attr "alternative" "11,12,13,14,15")
2981 (const_string "mmxmov")
2983 (const_string "ssemov")))
2984 (set (attr "prefix")
2985 (if_then_else (eq_attr "type" "sselog1,ssemov")
2986 (const_string "maybe_vex")
2987 (const_string "orig")))
2988 (set (attr "prefix_data16")
2989 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2991 (const_string "*")))
2993 (cond [(eq_attr "alternative" "3,4,9,10,14,15")
2995 (eq_attr "alternative" "11")
2997 (eq_attr "alternative" "5")
2998 (cond [(not (match_test "TARGET_SSE2"))
2999 (const_string "V4SF")
3000 (match_test "TARGET_AVX")
3001 (const_string "V4SF")
3002 (match_test "optimize_function_for_size_p (cfun)")
3003 (const_string "V4SF")
3004 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3007 (const_string "V4SF"))
3009 /* For architectures resolving dependencies on
3010 whole SSE registers use APS move to break dependency
3011 chains, otherwise use short move to avoid extra work.
3013 Do the same for architectures resolving dependencies on
3014 the parts. While in DF mode it is better to always handle
3015 just register parts, the SF mode is different due to lack
3016 of instructions to load just part of the register. It is
3017 better to maintain the whole registers in single format
3018 to avoid problems on using packed logical operations. */
3019 (and (eq_attr "alternative" "6")
3020 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3021 (match_test "TARGET_SSE_SPLIT_REGS")))
3022 (const_string "V4SF")
3024 (const_string "SF")))])
3027 [(set (match_operand 0 "any_fp_register_operand")
3028 (match_operand 1 "memory_operand"))]
3030 && (GET_MODE (operands[0]) == TFmode
3031 || GET_MODE (operands[0]) == XFmode
3032 || GET_MODE (operands[0]) == DFmode
3033 || GET_MODE (operands[0]) == SFmode)
3034 && (operands[2] = find_constant_src (insn))"
3035 [(set (match_dup 0) (match_dup 2))]
3037 rtx c = operands[2];
3038 int r = REGNO (operands[0]);
3040 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3041 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3046 [(set (match_operand 0 "any_fp_register_operand")
3047 (float_extend (match_operand 1 "memory_operand")))]
3049 && (GET_MODE (operands[0]) == TFmode
3050 || GET_MODE (operands[0]) == XFmode
3051 || GET_MODE (operands[0]) == DFmode)
3052 && (operands[2] = find_constant_src (insn))"
3053 [(set (match_dup 0) (match_dup 2))]
3055 rtx c = operands[2];
3056 int r = REGNO (operands[0]);
3058 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3059 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3063 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3065 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3066 (match_operand:X87MODEF 1 "immediate_operand"))]
3068 && (standard_80387_constant_p (operands[1]) == 8
3069 || standard_80387_constant_p (operands[1]) == 9)"
3070 [(set (match_dup 0)(match_dup 1))
3072 (neg:X87MODEF (match_dup 0)))]
3076 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3077 if (real_isnegzero (&r))
3078 operands[1] = CONST0_RTX (<MODE>mode);
3080 operands[1] = CONST1_RTX (<MODE>mode);
3084 [(set (match_operand 0 "nonimmediate_operand")
3085 (match_operand 1 "general_operand"))]
3087 && (GET_MODE (operands[0]) == TFmode
3088 || GET_MODE (operands[0]) == XFmode
3089 || GET_MODE (operands[0]) == DFmode)
3090 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3092 "ix86_split_long_move (operands); DONE;")
3094 (define_insn "swapxf"
3095 [(set (match_operand:XF 0 "register_operand" "+f")
3096 (match_operand:XF 1 "register_operand" "+f"))
3101 if (STACK_TOP_P (operands[0]))
3106 [(set_attr "type" "fxch")
3107 (set_attr "mode" "XF")])
3109 (define_insn "*swap<mode>"
3110 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3111 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3114 "TARGET_80387 || reload_completed"
3116 if (STACK_TOP_P (operands[0]))
3121 [(set_attr "type" "fxch")
3122 (set_attr "mode" "<MODE>")])
3124 ;; Zero extension instructions
3126 (define_expand "zero_extendsidi2"
3127 [(set (match_operand:DI 0 "nonimmediate_operand")
3128 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3130 (define_insn "*zero_extendsidi2_rex64"
3131 [(set (match_operand:DI 0 "nonimmediate_operand"
3132 "=r ,o,?*Ym,?*y,?*Yi,?*x")
3134 (match_operand:SI 1 "x86_64_zext_general_operand"
3135 "rmWz,0,r ,m ,r ,m")))]
3138 switch (get_attr_type (insn))
3141 if (ix86_use_lea_for_mov (insn, operands))
3142 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3144 return "mov{l}\t{%1, %k0|%k0, %1}";
3150 return "movd\t{%1, %0|%0, %1}";
3153 return "%vmovd\t{%1, %0|%0, %1}";
3159 [(set_attr "type" "imovx,multi,mmxmov,mmxmov,ssemov,ssemov")
3160 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3161 (set_attr "prefix_0f" "0,*,*,*,*,*")
3162 (set_attr "mode" "SI,SI,DI,DI,TI,TI")])
3164 (define_insn "*zero_extendsidi2"
3165 [(set (match_operand:DI 0 "nonimmediate_operand"
3166 "=ro,?r,?o,?*Ym,?*y,?*Yi,?*x")
3167 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand"
3168 "0 ,rm,r ,r ,m ,r ,m")))]
3174 movd\t{%1, %0|%0, %1}
3175 movd\t{%1, %0|%0, %1}
3176 %vmovd\t{%1, %0|%0, %1}
3177 %vmovd\t{%1, %0|%0, %1}"
3178 [(set_attr "isa" "*,*,*,*,*,*,sse2")
3179 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3180 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3181 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3184 [(set (match_operand:DI 0 "memory_operand")
3185 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3187 [(set (match_dup 4) (const_int 0))]
3188 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3191 [(set (match_operand:DI 0 "register_operand")
3192 (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3193 "!TARGET_64BIT && reload_completed
3194 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3195 && true_regnum (operands[0]) == true_regnum (operands[1])"
3196 [(set (match_dup 4) (const_int 0))]
3197 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3200 [(set (match_operand:DI 0 "nonimmediate_operand")
3201 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3202 "!TARGET_64BIT && reload_completed
3203 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3204 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3205 [(set (match_dup 3) (match_dup 1))
3206 (set (match_dup 4) (const_int 0))]
3207 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3209 (define_insn "zero_extend<mode>di2"
3210 [(set (match_operand:DI 0 "register_operand" "=r")
3212 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3214 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3215 [(set_attr "type" "imovx")
3216 (set_attr "mode" "SI")])
3218 (define_expand "zero_extend<mode>si2"
3219 [(set (match_operand:SI 0 "register_operand")
3220 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3223 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3225 operands[1] = force_reg (<MODE>mode, operands[1]);
3226 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3231 (define_insn_and_split "zero_extend<mode>si2_and"
3232 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3234 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3235 (clobber (reg:CC FLAGS_REG))]
3236 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3238 "&& reload_completed"
3239 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3240 (clobber (reg:CC FLAGS_REG))])]
3242 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3244 ix86_expand_clear (operands[0]);
3246 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3247 emit_insn (gen_movstrict<mode>
3248 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3252 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3254 [(set_attr "type" "alu1")
3255 (set_attr "mode" "SI")])
3257 (define_insn "*zero_extend<mode>si2"
3258 [(set (match_operand:SI 0 "register_operand" "=r")
3260 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3261 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3262 "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3263 [(set_attr "type" "imovx")
3264 (set_attr "mode" "SI")])
3266 (define_expand "zero_extendqihi2"
3267 [(set (match_operand:HI 0 "register_operand")
3268 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3271 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3273 operands[1] = force_reg (QImode, operands[1]);
3274 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3279 (define_insn_and_split "zero_extendqihi2_and"
3280 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3281 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3282 (clobber (reg:CC FLAGS_REG))]
3283 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3285 "&& reload_completed"
3286 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3287 (clobber (reg:CC FLAGS_REG))])]
3289 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3291 ix86_expand_clear (operands[0]);
3293 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3294 emit_insn (gen_movstrictqi
3295 (gen_lowpart (QImode, operands[0]), operands[1]));
3299 operands[0] = gen_lowpart (SImode, operands[0]);
3301 [(set_attr "type" "alu1")
3302 (set_attr "mode" "SI")])
3304 ; zero extend to SImode to avoid partial register stalls
3305 (define_insn "*zero_extendqihi2"
3306 [(set (match_operand:HI 0 "register_operand" "=r")
3307 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3308 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3309 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3310 [(set_attr "type" "imovx")
3311 (set_attr "mode" "SI")])
3313 ;; Sign extension instructions
3315 (define_expand "extendsidi2"
3316 [(set (match_operand:DI 0 "register_operand")
3317 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3322 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3327 (define_insn "*extendsidi2_rex64"
3328 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3329 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3333 movs{lq|x}\t{%1, %0|%0, %1}"
3334 [(set_attr "type" "imovx")
3335 (set_attr "mode" "DI")
3336 (set_attr "prefix_0f" "0")
3337 (set_attr "modrm" "0,1")])
3339 (define_insn "extendsidi2_1"
3340 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3341 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3342 (clobber (reg:CC FLAGS_REG))
3343 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3347 ;; Extend to memory case when source register does die.
3349 [(set (match_operand:DI 0 "memory_operand")
3350 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3351 (clobber (reg:CC FLAGS_REG))
3352 (clobber (match_operand:SI 2 "register_operand"))]
3354 && dead_or_set_p (insn, operands[1])
3355 && !reg_mentioned_p (operands[1], operands[0]))"
3356 [(set (match_dup 3) (match_dup 1))
3357 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3358 (clobber (reg:CC FLAGS_REG))])
3359 (set (match_dup 4) (match_dup 1))]
3360 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3362 ;; Extend to memory case when source register does not die.
3364 [(set (match_operand:DI 0 "memory_operand")
3365 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3366 (clobber (reg:CC FLAGS_REG))
3367 (clobber (match_operand:SI 2 "register_operand"))]
3371 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3373 emit_move_insn (operands[3], operands[1]);
3375 /* Generate a cltd if possible and doing so it profitable. */
3376 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3377 && true_regnum (operands[1]) == AX_REG
3378 && true_regnum (operands[2]) == DX_REG)
3380 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3384 emit_move_insn (operands[2], operands[1]);
3385 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3387 emit_move_insn (operands[4], operands[2]);
3391 ;; Extend to register case. Optimize case where source and destination
3392 ;; registers match and cases where we can use cltd.
3394 [(set (match_operand:DI 0 "register_operand")
3395 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3396 (clobber (reg:CC FLAGS_REG))
3397 (clobber (match_scratch:SI 2))]
3401 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3403 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3404 emit_move_insn (operands[3], operands[1]);
3406 /* Generate a cltd if possible and doing so it profitable. */
3407 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3408 && true_regnum (operands[3]) == AX_REG
3409 && true_regnum (operands[4]) == DX_REG)
3411 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3415 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3416 emit_move_insn (operands[4], operands[1]);
3418 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3422 (define_insn "extend<mode>di2"
3423 [(set (match_operand:DI 0 "register_operand" "=r")
3425 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3427 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3428 [(set_attr "type" "imovx")
3429 (set_attr "mode" "DI")])
3431 (define_insn "extendhisi2"
3432 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3433 (sign_extend:SI (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, %0|%0, %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 "*extendhisi2_zext"
3458 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3461 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3464 switch (get_attr_prefix_0f (insn))
3467 return "{cwtl|cwde}";
3469 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3472 [(set_attr "type" "imovx")
3473 (set_attr "mode" "SI")
3474 (set (attr "prefix_0f")
3475 ;; movsx is short decodable while cwtl is vector decoded.
3476 (if_then_else (and (eq_attr "cpu" "!k6")
3477 (eq_attr "alternative" "0"))
3479 (const_string "1")))
3481 (if_then_else (eq_attr "prefix_0f" "0")
3483 (const_string "1")))])
3485 (define_insn "extendqisi2"
3486 [(set (match_operand:SI 0 "register_operand" "=r")
3487 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3489 "movs{bl|x}\t{%1, %0|%0, %1}"
3490 [(set_attr "type" "imovx")
3491 (set_attr "mode" "SI")])
3493 (define_insn "*extendqisi2_zext"
3494 [(set (match_operand:DI 0 "register_operand" "=r")
3496 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3498 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3499 [(set_attr "type" "imovx")
3500 (set_attr "mode" "SI")])
3502 (define_insn "extendqihi2"
3503 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3504 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3507 switch (get_attr_prefix_0f (insn))
3510 return "{cbtw|cbw}";
3512 return "movs{bw|x}\t{%1, %0|%0, %1}";
3515 [(set_attr "type" "imovx")
3516 (set_attr "mode" "HI")
3517 (set (attr "prefix_0f")
3518 ;; movsx is short decodable while cwtl is vector decoded.
3519 (if_then_else (and (eq_attr "cpu" "!k6")
3520 (eq_attr "alternative" "0"))
3522 (const_string "1")))
3524 (if_then_else (eq_attr "prefix_0f" "0")
3526 (const_string "1")))])
3528 ;; Conversions between float and double.
3530 ;; These are all no-ops in the model used for the 80387.
3531 ;; So just emit moves.
3533 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3535 [(set (match_operand:DF 0 "push_operand")
3536 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3538 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3539 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3542 [(set (match_operand:XF 0 "push_operand")
3543 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3545 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3546 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3547 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3549 (define_expand "extendsfdf2"
3550 [(set (match_operand:DF 0 "nonimmediate_operand")
3551 (float_extend:DF (match_operand:SF 1 "general_operand")))]
3552 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3554 /* ??? Needed for compress_float_constant since all fp constants
3555 are TARGET_LEGITIMATE_CONSTANT_P. */
3556 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3558 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3559 && standard_80387_constant_p (operands[1]) > 0)
3561 operands[1] = simplify_const_unary_operation
3562 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3563 emit_move_insn_1 (operands[0], operands[1]);
3566 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3570 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3572 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3574 We do the conversion post reload to avoid producing of 128bit spills
3575 that might lead to ICE on 32bit target. The sequence unlikely combine
3578 [(set (match_operand:DF 0 "register_operand")
3580 (match_operand:SF 1 "nonimmediate_operand")))]
3581 "TARGET_USE_VECTOR_FP_CONVERTS
3582 && optimize_insn_for_speed_p ()
3583 && reload_completed && SSE_REG_P (operands[0])"
3588 (parallel [(const_int 0) (const_int 1)]))))]
3590 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3591 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3592 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3593 Try to avoid move when unpacking can be done in source. */
3594 if (REG_P (operands[1]))
3596 /* If it is unsafe to overwrite upper half of source, we need
3597 to move to destination and unpack there. */
3598 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3599 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3600 && true_regnum (operands[0]) != true_regnum (operands[1]))
3602 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3603 emit_move_insn (tmp, operands[1]);
3606 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3607 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3611 emit_insn (gen_vec_setv4sf_0 (operands[3],
3612 CONST0_RTX (V4SFmode), operands[1]));
3615 (define_insn "*extendsfdf2_mixed"
3616 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3618 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3619 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3621 switch (which_alternative)
3625 return output_387_reg_move (insn, operands);
3628 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3634 [(set_attr "type" "fmov,fmov,ssecvt")
3635 (set_attr "prefix" "orig,orig,maybe_vex")
3636 (set_attr "mode" "SF,XF,DF")])
3638 (define_insn "*extendsfdf2_sse"
3639 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3640 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3641 "TARGET_SSE2 && TARGET_SSE_MATH"
3642 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3643 [(set_attr "type" "ssecvt")
3644 (set_attr "prefix" "maybe_vex")
3645 (set_attr "mode" "DF")])
3647 (define_insn "*extendsfdf2_i387"
3648 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3649 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3651 "* return output_387_reg_move (insn, operands);"
3652 [(set_attr "type" "fmov")
3653 (set_attr "mode" "SF,XF")])
3655 (define_expand "extend<mode>xf2"
3656 [(set (match_operand:XF 0 "nonimmediate_operand")
3657 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
3660 /* ??? Needed for compress_float_constant since all fp constants
3661 are TARGET_LEGITIMATE_CONSTANT_P. */
3662 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3664 if (standard_80387_constant_p (operands[1]) > 0)
3666 operands[1] = simplify_const_unary_operation
3667 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3668 emit_move_insn_1 (operands[0], operands[1]);
3671 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3675 (define_insn "*extend<mode>xf2_i387"
3676 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3678 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3680 "* return output_387_reg_move (insn, operands);"
3681 [(set_attr "type" "fmov")
3682 (set_attr "mode" "<MODE>,XF")])
3684 ;; %%% This seems bad bad news.
3685 ;; This cannot output into an f-reg because there is no way to be sure
3686 ;; of truncating in that case. Otherwise this is just like a simple move
3687 ;; insn. So we pretend we can output to a reg in order to get better
3688 ;; register preferencing, but we really use a stack slot.
3690 ;; Conversion from DFmode to SFmode.
3692 (define_expand "truncdfsf2"
3693 [(set (match_operand:SF 0 "nonimmediate_operand")
3695 (match_operand:DF 1 "nonimmediate_operand")))]
3696 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3698 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3700 else if (flag_unsafe_math_optimizations)
3704 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3705 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3710 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
3712 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3714 We do the conversion post reload to avoid producing of 128bit spills
3715 that might lead to ICE on 32bit target. The sequence unlikely combine
3718 [(set (match_operand:SF 0 "register_operand")
3720 (match_operand:DF 1 "nonimmediate_operand")))]
3721 "TARGET_USE_VECTOR_FP_CONVERTS
3722 && optimize_insn_for_speed_p ()
3723 && reload_completed && SSE_REG_P (operands[0])"
3726 (float_truncate:V2SF
3730 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3731 operands[3] = CONST0_RTX (V2SFmode);
3732 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
3733 /* Use movsd for loading from memory, unpcklpd for registers.
3734 Try to avoid move when unpacking can be done in source, or SSE3
3735 movddup is available. */
3736 if (REG_P (operands[1]))
3739 && true_regnum (operands[0]) != true_regnum (operands[1])
3740 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3741 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
3743 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
3744 emit_move_insn (tmp, operands[1]);
3747 else if (!TARGET_SSE3)
3748 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3749 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
3752 emit_insn (gen_sse2_loadlpd (operands[4],
3753 CONST0_RTX (V2DFmode), operands[1]));
3756 (define_expand "truncdfsf2_with_temp"
3757 [(parallel [(set (match_operand:SF 0)
3758 (float_truncate:SF (match_operand:DF 1)))
3759 (clobber (match_operand:SF 2))])])
3761 (define_insn "*truncdfsf_fast_mixed"
3762 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
3764 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
3765 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3767 switch (which_alternative)
3770 return output_387_reg_move (insn, operands);
3772 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
3777 [(set_attr "type" "fmov,ssecvt")
3778 (set_attr "prefix" "orig,maybe_vex")
3779 (set_attr "mode" "SF")])
3781 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3782 ;; because nothing we do here is unsafe.
3783 (define_insn "*truncdfsf_fast_sse"
3784 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
3786 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
3787 "TARGET_SSE2 && TARGET_SSE_MATH"
3788 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
3789 [(set_attr "type" "ssecvt")
3790 (set_attr "prefix" "maybe_vex")
3791 (set_attr "mode" "SF")])
3793 (define_insn "*truncdfsf_fast_i387"
3794 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
3796 (match_operand:DF 1 "nonimmediate_operand" "f")))]
3797 "TARGET_80387 && flag_unsafe_math_optimizations"
3798 "* return output_387_reg_move (insn, operands);"
3799 [(set_attr "type" "fmov")
3800 (set_attr "mode" "SF")])
3802 (define_insn "*truncdfsf_mixed"
3803 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
3805 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
3806 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
3807 "TARGET_MIX_SSE_I387"
3809 switch (which_alternative)
3812 return output_387_reg_move (insn, operands);
3814 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
3820 [(set_attr "isa" "*,sse2,*,*,*")
3821 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
3822 (set_attr "unit" "*,*,i387,i387,i387")
3823 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
3824 (set_attr "mode" "SF")])
3826 (define_insn "*truncdfsf_i387"
3827 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
3829 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
3830 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
3833 switch (which_alternative)
3836 return output_387_reg_move (insn, operands);
3842 [(set_attr "type" "fmov,multi,multi,multi")
3843 (set_attr "unit" "*,i387,i387,i387")
3844 (set_attr "mode" "SF")])
3846 (define_insn "*truncdfsf2_i387_1"
3847 [(set (match_operand:SF 0 "memory_operand" "=m")
3849 (match_operand:DF 1 "register_operand" "f")))]
3851 && !(TARGET_SSE2 && TARGET_SSE_MATH)
3852 && !TARGET_MIX_SSE_I387"
3853 "* return output_387_reg_move (insn, operands);"
3854 [(set_attr "type" "fmov")
3855 (set_attr "mode" "SF")])
3858 [(set (match_operand:SF 0 "register_operand")
3860 (match_operand:DF 1 "fp_register_operand")))
3861 (clobber (match_operand 2))]
3863 [(set (match_dup 2) (match_dup 1))
3864 (set (match_dup 0) (match_dup 2))]
3865 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
3867 ;; Conversion from XFmode to {SF,DF}mode
3869 (define_expand "truncxf<mode>2"
3870 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
3871 (float_truncate:MODEF
3872 (match_operand:XF 1 "register_operand")))
3873 (clobber (match_dup 2))])]
3876 if (flag_unsafe_math_optimizations)
3878 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
3879 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
3880 if (reg != operands[0])
3881 emit_move_insn (operands[0], reg);
3885 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
3888 (define_insn "*truncxfsf2_mixed"
3889 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
3891 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
3892 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
3895 gcc_assert (!which_alternative);
3896 return output_387_reg_move (insn, operands);
3898 [(set_attr "type" "fmov,multi,multi,multi")
3899 (set_attr "unit" "*,i387,i387,i387")
3900 (set_attr "mode" "SF")])
3902 (define_insn "*truncxfdf2_mixed"
3903 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
3905 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
3906 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
3909 gcc_assert (!which_alternative);
3910 return output_387_reg_move (insn, operands);
3912 [(set_attr "isa" "*,*,sse2,*")
3913 (set_attr "type" "fmov,multi,multi,multi")
3914 (set_attr "unit" "*,i387,i387,i387")
3915 (set_attr "mode" "DF")])
3917 (define_insn "truncxf<mode>2_i387_noop"
3918 [(set (match_operand:MODEF 0 "register_operand" "=f")
3919 (float_truncate:MODEF
3920 (match_operand:XF 1 "register_operand" "f")))]
3921 "TARGET_80387 && flag_unsafe_math_optimizations"
3922 "* return output_387_reg_move (insn, operands);"
3923 [(set_attr "type" "fmov")
3924 (set_attr "mode" "<MODE>")])
3926 (define_insn "*truncxf<mode>2_i387"
3927 [(set (match_operand:MODEF 0 "memory_operand" "=m")
3928 (float_truncate:MODEF
3929 (match_operand:XF 1 "register_operand" "f")))]
3931 "* return output_387_reg_move (insn, operands);"
3932 [(set_attr "type" "fmov")
3933 (set_attr "mode" "<MODE>")])
3936 [(set (match_operand:MODEF 0 "register_operand")
3937 (float_truncate:MODEF
3938 (match_operand:XF 1 "register_operand")))
3939 (clobber (match_operand:MODEF 2 "memory_operand"))]
3940 "TARGET_80387 && reload_completed"
3941 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
3942 (set (match_dup 0) (match_dup 2))])
3945 [(set (match_operand:MODEF 0 "memory_operand")
3946 (float_truncate:MODEF
3947 (match_operand:XF 1 "register_operand")))
3948 (clobber (match_operand:MODEF 2 "memory_operand"))]
3950 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
3952 ;; Signed conversion to DImode.
3954 (define_expand "fix_truncxfdi2"
3955 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
3956 (fix:DI (match_operand:XF 1 "register_operand")))
3957 (clobber (reg:CC FLAGS_REG))])]
3962 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
3967 (define_expand "fix_trunc<mode>di2"
3968 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
3969 (fix:DI (match_operand:MODEF 1 "register_operand")))
3970 (clobber (reg:CC FLAGS_REG))])]
3971 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
3974 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
3976 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
3979 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
3981 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
3982 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
3983 if (out != operands[0])
3984 emit_move_insn (operands[0], out);
3989 ;; Signed conversion to SImode.
3991 (define_expand "fix_truncxfsi2"
3992 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
3993 (fix:SI (match_operand:XF 1 "register_operand")))
3994 (clobber (reg:CC FLAGS_REG))])]
3999 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4004 (define_expand "fix_trunc<mode>si2"
4005 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4006 (fix:SI (match_operand:MODEF 1 "register_operand")))
4007 (clobber (reg:CC FLAGS_REG))])]
4008 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4011 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4013 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4016 if (SSE_FLOAT_MODE_P (<MODE>mode))
4018 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4019 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4020 if (out != operands[0])
4021 emit_move_insn (operands[0], out);
4026 ;; Signed conversion to HImode.
4028 (define_expand "fix_trunc<mode>hi2"
4029 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4030 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4031 (clobber (reg:CC FLAGS_REG))])]
4033 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4037 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4042 ;; Unsigned conversion to SImode.
4044 (define_expand "fixuns_trunc<mode>si2"
4046 [(set (match_operand:SI 0 "register_operand")
4048 (match_operand:MODEF 1 "nonimmediate_operand")))
4050 (clobber (match_scratch:<ssevecmode> 3))
4051 (clobber (match_scratch:<ssevecmode> 4))])]
4052 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4054 enum machine_mode mode = <MODE>mode;
4055 enum machine_mode vecmode = <ssevecmode>mode;
4056 REAL_VALUE_TYPE TWO31r;
4059 if (optimize_insn_for_size_p ())
4062 real_ldexp (&TWO31r, &dconst1, 31);
4063 two31 = const_double_from_real_value (TWO31r, mode);
4064 two31 = ix86_build_const_vector (vecmode, true, two31);
4065 operands[2] = force_reg (vecmode, two31);
4068 (define_insn_and_split "*fixuns_trunc<mode>_1"
4069 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4071 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4072 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4073 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4074 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4075 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4076 && optimize_function_for_speed_p (cfun)"
4078 "&& reload_completed"
4081 ix86_split_convert_uns_si_sse (operands);
4085 ;; Unsigned conversion to HImode.
4086 ;; Without these patterns, we'll try the unsigned SI conversion which
4087 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4089 (define_expand "fixuns_trunc<mode>hi2"
4091 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4092 (set (match_operand:HI 0 "nonimmediate_operand")
4093 (subreg:HI (match_dup 2) 0))]
4094 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4095 "operands[2] = gen_reg_rtx (SImode);")
4097 ;; When SSE is available, it is always faster to use it!
4098 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4099 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4100 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4101 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4102 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4103 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4104 [(set_attr "type" "sseicvt")
4105 (set_attr "prefix" "maybe_vex")
4106 (set (attr "prefix_rex")
4108 (match_test "<SWI48:MODE>mode == DImode")
4110 (const_string "*")))
4111 (set_attr "mode" "<MODEF:MODE>")
4112 (set_attr "athlon_decode" "double,vector")
4113 (set_attr "amdfam10_decode" "double,double")
4114 (set_attr "bdver1_decode" "double,double")])
4116 ;; Avoid vector decoded forms of the instruction.
4118 [(match_scratch:MODEF 2 "x")
4119 (set (match_operand:SWI48 0 "register_operand")
4120 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4121 "TARGET_AVOID_VECTOR_DECODE
4122 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4123 && optimize_insn_for_speed_p ()"
4124 [(set (match_dup 2) (match_dup 1))
4125 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4127 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4128 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4129 (fix:SWI248x (match_operand 1 "register_operand")))]
4130 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4132 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4133 && (TARGET_64BIT || <MODE>mode != DImode))
4135 && can_create_pseudo_p ()"
4140 if (memory_operand (operands[0], VOIDmode))
4141 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4144 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4145 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4151 [(set_attr "type" "fisttp")
4152 (set_attr "mode" "<MODE>")])
4154 (define_insn "fix_trunc<mode>_i387_fisttp"
4155 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4156 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4157 (clobber (match_scratch:XF 2 "=&1f"))]
4158 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4160 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4161 && (TARGET_64BIT || <MODE>mode != DImode))
4162 && TARGET_SSE_MATH)"
4163 "* return output_fix_trunc (insn, operands, true);"
4164 [(set_attr "type" "fisttp")
4165 (set_attr "mode" "<MODE>")])
4167 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4168 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4169 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4170 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4171 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4172 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4174 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4175 && (TARGET_64BIT || <MODE>mode != DImode))
4176 && TARGET_SSE_MATH)"
4178 [(set_attr "type" "fisttp")
4179 (set_attr "mode" "<MODE>")])
4182 [(set (match_operand:SWI248x 0 "register_operand")
4183 (fix:SWI248x (match_operand 1 "register_operand")))
4184 (clobber (match_operand:SWI248x 2 "memory_operand"))
4185 (clobber (match_scratch 3))]
4187 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4188 (clobber (match_dup 3))])
4189 (set (match_dup 0) (match_dup 2))])
4192 [(set (match_operand:SWI248x 0 "memory_operand")
4193 (fix:SWI248x (match_operand 1 "register_operand")))
4194 (clobber (match_operand:SWI248x 2 "memory_operand"))
4195 (clobber (match_scratch 3))]
4197 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4198 (clobber (match_dup 3))])])
4200 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4201 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4202 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4203 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4204 ;; function in i386.c.
4205 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4206 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4207 (fix:SWI248x (match_operand 1 "register_operand")))
4208 (clobber (reg:CC FLAGS_REG))]
4209 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4211 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4212 && (TARGET_64BIT || <MODE>mode != DImode))
4213 && can_create_pseudo_p ()"
4218 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4220 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4221 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4222 if (memory_operand (operands[0], VOIDmode))
4223 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4224 operands[2], operands[3]));
4227 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4228 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4229 operands[2], operands[3],
4234 [(set_attr "type" "fistp")
4235 (set_attr "i387_cw" "trunc")
4236 (set_attr "mode" "<MODE>")])
4238 (define_insn "fix_truncdi_i387"
4239 [(set (match_operand:DI 0 "memory_operand" "=m")
4240 (fix:DI (match_operand 1 "register_operand" "f")))
4241 (use (match_operand:HI 2 "memory_operand" "m"))
4242 (use (match_operand:HI 3 "memory_operand" "m"))
4243 (clobber (match_scratch:XF 4 "=&1f"))]
4244 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4246 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4247 "* return output_fix_trunc (insn, operands, false);"
4248 [(set_attr "type" "fistp")
4249 (set_attr "i387_cw" "trunc")
4250 (set_attr "mode" "DI")])
4252 (define_insn "fix_truncdi_i387_with_temp"
4253 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4254 (fix:DI (match_operand 1 "register_operand" "f,f")))
4255 (use (match_operand:HI 2 "memory_operand" "m,m"))
4256 (use (match_operand:HI 3 "memory_operand" "m,m"))
4257 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4258 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4259 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4261 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4263 [(set_attr "type" "fistp")
4264 (set_attr "i387_cw" "trunc")
4265 (set_attr "mode" "DI")])
4268 [(set (match_operand:DI 0 "register_operand")
4269 (fix:DI (match_operand 1 "register_operand")))
4270 (use (match_operand:HI 2 "memory_operand"))
4271 (use (match_operand:HI 3 "memory_operand"))
4272 (clobber (match_operand:DI 4 "memory_operand"))
4273 (clobber (match_scratch 5))]
4275 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4278 (clobber (match_dup 5))])
4279 (set (match_dup 0) (match_dup 4))])
4282 [(set (match_operand:DI 0 "memory_operand")
4283 (fix:DI (match_operand 1 "register_operand")))
4284 (use (match_operand:HI 2 "memory_operand"))
4285 (use (match_operand:HI 3 "memory_operand"))
4286 (clobber (match_operand:DI 4 "memory_operand"))
4287 (clobber (match_scratch 5))]
4289 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4292 (clobber (match_dup 5))])])
4294 (define_insn "fix_trunc<mode>_i387"
4295 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4296 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4297 (use (match_operand:HI 2 "memory_operand" "m"))
4298 (use (match_operand:HI 3 "memory_operand" "m"))]
4299 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4301 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4302 "* return output_fix_trunc (insn, operands, false);"
4303 [(set_attr "type" "fistp")
4304 (set_attr "i387_cw" "trunc")
4305 (set_attr "mode" "<MODE>")])
4307 (define_insn "fix_trunc<mode>_i387_with_temp"
4308 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4309 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4310 (use (match_operand:HI 2 "memory_operand" "m,m"))
4311 (use (match_operand:HI 3 "memory_operand" "m,m"))
4312 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4313 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4315 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4317 [(set_attr "type" "fistp")
4318 (set_attr "i387_cw" "trunc")
4319 (set_attr "mode" "<MODE>")])
4322 [(set (match_operand:SWI24 0 "register_operand")
4323 (fix:SWI24 (match_operand 1 "register_operand")))
4324 (use (match_operand:HI 2 "memory_operand"))
4325 (use (match_operand:HI 3 "memory_operand"))
4326 (clobber (match_operand:SWI24 4 "memory_operand"))]
4328 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4330 (use (match_dup 3))])
4331 (set (match_dup 0) (match_dup 4))])
4334 [(set (match_operand:SWI24 0 "memory_operand")
4335 (fix:SWI24 (match_operand 1 "register_operand")))
4336 (use (match_operand:HI 2 "memory_operand"))
4337 (use (match_operand:HI 3 "memory_operand"))
4338 (clobber (match_operand:SWI24 4 "memory_operand"))]
4340 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4342 (use (match_dup 3))])])
4344 (define_insn "x86_fnstcw_1"
4345 [(set (match_operand:HI 0 "memory_operand" "=m")
4346 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4349 [(set (attr "length")
4350 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4351 (set_attr "mode" "HI")
4352 (set_attr "unit" "i387")
4353 (set_attr "bdver1_decode" "vector")])
4355 (define_insn "x86_fldcw_1"
4356 [(set (reg:HI FPCR_REG)
4357 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4360 [(set (attr "length")
4361 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4362 (set_attr "mode" "HI")
4363 (set_attr "unit" "i387")
4364 (set_attr "athlon_decode" "vector")
4365 (set_attr "amdfam10_decode" "vector")
4366 (set_attr "bdver1_decode" "vector")])
4368 ;; Conversion between fixed point and floating point.
4370 ;; Even though we only accept memory inputs, the backend _really_
4371 ;; wants to be able to do this between registers.
4373 (define_expand "floathi<mode>2"
4374 [(set (match_operand:X87MODEF 0 "register_operand")
4375 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand")))]
4377 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4378 || TARGET_MIX_SSE_I387)")
4380 ;; Pre-reload splitter to add memory clobber to the pattern.
4381 (define_insn_and_split "*floathi<mode>2_1"
4382 [(set (match_operand:X87MODEF 0 "register_operand")
4383 (float:X87MODEF (match_operand:HI 1 "register_operand")))]
4385 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4386 || TARGET_MIX_SSE_I387)
4387 && can_create_pseudo_p ()"
4390 [(parallel [(set (match_dup 0)
4391 (float:X87MODEF (match_dup 1)))
4392 (clobber (match_dup 2))])]
4393 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4395 (define_insn "*floathi<mode>2_i387_with_temp"
4396 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4397 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4398 (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4400 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4401 || TARGET_MIX_SSE_I387)"
4403 [(set_attr "type" "fmov,multi")
4404 (set_attr "mode" "<MODE>")
4405 (set_attr "unit" "*,i387")
4406 (set_attr "fp_int_src" "true")])
4408 (define_insn "*floathi<mode>2_i387"
4409 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4410 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4412 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4413 || TARGET_MIX_SSE_I387)"
4415 [(set_attr "type" "fmov")
4416 (set_attr "mode" "<MODE>")
4417 (set_attr "fp_int_src" "true")])
4420 [(set (match_operand:X87MODEF 0 "register_operand")
4421 (float:X87MODEF (match_operand:HI 1 "register_operand")))
4422 (clobber (match_operand:HI 2 "memory_operand"))]
4424 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4425 || TARGET_MIX_SSE_I387)
4426 && reload_completed"
4427 [(set (match_dup 2) (match_dup 1))
4428 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4431 [(set (match_operand:X87MODEF 0 "register_operand")
4432 (float:X87MODEF (match_operand:HI 1 "memory_operand")))
4433 (clobber (match_operand:HI 2 "memory_operand"))]
4435 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4436 || TARGET_MIX_SSE_I387)
4437 && reload_completed"
4438 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4440 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4441 [(set (match_operand:X87MODEF 0 "register_operand")
4443 (match_operand:SWI48x 1 "nonimmediate_operand")))]
4445 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4446 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4448 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4449 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4450 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4452 rtx reg = gen_reg_rtx (XFmode);
4453 rtx (*insn)(rtx, rtx);
4455 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4457 if (<X87MODEF:MODE>mode == SFmode)
4458 insn = gen_truncxfsf2;
4459 else if (<X87MODEF:MODE>mode == DFmode)
4460 insn = gen_truncxfdf2;
4464 emit_insn (insn (operands[0], reg));
4469 ;; Pre-reload splitter to add memory clobber to the pattern.
4470 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4471 [(set (match_operand:X87MODEF 0 "register_operand")
4472 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))]
4474 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4475 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4476 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4477 || TARGET_MIX_SSE_I387))
4478 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4479 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4480 && ((<SWI48x:MODE>mode == SImode
4481 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4482 && optimize_function_for_speed_p (cfun)
4483 && flag_trapping_math)
4484 || !(TARGET_INTER_UNIT_CONVERSIONS
4485 || optimize_function_for_size_p (cfun)))))
4486 && can_create_pseudo_p ()"
4489 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4490 (clobber (match_dup 2))])]
4492 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4494 /* Avoid store forwarding (partial memory) stall penalty
4495 by passing DImode value through XMM registers. */
4496 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4497 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4498 && optimize_function_for_speed_p (cfun))
4500 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4507 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4508 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4510 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4511 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4512 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4513 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4515 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4516 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4517 (set_attr "unit" "*,i387,*,*,*")
4518 (set_attr "athlon_decode" "*,*,double,direct,double")
4519 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4520 (set_attr "bdver1_decode" "*,*,double,direct,double")
4521 (set_attr "fp_int_src" "true")])
4523 (define_insn "*floatsi<mode>2_vector_mixed"
4524 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4525 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4526 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4527 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4531 [(set_attr "type" "fmov,sseicvt")
4532 (set_attr "mode" "<MODE>,<ssevecmode>")
4533 (set_attr "unit" "i387,*")
4534 (set_attr "athlon_decode" "*,direct")
4535 (set_attr "amdfam10_decode" "*,double")
4536 (set_attr "bdver1_decode" "*,direct")
4537 (set_attr "fp_int_src" "true")])
4539 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_with_temp"
4540 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4542 (match_operand:SWI48 1 "nonimmediate_operand" "m,?r,r,m")))
4543 (clobber (match_operand:SWI48 2 "memory_operand" "=X,m,m,X"))]
4544 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4546 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4547 (set_attr "mode" "<MODEF:MODE>")
4548 (set_attr "unit" "*,i387,*,*")
4549 (set_attr "athlon_decode" "*,*,double,direct")
4550 (set_attr "amdfam10_decode" "*,*,vector,double")
4551 (set_attr "bdver1_decode" "*,*,double,direct")
4552 (set_attr "fp_int_src" "true")])
4555 [(set (match_operand:MODEF 0 "register_operand")
4556 (float:MODEF (match_operand:SWI48 1 "register_operand")))
4557 (clobber (match_operand:SWI48 2 "memory_operand"))]
4558 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4559 && TARGET_INTER_UNIT_CONVERSIONS
4561 && (SSE_REG_P (operands[0])
4562 || (GET_CODE (operands[0]) == SUBREG
4563 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4564 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4567 [(set (match_operand:MODEF 0 "register_operand")
4568 (float:MODEF (match_operand:SWI48 1 "register_operand")))
4569 (clobber (match_operand:SWI48 2 "memory_operand"))]
4570 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4571 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4573 && (SSE_REG_P (operands[0])
4574 || (GET_CODE (operands[0]) == SUBREG
4575 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4576 [(set (match_dup 2) (match_dup 1))
4577 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4579 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_interunit"
4580 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4582 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
4583 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4584 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4587 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
4588 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4589 [(set_attr "type" "fmov,sseicvt,sseicvt")
4590 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4591 (set_attr "mode" "<MODEF:MODE>")
4592 (set (attr "prefix_rex")
4594 (and (eq_attr "prefix" "maybe_vex")
4595 (match_test "<SWI48:MODE>mode == DImode"))
4597 (const_string "*")))
4598 (set_attr "unit" "i387,*,*")
4599 (set_attr "athlon_decode" "*,double,direct")
4600 (set_attr "amdfam10_decode" "*,vector,double")
4601 (set_attr "bdver1_decode" "*,double,direct")
4602 (set_attr "fp_int_src" "true")])
4604 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_nointerunit"
4605 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4607 (match_operand:SWI48 1 "memory_operand" "m,m")))]
4608 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4609 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4612 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4613 [(set_attr "type" "fmov,sseicvt")
4614 (set_attr "prefix" "orig,maybe_vex")
4615 (set_attr "mode" "<MODEF:MODE>")
4616 (set (attr "prefix_rex")
4618 (and (eq_attr "prefix" "maybe_vex")
4619 (match_test "<SWI48:MODE>mode == DImode"))
4621 (const_string "*")))
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")])
4627 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4628 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4630 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4631 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4632 "TARGET_SSE2 && TARGET_SSE_MATH
4633 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4635 [(set_attr "type" "sseicvt")
4636 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4637 (set_attr "athlon_decode" "double,direct,double")
4638 (set_attr "amdfam10_decode" "vector,double,double")
4639 (set_attr "bdver1_decode" "double,direct,double")
4640 (set_attr "fp_int_src" "true")])
4642 (define_insn "*floatsi<mode>2_vector_sse"
4643 [(set (match_operand:MODEF 0 "register_operand" "=x")
4644 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4645 "TARGET_SSE2 && TARGET_SSE_MATH
4646 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4648 [(set_attr "type" "sseicvt")
4649 (set_attr "mode" "<MODE>")
4650 (set_attr "athlon_decode" "direct")
4651 (set_attr "amdfam10_decode" "double")
4652 (set_attr "bdver1_decode" "direct")
4653 (set_attr "fp_int_src" "true")])
4656 [(set (match_operand:MODEF 0 "register_operand")
4657 (float:MODEF (match_operand:SI 1 "register_operand")))
4658 (clobber (match_operand:SI 2 "memory_operand"))]
4659 "TARGET_SSE2 && TARGET_SSE_MATH
4660 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4662 && (SSE_REG_P (operands[0])
4663 || (GET_CODE (operands[0]) == SUBREG
4664 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4667 rtx op1 = operands[1];
4669 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4671 if (GET_CODE (op1) == SUBREG)
4672 op1 = SUBREG_REG (op1);
4674 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
4676 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4677 emit_insn (gen_sse2_loadld (operands[4],
4678 CONST0_RTX (V4SImode), operands[1]));
4680 /* We can ignore possible trapping value in the
4681 high part of SSE register for non-trapping math. */
4682 else if (SSE_REG_P (op1) && !flag_trapping_math)
4683 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4686 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4687 emit_move_insn (operands[2], operands[1]);
4688 emit_insn (gen_sse2_loadld (operands[4],
4689 CONST0_RTX (V4SImode), operands[2]));
4691 if (<ssevecmode>mode == V4SFmode)
4692 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4694 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4699 [(set (match_operand:MODEF 0 "register_operand")
4700 (float:MODEF (match_operand:SI 1 "memory_operand")))
4701 (clobber (match_operand:SI 2 "memory_operand"))]
4702 "TARGET_SSE2 && TARGET_SSE_MATH
4703 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4705 && (SSE_REG_P (operands[0])
4706 || (GET_CODE (operands[0]) == SUBREG
4707 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4710 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4712 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4714 emit_insn (gen_sse2_loadld (operands[4],
4715 CONST0_RTX (V4SImode), operands[1]));
4716 if (<ssevecmode>mode == V4SFmode)
4717 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4719 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4724 [(set (match_operand:MODEF 0 "register_operand")
4725 (float:MODEF (match_operand:SI 1 "register_operand")))]
4726 "TARGET_SSE2 && TARGET_SSE_MATH
4727 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4729 && (SSE_REG_P (operands[0])
4730 || (GET_CODE (operands[0]) == SUBREG
4731 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4734 rtx op1 = operands[1];
4736 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4738 if (GET_CODE (op1) == SUBREG)
4739 op1 = SUBREG_REG (op1);
4741 if (GENERAL_REG_P (op1))
4743 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4744 if (TARGET_INTER_UNIT_MOVES)
4745 emit_insn (gen_sse2_loadld (operands[4],
4746 CONST0_RTX (V4SImode), operands[1]));
4749 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
4751 emit_insn (gen_sse2_loadld (operands[4],
4752 CONST0_RTX (V4SImode), operands[5]));
4753 ix86_free_from_memory (GET_MODE (operands[1]));
4756 /* We can ignore possible trapping value in the
4757 high part of SSE register for non-trapping math. */
4758 else if (SSE_REG_P (op1) && !flag_trapping_math)
4759 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4762 if (<ssevecmode>mode == V4SFmode)
4763 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4765 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4770 [(set (match_operand:MODEF 0 "register_operand")
4771 (float:MODEF (match_operand:SI 1 "memory_operand")))]
4772 "TARGET_SSE2 && TARGET_SSE_MATH
4773 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4775 && (SSE_REG_P (operands[0])
4776 || (GET_CODE (operands[0]) == SUBREG
4777 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4780 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4782 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4784 emit_insn (gen_sse2_loadld (operands[4],
4785 CONST0_RTX (V4SImode), operands[1]));
4786 if (<ssevecmode>mode == V4SFmode)
4787 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4789 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4793 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_with_temp"
4794 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
4796 (match_operand:SWI48 1 "nonimmediate_operand" "r,m")))
4797 (clobber (match_operand:SWI48 2 "memory_operand" "=m,X"))]
4798 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
4800 [(set_attr "type" "sseicvt")
4801 (set_attr "mode" "<MODEF:MODE>")
4802 (set_attr "athlon_decode" "double,direct")
4803 (set_attr "amdfam10_decode" "vector,double")
4804 (set_attr "bdver1_decode" "double,direct")
4805 (set_attr "btver2_decode" "double,double")
4806 (set_attr "fp_int_src" "true")])
4808 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_interunit"
4809 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
4811 (match_operand:SWI48 1 "nonimmediate_operand" "r,m")))]
4812 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
4813 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4814 "%vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4815 [(set_attr "type" "sseicvt")
4816 (set_attr "prefix" "maybe_vex")
4817 (set_attr "mode" "<MODEF:MODE>")
4818 (set (attr "prefix_rex")
4820 (and (eq_attr "prefix" "maybe_vex")
4821 (match_test "<SWI48:MODE>mode == DImode"))
4823 (const_string "*")))
4824 (set_attr "athlon_decode" "double,direct")
4825 (set_attr "amdfam10_decode" "vector,double")
4826 (set_attr "bdver1_decode" "double,direct")
4827 (set_attr "btver2_decode" "double,double")
4828 (set_attr "fp_int_src" "true")])
4831 [(set (match_operand:MODEF 0 "register_operand")
4832 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))
4833 (clobber (match_operand:SWI48 2 "memory_operand"))]
4834 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
4835 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4837 && (SSE_REG_P (operands[0])
4838 || (GET_CODE (operands[0]) == SUBREG
4839 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4840 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4842 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_nointerunit"
4843 [(set (match_operand:MODEF 0 "register_operand" "=x")
4845 (match_operand:SWI48 1 "memory_operand" "m")))]
4846 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
4847 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4848 "%vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4849 [(set_attr "type" "sseicvt")
4850 (set_attr "prefix" "maybe_vex")
4851 (set_attr "mode" "<MODEF:MODE>")
4852 (set (attr "prefix_rex")
4854 (and (eq_attr "prefix" "maybe_vex")
4855 (match_test "<SWI48:MODE>mode == DImode"))
4857 (const_string "*")))
4858 (set_attr "athlon_decode" "direct")
4859 (set_attr "amdfam10_decode" "double")
4860 (set_attr "bdver1_decode" "direct")
4861 (set_attr "fp_int_src" "true")])
4864 [(set (match_operand:MODEF 0 "register_operand")
4865 (float:MODEF (match_operand:SWI48 1 "register_operand")))
4866 (clobber (match_operand:SWI48 2 "memory_operand"))]
4867 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
4868 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4870 && (SSE_REG_P (operands[0])
4871 || (GET_CODE (operands[0]) == SUBREG
4872 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4873 [(set (match_dup 2) (match_dup 1))
4874 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4877 [(set (match_operand:MODEF 0 "register_operand")
4878 (float:MODEF (match_operand:SWI48 1 "memory_operand")))
4879 (clobber (match_operand:SWI48 2 "memory_operand"))]
4880 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
4882 && (SSE_REG_P (operands[0])
4883 || (GET_CODE (operands[0]) == SUBREG
4884 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4885 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4887 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
4888 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4890 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
4891 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
4893 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
4897 [(set_attr "type" "fmov,multi")
4898 (set_attr "mode" "<X87MODEF:MODE>")
4899 (set_attr "unit" "*,i387")
4900 (set_attr "fp_int_src" "true")])
4902 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
4903 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4905 (match_operand:SWI48x 1 "memory_operand" "m")))]
4907 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
4909 [(set_attr "type" "fmov")
4910 (set_attr "mode" "<X87MODEF:MODE>")
4911 (set_attr "fp_int_src" "true")])
4914 [(set (match_operand:X87MODEF 0 "fp_register_operand")
4915 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))
4916 (clobber (match_operand:SWI48x 2 "memory_operand"))]
4918 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4919 && reload_completed"
4920 [(set (match_dup 2) (match_dup 1))
4921 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4924 [(set (match_operand:X87MODEF 0 "fp_register_operand")
4925 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand")))
4926 (clobber (match_operand:SWI48x 2 "memory_operand"))]
4928 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4929 && reload_completed"
4930 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4932 ;; Avoid store forwarding (partial memory) stall penalty
4933 ;; by passing DImode value through XMM registers. */
4935 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
4936 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4938 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
4939 (clobber (match_scratch:V4SI 3 "=X,x"))
4940 (clobber (match_scratch:V4SI 4 "=X,x"))
4941 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
4942 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4943 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4944 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
4946 [(set_attr "type" "multi")
4947 (set_attr "mode" "<X87MODEF:MODE>")
4948 (set_attr "unit" "i387")
4949 (set_attr "fp_int_src" "true")])
4952 [(set (match_operand:X87MODEF 0 "fp_register_operand")
4953 (float:X87MODEF (match_operand:DI 1 "register_operand")))
4954 (clobber (match_scratch:V4SI 3))
4955 (clobber (match_scratch:V4SI 4))
4956 (clobber (match_operand:DI 2 "memory_operand"))]
4957 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4958 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4959 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
4960 && reload_completed"
4961 [(set (match_dup 2) (match_dup 3))
4962 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
4964 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
4965 Assemble the 64-bit DImode value in an xmm register. */
4966 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
4967 gen_rtx_SUBREG (SImode, operands[1], 0)));
4968 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
4969 gen_rtx_SUBREG (SImode, operands[1], 4)));
4970 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
4973 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
4977 [(set (match_operand:X87MODEF 0 "fp_register_operand")
4978 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
4979 (clobber (match_scratch:V4SI 3))
4980 (clobber (match_scratch:V4SI 4))
4981 (clobber (match_operand:DI 2 "memory_operand"))]
4982 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4983 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4984 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
4985 && reload_completed"
4986 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4988 ;; Avoid store forwarding (partial memory) stall penalty by extending
4989 ;; SImode value to DImode through XMM register instead of pushing two
4990 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
4991 ;; targets benefit from this optimization. Also note that fild
4992 ;; loads from memory only.
4994 (define_insn "*floatunssi<mode>2_1"
4995 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4996 (unsigned_float:X87MODEF
4997 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
4998 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
4999 (clobber (match_scratch:SI 3 "=X,x"))]
5001 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5004 [(set_attr "type" "multi")
5005 (set_attr "mode" "<MODE>")])
5008 [(set (match_operand:X87MODEF 0 "register_operand")
5009 (unsigned_float:X87MODEF
5010 (match_operand:SI 1 "register_operand")))
5011 (clobber (match_operand:DI 2 "memory_operand"))
5012 (clobber (match_scratch:SI 3))]
5014 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5016 && reload_completed"
5017 [(set (match_dup 2) (match_dup 1))
5019 (float:X87MODEF (match_dup 2)))]
5020 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5023 [(set (match_operand:X87MODEF 0 "register_operand")
5024 (unsigned_float:X87MODEF
5025 (match_operand:SI 1 "memory_operand")))
5026 (clobber (match_operand:DI 2 "memory_operand"))
5027 (clobber (match_scratch:SI 3))]
5029 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5031 && reload_completed"
5032 [(set (match_dup 2) (match_dup 3))
5034 (float:X87MODEF (match_dup 2)))]
5036 emit_move_insn (operands[3], operands[1]);
5037 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5040 (define_expand "floatunssi<mode>2"
5042 [(set (match_operand:X87MODEF 0 "register_operand")
5043 (unsigned_float:X87MODEF
5044 (match_operand:SI 1 "nonimmediate_operand")))
5045 (clobber (match_dup 2))
5046 (clobber (match_scratch:SI 3))])]
5048 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5050 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5052 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5054 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5058 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5061 (define_expand "floatunsdisf2"
5062 [(use (match_operand:SF 0 "register_operand"))
5063 (use (match_operand:DI 1 "nonimmediate_operand"))]
5064 "TARGET_64BIT && TARGET_SSE_MATH"
5065 "x86_emit_floatuns (operands); DONE;")
5067 (define_expand "floatunsdidf2"
5068 [(use (match_operand:DF 0 "register_operand"))
5069 (use (match_operand:DI 1 "nonimmediate_operand"))]
5070 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5071 && TARGET_SSE2 && TARGET_SSE_MATH"
5074 x86_emit_floatuns (operands);
5076 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5080 ;; Load effective address instructions
5082 (define_insn_and_split "*lea<mode>"
5083 [(set (match_operand:SWI48 0 "register_operand" "=r")
5084 (match_operand:SWI48 1 "lea_address_operand" "p"))]
5087 if (SImode_address_operand (operands[1], VOIDmode))
5089 gcc_assert (TARGET_64BIT);
5090 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5093 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5095 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5098 enum machine_mode mode = <MODE>mode;
5101 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5102 change operands[] array behind our back. */
5103 pat = PATTERN (curr_insn);
5105 operands[0] = SET_DEST (pat);
5106 operands[1] = SET_SRC (pat);
5108 /* Emit all operations in SImode for zero-extended addresses. Recall
5109 that x86_64 inheretly zero-extends SImode operations to DImode. */
5110 if (SImode_address_operand (operands[1], VOIDmode))
5113 ix86_split_lea_for_addr (curr_insn, operands, mode);
5116 [(set_attr "type" "lea")
5119 (match_operand 1 "SImode_address_operand")
5121 (const_string "<MODE>")))])
5125 (define_expand "add<mode>3"
5126 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5127 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5128 (match_operand:SDWIM 2 "<general_operand>")))]
5130 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5132 (define_insn_and_split "*add<dwi>3_doubleword"
5133 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5135 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5136 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5137 (clobber (reg:CC FLAGS_REG))]
5138 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5141 [(parallel [(set (reg:CC FLAGS_REG)
5142 (unspec:CC [(match_dup 1) (match_dup 2)]
5145 (plus:DWIH (match_dup 1) (match_dup 2)))])
5146 (parallel [(set (match_dup 3)
5150 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5152 (clobber (reg:CC FLAGS_REG))])]
5153 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5155 (define_insn "*add<mode>3_cc"
5156 [(set (reg:CC FLAGS_REG)
5158 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5159 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5161 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5162 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5163 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5164 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5165 [(set_attr "type" "alu")
5166 (set_attr "mode" "<MODE>")])
5168 (define_insn "addqi3_cc"
5169 [(set (reg:CC FLAGS_REG)
5171 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5172 (match_operand:QI 2 "general_operand" "qn,qm")]
5174 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5175 (plus:QI (match_dup 1) (match_dup 2)))]
5176 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5177 "add{b}\t{%2, %0|%0, %2}"
5178 [(set_attr "type" "alu")
5179 (set_attr "mode" "QI")])
5181 (define_insn "*add<mode>_1"
5182 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5184 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5185 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5186 (clobber (reg:CC FLAGS_REG))]
5187 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5189 switch (get_attr_type (insn))
5195 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5196 if (operands[2] == const1_rtx)
5197 return "inc{<imodesuffix>}\t%0";
5200 gcc_assert (operands[2] == constm1_rtx);
5201 return "dec{<imodesuffix>}\t%0";
5205 /* For most processors, ADD is faster than LEA. This alternative
5206 was added to use ADD as much as possible. */
5207 if (which_alternative == 2)
5210 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5213 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5214 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5215 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5217 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5221 (cond [(eq_attr "alternative" "3")
5222 (const_string "lea")
5223 (match_operand:SWI48 2 "incdec_operand")
5224 (const_string "incdec")
5226 (const_string "alu")))
5227 (set (attr "length_immediate")
5229 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5231 (const_string "*")))
5232 (set_attr "mode" "<MODE>")])
5234 ;; It may seem that nonimmediate operand is proper one for operand 1.
5235 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5236 ;; we take care in ix86_binary_operator_ok to not allow two memory
5237 ;; operands so proper swapping will be done in reload. This allow
5238 ;; patterns constructed from addsi_1 to match.
5240 (define_insn "addsi_1_zext"
5241 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5243 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5244 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5245 (clobber (reg:CC FLAGS_REG))]
5246 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5248 switch (get_attr_type (insn))
5254 if (operands[2] == const1_rtx)
5255 return "inc{l}\t%k0";
5258 gcc_assert (operands[2] == constm1_rtx);
5259 return "dec{l}\t%k0";
5263 /* For most processors, ADD is faster than LEA. This alternative
5264 was added to use ADD as much as possible. */
5265 if (which_alternative == 1)
5268 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5271 if (x86_maybe_negate_const_int (&operands[2], SImode))
5272 return "sub{l}\t{%2, %k0|%k0, %2}";
5274 return "add{l}\t{%2, %k0|%k0, %2}";
5278 (cond [(eq_attr "alternative" "2")
5279 (const_string "lea")
5280 (match_operand:SI 2 "incdec_operand")
5281 (const_string "incdec")
5283 (const_string "alu")))
5284 (set (attr "length_immediate")
5286 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5288 (const_string "*")))
5289 (set_attr "mode" "SI")])
5291 (define_insn "*addhi_1"
5292 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5293 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5294 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5295 (clobber (reg:CC FLAGS_REG))]
5296 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5298 switch (get_attr_type (insn))
5304 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5305 if (operands[2] == const1_rtx)
5306 return "inc{w}\t%0";
5309 gcc_assert (operands[2] == constm1_rtx);
5310 return "dec{w}\t%0";
5314 /* For most processors, ADD is faster than LEA. This alternative
5315 was added to use ADD as much as possible. */
5316 if (which_alternative == 2)
5319 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5322 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5323 if (x86_maybe_negate_const_int (&operands[2], HImode))
5324 return "sub{w}\t{%2, %0|%0, %2}";
5326 return "add{w}\t{%2, %0|%0, %2}";
5330 (cond [(eq_attr "alternative" "3")
5331 (const_string "lea")
5332 (match_operand:HI 2 "incdec_operand")
5333 (const_string "incdec")
5335 (const_string "alu")))
5336 (set (attr "length_immediate")
5338 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5340 (const_string "*")))
5341 (set_attr "mode" "HI,HI,HI,SI")])
5343 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5344 (define_insn "*addqi_1"
5345 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5346 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5347 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5348 (clobber (reg:CC FLAGS_REG))]
5349 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5351 bool widen = (which_alternative == 3 || which_alternative == 4);
5353 switch (get_attr_type (insn))
5359 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5360 if (operands[2] == const1_rtx)
5361 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5364 gcc_assert (operands[2] == constm1_rtx);
5365 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5369 /* For most processors, ADD is faster than LEA. These alternatives
5370 were added to use ADD as much as possible. */
5371 if (which_alternative == 2 || which_alternative == 4)
5374 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5377 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5378 if (x86_maybe_negate_const_int (&operands[2], QImode))
5381 return "sub{l}\t{%2, %k0|%k0, %2}";
5383 return "sub{b}\t{%2, %0|%0, %2}";
5386 return "add{l}\t{%k2, %k0|%k0, %k2}";
5388 return "add{b}\t{%2, %0|%0, %2}";
5392 (cond [(eq_attr "alternative" "5")
5393 (const_string "lea")
5394 (match_operand:QI 2 "incdec_operand")
5395 (const_string "incdec")
5397 (const_string "alu")))
5398 (set (attr "length_immediate")
5400 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5402 (const_string "*")))
5403 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5405 (define_insn "*addqi_1_slp"
5406 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5407 (plus:QI (match_dup 0)
5408 (match_operand:QI 1 "general_operand" "qn,qm")))
5409 (clobber (reg:CC FLAGS_REG))]
5410 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5411 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5413 switch (get_attr_type (insn))
5416 if (operands[1] == const1_rtx)
5417 return "inc{b}\t%0";
5420 gcc_assert (operands[1] == constm1_rtx);
5421 return "dec{b}\t%0";
5425 if (x86_maybe_negate_const_int (&operands[1], QImode))
5426 return "sub{b}\t{%1, %0|%0, %1}";
5428 return "add{b}\t{%1, %0|%0, %1}";
5432 (if_then_else (match_operand:QI 1 "incdec_operand")
5433 (const_string "incdec")
5434 (const_string "alu1")))
5435 (set (attr "memory")
5436 (if_then_else (match_operand 1 "memory_operand")
5437 (const_string "load")
5438 (const_string "none")))
5439 (set_attr "mode" "QI")])
5441 ;; Split non destructive adds if we cannot use lea.
5443 [(set (match_operand:SWI48 0 "register_operand")
5444 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5445 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5446 (clobber (reg:CC FLAGS_REG))]
5447 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5448 [(set (match_dup 0) (match_dup 1))
5449 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5450 (clobber (reg:CC FLAGS_REG))])])
5452 ;; Convert add to the lea pattern to avoid flags dependency.
5454 [(set (match_operand:SWI 0 "register_operand")
5455 (plus:SWI (match_operand:SWI 1 "register_operand")
5456 (match_operand:SWI 2 "<nonmemory_operand>")))
5457 (clobber (reg:CC FLAGS_REG))]
5458 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5461 enum machine_mode mode = <MODE>mode;
5464 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5467 operands[0] = gen_lowpart (mode, operands[0]);
5468 operands[1] = gen_lowpart (mode, operands[1]);
5469 operands[2] = gen_lowpart (mode, operands[2]);
5472 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5474 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5478 ;; Split non destructive adds if we cannot use lea.
5480 [(set (match_operand:DI 0 "register_operand")
5482 (plus:SI (match_operand:SI 1 "register_operand")
5483 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5484 (clobber (reg:CC FLAGS_REG))]
5486 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5487 [(set (match_dup 3) (match_dup 1))
5488 (parallel [(set (match_dup 0)
5489 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5490 (clobber (reg:CC FLAGS_REG))])]
5491 "operands[3] = gen_lowpart (SImode, operands[0]);")
5493 ;; Convert add to the lea pattern to avoid flags dependency.
5495 [(set (match_operand:DI 0 "register_operand")
5497 (plus:SI (match_operand:SI 1 "register_operand")
5498 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5499 (clobber (reg:CC FLAGS_REG))]
5500 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5502 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5504 (define_insn "*add<mode>_2"
5505 [(set (reg FLAGS_REG)
5508 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5509 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5511 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5512 (plus:SWI (match_dup 1) (match_dup 2)))]
5513 "ix86_match_ccmode (insn, CCGOCmode)
5514 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5516 switch (get_attr_type (insn))
5519 if (operands[2] == const1_rtx)
5520 return "inc{<imodesuffix>}\t%0";
5523 gcc_assert (operands[2] == constm1_rtx);
5524 return "dec{<imodesuffix>}\t%0";
5528 if (which_alternative == 2)
5531 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5534 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5535 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5536 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5538 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5542 (if_then_else (match_operand:SWI 2 "incdec_operand")
5543 (const_string "incdec")
5544 (const_string "alu")))
5545 (set (attr "length_immediate")
5547 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5549 (const_string "*")))
5550 (set_attr "mode" "<MODE>")])
5552 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5553 (define_insn "*addsi_2_zext"
5554 [(set (reg FLAGS_REG)
5556 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5557 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5559 (set (match_operand:DI 0 "register_operand" "=r,r")
5560 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5561 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5562 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5564 switch (get_attr_type (insn))
5567 if (operands[2] == const1_rtx)
5568 return "inc{l}\t%k0";
5571 gcc_assert (operands[2] == constm1_rtx);
5572 return "dec{l}\t%k0";
5576 if (which_alternative == 1)
5579 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5582 if (x86_maybe_negate_const_int (&operands[2], SImode))
5583 return "sub{l}\t{%2, %k0|%k0, %2}";
5585 return "add{l}\t{%2, %k0|%k0, %2}";
5589 (if_then_else (match_operand:SI 2 "incdec_operand")
5590 (const_string "incdec")
5591 (const_string "alu")))
5592 (set (attr "length_immediate")
5594 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5596 (const_string "*")))
5597 (set_attr "mode" "SI")])
5599 (define_insn "*add<mode>_3"
5600 [(set (reg FLAGS_REG)
5602 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5603 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5604 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5605 "ix86_match_ccmode (insn, CCZmode)
5606 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5608 switch (get_attr_type (insn))
5611 if (operands[2] == const1_rtx)
5612 return "inc{<imodesuffix>}\t%0";
5615 gcc_assert (operands[2] == constm1_rtx);
5616 return "dec{<imodesuffix>}\t%0";
5620 if (which_alternative == 1)
5623 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5626 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5627 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5628 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5630 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5634 (if_then_else (match_operand:SWI 2 "incdec_operand")
5635 (const_string "incdec")
5636 (const_string "alu")))
5637 (set (attr "length_immediate")
5639 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5641 (const_string "*")))
5642 (set_attr "mode" "<MODE>")])
5644 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5645 (define_insn "*addsi_3_zext"
5646 [(set (reg FLAGS_REG)
5648 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5649 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5650 (set (match_operand:DI 0 "register_operand" "=r,r")
5651 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5652 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5653 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5655 switch (get_attr_type (insn))
5658 if (operands[2] == const1_rtx)
5659 return "inc{l}\t%k0";
5662 gcc_assert (operands[2] == constm1_rtx);
5663 return "dec{l}\t%k0";
5667 if (which_alternative == 1)
5670 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5673 if (x86_maybe_negate_const_int (&operands[2], SImode))
5674 return "sub{l}\t{%2, %k0|%k0, %2}";
5676 return "add{l}\t{%2, %k0|%k0, %2}";
5680 (if_then_else (match_operand:SI 2 "incdec_operand")
5681 (const_string "incdec")
5682 (const_string "alu")))
5683 (set (attr "length_immediate")
5685 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5687 (const_string "*")))
5688 (set_attr "mode" "SI")])
5690 ; For comparisons against 1, -1 and 128, we may generate better code
5691 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5692 ; is matched then. We can't accept general immediate, because for
5693 ; case of overflows, the result is messed up.
5694 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5695 ; only for comparisons not depending on it.
5697 (define_insn "*adddi_4"
5698 [(set (reg FLAGS_REG)
5700 (match_operand:DI 1 "nonimmediate_operand" "0")
5701 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5702 (clobber (match_scratch:DI 0 "=rm"))]
5704 && ix86_match_ccmode (insn, CCGCmode)"
5706 switch (get_attr_type (insn))
5709 if (operands[2] == constm1_rtx)
5710 return "inc{q}\t%0";
5713 gcc_assert (operands[2] == const1_rtx);
5714 return "dec{q}\t%0";
5718 if (x86_maybe_negate_const_int (&operands[2], DImode))
5719 return "add{q}\t{%2, %0|%0, %2}";
5721 return "sub{q}\t{%2, %0|%0, %2}";
5725 (if_then_else (match_operand:DI 2 "incdec_operand")
5726 (const_string "incdec")
5727 (const_string "alu")))
5728 (set (attr "length_immediate")
5730 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5732 (const_string "*")))
5733 (set_attr "mode" "DI")])
5735 ; For comparisons against 1, -1 and 128, we may generate better code
5736 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5737 ; is matched then. We can't accept general immediate, because for
5738 ; case of overflows, the result is messed up.
5739 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5740 ; only for comparisons not depending on it.
5742 (define_insn "*add<mode>_4"
5743 [(set (reg FLAGS_REG)
5745 (match_operand:SWI124 1 "nonimmediate_operand" "0")
5746 (match_operand:SWI124 2 "const_int_operand" "n")))
5747 (clobber (match_scratch:SWI124 0 "=<r>m"))]
5748 "ix86_match_ccmode (insn, CCGCmode)"
5750 switch (get_attr_type (insn))
5753 if (operands[2] == constm1_rtx)
5754 return "inc{<imodesuffix>}\t%0";
5757 gcc_assert (operands[2] == const1_rtx);
5758 return "dec{<imodesuffix>}\t%0";
5762 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5763 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5765 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5769 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
5770 (const_string "incdec")
5771 (const_string "alu")))
5772 (set (attr "length_immediate")
5774 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5776 (const_string "*")))
5777 (set_attr "mode" "<MODE>")])
5779 (define_insn "*add<mode>_5"
5780 [(set (reg FLAGS_REG)
5783 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
5784 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5786 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5787 "ix86_match_ccmode (insn, CCGOCmode)
5788 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5790 switch (get_attr_type (insn))
5793 if (operands[2] == const1_rtx)
5794 return "inc{<imodesuffix>}\t%0";
5797 gcc_assert (operands[2] == constm1_rtx);
5798 return "dec{<imodesuffix>}\t%0";
5802 if (which_alternative == 1)
5805 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5808 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5809 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5810 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5812 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5816 (if_then_else (match_operand:SWI 2 "incdec_operand")
5817 (const_string "incdec")
5818 (const_string "alu")))
5819 (set (attr "length_immediate")
5821 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5823 (const_string "*")))
5824 (set_attr "mode" "<MODE>")])
5826 (define_insn "*addqi_ext_1_rex64"
5827 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
5832 (match_operand 1 "ext_register_operand" "0")
5835 (match_operand:QI 2 "nonmemory_operand" "Qn")))
5836 (clobber (reg:CC FLAGS_REG))]
5839 switch (get_attr_type (insn))
5842 if (operands[2] == const1_rtx)
5843 return "inc{b}\t%h0";
5846 gcc_assert (operands[2] == constm1_rtx);
5847 return "dec{b}\t%h0";
5851 return "add{b}\t{%2, %h0|%h0, %2}";
5855 (if_then_else (match_operand:QI 2 "incdec_operand")
5856 (const_string "incdec")
5857 (const_string "alu")))
5858 (set_attr "modrm" "1")
5859 (set_attr "mode" "QI")])
5861 (define_insn "addqi_ext_1"
5862 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
5867 (match_operand 1 "ext_register_operand" "0")
5870 (match_operand:QI 2 "general_operand" "Qmn")))
5871 (clobber (reg:CC FLAGS_REG))]
5874 switch (get_attr_type (insn))
5877 if (operands[2] == const1_rtx)
5878 return "inc{b}\t%h0";
5881 gcc_assert (operands[2] == constm1_rtx);
5882 return "dec{b}\t%h0";
5886 return "add{b}\t{%2, %h0|%h0, %2}";
5890 (if_then_else (match_operand:QI 2 "incdec_operand")
5891 (const_string "incdec")
5892 (const_string "alu")))
5893 (set_attr "modrm" "1")
5894 (set_attr "mode" "QI")])
5896 (define_insn "*addqi_ext_2"
5897 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
5902 (match_operand 1 "ext_register_operand" "%0")
5906 (match_operand 2 "ext_register_operand" "Q")
5909 (clobber (reg:CC FLAGS_REG))]
5911 "add{b}\t{%h2, %h0|%h0, %h2}"
5912 [(set_attr "type" "alu")
5913 (set_attr "mode" "QI")])
5915 ;; The lea patterns for modes less than 32 bits need to be matched by
5916 ;; several insns converted to real lea by splitters.
5918 (define_insn_and_split "*lea_general_1"
5919 [(set (match_operand 0 "register_operand" "=r")
5920 (plus (plus (match_operand 1 "index_register_operand" "l")
5921 (match_operand 2 "register_operand" "r"))
5922 (match_operand 3 "immediate_operand" "i")))]
5923 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5924 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5925 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5926 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5927 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5928 || GET_MODE (operands[3]) == VOIDmode)"
5930 "&& reload_completed"
5933 enum machine_mode mode = SImode;
5936 operands[0] = gen_lowpart (mode, operands[0]);
5937 operands[1] = gen_lowpart (mode, operands[1]);
5938 operands[2] = gen_lowpart (mode, operands[2]);
5939 operands[3] = gen_lowpart (mode, operands[3]);
5941 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
5944 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5947 [(set_attr "type" "lea")
5948 (set_attr "mode" "SI")])
5950 (define_insn_and_split "*lea_general_2"
5951 [(set (match_operand 0 "register_operand" "=r")
5952 (plus (mult (match_operand 1 "index_register_operand" "l")
5953 (match_operand 2 "const248_operand" "n"))
5954 (match_operand 3 "nonmemory_operand" "ri")))]
5955 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5956 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5957 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5958 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5959 || GET_MODE (operands[3]) == VOIDmode)"
5961 "&& reload_completed"
5964 enum machine_mode mode = SImode;
5967 operands[0] = gen_lowpart (mode, operands[0]);
5968 operands[1] = gen_lowpart (mode, operands[1]);
5969 operands[3] = gen_lowpart (mode, operands[3]);
5971 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
5974 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5977 [(set_attr "type" "lea")
5978 (set_attr "mode" "SI")])
5980 (define_insn_and_split "*lea_general_3"
5981 [(set (match_operand 0 "register_operand" "=r")
5982 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
5983 (match_operand 2 "const248_operand" "n"))
5984 (match_operand 3 "register_operand" "r"))
5985 (match_operand 4 "immediate_operand" "i")))]
5986 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5987 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5988 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5989 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
5991 "&& reload_completed"
5994 enum machine_mode mode = SImode;
5997 operands[0] = gen_lowpart (mode, operands[0]);
5998 operands[1] = gen_lowpart (mode, operands[1]);
5999 operands[3] = gen_lowpart (mode, operands[3]);
6000 operands[4] = gen_lowpart (mode, operands[4]);
6002 pat = gen_rtx_PLUS (mode,
6004 gen_rtx_MULT (mode, operands[1],
6009 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6012 [(set_attr "type" "lea")
6013 (set_attr "mode" "SI")])
6015 (define_insn_and_split "*lea_general_4"
6016 [(set (match_operand 0 "register_operand" "=r")
6018 (match_operand 1 "index_register_operand" "l")
6019 (match_operand 2 "const_int_operand" "n"))
6020 (match_operand 3 "const_int_operand" "n")))]
6021 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6022 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6023 || GET_MODE (operands[0]) == SImode
6024 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6025 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6026 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6027 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6028 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6030 "&& reload_completed"
6033 enum machine_mode mode = GET_MODE (operands[0]);
6036 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6039 operands[0] = gen_lowpart (mode, operands[0]);
6040 operands[1] = gen_lowpart (mode, operands[1]);
6043 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6045 pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6046 INTVAL (operands[3]));
6048 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6051 [(set_attr "type" "lea")
6053 (if_then_else (match_operand:DI 0)
6055 (const_string "SI")))])
6057 ;; Subtract instructions
6059 (define_expand "sub<mode>3"
6060 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6061 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6062 (match_operand:SDWIM 2 "<general_operand>")))]
6064 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6066 (define_insn_and_split "*sub<dwi>3_doubleword"
6067 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6069 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6070 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6071 (clobber (reg:CC FLAGS_REG))]
6072 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6075 [(parallel [(set (reg:CC FLAGS_REG)
6076 (compare:CC (match_dup 1) (match_dup 2)))
6078 (minus:DWIH (match_dup 1) (match_dup 2)))])
6079 (parallel [(set (match_dup 3)
6083 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6085 (clobber (reg:CC FLAGS_REG))])]
6086 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6088 (define_insn "*sub<mode>_1"
6089 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6091 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6092 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6093 (clobber (reg:CC FLAGS_REG))]
6094 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6095 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6096 [(set_attr "type" "alu")
6097 (set_attr "mode" "<MODE>")])
6099 (define_insn "*subsi_1_zext"
6100 [(set (match_operand:DI 0 "register_operand" "=r")
6102 (minus:SI (match_operand:SI 1 "register_operand" "0")
6103 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6104 (clobber (reg:CC FLAGS_REG))]
6105 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6106 "sub{l}\t{%2, %k0|%k0, %2}"
6107 [(set_attr "type" "alu")
6108 (set_attr "mode" "SI")])
6110 (define_insn "*subqi_1_slp"
6111 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6112 (minus:QI (match_dup 0)
6113 (match_operand:QI 1 "general_operand" "qn,qm")))
6114 (clobber (reg:CC FLAGS_REG))]
6115 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6116 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6117 "sub{b}\t{%1, %0|%0, %1}"
6118 [(set_attr "type" "alu1")
6119 (set_attr "mode" "QI")])
6121 (define_insn "*sub<mode>_2"
6122 [(set (reg FLAGS_REG)
6125 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6126 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6128 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6129 (minus:SWI (match_dup 1) (match_dup 2)))]
6130 "ix86_match_ccmode (insn, CCGOCmode)
6131 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6132 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6133 [(set_attr "type" "alu")
6134 (set_attr "mode" "<MODE>")])
6136 (define_insn "*subsi_2_zext"
6137 [(set (reg FLAGS_REG)
6139 (minus:SI (match_operand:SI 1 "register_operand" "0")
6140 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6142 (set (match_operand:DI 0 "register_operand" "=r")
6144 (minus:SI (match_dup 1)
6146 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6147 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6148 "sub{l}\t{%2, %k0|%k0, %2}"
6149 [(set_attr "type" "alu")
6150 (set_attr "mode" "SI")])
6152 (define_insn "*sub<mode>_3"
6153 [(set (reg FLAGS_REG)
6154 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6155 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6156 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6157 (minus:SWI (match_dup 1) (match_dup 2)))]
6158 "ix86_match_ccmode (insn, CCmode)
6159 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6160 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6161 [(set_attr "type" "alu")
6162 (set_attr "mode" "<MODE>")])
6164 (define_insn "*subsi_3_zext"
6165 [(set (reg FLAGS_REG)
6166 (compare (match_operand:SI 1 "register_operand" "0")
6167 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6168 (set (match_operand:DI 0 "register_operand" "=r")
6170 (minus:SI (match_dup 1)
6172 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6173 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6174 "sub{l}\t{%2, %1|%1, %2}"
6175 [(set_attr "type" "alu")
6176 (set_attr "mode" "SI")])
6178 ;; Add with carry and subtract with borrow
6180 (define_expand "<plusminus_insn><mode>3_carry"
6182 [(set (match_operand:SWI 0 "nonimmediate_operand")
6184 (match_operand:SWI 1 "nonimmediate_operand")
6185 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6186 [(match_operand 3 "flags_reg_operand")
6188 (match_operand:SWI 2 "<general_operand>"))))
6189 (clobber (reg:CC FLAGS_REG))])]
6190 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6192 (define_insn "*<plusminus_insn><mode>3_carry"
6193 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6195 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6197 (match_operator 3 "ix86_carry_flag_operator"
6198 [(reg FLAGS_REG) (const_int 0)])
6199 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6200 (clobber (reg:CC FLAGS_REG))]
6201 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6202 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6203 [(set_attr "type" "alu")
6204 (set_attr "use_carry" "1")
6205 (set_attr "pent_pair" "pu")
6206 (set_attr "mode" "<MODE>")])
6208 (define_insn "*addsi3_carry_zext"
6209 [(set (match_operand:DI 0 "register_operand" "=r")
6211 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6212 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6213 [(reg FLAGS_REG) (const_int 0)])
6214 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6215 (clobber (reg:CC FLAGS_REG))]
6216 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6217 "adc{l}\t{%2, %k0|%k0, %2}"
6218 [(set_attr "type" "alu")
6219 (set_attr "use_carry" "1")
6220 (set_attr "pent_pair" "pu")
6221 (set_attr "mode" "SI")])
6223 (define_insn "*subsi3_carry_zext"
6224 [(set (match_operand:DI 0 "register_operand" "=r")
6226 (minus:SI (match_operand:SI 1 "register_operand" "0")
6227 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6228 [(reg FLAGS_REG) (const_int 0)])
6229 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6230 (clobber (reg:CC FLAGS_REG))]
6231 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6232 "sbb{l}\t{%2, %k0|%k0, %2}"
6233 [(set_attr "type" "alu")
6234 (set_attr "pent_pair" "pu")
6235 (set_attr "mode" "SI")])
6239 (define_insn "adcx<mode>3"
6240 [(set (reg:CCC FLAGS_REG)
6243 (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6245 (match_operator 4 "ix86_carry_flag_operator"
6246 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6247 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6249 (set (match_operand:SWI48 0 "register_operand" "=r")
6250 (plus:SWI48 (match_dup 1)
6251 (plus:SWI48 (match_op_dup 4
6252 [(match_dup 3) (const_int 0)])
6254 "TARGET_ADX && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6255 "adcx\t{%2, %0|%0, %2}"
6256 [(set_attr "type" "alu")
6257 (set_attr "use_carry" "1")
6258 (set_attr "mode" "<MODE>")])
6260 ;; Overflow setting add and subtract instructions
6262 (define_insn "*add<mode>3_cconly_overflow"
6263 [(set (reg:CCC FLAGS_REG)
6266 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6267 (match_operand:SWI 2 "<general_operand>" "<g>"))
6269 (clobber (match_scratch:SWI 0 "=<r>"))]
6270 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6271 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6272 [(set_attr "type" "alu")
6273 (set_attr "mode" "<MODE>")])
6275 (define_insn "*sub<mode>3_cconly_overflow"
6276 [(set (reg:CCC FLAGS_REG)
6279 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6280 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6283 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6284 [(set_attr "type" "icmp")
6285 (set_attr "mode" "<MODE>")])
6287 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6288 [(set (reg:CCC FLAGS_REG)
6291 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6292 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6294 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6295 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6296 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6297 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6298 [(set_attr "type" "alu")
6299 (set_attr "mode" "<MODE>")])
6301 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6302 [(set (reg:CCC FLAGS_REG)
6305 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6306 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6308 (set (match_operand:DI 0 "register_operand" "=r")
6309 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6310 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6311 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6312 [(set_attr "type" "alu")
6313 (set_attr "mode" "SI")])
6315 ;; The patterns that match these are at the end of this file.
6317 (define_expand "<plusminus_insn>xf3"
6318 [(set (match_operand:XF 0 "register_operand")
6320 (match_operand:XF 1 "register_operand")
6321 (match_operand:XF 2 "register_operand")))]
6324 (define_expand "<plusminus_insn><mode>3"
6325 [(set (match_operand:MODEF 0 "register_operand")
6327 (match_operand:MODEF 1 "register_operand")
6328 (match_operand:MODEF 2 "nonimmediate_operand")))]
6329 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6330 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6332 ;; Multiply instructions
6334 (define_expand "mul<mode>3"
6335 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6337 (match_operand:SWIM248 1 "register_operand")
6338 (match_operand:SWIM248 2 "<general_operand>")))
6339 (clobber (reg:CC FLAGS_REG))])])
6341 (define_expand "mulqi3"
6342 [(parallel [(set (match_operand:QI 0 "register_operand")
6344 (match_operand:QI 1 "register_operand")
6345 (match_operand:QI 2 "nonimmediate_operand")))
6346 (clobber (reg:CC FLAGS_REG))])]
6347 "TARGET_QIMODE_MATH")
6350 ;; IMUL reg32/64, reg32/64, imm8 Direct
6351 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6352 ;; IMUL reg32/64, reg32/64, imm32 Direct
6353 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6354 ;; IMUL reg32/64, reg32/64 Direct
6355 ;; IMUL reg32/64, mem32/64 Direct
6357 ;; On BDVER1, all above IMULs use DirectPath
6359 (define_insn "*mul<mode>3_1"
6360 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6362 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6363 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6364 (clobber (reg:CC FLAGS_REG))]
6365 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6367 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6368 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6369 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6370 [(set_attr "type" "imul")
6371 (set_attr "prefix_0f" "0,0,1")
6372 (set (attr "athlon_decode")
6373 (cond [(eq_attr "cpu" "athlon")
6374 (const_string "vector")
6375 (eq_attr "alternative" "1")
6376 (const_string "vector")
6377 (and (eq_attr "alternative" "2")
6378 (match_operand 1 "memory_operand"))
6379 (const_string "vector")]
6380 (const_string "direct")))
6381 (set (attr "amdfam10_decode")
6382 (cond [(and (eq_attr "alternative" "0,1")
6383 (match_operand 1 "memory_operand"))
6384 (const_string "vector")]
6385 (const_string "direct")))
6386 (set_attr "bdver1_decode" "direct")
6387 (set_attr "mode" "<MODE>")])
6389 (define_insn "*mulsi3_1_zext"
6390 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6392 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6393 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6394 (clobber (reg:CC FLAGS_REG))]
6396 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6398 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6399 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6400 imul{l}\t{%2, %k0|%k0, %2}"
6401 [(set_attr "type" "imul")
6402 (set_attr "prefix_0f" "0,0,1")
6403 (set (attr "athlon_decode")
6404 (cond [(eq_attr "cpu" "athlon")
6405 (const_string "vector")
6406 (eq_attr "alternative" "1")
6407 (const_string "vector")
6408 (and (eq_attr "alternative" "2")
6409 (match_operand 1 "memory_operand"))
6410 (const_string "vector")]
6411 (const_string "direct")))
6412 (set (attr "amdfam10_decode")
6413 (cond [(and (eq_attr "alternative" "0,1")
6414 (match_operand 1 "memory_operand"))
6415 (const_string "vector")]
6416 (const_string "direct")))
6417 (set_attr "bdver1_decode" "direct")
6418 (set_attr "mode" "SI")])
6421 ;; IMUL reg16, reg16, imm8 VectorPath
6422 ;; IMUL reg16, mem16, imm8 VectorPath
6423 ;; IMUL reg16, reg16, imm16 VectorPath
6424 ;; IMUL reg16, mem16, imm16 VectorPath
6425 ;; IMUL reg16, reg16 Direct
6426 ;; IMUL reg16, mem16 Direct
6428 ;; On BDVER1, all HI MULs use DoublePath
6430 (define_insn "*mulhi3_1"
6431 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6432 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6433 (match_operand:HI 2 "general_operand" "K,n,mr")))
6434 (clobber (reg:CC FLAGS_REG))]
6436 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6438 imul{w}\t{%2, %1, %0|%0, %1, %2}
6439 imul{w}\t{%2, %1, %0|%0, %1, %2}
6440 imul{w}\t{%2, %0|%0, %2}"
6441 [(set_attr "type" "imul")
6442 (set_attr "prefix_0f" "0,0,1")
6443 (set (attr "athlon_decode")
6444 (cond [(eq_attr "cpu" "athlon")
6445 (const_string "vector")
6446 (eq_attr "alternative" "1,2")
6447 (const_string "vector")]
6448 (const_string "direct")))
6449 (set (attr "amdfam10_decode")
6450 (cond [(eq_attr "alternative" "0,1")
6451 (const_string "vector")]
6452 (const_string "direct")))
6453 (set_attr "bdver1_decode" "double")
6454 (set_attr "mode" "HI")])
6456 ;;On AMDFAM10 and BDVER1
6460 (define_insn "*mulqi3_1"
6461 [(set (match_operand:QI 0 "register_operand" "=a")
6462 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6463 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6464 (clobber (reg:CC FLAGS_REG))]
6466 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6468 [(set_attr "type" "imul")
6469 (set_attr "length_immediate" "0")
6470 (set (attr "athlon_decode")
6471 (if_then_else (eq_attr "cpu" "athlon")
6472 (const_string "vector")
6473 (const_string "direct")))
6474 (set_attr "amdfam10_decode" "direct")
6475 (set_attr "bdver1_decode" "direct")
6476 (set_attr "mode" "QI")])
6478 (define_expand "<u>mul<mode><dwi>3"
6479 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6482 (match_operand:DWIH 1 "nonimmediate_operand"))
6484 (match_operand:DWIH 2 "register_operand"))))
6485 (clobber (reg:CC FLAGS_REG))])])
6487 (define_expand "<u>mulqihi3"
6488 [(parallel [(set (match_operand:HI 0 "register_operand")
6491 (match_operand:QI 1 "nonimmediate_operand"))
6493 (match_operand:QI 2 "register_operand"))))
6494 (clobber (reg:CC FLAGS_REG))])]
6495 "TARGET_QIMODE_MATH")
6497 (define_insn "*bmi2_umulditi3_1"
6498 [(set (match_operand:DI 0 "register_operand" "=r")
6500 (match_operand:DI 2 "nonimmediate_operand" "%d")
6501 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6502 (set (match_operand:DI 1 "register_operand" "=r")
6505 (mult:TI (zero_extend:TI (match_dup 2))
6506 (zero_extend:TI (match_dup 3)))
6508 "TARGET_64BIT && TARGET_BMI2
6509 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6510 "mulx\t{%3, %0, %1|%1, %0, %3}"
6511 [(set_attr "type" "imulx")
6512 (set_attr "prefix" "vex")
6513 (set_attr "mode" "DI")])
6515 (define_insn "*bmi2_umulsidi3_1"
6516 [(set (match_operand:SI 0 "register_operand" "=r")
6518 (match_operand:SI 2 "nonimmediate_operand" "%d")
6519 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6520 (set (match_operand:SI 1 "register_operand" "=r")
6523 (mult:DI (zero_extend:DI (match_dup 2))
6524 (zero_extend:DI (match_dup 3)))
6526 "!TARGET_64BIT && TARGET_BMI2
6527 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6528 "mulx\t{%3, %0, %1|%1, %0, %3}"
6529 [(set_attr "type" "imulx")
6530 (set_attr "prefix" "vex")
6531 (set_attr "mode" "SI")])
6533 (define_insn "*umul<mode><dwi>3_1"
6534 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6537 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6539 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6540 (clobber (reg:CC FLAGS_REG))]
6541 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6544 mul{<imodesuffix>}\t%2"
6545 [(set_attr "isa" "bmi2,*")
6546 (set_attr "type" "imulx,imul")
6547 (set_attr "length_immediate" "*,0")
6548 (set (attr "athlon_decode")
6549 (cond [(eq_attr "alternative" "1")
6550 (if_then_else (eq_attr "cpu" "athlon")
6551 (const_string "vector")
6552 (const_string "double"))]
6553 (const_string "*")))
6554 (set_attr "amdfam10_decode" "*,double")
6555 (set_attr "bdver1_decode" "*,direct")
6556 (set_attr "prefix" "vex,orig")
6557 (set_attr "mode" "<MODE>")])
6559 ;; Convert mul to the mulx pattern to avoid flags dependency.
6561 [(set (match_operand:<DWI> 0 "register_operand")
6564 (match_operand:DWIH 1 "register_operand"))
6566 (match_operand:DWIH 2 "nonimmediate_operand"))))
6567 (clobber (reg:CC FLAGS_REG))]
6568 "TARGET_BMI2 && reload_completed
6569 && true_regnum (operands[1]) == DX_REG"
6570 [(parallel [(set (match_dup 3)
6571 (mult:DWIH (match_dup 1) (match_dup 2)))
6575 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6576 (zero_extend:<DWI> (match_dup 2)))
6579 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6581 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6584 (define_insn "*mul<mode><dwi>3_1"
6585 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6588 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6590 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6591 (clobber (reg:CC FLAGS_REG))]
6592 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6593 "imul{<imodesuffix>}\t%2"
6594 [(set_attr "type" "imul")
6595 (set_attr "length_immediate" "0")
6596 (set (attr "athlon_decode")
6597 (if_then_else (eq_attr "cpu" "athlon")
6598 (const_string "vector")
6599 (const_string "double")))
6600 (set_attr "amdfam10_decode" "double")
6601 (set_attr "bdver1_decode" "direct")
6602 (set_attr "mode" "<MODE>")])
6604 (define_insn "*<u>mulqihi3_1"
6605 [(set (match_operand:HI 0 "register_operand" "=a")
6608 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6610 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6611 (clobber (reg:CC FLAGS_REG))]
6613 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6614 "<sgnprefix>mul{b}\t%2"
6615 [(set_attr "type" "imul")
6616 (set_attr "length_immediate" "0")
6617 (set (attr "athlon_decode")
6618 (if_then_else (eq_attr "cpu" "athlon")
6619 (const_string "vector")
6620 (const_string "direct")))
6621 (set_attr "amdfam10_decode" "direct")
6622 (set_attr "bdver1_decode" "direct")
6623 (set_attr "mode" "QI")])
6625 (define_expand "<s>mul<mode>3_highpart"
6626 [(parallel [(set (match_operand:SWI48 0 "register_operand")
6631 (match_operand:SWI48 1 "nonimmediate_operand"))
6633 (match_operand:SWI48 2 "register_operand")))
6635 (clobber (match_scratch:SWI48 3))
6636 (clobber (reg:CC FLAGS_REG))])]
6638 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6640 (define_insn "*<s>muldi3_highpart_1"
6641 [(set (match_operand:DI 0 "register_operand" "=d")
6646 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6648 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6650 (clobber (match_scratch:DI 3 "=1"))
6651 (clobber (reg:CC FLAGS_REG))]
6653 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6654 "<sgnprefix>mul{q}\t%2"
6655 [(set_attr "type" "imul")
6656 (set_attr "length_immediate" "0")
6657 (set (attr "athlon_decode")
6658 (if_then_else (eq_attr "cpu" "athlon")
6659 (const_string "vector")
6660 (const_string "double")))
6661 (set_attr "amdfam10_decode" "double")
6662 (set_attr "bdver1_decode" "direct")
6663 (set_attr "mode" "DI")])
6665 (define_insn "*<s>mulsi3_highpart_1"
6666 [(set (match_operand:SI 0 "register_operand" "=d")
6671 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6673 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6675 (clobber (match_scratch:SI 3 "=1"))
6676 (clobber (reg:CC FLAGS_REG))]
6677 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6678 "<sgnprefix>mul{l}\t%2"
6679 [(set_attr "type" "imul")
6680 (set_attr "length_immediate" "0")
6681 (set (attr "athlon_decode")
6682 (if_then_else (eq_attr "cpu" "athlon")
6683 (const_string "vector")
6684 (const_string "double")))
6685 (set_attr "amdfam10_decode" "double")
6686 (set_attr "bdver1_decode" "direct")
6687 (set_attr "mode" "SI")])
6689 (define_insn "*<s>mulsi3_highpart_zext"
6690 [(set (match_operand:DI 0 "register_operand" "=d")
6691 (zero_extend:DI (truncate:SI
6693 (mult:DI (any_extend:DI
6694 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6696 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6698 (clobber (match_scratch:SI 3 "=1"))
6699 (clobber (reg:CC FLAGS_REG))]
6701 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6702 "<sgnprefix>mul{l}\t%2"
6703 [(set_attr "type" "imul")
6704 (set_attr "length_immediate" "0")
6705 (set (attr "athlon_decode")
6706 (if_then_else (eq_attr "cpu" "athlon")
6707 (const_string "vector")
6708 (const_string "double")))
6709 (set_attr "amdfam10_decode" "double")
6710 (set_attr "bdver1_decode" "direct")
6711 (set_attr "mode" "SI")])
6713 ;; The patterns that match these are at the end of this file.
6715 (define_expand "mulxf3"
6716 [(set (match_operand:XF 0 "register_operand")
6717 (mult:XF (match_operand:XF 1 "register_operand")
6718 (match_operand:XF 2 "register_operand")))]
6721 (define_expand "mul<mode>3"
6722 [(set (match_operand:MODEF 0 "register_operand")
6723 (mult:MODEF (match_operand:MODEF 1 "register_operand")
6724 (match_operand:MODEF 2 "nonimmediate_operand")))]
6725 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6726 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6728 ;; Divide instructions
6730 ;; The patterns that match these are at the end of this file.
6732 (define_expand "divxf3"
6733 [(set (match_operand:XF 0 "register_operand")
6734 (div:XF (match_operand:XF 1 "register_operand")
6735 (match_operand:XF 2 "register_operand")))]
6738 (define_expand "divdf3"
6739 [(set (match_operand:DF 0 "register_operand")
6740 (div:DF (match_operand:DF 1 "register_operand")
6741 (match_operand:DF 2 "nonimmediate_operand")))]
6742 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
6743 || (TARGET_SSE2 && TARGET_SSE_MATH)")
6745 (define_expand "divsf3"
6746 [(set (match_operand:SF 0 "register_operand")
6747 (div:SF (match_operand:SF 1 "register_operand")
6748 (match_operand:SF 2 "nonimmediate_operand")))]
6749 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
6754 && optimize_insn_for_speed_p ()
6755 && flag_finite_math_only && !flag_trapping_math
6756 && flag_unsafe_math_optimizations)
6758 ix86_emit_swdivsf (operands[0], operands[1],
6759 operands[2], SFmode);
6764 ;; Divmod instructions.
6766 (define_expand "divmod<mode>4"
6767 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6769 (match_operand:SWIM248 1 "register_operand")
6770 (match_operand:SWIM248 2 "nonimmediate_operand")))
6771 (set (match_operand:SWIM248 3 "register_operand")
6772 (mod:SWIM248 (match_dup 1) (match_dup 2)))
6773 (clobber (reg:CC FLAGS_REG))])])
6775 ;; Split with 8bit unsigned divide:
6776 ;; if (dividend an divisor are in [0-255])
6777 ;; use 8bit unsigned integer divide
6779 ;; use original integer divide
6781 [(set (match_operand:SWI48 0 "register_operand")
6782 (div:SWI48 (match_operand:SWI48 2 "register_operand")
6783 (match_operand:SWI48 3 "nonimmediate_operand")))
6784 (set (match_operand:SWI48 1 "register_operand")
6785 (mod:SWI48 (match_dup 2) (match_dup 3)))
6786 (clobber (reg:CC FLAGS_REG))]
6787 "TARGET_USE_8BIT_IDIV
6788 && TARGET_QIMODE_MATH
6789 && can_create_pseudo_p ()
6790 && !optimize_insn_for_size_p ()"
6792 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
6794 (define_insn_and_split "divmod<mode>4_1"
6795 [(set (match_operand:SWI48 0 "register_operand" "=a")
6796 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
6797 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
6798 (set (match_operand:SWI48 1 "register_operand" "=&d")
6799 (mod:SWI48 (match_dup 2) (match_dup 3)))
6800 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
6801 (clobber (reg:CC FLAGS_REG))]
6805 [(parallel [(set (match_dup 1)
6806 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
6807 (clobber (reg:CC FLAGS_REG))])
6808 (parallel [(set (match_dup 0)
6809 (div:SWI48 (match_dup 2) (match_dup 3)))
6811 (mod:SWI48 (match_dup 2) (match_dup 3)))
6813 (clobber (reg:CC FLAGS_REG))])]
6815 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
6817 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
6818 operands[4] = operands[2];
6821 /* Avoid use of cltd in favor of a mov+shift. */
6822 emit_move_insn (operands[1], operands[2]);
6823 operands[4] = operands[1];
6826 [(set_attr "type" "multi")
6827 (set_attr "mode" "<MODE>")])
6829 (define_insn_and_split "*divmod<mode>4"
6830 [(set (match_operand:SWIM248 0 "register_operand" "=a")
6831 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
6832 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
6833 (set (match_operand:SWIM248 1 "register_operand" "=&d")
6834 (mod:SWIM248 (match_dup 2) (match_dup 3)))
6835 (clobber (reg:CC FLAGS_REG))]
6839 [(parallel [(set (match_dup 1)
6840 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
6841 (clobber (reg:CC FLAGS_REG))])
6842 (parallel [(set (match_dup 0)
6843 (div:SWIM248 (match_dup 2) (match_dup 3)))
6845 (mod:SWIM248 (match_dup 2) (match_dup 3)))
6847 (clobber (reg:CC FLAGS_REG))])]
6849 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
6851 if (<MODE>mode != HImode
6852 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
6853 operands[4] = operands[2];
6856 /* Avoid use of cltd in favor of a mov+shift. */
6857 emit_move_insn (operands[1], operands[2]);
6858 operands[4] = operands[1];
6861 [(set_attr "type" "multi")
6862 (set_attr "mode" "<MODE>")])
6864 (define_insn "*divmod<mode>4_noext"
6865 [(set (match_operand:SWIM248 0 "register_operand" "=a")
6866 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
6867 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
6868 (set (match_operand:SWIM248 1 "register_operand" "=d")
6869 (mod:SWIM248 (match_dup 2) (match_dup 3)))
6870 (use (match_operand:SWIM248 4 "register_operand" "1"))
6871 (clobber (reg:CC FLAGS_REG))]
6873 "idiv{<imodesuffix>}\t%3"
6874 [(set_attr "type" "idiv")
6875 (set_attr "mode" "<MODE>")])
6877 (define_expand "divmodqi4"
6878 [(parallel [(set (match_operand:QI 0 "register_operand")
6880 (match_operand:QI 1 "register_operand")
6881 (match_operand:QI 2 "nonimmediate_operand")))
6882 (set (match_operand:QI 3 "register_operand")
6883 (mod:QI (match_dup 1) (match_dup 2)))
6884 (clobber (reg:CC FLAGS_REG))])]
6885 "TARGET_QIMODE_MATH"
6890 tmp0 = gen_reg_rtx (HImode);
6891 tmp1 = gen_reg_rtx (HImode);
6893 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
6895 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
6896 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
6898 /* Extract remainder from AH. */
6899 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
6900 insn = emit_move_insn (operands[3], tmp1);
6902 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
6903 set_unique_reg_note (insn, REG_EQUAL, mod);
6905 /* Extract quotient from AL. */
6906 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
6908 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
6909 set_unique_reg_note (insn, REG_EQUAL, div);
6914 ;; Divide AX by r/m8, with result stored in
6917 ;; Change div/mod to HImode and extend the second argument to HImode
6918 ;; so that mode of div/mod matches with mode of arguments. Otherwise
6919 ;; combine may fail.
6920 (define_insn "divmodhiqi3"
6921 [(set (match_operand:HI 0 "register_operand" "=a")
6926 (mod:HI (match_operand:HI 1 "register_operand" "0")
6928 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
6932 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
6933 (clobber (reg:CC FLAGS_REG))]
6934 "TARGET_QIMODE_MATH"
6936 [(set_attr "type" "idiv")
6937 (set_attr "mode" "QI")])
6939 (define_expand "udivmod<mode>4"
6940 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6942 (match_operand:SWIM248 1 "register_operand")
6943 (match_operand:SWIM248 2 "nonimmediate_operand")))
6944 (set (match_operand:SWIM248 3 "register_operand")
6945 (umod:SWIM248 (match_dup 1) (match_dup 2)))
6946 (clobber (reg:CC FLAGS_REG))])])
6948 ;; Split with 8bit unsigned divide:
6949 ;; if (dividend an divisor are in [0-255])
6950 ;; use 8bit unsigned integer divide
6952 ;; use original integer divide
6954 [(set (match_operand:SWI48 0 "register_operand")
6955 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
6956 (match_operand:SWI48 3 "nonimmediate_operand")))
6957 (set (match_operand:SWI48 1 "register_operand")
6958 (umod:SWI48 (match_dup 2) (match_dup 3)))
6959 (clobber (reg:CC FLAGS_REG))]
6960 "TARGET_USE_8BIT_IDIV
6961 && TARGET_QIMODE_MATH
6962 && can_create_pseudo_p ()
6963 && !optimize_insn_for_size_p ()"
6965 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
6967 (define_insn_and_split "udivmod<mode>4_1"
6968 [(set (match_operand:SWI48 0 "register_operand" "=a")
6969 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
6970 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
6971 (set (match_operand:SWI48 1 "register_operand" "=&d")
6972 (umod:SWI48 (match_dup 2) (match_dup 3)))
6973 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
6974 (clobber (reg:CC FLAGS_REG))]
6978 [(set (match_dup 1) (const_int 0))
6979 (parallel [(set (match_dup 0)
6980 (udiv:SWI48 (match_dup 2) (match_dup 3)))
6982 (umod:SWI48 (match_dup 2) (match_dup 3)))
6984 (clobber (reg:CC FLAGS_REG))])]
6986 [(set_attr "type" "multi")
6987 (set_attr "mode" "<MODE>")])
6989 (define_insn_and_split "*udivmod<mode>4"
6990 [(set (match_operand:SWIM248 0 "register_operand" "=a")
6991 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
6992 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
6993 (set (match_operand:SWIM248 1 "register_operand" "=&d")
6994 (umod:SWIM248 (match_dup 2) (match_dup 3)))
6995 (clobber (reg:CC FLAGS_REG))]
6999 [(set (match_dup 1) (const_int 0))
7000 (parallel [(set (match_dup 0)
7001 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7003 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7005 (clobber (reg:CC FLAGS_REG))])]
7007 [(set_attr "type" "multi")
7008 (set_attr "mode" "<MODE>")])
7010 (define_insn "*udivmod<mode>4_noext"
7011 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7012 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7013 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7014 (set (match_operand:SWIM248 1 "register_operand" "=d")
7015 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7016 (use (match_operand:SWIM248 4 "register_operand" "1"))
7017 (clobber (reg:CC FLAGS_REG))]
7019 "div{<imodesuffix>}\t%3"
7020 [(set_attr "type" "idiv")
7021 (set_attr "mode" "<MODE>")])
7023 (define_expand "udivmodqi4"
7024 [(parallel [(set (match_operand:QI 0 "register_operand")
7026 (match_operand:QI 1 "register_operand")
7027 (match_operand:QI 2 "nonimmediate_operand")))
7028 (set (match_operand:QI 3 "register_operand")
7029 (umod:QI (match_dup 1) (match_dup 2)))
7030 (clobber (reg:CC FLAGS_REG))])]
7031 "TARGET_QIMODE_MATH"
7036 tmp0 = gen_reg_rtx (HImode);
7037 tmp1 = gen_reg_rtx (HImode);
7039 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7041 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7042 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7044 /* Extract remainder from AH. */
7045 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7046 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7047 insn = emit_move_insn (operands[3], tmp1);
7049 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7050 set_unique_reg_note (insn, REG_EQUAL, mod);
7052 /* Extract quotient from AL. */
7053 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7055 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7056 set_unique_reg_note (insn, REG_EQUAL, div);
7061 (define_insn "udivmodhiqi3"
7062 [(set (match_operand:HI 0 "register_operand" "=a")
7067 (mod:HI (match_operand:HI 1 "register_operand" "0")
7069 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7073 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7074 (clobber (reg:CC FLAGS_REG))]
7075 "TARGET_QIMODE_MATH"
7077 [(set_attr "type" "idiv")
7078 (set_attr "mode" "QI")])
7080 ;; We cannot use div/idiv for double division, because it causes
7081 ;; "division by zero" on the overflow and that's not what we expect
7082 ;; from truncate. Because true (non truncating) double division is
7083 ;; never generated, we can't create this insn anyway.
7086 ; [(set (match_operand:SI 0 "register_operand" "=a")
7088 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7090 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7091 ; (set (match_operand:SI 3 "register_operand" "=d")
7093 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7094 ; (clobber (reg:CC FLAGS_REG))]
7096 ; "div{l}\t{%2, %0|%0, %2}"
7097 ; [(set_attr "type" "idiv")])
7099 ;;- Logical AND instructions
7101 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7102 ;; Note that this excludes ah.
7104 (define_expand "testsi_ccno_1"
7105 [(set (reg:CCNO FLAGS_REG)
7107 (and:SI (match_operand:SI 0 "nonimmediate_operand")
7108 (match_operand:SI 1 "x86_64_nonmemory_operand"))
7111 (define_expand "testqi_ccz_1"
7112 [(set (reg:CCZ FLAGS_REG)
7113 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7114 (match_operand:QI 1 "nonmemory_operand"))
7117 (define_expand "testdi_ccno_1"
7118 [(set (reg:CCNO FLAGS_REG)
7120 (and:DI (match_operand:DI 0 "nonimmediate_operand")
7121 (match_operand:DI 1 "x86_64_szext_general_operand"))
7123 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7125 (define_insn "*testdi_1"
7126 [(set (reg FLAGS_REG)
7129 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7130 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7132 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7133 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7135 test{l}\t{%k1, %k0|%k0, %k1}
7136 test{l}\t{%k1, %k0|%k0, %k1}
7137 test{q}\t{%1, %0|%0, %1}
7138 test{q}\t{%1, %0|%0, %1}
7139 test{q}\t{%1, %0|%0, %1}"
7140 [(set_attr "type" "test")
7141 (set_attr "modrm" "0,1,0,1,1")
7142 (set_attr "mode" "SI,SI,DI,DI,DI")])
7144 (define_insn "*testqi_1_maybe_si"
7145 [(set (reg FLAGS_REG)
7148 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7149 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7151 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7152 && ix86_match_ccmode (insn,
7153 CONST_INT_P (operands[1])
7154 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7156 if (which_alternative == 3)
7158 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7159 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7160 return "test{l}\t{%1, %k0|%k0, %1}";
7162 return "test{b}\t{%1, %0|%0, %1}";
7164 [(set_attr "type" "test")
7165 (set_attr "modrm" "0,1,1,1")
7166 (set_attr "mode" "QI,QI,QI,SI")
7167 (set_attr "pent_pair" "uv,np,uv,np")])
7169 (define_insn "*test<mode>_1"
7170 [(set (reg FLAGS_REG)
7173 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7174 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7176 "ix86_match_ccmode (insn, CCNOmode)
7177 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7178 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7179 [(set_attr "type" "test")
7180 (set_attr "modrm" "0,1,1")
7181 (set_attr "mode" "<MODE>")
7182 (set_attr "pent_pair" "uv,np,uv")])
7184 (define_expand "testqi_ext_ccno_0"
7185 [(set (reg:CCNO FLAGS_REG)
7189 (match_operand 0 "ext_register_operand")
7192 (match_operand 1 "const_int_operand"))
7195 (define_insn "*testqi_ext_0"
7196 [(set (reg FLAGS_REG)
7200 (match_operand 0 "ext_register_operand" "Q")
7203 (match_operand 1 "const_int_operand" "n"))
7205 "ix86_match_ccmode (insn, CCNOmode)"
7206 "test{b}\t{%1, %h0|%h0, %1}"
7207 [(set_attr "type" "test")
7208 (set_attr "mode" "QI")
7209 (set_attr "length_immediate" "1")
7210 (set_attr "modrm" "1")
7211 (set_attr "pent_pair" "np")])
7213 (define_insn "*testqi_ext_1_rex64"
7214 [(set (reg FLAGS_REG)
7218 (match_operand 0 "ext_register_operand" "Q")
7222 (match_operand:QI 1 "register_operand" "Q")))
7224 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7225 "test{b}\t{%1, %h0|%h0, %1}"
7226 [(set_attr "type" "test")
7227 (set_attr "mode" "QI")])
7229 (define_insn "*testqi_ext_1"
7230 [(set (reg FLAGS_REG)
7234 (match_operand 0 "ext_register_operand" "Q")
7238 (match_operand:QI 1 "general_operand" "Qm")))
7240 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7241 "test{b}\t{%1, %h0|%h0, %1}"
7242 [(set_attr "type" "test")
7243 (set_attr "mode" "QI")])
7245 (define_insn "*testqi_ext_2"
7246 [(set (reg FLAGS_REG)
7250 (match_operand 0 "ext_register_operand" "Q")
7254 (match_operand 1 "ext_register_operand" "Q")
7258 "ix86_match_ccmode (insn, CCNOmode)"
7259 "test{b}\t{%h1, %h0|%h0, %h1}"
7260 [(set_attr "type" "test")
7261 (set_attr "mode" "QI")])
7263 (define_insn "*testqi_ext_3_rex64"
7264 [(set (reg FLAGS_REG)
7265 (compare (zero_extract:DI
7266 (match_operand 0 "nonimmediate_operand" "rm")
7267 (match_operand:DI 1 "const_int_operand")
7268 (match_operand:DI 2 "const_int_operand"))
7271 && ix86_match_ccmode (insn, CCNOmode)
7272 && INTVAL (operands[1]) > 0
7273 && INTVAL (operands[2]) >= 0
7274 /* Ensure that resulting mask is zero or sign extended operand. */
7275 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7276 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7277 && INTVAL (operands[1]) > 32))
7278 && (GET_MODE (operands[0]) == SImode
7279 || GET_MODE (operands[0]) == DImode
7280 || GET_MODE (operands[0]) == HImode
7281 || GET_MODE (operands[0]) == QImode)"
7284 ;; Combine likes to form bit extractions for some tests. Humor it.
7285 (define_insn "*testqi_ext_3"
7286 [(set (reg FLAGS_REG)
7287 (compare (zero_extract:SI
7288 (match_operand 0 "nonimmediate_operand" "rm")
7289 (match_operand:SI 1 "const_int_operand")
7290 (match_operand:SI 2 "const_int_operand"))
7292 "ix86_match_ccmode (insn, CCNOmode)
7293 && INTVAL (operands[1]) > 0
7294 && INTVAL (operands[2]) >= 0
7295 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7296 && (GET_MODE (operands[0]) == SImode
7297 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7298 || GET_MODE (operands[0]) == HImode
7299 || GET_MODE (operands[0]) == QImode)"
7303 [(set (match_operand 0 "flags_reg_operand")
7304 (match_operator 1 "compare_operator"
7306 (match_operand 2 "nonimmediate_operand")
7307 (match_operand 3 "const_int_operand")
7308 (match_operand 4 "const_int_operand"))
7310 "ix86_match_ccmode (insn, CCNOmode)"
7311 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7313 rtx val = operands[2];
7314 HOST_WIDE_INT len = INTVAL (operands[3]);
7315 HOST_WIDE_INT pos = INTVAL (operands[4]);
7317 enum machine_mode mode, submode;
7319 mode = GET_MODE (val);
7322 /* ??? Combine likes to put non-volatile mem extractions in QImode
7323 no matter the size of the test. So find a mode that works. */
7324 if (! MEM_VOLATILE_P (val))
7326 mode = smallest_mode_for_size (pos + len, MODE_INT);
7327 val = adjust_address (val, mode, 0);
7330 else if (GET_CODE (val) == SUBREG
7331 && (submode = GET_MODE (SUBREG_REG (val)),
7332 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7333 && pos + len <= GET_MODE_BITSIZE (submode)
7334 && GET_MODE_CLASS (submode) == MODE_INT)
7336 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7338 val = SUBREG_REG (val);
7340 else if (mode == HImode && pos + len <= 8)
7342 /* Small HImode tests can be converted to QImode. */
7344 val = gen_lowpart (QImode, val);
7347 if (len == HOST_BITS_PER_WIDE_INT)
7350 mask = ((HOST_WIDE_INT)1 << len) - 1;
7353 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7356 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7357 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7358 ;; this is relatively important trick.
7359 ;; Do the conversion only post-reload to avoid limiting of the register class
7362 [(set (match_operand 0 "flags_reg_operand")
7363 (match_operator 1 "compare_operator"
7364 [(and (match_operand 2 "register_operand")
7365 (match_operand 3 "const_int_operand"))
7368 && QI_REG_P (operands[2])
7369 && GET_MODE (operands[2]) != QImode
7370 && ((ix86_match_ccmode (insn, CCZmode)
7371 && !(INTVAL (operands[3]) & ~(255 << 8)))
7372 || (ix86_match_ccmode (insn, CCNOmode)
7373 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7376 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7380 operands[2] = gen_lowpart (SImode, operands[2]);
7381 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7385 [(set (match_operand 0 "flags_reg_operand")
7386 (match_operator 1 "compare_operator"
7387 [(and (match_operand 2 "nonimmediate_operand")
7388 (match_operand 3 "const_int_operand"))
7391 && GET_MODE (operands[2]) != QImode
7392 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7393 && ((ix86_match_ccmode (insn, CCZmode)
7394 && !(INTVAL (operands[3]) & ~255))
7395 || (ix86_match_ccmode (insn, CCNOmode)
7396 && !(INTVAL (operands[3]) & ~127)))"
7398 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7401 operands[2] = gen_lowpart (QImode, operands[2]);
7402 operands[3] = gen_lowpart (QImode, operands[3]);
7405 ;; %%% This used to optimize known byte-wide and operations to memory,
7406 ;; and sometimes to QImode registers. If this is considered useful,
7407 ;; it should be done with splitters.
7409 (define_expand "and<mode>3"
7410 [(set (match_operand:SWIM 0 "nonimmediate_operand")
7411 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7412 (match_operand:SWIM 2 "<general_szext_operand>")))]
7415 enum machine_mode mode = <MODE>mode;
7416 rtx (*insn) (rtx, rtx);
7418 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7420 HOST_WIDE_INT ival = INTVAL (operands[2]);
7422 if (ival == (HOST_WIDE_INT) 0xffffffff)
7424 else if (ival == 0xffff)
7426 else if (ival == 0xff)
7430 if (mode == <MODE>mode)
7432 ix86_expand_binary_operator (AND, <MODE>mode, operands);
7436 if (<MODE>mode == DImode)
7437 insn = (mode == SImode)
7438 ? gen_zero_extendsidi2
7440 ? gen_zero_extendhidi2
7441 : gen_zero_extendqidi2;
7442 else if (<MODE>mode == SImode)
7443 insn = (mode == HImode)
7444 ? gen_zero_extendhisi2
7445 : gen_zero_extendqisi2;
7446 else if (<MODE>mode == HImode)
7447 insn = gen_zero_extendqihi2;
7451 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7455 (define_insn "*anddi_1"
7456 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7458 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7459 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7460 (clobber (reg:CC FLAGS_REG))]
7461 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7463 switch (get_attr_type (insn))
7469 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7470 if (get_attr_mode (insn) == MODE_SI)
7471 return "and{l}\t{%k2, %k0|%k0, %k2}";
7473 return "and{q}\t{%2, %0|%0, %2}";
7476 [(set_attr "type" "alu,alu,alu,imovx")
7477 (set_attr "length_immediate" "*,*,*,0")
7478 (set (attr "prefix_rex")
7480 (and (eq_attr "type" "imovx")
7481 (and (match_test "INTVAL (operands[2]) == 0xff")
7482 (match_operand 1 "ext_QIreg_operand")))
7484 (const_string "*")))
7485 (set_attr "mode" "SI,DI,DI,SI")])
7487 (define_insn "*andsi_1"
7488 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya")
7489 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7490 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7491 (clobber (reg:CC FLAGS_REG))]
7492 "ix86_binary_operator_ok (AND, SImode, operands)"
7494 switch (get_attr_type (insn))
7500 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7501 return "and{l}\t{%2, %0|%0, %2}";
7504 [(set_attr "type" "alu,alu,imovx")
7505 (set (attr "prefix_rex")
7507 (and (eq_attr "type" "imovx")
7508 (and (match_test "INTVAL (operands[2]) == 0xff")
7509 (match_operand 1 "ext_QIreg_operand")))
7511 (const_string "*")))
7512 (set_attr "length_immediate" "*,*,0")
7513 (set_attr "mode" "SI")])
7515 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7516 (define_insn "*andsi_1_zext"
7517 [(set (match_operand:DI 0 "register_operand" "=r")
7519 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7520 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7521 (clobber (reg:CC FLAGS_REG))]
7522 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7523 "and{l}\t{%2, %k0|%k0, %2}"
7524 [(set_attr "type" "alu")
7525 (set_attr "mode" "SI")])
7527 (define_insn "*andhi_1"
7528 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya")
7529 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7530 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7531 (clobber (reg:CC FLAGS_REG))]
7532 "ix86_binary_operator_ok (AND, HImode, operands)"
7534 switch (get_attr_type (insn))
7540 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7541 return "and{w}\t{%2, %0|%0, %2}";
7544 [(set_attr "type" "alu,alu,imovx")
7545 (set_attr "length_immediate" "*,*,0")
7546 (set (attr "prefix_rex")
7548 (and (eq_attr "type" "imovx")
7549 (match_operand 1 "ext_QIreg_operand"))
7551 (const_string "*")))
7552 (set_attr "mode" "HI,HI,SI")])
7554 ;; %%% Potential partial reg stall on alternative 2. What to do?
7555 (define_insn "*andqi_1"
7556 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7557 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7558 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7559 (clobber (reg:CC FLAGS_REG))]
7560 "ix86_binary_operator_ok (AND, QImode, operands)"
7562 and{b}\t{%2, %0|%0, %2}
7563 and{b}\t{%2, %0|%0, %2}
7564 and{l}\t{%k2, %k0|%k0, %k2}"
7565 [(set_attr "type" "alu")
7566 (set_attr "mode" "QI,QI,SI")])
7568 (define_insn "*andqi_1_slp"
7569 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7570 (and:QI (match_dup 0)
7571 (match_operand:QI 1 "general_operand" "qn,qmn")))
7572 (clobber (reg:CC FLAGS_REG))]
7573 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7574 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7575 "and{b}\t{%1, %0|%0, %1}"
7576 [(set_attr "type" "alu1")
7577 (set_attr "mode" "QI")])
7579 ;; Turn *anddi_1 into *andsi_1_zext if possible.
7581 [(set (match_operand:DI 0 "register_operand")
7582 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
7583 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
7584 (clobber (reg:CC FLAGS_REG))]
7586 [(parallel [(set (match_dup 0)
7587 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
7588 (clobber (reg:CC FLAGS_REG))])]
7589 "operands[2] = gen_lowpart (SImode, operands[2]);")
7592 [(set (match_operand:SWI248 0 "register_operand")
7593 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
7594 (match_operand:SWI248 2 "const_int_operand")))
7595 (clobber (reg:CC FLAGS_REG))]
7597 && true_regnum (operands[0]) != true_regnum (operands[1])"
7600 HOST_WIDE_INT ival = INTVAL (operands[2]);
7601 enum machine_mode mode;
7602 rtx (*insn) (rtx, rtx);
7604 if (ival == (HOST_WIDE_INT) 0xffffffff)
7606 else if (ival == 0xffff)
7610 gcc_assert (ival == 0xff);
7614 if (<MODE>mode == DImode)
7615 insn = (mode == SImode)
7616 ? gen_zero_extendsidi2
7618 ? gen_zero_extendhidi2
7619 : gen_zero_extendqidi2;
7622 if (<MODE>mode != SImode)
7623 /* Zero extend to SImode to avoid partial register stalls. */
7624 operands[0] = gen_lowpart (SImode, operands[0]);
7626 insn = (mode == HImode)
7627 ? gen_zero_extendhisi2
7628 : gen_zero_extendqisi2;
7630 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7635 [(set (match_operand 0 "register_operand")
7637 (const_int -65536)))
7638 (clobber (reg:CC FLAGS_REG))]
7639 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7640 || optimize_function_for_size_p (cfun)"
7641 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7642 "operands[1] = gen_lowpart (HImode, operands[0]);")
7645 [(set (match_operand 0 "ext_register_operand")
7648 (clobber (reg:CC FLAGS_REG))]
7649 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7650 && reload_completed"
7651 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7652 "operands[1] = gen_lowpart (QImode, operands[0]);")
7655 [(set (match_operand 0 "ext_register_operand")
7657 (const_int -65281)))
7658 (clobber (reg:CC FLAGS_REG))]
7659 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7660 && reload_completed"
7661 [(parallel [(set (zero_extract:SI (match_dup 0)
7665 (zero_extract:SI (match_dup 0)
7668 (zero_extract:SI (match_dup 0)
7671 (clobber (reg:CC FLAGS_REG))])]
7672 "operands[0] = gen_lowpart (SImode, operands[0]);")
7674 (define_insn "*anddi_2"
7675 [(set (reg FLAGS_REG)
7678 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7679 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7681 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7682 (and:DI (match_dup 1) (match_dup 2)))]
7683 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7684 && ix86_binary_operator_ok (AND, DImode, operands)"
7686 and{l}\t{%k2, %k0|%k0, %k2}
7687 and{q}\t{%2, %0|%0, %2}
7688 and{q}\t{%2, %0|%0, %2}"
7689 [(set_attr "type" "alu")
7690 (set_attr "mode" "SI,DI,DI")])
7692 (define_insn "*andqi_2_maybe_si"
7693 [(set (reg FLAGS_REG)
7695 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7696 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7698 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7699 (and:QI (match_dup 1) (match_dup 2)))]
7700 "ix86_binary_operator_ok (AND, QImode, operands)
7701 && ix86_match_ccmode (insn,
7702 CONST_INT_P (operands[2])
7703 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7705 if (which_alternative == 2)
7707 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7708 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7709 return "and{l}\t{%2, %k0|%k0, %2}";
7711 return "and{b}\t{%2, %0|%0, %2}";
7713 [(set_attr "type" "alu")
7714 (set_attr "mode" "QI,QI,SI")])
7716 (define_insn "*and<mode>_2"
7717 [(set (reg FLAGS_REG)
7718 (compare (and:SWI124
7719 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7720 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7722 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7723 (and:SWI124 (match_dup 1) (match_dup 2)))]
7724 "ix86_match_ccmode (insn, CCNOmode)
7725 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7726 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7727 [(set_attr "type" "alu")
7728 (set_attr "mode" "<MODE>")])
7730 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7731 (define_insn "*andsi_2_zext"
7732 [(set (reg FLAGS_REG)
7734 (match_operand:SI 1 "nonimmediate_operand" "%0")
7735 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7737 (set (match_operand:DI 0 "register_operand" "=r")
7738 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7739 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7740 && ix86_binary_operator_ok (AND, SImode, operands)"
7741 "and{l}\t{%2, %k0|%k0, %2}"
7742 [(set_attr "type" "alu")
7743 (set_attr "mode" "SI")])
7745 (define_insn "*andqi_2_slp"
7746 [(set (reg FLAGS_REG)
7748 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7749 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
7751 (set (strict_low_part (match_dup 0))
7752 (and:QI (match_dup 0) (match_dup 1)))]
7753 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7754 && ix86_match_ccmode (insn, CCNOmode)
7755 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7756 "and{b}\t{%1, %0|%0, %1}"
7757 [(set_attr "type" "alu1")
7758 (set_attr "mode" "QI")])
7760 ;; ??? A bug in recog prevents it from recognizing a const_int as an
7761 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
7762 ;; for a QImode operand, which of course failed.
7763 (define_insn "andqi_ext_0"
7764 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7769 (match_operand 1 "ext_register_operand" "0")
7772 (match_operand 2 "const_int_operand" "n")))
7773 (clobber (reg:CC FLAGS_REG))]
7775 "and{b}\t{%2, %h0|%h0, %2}"
7776 [(set_attr "type" "alu")
7777 (set_attr "length_immediate" "1")
7778 (set_attr "modrm" "1")
7779 (set_attr "mode" "QI")])
7781 ;; Generated by peephole translating test to and. This shows up
7782 ;; often in fp comparisons.
7783 (define_insn "*andqi_ext_0_cc"
7784 [(set (reg FLAGS_REG)
7788 (match_operand 1 "ext_register_operand" "0")
7791 (match_operand 2 "const_int_operand" "n"))
7793 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7802 "ix86_match_ccmode (insn, CCNOmode)"
7803 "and{b}\t{%2, %h0|%h0, %2}"
7804 [(set_attr "type" "alu")
7805 (set_attr "length_immediate" "1")
7806 (set_attr "modrm" "1")
7807 (set_attr "mode" "QI")])
7809 (define_insn "*andqi_ext_1_rex64"
7810 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7815 (match_operand 1 "ext_register_operand" "0")
7819 (match_operand 2 "ext_register_operand" "Q"))))
7820 (clobber (reg:CC FLAGS_REG))]
7822 "and{b}\t{%2, %h0|%h0, %2}"
7823 [(set_attr "type" "alu")
7824 (set_attr "length_immediate" "0")
7825 (set_attr "mode" "QI")])
7827 (define_insn "*andqi_ext_1"
7828 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7833 (match_operand 1 "ext_register_operand" "0")
7837 (match_operand:QI 2 "general_operand" "Qm"))))
7838 (clobber (reg:CC FLAGS_REG))]
7840 "and{b}\t{%2, %h0|%h0, %2}"
7841 [(set_attr "type" "alu")
7842 (set_attr "length_immediate" "0")
7843 (set_attr "mode" "QI")])
7845 (define_insn "*andqi_ext_2"
7846 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7851 (match_operand 1 "ext_register_operand" "%0")
7855 (match_operand 2 "ext_register_operand" "Q")
7858 (clobber (reg:CC FLAGS_REG))]
7860 "and{b}\t{%h2, %h0|%h0, %h2}"
7861 [(set_attr "type" "alu")
7862 (set_attr "length_immediate" "0")
7863 (set_attr "mode" "QI")])
7865 ;; Convert wide AND instructions with immediate operand to shorter QImode
7866 ;; equivalents when possible.
7867 ;; Don't do the splitting with memory operands, since it introduces risk
7868 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
7869 ;; for size, but that can (should?) be handled by generic code instead.
7871 [(set (match_operand 0 "register_operand")
7872 (and (match_operand 1 "register_operand")
7873 (match_operand 2 "const_int_operand")))
7874 (clobber (reg:CC FLAGS_REG))]
7876 && QI_REG_P (operands[0])
7877 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7878 && !(~INTVAL (operands[2]) & ~(255 << 8))
7879 && GET_MODE (operands[0]) != QImode"
7880 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
7881 (and:SI (zero_extract:SI (match_dup 1)
7882 (const_int 8) (const_int 8))
7884 (clobber (reg:CC FLAGS_REG))])]
7886 operands[0] = gen_lowpart (SImode, operands[0]);
7887 operands[1] = gen_lowpart (SImode, operands[1]);
7888 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
7891 ;; Since AND can be encoded with sign extended immediate, this is only
7892 ;; profitable when 7th bit is not set.
7894 [(set (match_operand 0 "register_operand")
7895 (and (match_operand 1 "general_operand")
7896 (match_operand 2 "const_int_operand")))
7897 (clobber (reg:CC FLAGS_REG))]
7899 && ANY_QI_REG_P (operands[0])
7900 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7901 && !(~INTVAL (operands[2]) & ~255)
7902 && !(INTVAL (operands[2]) & 128)
7903 && GET_MODE (operands[0]) != QImode"
7904 [(parallel [(set (strict_low_part (match_dup 0))
7905 (and:QI (match_dup 1)
7907 (clobber (reg:CC FLAGS_REG))])]
7909 operands[0] = gen_lowpart (QImode, operands[0]);
7910 operands[1] = gen_lowpart (QImode, operands[1]);
7911 operands[2] = gen_lowpart (QImode, operands[2]);
7914 ;; Logical inclusive and exclusive OR instructions
7916 ;; %%% This used to optimize known byte-wide and operations to memory.
7917 ;; If this is considered useful, it should be done with splitters.
7919 (define_expand "<code><mode>3"
7920 [(set (match_operand:SWIM 0 "nonimmediate_operand")
7921 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7922 (match_operand:SWIM 2 "<general_operand>")))]
7924 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
7926 (define_insn "*<code><mode>_1"
7927 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
7929 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
7930 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
7931 (clobber (reg:CC FLAGS_REG))]
7932 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7933 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7934 [(set_attr "type" "alu")
7935 (set_attr "mode" "<MODE>")])
7937 ;; %%% Potential partial reg stall on alternative 2. What to do?
7938 (define_insn "*<code>qi_1"
7939 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
7940 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7941 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
7942 (clobber (reg:CC FLAGS_REG))]
7943 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
7945 <logic>{b}\t{%2, %0|%0, %2}
7946 <logic>{b}\t{%2, %0|%0, %2}
7947 <logic>{l}\t{%k2, %k0|%k0, %k2}"
7948 [(set_attr "type" "alu")
7949 (set_attr "mode" "QI,QI,SI")])
7951 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7952 (define_insn "*<code>si_1_zext"
7953 [(set (match_operand:DI 0 "register_operand" "=r")
7955 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7956 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7957 (clobber (reg:CC FLAGS_REG))]
7958 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7959 "<logic>{l}\t{%2, %k0|%k0, %2}"
7960 [(set_attr "type" "alu")
7961 (set_attr "mode" "SI")])
7963 (define_insn "*<code>si_1_zext_imm"
7964 [(set (match_operand:DI 0 "register_operand" "=r")
7966 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
7967 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
7968 (clobber (reg:CC FLAGS_REG))]
7969 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7970 "<logic>{l}\t{%2, %k0|%k0, %2}"
7971 [(set_attr "type" "alu")
7972 (set_attr "mode" "SI")])
7974 (define_insn "*<code>qi_1_slp"
7975 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
7976 (any_or:QI (match_dup 0)
7977 (match_operand:QI 1 "general_operand" "qmn,qn")))
7978 (clobber (reg:CC FLAGS_REG))]
7979 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7980 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7981 "<logic>{b}\t{%1, %0|%0, %1}"
7982 [(set_attr "type" "alu1")
7983 (set_attr "mode" "QI")])
7985 (define_insn "*<code><mode>_2"
7986 [(set (reg FLAGS_REG)
7987 (compare (any_or:SWI
7988 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
7989 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
7991 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
7992 (any_or:SWI (match_dup 1) (match_dup 2)))]
7993 "ix86_match_ccmode (insn, CCNOmode)
7994 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7995 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7996 [(set_attr "type" "alu")
7997 (set_attr "mode" "<MODE>")])
7999 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8000 ;; ??? Special case for immediate operand is missing - it is tricky.
8001 (define_insn "*<code>si_2_zext"
8002 [(set (reg FLAGS_REG)
8003 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8004 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8006 (set (match_operand:DI 0 "register_operand" "=r")
8007 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8008 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8009 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8010 "<logic>{l}\t{%2, %k0|%k0, %2}"
8011 [(set_attr "type" "alu")
8012 (set_attr "mode" "SI")])
8014 (define_insn "*<code>si_2_zext_imm"
8015 [(set (reg FLAGS_REG)
8017 (match_operand:SI 1 "nonimmediate_operand" "%0")
8018 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8020 (set (match_operand:DI 0 "register_operand" "=r")
8021 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8022 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8023 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8024 "<logic>{l}\t{%2, %k0|%k0, %2}"
8025 [(set_attr "type" "alu")
8026 (set_attr "mode" "SI")])
8028 (define_insn "*<code>qi_2_slp"
8029 [(set (reg FLAGS_REG)
8030 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8031 (match_operand:QI 1 "general_operand" "qmn,qn"))
8033 (set (strict_low_part (match_dup 0))
8034 (any_or:QI (match_dup 0) (match_dup 1)))]
8035 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8036 && ix86_match_ccmode (insn, CCNOmode)
8037 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8038 "<logic>{b}\t{%1, %0|%0, %1}"
8039 [(set_attr "type" "alu1")
8040 (set_attr "mode" "QI")])
8042 (define_insn "*<code><mode>_3"
8043 [(set (reg FLAGS_REG)
8044 (compare (any_or:SWI
8045 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8046 (match_operand:SWI 2 "<general_operand>" "<g>"))
8048 (clobber (match_scratch:SWI 0 "=<r>"))]
8049 "ix86_match_ccmode (insn, CCNOmode)
8050 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8051 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8052 [(set_attr "type" "alu")
8053 (set_attr "mode" "<MODE>")])
8055 (define_insn "*<code>qi_ext_0"
8056 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8061 (match_operand 1 "ext_register_operand" "0")
8064 (match_operand 2 "const_int_operand" "n")))
8065 (clobber (reg:CC FLAGS_REG))]
8066 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8067 "<logic>{b}\t{%2, %h0|%h0, %2}"
8068 [(set_attr "type" "alu")
8069 (set_attr "length_immediate" "1")
8070 (set_attr "modrm" "1")
8071 (set_attr "mode" "QI")])
8073 (define_insn "*<code>qi_ext_1_rex64"
8074 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8079 (match_operand 1 "ext_register_operand" "0")
8083 (match_operand 2 "ext_register_operand" "Q"))))
8084 (clobber (reg:CC FLAGS_REG))]
8086 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8087 "<logic>{b}\t{%2, %h0|%h0, %2}"
8088 [(set_attr "type" "alu")
8089 (set_attr "length_immediate" "0")
8090 (set_attr "mode" "QI")])
8092 (define_insn "*<code>qi_ext_1"
8093 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8098 (match_operand 1 "ext_register_operand" "0")
8102 (match_operand:QI 2 "general_operand" "Qm"))))
8103 (clobber (reg:CC FLAGS_REG))]
8105 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8106 "<logic>{b}\t{%2, %h0|%h0, %2}"
8107 [(set_attr "type" "alu")
8108 (set_attr "length_immediate" "0")
8109 (set_attr "mode" "QI")])
8111 (define_insn "*<code>qi_ext_2"
8112 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8116 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8119 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8122 (clobber (reg:CC FLAGS_REG))]
8123 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8124 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8125 [(set_attr "type" "alu")
8126 (set_attr "length_immediate" "0")
8127 (set_attr "mode" "QI")])
8130 [(set (match_operand 0 "register_operand")
8131 (any_or (match_operand 1 "register_operand")
8132 (match_operand 2 "const_int_operand")))
8133 (clobber (reg:CC FLAGS_REG))]
8135 && QI_REG_P (operands[0])
8136 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8137 && !(INTVAL (operands[2]) & ~(255 << 8))
8138 && GET_MODE (operands[0]) != QImode"
8139 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8140 (any_or:SI (zero_extract:SI (match_dup 1)
8141 (const_int 8) (const_int 8))
8143 (clobber (reg:CC FLAGS_REG))])]
8145 operands[0] = gen_lowpart (SImode, operands[0]);
8146 operands[1] = gen_lowpart (SImode, operands[1]);
8147 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8150 ;; Since OR can be encoded with sign extended immediate, this is only
8151 ;; profitable when 7th bit is set.
8153 [(set (match_operand 0 "register_operand")
8154 (any_or (match_operand 1 "general_operand")
8155 (match_operand 2 "const_int_operand")))
8156 (clobber (reg:CC FLAGS_REG))]
8158 && ANY_QI_REG_P (operands[0])
8159 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8160 && !(INTVAL (operands[2]) & ~255)
8161 && (INTVAL (operands[2]) & 128)
8162 && GET_MODE (operands[0]) != QImode"
8163 [(parallel [(set (strict_low_part (match_dup 0))
8164 (any_or:QI (match_dup 1)
8166 (clobber (reg:CC FLAGS_REG))])]
8168 operands[0] = gen_lowpart (QImode, operands[0]);
8169 operands[1] = gen_lowpart (QImode, operands[1]);
8170 operands[2] = gen_lowpart (QImode, operands[2]);
8173 (define_expand "xorqi_cc_ext_1"
8175 (set (reg:CCNO FLAGS_REG)
8179 (match_operand 1 "ext_register_operand")
8182 (match_operand:QI 2 "general_operand"))
8184 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8194 (define_insn "*xorqi_cc_ext_1_rex64"
8195 [(set (reg FLAGS_REG)
8199 (match_operand 1 "ext_register_operand" "0")
8202 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8204 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8213 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8214 "xor{b}\t{%2, %h0|%h0, %2}"
8215 [(set_attr "type" "alu")
8216 (set_attr "modrm" "1")
8217 (set_attr "mode" "QI")])
8219 (define_insn "*xorqi_cc_ext_1"
8220 [(set (reg FLAGS_REG)
8224 (match_operand 1 "ext_register_operand" "0")
8227 (match_operand:QI 2 "general_operand" "qmn"))
8229 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8238 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8239 "xor{b}\t{%2, %h0|%h0, %2}"
8240 [(set_attr "type" "alu")
8241 (set_attr "modrm" "1")
8242 (set_attr "mode" "QI")])
8244 ;; Negation instructions
8246 (define_expand "neg<mode>2"
8247 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8248 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8250 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8252 (define_insn_and_split "*neg<dwi>2_doubleword"
8253 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8254 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8255 (clobber (reg:CC FLAGS_REG))]
8256 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8260 [(set (reg:CCZ FLAGS_REG)
8261 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8262 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8265 (plus:DWIH (match_dup 3)
8266 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8268 (clobber (reg:CC FLAGS_REG))])
8271 (neg:DWIH (match_dup 2)))
8272 (clobber (reg:CC FLAGS_REG))])]
8273 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8275 (define_insn "*neg<mode>2_1"
8276 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8277 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8278 (clobber (reg:CC FLAGS_REG))]
8279 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8280 "neg{<imodesuffix>}\t%0"
8281 [(set_attr "type" "negnot")
8282 (set_attr "mode" "<MODE>")])
8284 ;; Combine is quite creative about this pattern.
8285 (define_insn "*negsi2_1_zext"
8286 [(set (match_operand:DI 0 "register_operand" "=r")
8288 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8291 (clobber (reg:CC FLAGS_REG))]
8292 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8294 [(set_attr "type" "negnot")
8295 (set_attr "mode" "SI")])
8297 ;; The problem with neg is that it does not perform (compare x 0),
8298 ;; it really performs (compare 0 x), which leaves us with the zero
8299 ;; flag being the only useful item.
8301 (define_insn "*neg<mode>2_cmpz"
8302 [(set (reg:CCZ FLAGS_REG)
8304 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8306 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8307 (neg:SWI (match_dup 1)))]
8308 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8309 "neg{<imodesuffix>}\t%0"
8310 [(set_attr "type" "negnot")
8311 (set_attr "mode" "<MODE>")])
8313 (define_insn "*negsi2_cmpz_zext"
8314 [(set (reg:CCZ FLAGS_REG)
8318 (match_operand:DI 1 "register_operand" "0")
8322 (set (match_operand:DI 0 "register_operand" "=r")
8323 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8326 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8328 [(set_attr "type" "negnot")
8329 (set_attr "mode" "SI")])
8331 ;; Changing of sign for FP values is doable using integer unit too.
8333 (define_expand "<code><mode>2"
8334 [(set (match_operand:X87MODEF 0 "register_operand")
8335 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8336 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8337 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8339 (define_insn "*absneg<mode>2_mixed"
8340 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8341 (match_operator:MODEF 3 "absneg_operator"
8342 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8343 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8344 (clobber (reg:CC FLAGS_REG))]
8345 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8348 (define_insn "*absneg<mode>2_sse"
8349 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8350 (match_operator:MODEF 3 "absneg_operator"
8351 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8352 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8353 (clobber (reg:CC FLAGS_REG))]
8354 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8357 (define_insn "*absneg<mode>2_i387"
8358 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8359 (match_operator:X87MODEF 3 "absneg_operator"
8360 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8361 (use (match_operand 2))
8362 (clobber (reg:CC FLAGS_REG))]
8363 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8366 (define_expand "<code>tf2"
8367 [(set (match_operand:TF 0 "register_operand")
8368 (absneg:TF (match_operand:TF 1 "register_operand")))]
8370 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8372 (define_insn "*absnegtf2_sse"
8373 [(set (match_operand:TF 0 "register_operand" "=x,x")
8374 (match_operator:TF 3 "absneg_operator"
8375 [(match_operand:TF 1 "register_operand" "0,x")]))
8376 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8377 (clobber (reg:CC FLAGS_REG))]
8381 ;; Splitters for fp abs and neg.
8384 [(set (match_operand 0 "fp_register_operand")
8385 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8386 (use (match_operand 2))
8387 (clobber (reg:CC FLAGS_REG))]
8389 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8392 [(set (match_operand 0 "register_operand")
8393 (match_operator 3 "absneg_operator"
8394 [(match_operand 1 "register_operand")]))
8395 (use (match_operand 2 "nonimmediate_operand"))
8396 (clobber (reg:CC FLAGS_REG))]
8397 "reload_completed && SSE_REG_P (operands[0])"
8398 [(set (match_dup 0) (match_dup 3))]
8400 enum machine_mode mode = GET_MODE (operands[0]);
8401 enum machine_mode vmode = GET_MODE (operands[2]);
8404 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8405 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8406 if (operands_match_p (operands[0], operands[2]))
8409 operands[1] = operands[2];
8412 if (GET_CODE (operands[3]) == ABS)
8413 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8415 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8420 [(set (match_operand:SF 0 "register_operand")
8421 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8422 (use (match_operand:V4SF 2))
8423 (clobber (reg:CC FLAGS_REG))]
8425 [(parallel [(set (match_dup 0) (match_dup 1))
8426 (clobber (reg:CC FLAGS_REG))])]
8429 operands[0] = gen_lowpart (SImode, operands[0]);
8430 if (GET_CODE (operands[1]) == ABS)
8432 tmp = gen_int_mode (0x7fffffff, SImode);
8433 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8437 tmp = gen_int_mode (0x80000000, SImode);
8438 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8444 [(set (match_operand:DF 0 "register_operand")
8445 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8446 (use (match_operand 2))
8447 (clobber (reg:CC FLAGS_REG))]
8449 [(parallel [(set (match_dup 0) (match_dup 1))
8450 (clobber (reg:CC FLAGS_REG))])]
8455 tmp = gen_lowpart (DImode, operands[0]);
8456 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8459 if (GET_CODE (operands[1]) == ABS)
8462 tmp = gen_rtx_NOT (DImode, tmp);
8466 operands[0] = gen_highpart (SImode, operands[0]);
8467 if (GET_CODE (operands[1]) == ABS)
8469 tmp = gen_int_mode (0x7fffffff, SImode);
8470 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8474 tmp = gen_int_mode (0x80000000, SImode);
8475 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8482 [(set (match_operand:XF 0 "register_operand")
8483 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8484 (use (match_operand 2))
8485 (clobber (reg:CC FLAGS_REG))]
8487 [(parallel [(set (match_dup 0) (match_dup 1))
8488 (clobber (reg:CC FLAGS_REG))])]
8491 operands[0] = gen_rtx_REG (SImode,
8492 true_regnum (operands[0])
8493 + (TARGET_64BIT ? 1 : 2));
8494 if (GET_CODE (operands[1]) == ABS)
8496 tmp = GEN_INT (0x7fff);
8497 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8501 tmp = GEN_INT (0x8000);
8502 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8507 ;; Conditionalize these after reload. If they match before reload, we
8508 ;; lose the clobber and ability to use integer instructions.
8510 (define_insn "*<code><mode>2_1"
8511 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8512 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8514 && (reload_completed
8515 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8516 "f<absneg_mnemonic>"
8517 [(set_attr "type" "fsgn")
8518 (set_attr "mode" "<MODE>")])
8520 (define_insn "*<code>extendsfdf2"
8521 [(set (match_operand:DF 0 "register_operand" "=f")
8522 (absneg:DF (float_extend:DF
8523 (match_operand:SF 1 "register_operand" "0"))))]
8524 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8525 "f<absneg_mnemonic>"
8526 [(set_attr "type" "fsgn")
8527 (set_attr "mode" "DF")])
8529 (define_insn "*<code>extendsfxf2"
8530 [(set (match_operand:XF 0 "register_operand" "=f")
8531 (absneg:XF (float_extend:XF
8532 (match_operand:SF 1 "register_operand" "0"))))]
8534 "f<absneg_mnemonic>"
8535 [(set_attr "type" "fsgn")
8536 (set_attr "mode" "XF")])
8538 (define_insn "*<code>extenddfxf2"
8539 [(set (match_operand:XF 0 "register_operand" "=f")
8540 (absneg:XF (float_extend:XF
8541 (match_operand:DF 1 "register_operand" "0"))))]
8543 "f<absneg_mnemonic>"
8544 [(set_attr "type" "fsgn")
8545 (set_attr "mode" "XF")])
8547 ;; Copysign instructions
8549 (define_mode_iterator CSGNMODE [SF DF TF])
8550 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8552 (define_expand "copysign<mode>3"
8553 [(match_operand:CSGNMODE 0 "register_operand")
8554 (match_operand:CSGNMODE 1 "nonmemory_operand")
8555 (match_operand:CSGNMODE 2 "register_operand")]
8556 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8557 || (TARGET_SSE && (<MODE>mode == TFmode))"
8558 "ix86_expand_copysign (operands); DONE;")
8560 (define_insn_and_split "copysign<mode>3_const"
8561 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8563 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8564 (match_operand:CSGNMODE 2 "register_operand" "0")
8565 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8567 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8568 || (TARGET_SSE && (<MODE>mode == TFmode))"
8570 "&& reload_completed"
8572 "ix86_split_copysign_const (operands); DONE;")
8574 (define_insn "copysign<mode>3_var"
8575 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8577 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8578 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8579 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8580 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8582 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8583 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8584 || (TARGET_SSE && (<MODE>mode == TFmode))"
8588 [(set (match_operand:CSGNMODE 0 "register_operand")
8590 [(match_operand:CSGNMODE 2 "register_operand")
8591 (match_operand:CSGNMODE 3 "register_operand")
8592 (match_operand:<CSGNVMODE> 4)
8593 (match_operand:<CSGNVMODE> 5)]
8595 (clobber (match_scratch:<CSGNVMODE> 1))]
8596 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8597 || (TARGET_SSE && (<MODE>mode == TFmode)))
8598 && reload_completed"
8600 "ix86_split_copysign_var (operands); DONE;")
8602 ;; One complement instructions
8604 (define_expand "one_cmpl<mode>2"
8605 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8606 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
8608 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8610 (define_insn "*one_cmpl<mode>2_1"
8611 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8612 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8613 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8614 "not{<imodesuffix>}\t%0"
8615 [(set_attr "type" "negnot")
8616 (set_attr "mode" "<MODE>")])
8618 ;; %%% Potential partial reg stall on alternative 1. What to do?
8619 (define_insn "*one_cmplqi2_1"
8620 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8621 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8622 "ix86_unary_operator_ok (NOT, QImode, operands)"
8626 [(set_attr "type" "negnot")
8627 (set_attr "mode" "QI,SI")])
8629 ;; ??? Currently never generated - xor is used instead.
8630 (define_insn "*one_cmplsi2_1_zext"
8631 [(set (match_operand:DI 0 "register_operand" "=r")
8633 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8634 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8636 [(set_attr "type" "negnot")
8637 (set_attr "mode" "SI")])
8639 (define_insn "*one_cmpl<mode>2_2"
8640 [(set (reg FLAGS_REG)
8641 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8643 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8644 (not:SWI (match_dup 1)))]
8645 "ix86_match_ccmode (insn, CCNOmode)
8646 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8648 [(set_attr "type" "alu1")
8649 (set_attr "mode" "<MODE>")])
8652 [(set (match_operand 0 "flags_reg_operand")
8653 (match_operator 2 "compare_operator"
8654 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
8656 (set (match_operand:SWI 1 "nonimmediate_operand")
8657 (not:SWI (match_dup 3)))]
8658 "ix86_match_ccmode (insn, CCNOmode)"
8659 [(parallel [(set (match_dup 0)
8660 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8663 (xor:SWI (match_dup 3) (const_int -1)))])])
8665 ;; ??? Currently never generated - xor is used instead.
8666 (define_insn "*one_cmplsi2_2_zext"
8667 [(set (reg FLAGS_REG)
8668 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8670 (set (match_operand:DI 0 "register_operand" "=r")
8671 (zero_extend:DI (not:SI (match_dup 1))))]
8672 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8673 && ix86_unary_operator_ok (NOT, SImode, operands)"
8675 [(set_attr "type" "alu1")
8676 (set_attr "mode" "SI")])
8679 [(set (match_operand 0 "flags_reg_operand")
8680 (match_operator 2 "compare_operator"
8681 [(not:SI (match_operand:SI 3 "register_operand"))
8683 (set (match_operand:DI 1 "register_operand")
8684 (zero_extend:DI (not:SI (match_dup 3))))]
8685 "ix86_match_ccmode (insn, CCNOmode)"
8686 [(parallel [(set (match_dup 0)
8687 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8690 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8692 ;; Shift instructions
8694 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8695 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8696 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8697 ;; from the assembler input.
8699 ;; This instruction shifts the target reg/mem as usual, but instead of
8700 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8701 ;; is a left shift double, bits are taken from the high order bits of
8702 ;; reg, else if the insn is a shift right double, bits are taken from the
8703 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8704 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8706 ;; Since sh[lr]d does not change the `reg' operand, that is done
8707 ;; separately, making all shifts emit pairs of shift double and normal
8708 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8709 ;; support a 63 bit shift, each shift where the count is in a reg expands
8710 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8712 ;; If the shift count is a constant, we need never emit more than one
8713 ;; shift pair, instead using moves and sign extension for counts greater
8716 (define_expand "ashl<mode>3"
8717 [(set (match_operand:SDWIM 0 "<shift_operand>")
8718 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
8719 (match_operand:QI 2 "nonmemory_operand")))]
8721 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8723 (define_insn "*ashl<mode>3_doubleword"
8724 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8725 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8726 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8727 (clobber (reg:CC FLAGS_REG))]
8730 [(set_attr "type" "multi")])
8733 [(set (match_operand:DWI 0 "register_operand")
8734 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
8735 (match_operand:QI 2 "nonmemory_operand")))
8736 (clobber (reg:CC FLAGS_REG))]
8737 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8739 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8741 ;; By default we don't ask for a scratch register, because when DWImode
8742 ;; values are manipulated, registers are already at a premium. But if
8743 ;; we have one handy, we won't turn it away.
8746 [(match_scratch:DWIH 3 "r")
8747 (parallel [(set (match_operand:<DWI> 0 "register_operand")
8749 (match_operand:<DWI> 1 "nonmemory_operand")
8750 (match_operand:QI 2 "nonmemory_operand")))
8751 (clobber (reg:CC FLAGS_REG))])
8755 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
8757 (define_insn "x86_64_shld"
8758 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
8759 (ior:DI (ashift:DI (match_dup 0)
8760 (match_operand:QI 2 "nonmemory_operand" "Jc"))
8761 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8762 (minus:QI (const_int 64) (match_dup 2)))))
8763 (clobber (reg:CC FLAGS_REG))]
8765 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
8766 [(set_attr "type" "ishift")
8767 (set_attr "prefix_0f" "1")
8768 (set_attr "mode" "DI")
8769 (set_attr "athlon_decode" "vector")
8770 (set_attr "amdfam10_decode" "vector")
8771 (set_attr "bdver1_decode" "vector")])
8773 (define_insn "x86_shld"
8774 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
8775 (ior:SI (ashift:SI (match_dup 0)
8776 (match_operand:QI 2 "nonmemory_operand" "Ic"))
8777 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8778 (minus:QI (const_int 32) (match_dup 2)))))
8779 (clobber (reg:CC FLAGS_REG))]
8781 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
8782 [(set_attr "type" "ishift")
8783 (set_attr "prefix_0f" "1")
8784 (set_attr "mode" "SI")
8785 (set_attr "pent_pair" "np")
8786 (set_attr "athlon_decode" "vector")
8787 (set_attr "amdfam10_decode" "vector")
8788 (set_attr "bdver1_decode" "vector")])
8790 (define_expand "x86_shift<mode>_adj_1"
8791 [(set (reg:CCZ FLAGS_REG)
8792 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
8795 (set (match_operand:SWI48 0 "register_operand")
8796 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8797 (match_operand:SWI48 1 "register_operand")
8800 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8801 (match_operand:SWI48 3 "register_operand")
8804 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
8806 (define_expand "x86_shift<mode>_adj_2"
8807 [(use (match_operand:SWI48 0 "register_operand"))
8808 (use (match_operand:SWI48 1 "register_operand"))
8809 (use (match_operand:QI 2 "register_operand"))]
8812 rtx label = gen_label_rtx ();
8815 emit_insn (gen_testqi_ccz_1 (operands[2],
8816 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
8818 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
8819 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
8820 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
8821 gen_rtx_LABEL_REF (VOIDmode, label),
8823 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
8824 JUMP_LABEL (tmp) = label;
8826 emit_move_insn (operands[0], operands[1]);
8827 ix86_expand_clear (operands[1]);
8830 LABEL_NUSES (label) = 1;
8835 ;; Avoid useless masking of count operand.
8836 (define_insn_and_split "*ashl<mode>3_mask"
8837 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
8839 (match_operand:SWI48 1 "nonimmediate_operand" "0")
8842 (match_operand:SI 2 "nonimmediate_operand" "c")
8843 (match_operand:SI 3 "const_int_operand" "n")) 0)))
8844 (clobber (reg:CC FLAGS_REG))]
8845 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
8846 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
8847 == GET_MODE_BITSIZE (<MODE>mode)-1"
8850 [(parallel [(set (match_dup 0)
8851 (ashift:SWI48 (match_dup 1) (match_dup 2)))
8852 (clobber (reg:CC FLAGS_REG))])]
8854 if (can_create_pseudo_p ())
8855 operands [2] = force_reg (SImode, operands[2]);
8857 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
8859 [(set_attr "type" "ishift")
8860 (set_attr "mode" "<MODE>")])
8862 (define_insn "*bmi2_ashl<mode>3_1"
8863 [(set (match_operand:SWI48 0 "register_operand" "=r")
8864 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
8865 (match_operand:SWI48 2 "register_operand" "r")))]
8867 "shlx\t{%2, %1, %0|%0, %1, %2}"
8868 [(set_attr "type" "ishiftx")
8869 (set_attr "mode" "<MODE>")])
8871 (define_insn "*ashl<mode>3_1"
8872 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
8873 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
8874 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
8875 (clobber (reg:CC FLAGS_REG))]
8876 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
8878 switch (get_attr_type (insn))
8885 gcc_assert (operands[2] == const1_rtx);
8886 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8887 return "add{<imodesuffix>}\t%0, %0";
8890 if (operands[2] == const1_rtx
8891 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
8892 return "sal{<imodesuffix>}\t%0";
8894 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
8897 [(set_attr "isa" "*,*,bmi2")
8899 (cond [(eq_attr "alternative" "1")
8900 (const_string "lea")
8901 (eq_attr "alternative" "2")
8902 (const_string "ishiftx")
8903 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
8904 (match_operand 0 "register_operand"))
8905 (match_operand 2 "const1_operand"))
8906 (const_string "alu")
8908 (const_string "ishift")))
8909 (set (attr "length_immediate")
8911 (ior (eq_attr "type" "alu")
8912 (and (eq_attr "type" "ishift")
8913 (and (match_operand 2 "const1_operand")
8914 (ior (match_test "TARGET_SHIFT1")
8915 (match_test "optimize_function_for_size_p (cfun)")))))
8917 (const_string "*")))
8918 (set_attr "mode" "<MODE>")])
8920 ;; Convert shift to the shiftx pattern to avoid flags dependency.
8922 [(set (match_operand:SWI48 0 "register_operand")
8923 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
8924 (match_operand:QI 2 "register_operand")))
8925 (clobber (reg:CC FLAGS_REG))]
8926 "TARGET_BMI2 && reload_completed"
8928 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
8929 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
8931 (define_insn "*bmi2_ashlsi3_1_zext"
8932 [(set (match_operand:DI 0 "register_operand" "=r")
8934 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
8935 (match_operand:SI 2 "register_operand" "r"))))]
8936 "TARGET_64BIT && TARGET_BMI2"
8937 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
8938 [(set_attr "type" "ishiftx")
8939 (set_attr "mode" "SI")])
8941 (define_insn "*ashlsi3_1_zext"
8942 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
8944 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
8945 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
8946 (clobber (reg:CC FLAGS_REG))]
8947 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
8949 switch (get_attr_type (insn))
8956 gcc_assert (operands[2] == const1_rtx);
8957 return "add{l}\t%k0, %k0";
8960 if (operands[2] == const1_rtx
8961 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
8962 return "sal{l}\t%k0";
8964 return "sal{l}\t{%2, %k0|%k0, %2}";
8967 [(set_attr "isa" "*,*,bmi2")
8969 (cond [(eq_attr "alternative" "1")
8970 (const_string "lea")
8971 (eq_attr "alternative" "2")
8972 (const_string "ishiftx")
8973 (and (match_test "TARGET_DOUBLE_WITH_ADD")
8974 (match_operand 2 "const1_operand"))
8975 (const_string "alu")
8977 (const_string "ishift")))
8978 (set (attr "length_immediate")
8980 (ior (eq_attr "type" "alu")
8981 (and (eq_attr "type" "ishift")
8982 (and (match_operand 2 "const1_operand")
8983 (ior (match_test "TARGET_SHIFT1")
8984 (match_test "optimize_function_for_size_p (cfun)")))))
8986 (const_string "*")))
8987 (set_attr "mode" "SI")])
8989 ;; Convert shift to the shiftx pattern to avoid flags dependency.
8991 [(set (match_operand:DI 0 "register_operand")
8993 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
8994 (match_operand:QI 2 "register_operand"))))
8995 (clobber (reg:CC FLAGS_REG))]
8996 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
8998 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
8999 "operands[2] = gen_lowpart (SImode, operands[2]);")
9001 (define_insn "*ashlhi3_1"
9002 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9003 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9004 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9005 (clobber (reg:CC FLAGS_REG))]
9006 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9008 switch (get_attr_type (insn))
9014 gcc_assert (operands[2] == const1_rtx);
9015 return "add{w}\t%0, %0";
9018 if (operands[2] == const1_rtx
9019 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9020 return "sal{w}\t%0";
9022 return "sal{w}\t{%2, %0|%0, %2}";
9026 (cond [(eq_attr "alternative" "1")
9027 (const_string "lea")
9028 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9029 (match_operand 0 "register_operand"))
9030 (match_operand 2 "const1_operand"))
9031 (const_string "alu")
9033 (const_string "ishift")))
9034 (set (attr "length_immediate")
9036 (ior (eq_attr "type" "alu")
9037 (and (eq_attr "type" "ishift")
9038 (and (match_operand 2 "const1_operand")
9039 (ior (match_test "TARGET_SHIFT1")
9040 (match_test "optimize_function_for_size_p (cfun)")))))
9042 (const_string "*")))
9043 (set_attr "mode" "HI,SI")])
9045 ;; %%% Potential partial reg stall on alternative 1. What to do?
9046 (define_insn "*ashlqi3_1"
9047 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9048 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9049 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9050 (clobber (reg:CC FLAGS_REG))]
9051 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9053 switch (get_attr_type (insn))
9059 gcc_assert (operands[2] == const1_rtx);
9060 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9061 return "add{l}\t%k0, %k0";
9063 return "add{b}\t%0, %0";
9066 if (operands[2] == const1_rtx
9067 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9069 if (get_attr_mode (insn) == MODE_SI)
9070 return "sal{l}\t%k0";
9072 return "sal{b}\t%0";
9076 if (get_attr_mode (insn) == MODE_SI)
9077 return "sal{l}\t{%2, %k0|%k0, %2}";
9079 return "sal{b}\t{%2, %0|%0, %2}";
9084 (cond [(eq_attr "alternative" "2")
9085 (const_string "lea")
9086 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9087 (match_operand 0 "register_operand"))
9088 (match_operand 2 "const1_operand"))
9089 (const_string "alu")
9091 (const_string "ishift")))
9092 (set (attr "length_immediate")
9094 (ior (eq_attr "type" "alu")
9095 (and (eq_attr "type" "ishift")
9096 (and (match_operand 2 "const1_operand")
9097 (ior (match_test "TARGET_SHIFT1")
9098 (match_test "optimize_function_for_size_p (cfun)")))))
9100 (const_string "*")))
9101 (set_attr "mode" "QI,SI,SI")])
9103 (define_insn "*ashlqi3_1_slp"
9104 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9105 (ashift:QI (match_dup 0)
9106 (match_operand:QI 1 "nonmemory_operand" "cI")))
9107 (clobber (reg:CC FLAGS_REG))]
9108 "(optimize_function_for_size_p (cfun)
9109 || !TARGET_PARTIAL_FLAG_REG_STALL
9110 || (operands[1] == const1_rtx
9112 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9114 switch (get_attr_type (insn))
9117 gcc_assert (operands[1] == const1_rtx);
9118 return "add{b}\t%0, %0";
9121 if (operands[1] == const1_rtx
9122 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9123 return "sal{b}\t%0";
9125 return "sal{b}\t{%1, %0|%0, %1}";
9129 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9130 (match_operand 0 "register_operand"))
9131 (match_operand 1 "const1_operand"))
9132 (const_string "alu")
9134 (const_string "ishift1")))
9135 (set (attr "length_immediate")
9137 (ior (eq_attr "type" "alu")
9138 (and (eq_attr "type" "ishift1")
9139 (and (match_operand 1 "const1_operand")
9140 (ior (match_test "TARGET_SHIFT1")
9141 (match_test "optimize_function_for_size_p (cfun)")))))
9143 (const_string "*")))
9144 (set_attr "mode" "QI")])
9146 ;; Convert ashift to the lea pattern to avoid flags dependency.
9148 [(set (match_operand 0 "register_operand")
9149 (ashift (match_operand 1 "index_register_operand")
9150 (match_operand:QI 2 "const_int_operand")))
9151 (clobber (reg:CC FLAGS_REG))]
9152 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9154 && true_regnum (operands[0]) != true_regnum (operands[1])"
9157 enum machine_mode mode = GET_MODE (operands[0]);
9160 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9163 operands[0] = gen_lowpart (mode, operands[0]);
9164 operands[1] = gen_lowpart (mode, operands[1]);
9167 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9169 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9171 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9175 ;; Convert ashift to the lea pattern to avoid flags dependency.
9177 [(set (match_operand:DI 0 "register_operand")
9179 (ashift:SI (match_operand:SI 1 "index_register_operand")
9180 (match_operand:QI 2 "const_int_operand"))))
9181 (clobber (reg:CC FLAGS_REG))]
9182 "TARGET_64BIT && reload_completed
9183 && true_regnum (operands[0]) != true_regnum (operands[1])"
9185 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
9187 operands[1] = gen_lowpart (SImode, operands[1]);
9188 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), SImode);
9191 ;; This pattern can't accept a variable shift count, since shifts by
9192 ;; zero don't affect the flags. We assume that shifts by constant
9193 ;; zero are optimized away.
9194 (define_insn "*ashl<mode>3_cmp"
9195 [(set (reg FLAGS_REG)
9197 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9198 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9200 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9201 (ashift:SWI (match_dup 1) (match_dup 2)))]
9202 "(optimize_function_for_size_p (cfun)
9203 || !TARGET_PARTIAL_FLAG_REG_STALL
9204 || (operands[2] == const1_rtx
9206 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9207 && ix86_match_ccmode (insn, CCGOCmode)
9208 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9210 switch (get_attr_type (insn))
9213 gcc_assert (operands[2] == const1_rtx);
9214 return "add{<imodesuffix>}\t%0, %0";
9217 if (operands[2] == const1_rtx
9218 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9219 return "sal{<imodesuffix>}\t%0";
9221 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9225 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9226 (match_operand 0 "register_operand"))
9227 (match_operand 2 "const1_operand"))
9228 (const_string "alu")
9230 (const_string "ishift")))
9231 (set (attr "length_immediate")
9233 (ior (eq_attr "type" "alu")
9234 (and (eq_attr "type" "ishift")
9235 (and (match_operand 2 "const1_operand")
9236 (ior (match_test "TARGET_SHIFT1")
9237 (match_test "optimize_function_for_size_p (cfun)")))))
9239 (const_string "*")))
9240 (set_attr "mode" "<MODE>")])
9242 (define_insn "*ashlsi3_cmp_zext"
9243 [(set (reg FLAGS_REG)
9245 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9246 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9248 (set (match_operand:DI 0 "register_operand" "=r")
9249 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9251 && (optimize_function_for_size_p (cfun)
9252 || !TARGET_PARTIAL_FLAG_REG_STALL
9253 || (operands[2] == const1_rtx
9255 || TARGET_DOUBLE_WITH_ADD)))
9256 && ix86_match_ccmode (insn, CCGOCmode)
9257 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9259 switch (get_attr_type (insn))
9262 gcc_assert (operands[2] == const1_rtx);
9263 return "add{l}\t%k0, %k0";
9266 if (operands[2] == const1_rtx
9267 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9268 return "sal{l}\t%k0";
9270 return "sal{l}\t{%2, %k0|%k0, %2}";
9274 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9275 (match_operand 2 "const1_operand"))
9276 (const_string "alu")
9278 (const_string "ishift")))
9279 (set (attr "length_immediate")
9281 (ior (eq_attr "type" "alu")
9282 (and (eq_attr "type" "ishift")
9283 (and (match_operand 2 "const1_operand")
9284 (ior (match_test "TARGET_SHIFT1")
9285 (match_test "optimize_function_for_size_p (cfun)")))))
9287 (const_string "*")))
9288 (set_attr "mode" "SI")])
9290 (define_insn "*ashl<mode>3_cconly"
9291 [(set (reg FLAGS_REG)
9293 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9294 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9296 (clobber (match_scratch:SWI 0 "=<r>"))]
9297 "(optimize_function_for_size_p (cfun)
9298 || !TARGET_PARTIAL_FLAG_REG_STALL
9299 || (operands[2] == const1_rtx
9301 || TARGET_DOUBLE_WITH_ADD)))
9302 && ix86_match_ccmode (insn, CCGOCmode)"
9304 switch (get_attr_type (insn))
9307 gcc_assert (operands[2] == const1_rtx);
9308 return "add{<imodesuffix>}\t%0, %0";
9311 if (operands[2] == const1_rtx
9312 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9313 return "sal{<imodesuffix>}\t%0";
9315 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9319 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9320 (match_operand 0 "register_operand"))
9321 (match_operand 2 "const1_operand"))
9322 (const_string "alu")
9324 (const_string "ishift")))
9325 (set (attr "length_immediate")
9327 (ior (eq_attr "type" "alu")
9328 (and (eq_attr "type" "ishift")
9329 (and (match_operand 2 "const1_operand")
9330 (ior (match_test "TARGET_SHIFT1")
9331 (match_test "optimize_function_for_size_p (cfun)")))))
9333 (const_string "*")))
9334 (set_attr "mode" "<MODE>")])
9336 ;; See comment above `ashl<mode>3' about how this works.
9338 (define_expand "<shift_insn><mode>3"
9339 [(set (match_operand:SDWIM 0 "<shift_operand>")
9340 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9341 (match_operand:QI 2 "nonmemory_operand")))]
9343 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9345 ;; Avoid useless masking of count operand.
9346 (define_insn_and_split "*<shift_insn><mode>3_mask"
9347 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9349 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9352 (match_operand:SI 2 "nonimmediate_operand" "c")
9353 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9354 (clobber (reg:CC FLAGS_REG))]
9355 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9356 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9357 == GET_MODE_BITSIZE (<MODE>mode)-1"
9360 [(parallel [(set (match_dup 0)
9361 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9362 (clobber (reg:CC FLAGS_REG))])]
9364 if (can_create_pseudo_p ())
9365 operands [2] = force_reg (SImode, operands[2]);
9367 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9369 [(set_attr "type" "ishift")
9370 (set_attr "mode" "<MODE>")])
9372 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9373 [(set (match_operand:DWI 0 "register_operand" "=r")
9374 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9375 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9376 (clobber (reg:CC FLAGS_REG))]
9379 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9381 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9382 [(set_attr "type" "multi")])
9384 ;; By default we don't ask for a scratch register, because when DWImode
9385 ;; values are manipulated, registers are already at a premium. But if
9386 ;; we have one handy, we won't turn it away.
9389 [(match_scratch:DWIH 3 "r")
9390 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9392 (match_operand:<DWI> 1 "register_operand")
9393 (match_operand:QI 2 "nonmemory_operand")))
9394 (clobber (reg:CC FLAGS_REG))])
9398 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9400 (define_insn "x86_64_shrd"
9401 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9402 (ior:DI (ashiftrt:DI (match_dup 0)
9403 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9404 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9405 (minus:QI (const_int 64) (match_dup 2)))))
9406 (clobber (reg:CC FLAGS_REG))]
9408 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9409 [(set_attr "type" "ishift")
9410 (set_attr "prefix_0f" "1")
9411 (set_attr "mode" "DI")
9412 (set_attr "athlon_decode" "vector")
9413 (set_attr "amdfam10_decode" "vector")
9414 (set_attr "bdver1_decode" "vector")])
9416 (define_insn "x86_shrd"
9417 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9418 (ior:SI (ashiftrt:SI (match_dup 0)
9419 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9420 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9421 (minus:QI (const_int 32) (match_dup 2)))))
9422 (clobber (reg:CC FLAGS_REG))]
9424 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9425 [(set_attr "type" "ishift")
9426 (set_attr "prefix_0f" "1")
9427 (set_attr "mode" "SI")
9428 (set_attr "pent_pair" "np")
9429 (set_attr "athlon_decode" "vector")
9430 (set_attr "amdfam10_decode" "vector")
9431 (set_attr "bdver1_decode" "vector")])
9433 (define_insn "ashrdi3_cvt"
9434 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9435 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9436 (match_operand:QI 2 "const_int_operand")))
9437 (clobber (reg:CC FLAGS_REG))]
9438 "TARGET_64BIT && INTVAL (operands[2]) == 63
9439 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9440 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9443 sar{q}\t{%2, %0|%0, %2}"
9444 [(set_attr "type" "imovx,ishift")
9445 (set_attr "prefix_0f" "0,*")
9446 (set_attr "length_immediate" "0,*")
9447 (set_attr "modrm" "0,1")
9448 (set_attr "mode" "DI")])
9450 (define_insn "ashrsi3_cvt"
9451 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9452 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9453 (match_operand:QI 2 "const_int_operand")))
9454 (clobber (reg:CC FLAGS_REG))]
9455 "INTVAL (operands[2]) == 31
9456 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9457 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9460 sar{l}\t{%2, %0|%0, %2}"
9461 [(set_attr "type" "imovx,ishift")
9462 (set_attr "prefix_0f" "0,*")
9463 (set_attr "length_immediate" "0,*")
9464 (set_attr "modrm" "0,1")
9465 (set_attr "mode" "SI")])
9467 (define_insn "*ashrsi3_cvt_zext"
9468 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9470 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9471 (match_operand:QI 2 "const_int_operand"))))
9472 (clobber (reg:CC FLAGS_REG))]
9473 "TARGET_64BIT && INTVAL (operands[2]) == 31
9474 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9475 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9478 sar{l}\t{%2, %k0|%k0, %2}"
9479 [(set_attr "type" "imovx,ishift")
9480 (set_attr "prefix_0f" "0,*")
9481 (set_attr "length_immediate" "0,*")
9482 (set_attr "modrm" "0,1")
9483 (set_attr "mode" "SI")])
9485 (define_expand "x86_shift<mode>_adj_3"
9486 [(use (match_operand:SWI48 0 "register_operand"))
9487 (use (match_operand:SWI48 1 "register_operand"))
9488 (use (match_operand:QI 2 "register_operand"))]
9491 rtx label = gen_label_rtx ();
9494 emit_insn (gen_testqi_ccz_1 (operands[2],
9495 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9497 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9498 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9499 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9500 gen_rtx_LABEL_REF (VOIDmode, label),
9502 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9503 JUMP_LABEL (tmp) = label;
9505 emit_move_insn (operands[0], operands[1]);
9506 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9507 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9509 LABEL_NUSES (label) = 1;
9514 (define_insn "*bmi2_<shift_insn><mode>3_1"
9515 [(set (match_operand:SWI48 0 "register_operand" "=r")
9516 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9517 (match_operand:SWI48 2 "register_operand" "r")))]
9519 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9520 [(set_attr "type" "ishiftx")
9521 (set_attr "mode" "<MODE>")])
9523 (define_insn "*<shift_insn><mode>3_1"
9524 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9526 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9527 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9528 (clobber (reg:CC FLAGS_REG))]
9529 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9531 switch (get_attr_type (insn))
9537 if (operands[2] == const1_rtx
9538 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9539 return "<shift>{<imodesuffix>}\t%0";
9541 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9544 [(set_attr "isa" "*,bmi2")
9545 (set_attr "type" "ishift,ishiftx")
9546 (set (attr "length_immediate")
9548 (and (match_operand 2 "const1_operand")
9549 (ior (match_test "TARGET_SHIFT1")
9550 (match_test "optimize_function_for_size_p (cfun)")))
9552 (const_string "*")))
9553 (set_attr "mode" "<MODE>")])
9555 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9557 [(set (match_operand:SWI48 0 "register_operand")
9558 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9559 (match_operand:QI 2 "register_operand")))
9560 (clobber (reg:CC FLAGS_REG))]
9561 "TARGET_BMI2 && reload_completed"
9563 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9564 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9566 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9567 [(set (match_operand:DI 0 "register_operand" "=r")
9569 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9570 (match_operand:SI 2 "register_operand" "r"))))]
9571 "TARGET_64BIT && TARGET_BMI2"
9572 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9573 [(set_attr "type" "ishiftx")
9574 (set_attr "mode" "SI")])
9576 (define_insn "*<shift_insn>si3_1_zext"
9577 [(set (match_operand:DI 0 "register_operand" "=r,r")
9579 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9580 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9581 (clobber (reg:CC FLAGS_REG))]
9582 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9584 switch (get_attr_type (insn))
9590 if (operands[2] == const1_rtx
9591 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9592 return "<shift>{l}\t%k0";
9594 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9597 [(set_attr "isa" "*,bmi2")
9598 (set_attr "type" "ishift,ishiftx")
9599 (set (attr "length_immediate")
9601 (and (match_operand 2 "const1_operand")
9602 (ior (match_test "TARGET_SHIFT1")
9603 (match_test "optimize_function_for_size_p (cfun)")))
9605 (const_string "*")))
9606 (set_attr "mode" "SI")])
9608 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9610 [(set (match_operand:DI 0 "register_operand")
9612 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
9613 (match_operand:QI 2 "register_operand"))))
9614 (clobber (reg:CC FLAGS_REG))]
9615 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9617 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9618 "operands[2] = gen_lowpart (SImode, operands[2]);")
9620 (define_insn "*<shift_insn><mode>3_1"
9621 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9623 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9624 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9625 (clobber (reg:CC FLAGS_REG))]
9626 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9628 if (operands[2] == const1_rtx
9629 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9630 return "<shift>{<imodesuffix>}\t%0";
9632 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9634 [(set_attr "type" "ishift")
9635 (set (attr "length_immediate")
9637 (and (match_operand 2 "const1_operand")
9638 (ior (match_test "TARGET_SHIFT1")
9639 (match_test "optimize_function_for_size_p (cfun)")))
9641 (const_string "*")))
9642 (set_attr "mode" "<MODE>")])
9644 (define_insn "*<shift_insn>qi3_1_slp"
9645 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9646 (any_shiftrt:QI (match_dup 0)
9647 (match_operand:QI 1 "nonmemory_operand" "cI")))
9648 (clobber (reg:CC FLAGS_REG))]
9649 "(optimize_function_for_size_p (cfun)
9650 || !TARGET_PARTIAL_REG_STALL
9651 || (operands[1] == const1_rtx
9654 if (operands[1] == const1_rtx
9655 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9656 return "<shift>{b}\t%0";
9658 return "<shift>{b}\t{%1, %0|%0, %1}";
9660 [(set_attr "type" "ishift1")
9661 (set (attr "length_immediate")
9663 (and (match_operand 1 "const1_operand")
9664 (ior (match_test "TARGET_SHIFT1")
9665 (match_test "optimize_function_for_size_p (cfun)")))
9667 (const_string "*")))
9668 (set_attr "mode" "QI")])
9670 ;; This pattern can't accept a variable shift count, since shifts by
9671 ;; zero don't affect the flags. We assume that shifts by constant
9672 ;; zero are optimized away.
9673 (define_insn "*<shift_insn><mode>3_cmp"
9674 [(set (reg FLAGS_REG)
9677 (match_operand:SWI 1 "nonimmediate_operand" "0")
9678 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9680 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9681 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9682 "(optimize_function_for_size_p (cfun)
9683 || !TARGET_PARTIAL_FLAG_REG_STALL
9684 || (operands[2] == const1_rtx
9686 && ix86_match_ccmode (insn, CCGOCmode)
9687 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9689 if (operands[2] == const1_rtx
9690 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9691 return "<shift>{<imodesuffix>}\t%0";
9693 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9695 [(set_attr "type" "ishift")
9696 (set (attr "length_immediate")
9698 (and (match_operand 2 "const1_operand")
9699 (ior (match_test "TARGET_SHIFT1")
9700 (match_test "optimize_function_for_size_p (cfun)")))
9702 (const_string "*")))
9703 (set_attr "mode" "<MODE>")])
9705 (define_insn "*<shift_insn>si3_cmp_zext"
9706 [(set (reg FLAGS_REG)
9708 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9709 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9711 (set (match_operand:DI 0 "register_operand" "=r")
9712 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9714 && (optimize_function_for_size_p (cfun)
9715 || !TARGET_PARTIAL_FLAG_REG_STALL
9716 || (operands[2] == const1_rtx
9718 && ix86_match_ccmode (insn, CCGOCmode)
9719 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9721 if (operands[2] == const1_rtx
9722 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9723 return "<shift>{l}\t%k0";
9725 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9727 [(set_attr "type" "ishift")
9728 (set (attr "length_immediate")
9730 (and (match_operand 2 "const1_operand")
9731 (ior (match_test "TARGET_SHIFT1")
9732 (match_test "optimize_function_for_size_p (cfun)")))
9734 (const_string "*")))
9735 (set_attr "mode" "SI")])
9737 (define_insn "*<shift_insn><mode>3_cconly"
9738 [(set (reg FLAGS_REG)
9741 (match_operand:SWI 1 "register_operand" "0")
9742 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9744 (clobber (match_scratch:SWI 0 "=<r>"))]
9745 "(optimize_function_for_size_p (cfun)
9746 || !TARGET_PARTIAL_FLAG_REG_STALL
9747 || (operands[2] == const1_rtx
9749 && ix86_match_ccmode (insn, CCGOCmode)"
9751 if (operands[2] == const1_rtx
9752 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9753 return "<shift>{<imodesuffix>}\t%0";
9755 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9757 [(set_attr "type" "ishift")
9758 (set (attr "length_immediate")
9760 (and (match_operand 2 "const1_operand")
9761 (ior (match_test "TARGET_SHIFT1")
9762 (match_test "optimize_function_for_size_p (cfun)")))
9764 (const_string "*")))
9765 (set_attr "mode" "<MODE>")])
9767 ;; Rotate instructions
9769 (define_expand "<rotate_insn>ti3"
9770 [(set (match_operand:TI 0 "register_operand")
9771 (any_rotate:TI (match_operand:TI 1 "register_operand")
9772 (match_operand:QI 2 "nonmemory_operand")))]
9775 if (const_1_to_63_operand (operands[2], VOIDmode))
9776 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
9777 (operands[0], operands[1], operands[2]));
9784 (define_expand "<rotate_insn>di3"
9785 [(set (match_operand:DI 0 "shiftdi_operand")
9786 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
9787 (match_operand:QI 2 "nonmemory_operand")))]
9791 ix86_expand_binary_operator (<CODE>, DImode, operands);
9792 else if (const_1_to_31_operand (operands[2], VOIDmode))
9793 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
9794 (operands[0], operands[1], operands[2]));
9801 (define_expand "<rotate_insn><mode>3"
9802 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
9803 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
9804 (match_operand:QI 2 "nonmemory_operand")))]
9806 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9808 ;; Avoid useless masking of count operand.
9809 (define_insn_and_split "*<rotate_insn><mode>3_mask"
9810 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9812 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9815 (match_operand:SI 2 "nonimmediate_operand" "c")
9816 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9817 (clobber (reg:CC FLAGS_REG))]
9818 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9819 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9820 == GET_MODE_BITSIZE (<MODE>mode)-1"
9823 [(parallel [(set (match_dup 0)
9824 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
9825 (clobber (reg:CC FLAGS_REG))])]
9827 if (can_create_pseudo_p ())
9828 operands [2] = force_reg (SImode, operands[2]);
9830 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9832 [(set_attr "type" "rotate")
9833 (set_attr "mode" "<MODE>")])
9835 ;; Implement rotation using two double-precision
9836 ;; shift instructions and a scratch register.
9838 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
9839 [(set (match_operand:<DWI> 0 "register_operand" "=r")
9840 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
9841 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
9842 (clobber (reg:CC FLAGS_REG))
9843 (clobber (match_scratch:DWIH 3 "=&r"))]
9847 [(set (match_dup 3) (match_dup 4))
9850 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
9851 (lshiftrt:DWIH (match_dup 5)
9852 (minus:QI (match_dup 6) (match_dup 2)))))
9853 (clobber (reg:CC FLAGS_REG))])
9856 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
9857 (lshiftrt:DWIH (match_dup 3)
9858 (minus:QI (match_dup 6) (match_dup 2)))))
9859 (clobber (reg:CC FLAGS_REG))])]
9861 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
9863 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
9866 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
9867 [(set (match_operand:<DWI> 0 "register_operand" "=r")
9868 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
9869 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
9870 (clobber (reg:CC FLAGS_REG))
9871 (clobber (match_scratch:DWIH 3 "=&r"))]
9875 [(set (match_dup 3) (match_dup 4))
9878 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
9879 (ashift:DWIH (match_dup 5)
9880 (minus:QI (match_dup 6) (match_dup 2)))))
9881 (clobber (reg:CC FLAGS_REG))])
9884 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
9885 (ashift:DWIH (match_dup 3)
9886 (minus:QI (match_dup 6) (match_dup 2)))))
9887 (clobber (reg:CC FLAGS_REG))])]
9889 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
9891 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
9894 (define_insn "*bmi2_rorx<mode>3_1"
9895 [(set (match_operand:SWI48 0 "register_operand" "=r")
9896 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9897 (match_operand:QI 2 "immediate_operand" "<S>")))]
9899 "rorx\t{%2, %1, %0|%0, %1, %2}"
9900 [(set_attr "type" "rotatex")
9901 (set_attr "mode" "<MODE>")])
9903 (define_insn "*<rotate_insn><mode>3_1"
9904 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9906 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9907 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
9908 (clobber (reg:CC FLAGS_REG))]
9909 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9911 switch (get_attr_type (insn))
9917 if (operands[2] == const1_rtx
9918 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9919 return "<rotate>{<imodesuffix>}\t%0";
9921 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
9924 [(set_attr "isa" "*,bmi2")
9925 (set_attr "type" "rotate,rotatex")
9926 (set (attr "length_immediate")
9928 (and (eq_attr "type" "rotate")
9929 (and (match_operand 2 "const1_operand")
9930 (ior (match_test "TARGET_SHIFT1")
9931 (match_test "optimize_function_for_size_p (cfun)"))))
9933 (const_string "*")))
9934 (set_attr "mode" "<MODE>")])
9936 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
9938 [(set (match_operand:SWI48 0 "register_operand")
9939 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9940 (match_operand:QI 2 "immediate_operand")))
9941 (clobber (reg:CC FLAGS_REG))]
9942 "TARGET_BMI2 && reload_completed"
9944 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
9947 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
9951 [(set (match_operand:SWI48 0 "register_operand")
9952 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9953 (match_operand:QI 2 "immediate_operand")))
9954 (clobber (reg:CC FLAGS_REG))]
9955 "TARGET_BMI2 && reload_completed"
9957 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
9959 (define_insn "*bmi2_rorxsi3_1_zext"
9960 [(set (match_operand:DI 0 "register_operand" "=r")
9962 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9963 (match_operand:QI 2 "immediate_operand" "I"))))]
9964 "TARGET_64BIT && TARGET_BMI2"
9965 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
9966 [(set_attr "type" "rotatex")
9967 (set_attr "mode" "SI")])
9969 (define_insn "*<rotate_insn>si3_1_zext"
9970 [(set (match_operand:DI 0 "register_operand" "=r,r")
9972 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9973 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
9974 (clobber (reg:CC FLAGS_REG))]
9975 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9977 switch (get_attr_type (insn))
9983 if (operands[2] == const1_rtx
9984 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9985 return "<rotate>{l}\t%k0";
9987 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
9990 [(set_attr "isa" "*,bmi2")
9991 (set_attr "type" "rotate,rotatex")
9992 (set (attr "length_immediate")
9994 (and (eq_attr "type" "rotate")
9995 (and (match_operand 2 "const1_operand")
9996 (ior (match_test "TARGET_SHIFT1")
9997 (match_test "optimize_function_for_size_p (cfun)"))))
9999 (const_string "*")))
10000 (set_attr "mode" "SI")])
10002 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10004 [(set (match_operand:DI 0 "register_operand")
10006 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10007 (match_operand:QI 2 "immediate_operand"))))
10008 (clobber (reg:CC FLAGS_REG))]
10009 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10010 [(set (match_dup 0)
10011 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10014 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10018 [(set (match_operand:DI 0 "register_operand")
10020 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10021 (match_operand:QI 2 "immediate_operand"))))
10022 (clobber (reg:CC FLAGS_REG))]
10023 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10024 [(set (match_dup 0)
10025 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10027 (define_insn "*<rotate_insn><mode>3_1"
10028 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10029 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10030 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10031 (clobber (reg:CC FLAGS_REG))]
10032 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10034 if (operands[2] == const1_rtx
10035 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10036 return "<rotate>{<imodesuffix>}\t%0";
10038 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10040 [(set_attr "type" "rotate")
10041 (set (attr "length_immediate")
10043 (and (match_operand 2 "const1_operand")
10044 (ior (match_test "TARGET_SHIFT1")
10045 (match_test "optimize_function_for_size_p (cfun)")))
10047 (const_string "*")))
10048 (set_attr "mode" "<MODE>")])
10050 (define_insn "*<rotate_insn>qi3_1_slp"
10051 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10052 (any_rotate:QI (match_dup 0)
10053 (match_operand:QI 1 "nonmemory_operand" "cI")))
10054 (clobber (reg:CC FLAGS_REG))]
10055 "(optimize_function_for_size_p (cfun)
10056 || !TARGET_PARTIAL_REG_STALL
10057 || (operands[1] == const1_rtx
10058 && TARGET_SHIFT1))"
10060 if (operands[1] == const1_rtx
10061 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10062 return "<rotate>{b}\t%0";
10064 return "<rotate>{b}\t{%1, %0|%0, %1}";
10066 [(set_attr "type" "rotate1")
10067 (set (attr "length_immediate")
10069 (and (match_operand 1 "const1_operand")
10070 (ior (match_test "TARGET_SHIFT1")
10071 (match_test "optimize_function_for_size_p (cfun)")))
10073 (const_string "*")))
10074 (set_attr "mode" "QI")])
10077 [(set (match_operand:HI 0 "register_operand")
10078 (any_rotate:HI (match_dup 0) (const_int 8)))
10079 (clobber (reg:CC FLAGS_REG))]
10081 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10082 [(parallel [(set (strict_low_part (match_dup 0))
10083 (bswap:HI (match_dup 0)))
10084 (clobber (reg:CC FLAGS_REG))])])
10086 ;; Bit set / bit test instructions
10088 (define_expand "extv"
10089 [(set (match_operand:SI 0 "register_operand")
10090 (sign_extract:SI (match_operand:SI 1 "register_operand")
10091 (match_operand:SI 2 "const8_operand")
10092 (match_operand:SI 3 "const8_operand")))]
10095 /* Handle extractions from %ah et al. */
10096 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10099 /* From mips.md: extract_bit_field doesn't verify that our source
10100 matches the predicate, so check it again here. */
10101 if (! ext_register_operand (operands[1], VOIDmode))
10105 (define_expand "extzv"
10106 [(set (match_operand:SI 0 "register_operand")
10107 (zero_extract:SI (match_operand 1 "ext_register_operand")
10108 (match_operand:SI 2 "const8_operand")
10109 (match_operand:SI 3 "const8_operand")))]
10112 /* Handle extractions from %ah et al. */
10113 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10116 /* From mips.md: extract_bit_field doesn't verify that our source
10117 matches the predicate, so check it again here. */
10118 if (! ext_register_operand (operands[1], VOIDmode))
10122 (define_expand "insv"
10123 [(set (zero_extract (match_operand 0 "register_operand")
10124 (match_operand 1 "const_int_operand")
10125 (match_operand 2 "const_int_operand"))
10126 (match_operand 3 "register_operand"))]
10129 rtx (*gen_mov_insv_1) (rtx, rtx);
10131 if (ix86_expand_pinsr (operands))
10134 /* Handle insertions to %ah et al. */
10135 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10138 /* From mips.md: insert_bit_field doesn't verify that our source
10139 matches the predicate, so check it again here. */
10140 if (! ext_register_operand (operands[0], VOIDmode))
10143 gen_mov_insv_1 = (TARGET_64BIT
10144 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10146 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10150 ;; %%% bts, btr, btc, bt.
10151 ;; In general these instructions are *slow* when applied to memory,
10152 ;; since they enforce atomic operation. When applied to registers,
10153 ;; it depends on the cpu implementation. They're never faster than
10154 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10155 ;; no point. But in 64-bit, we can't hold the relevant immediates
10156 ;; within the instruction itself, so operating on bits in the high
10157 ;; 32-bits of a register becomes easier.
10159 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10160 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10161 ;; negdf respectively, so they can never be disabled entirely.
10163 (define_insn "*btsq"
10164 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10166 (match_operand:DI 1 "const_0_to_63_operand"))
10168 (clobber (reg:CC FLAGS_REG))]
10169 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10170 "bts{q}\t{%1, %0|%0, %1}"
10171 [(set_attr "type" "alu1")
10172 (set_attr "prefix_0f" "1")
10173 (set_attr "mode" "DI")])
10175 (define_insn "*btrq"
10176 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10178 (match_operand:DI 1 "const_0_to_63_operand"))
10180 (clobber (reg:CC FLAGS_REG))]
10181 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10182 "btr{q}\t{%1, %0|%0, %1}"
10183 [(set_attr "type" "alu1")
10184 (set_attr "prefix_0f" "1")
10185 (set_attr "mode" "DI")])
10187 (define_insn "*btcq"
10188 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10190 (match_operand:DI 1 "const_0_to_63_operand"))
10191 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10192 (clobber (reg:CC FLAGS_REG))]
10193 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10194 "btc{q}\t{%1, %0|%0, %1}"
10195 [(set_attr "type" "alu1")
10196 (set_attr "prefix_0f" "1")
10197 (set_attr "mode" "DI")])
10199 ;; Allow Nocona to avoid these instructions if a register is available.
10202 [(match_scratch:DI 2 "r")
10203 (parallel [(set (zero_extract:DI
10204 (match_operand:DI 0 "register_operand")
10206 (match_operand:DI 1 "const_0_to_63_operand"))
10208 (clobber (reg:CC FLAGS_REG))])]
10209 "TARGET_64BIT && !TARGET_USE_BT"
10212 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10215 if (HOST_BITS_PER_WIDE_INT >= 64)
10216 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10217 else if (i < HOST_BITS_PER_WIDE_INT)
10218 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10220 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10222 op1 = immed_double_const (lo, hi, DImode);
10225 emit_move_insn (operands[2], op1);
10229 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10234 [(match_scratch:DI 2 "r")
10235 (parallel [(set (zero_extract:DI
10236 (match_operand:DI 0 "register_operand")
10238 (match_operand:DI 1 "const_0_to_63_operand"))
10240 (clobber (reg:CC FLAGS_REG))])]
10241 "TARGET_64BIT && !TARGET_USE_BT"
10244 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10247 if (HOST_BITS_PER_WIDE_INT >= 64)
10248 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10249 else if (i < HOST_BITS_PER_WIDE_INT)
10250 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10252 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10254 op1 = immed_double_const (~lo, ~hi, DImode);
10257 emit_move_insn (operands[2], op1);
10261 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10266 [(match_scratch:DI 2 "r")
10267 (parallel [(set (zero_extract:DI
10268 (match_operand:DI 0 "register_operand")
10270 (match_operand:DI 1 "const_0_to_63_operand"))
10271 (not:DI (zero_extract:DI
10272 (match_dup 0) (const_int 1) (match_dup 1))))
10273 (clobber (reg:CC FLAGS_REG))])]
10274 "TARGET_64BIT && !TARGET_USE_BT"
10277 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10280 if (HOST_BITS_PER_WIDE_INT >= 64)
10281 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10282 else if (i < HOST_BITS_PER_WIDE_INT)
10283 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10285 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10287 op1 = immed_double_const (lo, hi, DImode);
10290 emit_move_insn (operands[2], op1);
10294 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10298 (define_insn "*bt<mode>"
10299 [(set (reg:CCC FLAGS_REG)
10301 (zero_extract:SWI48
10302 (match_operand:SWI48 0 "register_operand" "r")
10304 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10306 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10307 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10308 [(set_attr "type" "alu1")
10309 (set_attr "prefix_0f" "1")
10310 (set_attr "mode" "<MODE>")])
10312 ;; Store-flag instructions.
10314 ;; For all sCOND expanders, also expand the compare or test insn that
10315 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10317 (define_insn_and_split "*setcc_di_1"
10318 [(set (match_operand:DI 0 "register_operand" "=q")
10319 (match_operator:DI 1 "ix86_comparison_operator"
10320 [(reg FLAGS_REG) (const_int 0)]))]
10321 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10323 "&& reload_completed"
10324 [(set (match_dup 2) (match_dup 1))
10325 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10327 PUT_MODE (operands[1], QImode);
10328 operands[2] = gen_lowpart (QImode, operands[0]);
10331 (define_insn_and_split "*setcc_si_1_and"
10332 [(set (match_operand:SI 0 "register_operand" "=q")
10333 (match_operator:SI 1 "ix86_comparison_operator"
10334 [(reg FLAGS_REG) (const_int 0)]))
10335 (clobber (reg:CC FLAGS_REG))]
10336 "!TARGET_PARTIAL_REG_STALL
10337 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10339 "&& reload_completed"
10340 [(set (match_dup 2) (match_dup 1))
10341 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10342 (clobber (reg:CC FLAGS_REG))])]
10344 PUT_MODE (operands[1], QImode);
10345 operands[2] = gen_lowpart (QImode, operands[0]);
10348 (define_insn_and_split "*setcc_si_1_movzbl"
10349 [(set (match_operand:SI 0 "register_operand" "=q")
10350 (match_operator:SI 1 "ix86_comparison_operator"
10351 [(reg FLAGS_REG) (const_int 0)]))]
10352 "!TARGET_PARTIAL_REG_STALL
10353 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10355 "&& reload_completed"
10356 [(set (match_dup 2) (match_dup 1))
10357 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10359 PUT_MODE (operands[1], QImode);
10360 operands[2] = gen_lowpart (QImode, operands[0]);
10363 (define_insn "*setcc_qi"
10364 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10365 (match_operator:QI 1 "ix86_comparison_operator"
10366 [(reg FLAGS_REG) (const_int 0)]))]
10369 [(set_attr "type" "setcc")
10370 (set_attr "mode" "QI")])
10372 (define_insn "*setcc_qi_slp"
10373 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10374 (match_operator:QI 1 "ix86_comparison_operator"
10375 [(reg FLAGS_REG) (const_int 0)]))]
10378 [(set_attr "type" "setcc")
10379 (set_attr "mode" "QI")])
10381 ;; In general it is not safe to assume too much about CCmode registers,
10382 ;; so simplify-rtx stops when it sees a second one. Under certain
10383 ;; conditions this is safe on x86, so help combine not create
10390 [(set (match_operand:QI 0 "nonimmediate_operand")
10391 (ne:QI (match_operator 1 "ix86_comparison_operator"
10392 [(reg FLAGS_REG) (const_int 0)])
10395 [(set (match_dup 0) (match_dup 1))]
10396 "PUT_MODE (operands[1], QImode);")
10399 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10400 (ne:QI (match_operator 1 "ix86_comparison_operator"
10401 [(reg FLAGS_REG) (const_int 0)])
10404 [(set (match_dup 0) (match_dup 1))]
10405 "PUT_MODE (operands[1], QImode);")
10408 [(set (match_operand:QI 0 "nonimmediate_operand")
10409 (eq:QI (match_operator 1 "ix86_comparison_operator"
10410 [(reg FLAGS_REG) (const_int 0)])
10413 [(set (match_dup 0) (match_dup 1))]
10415 rtx new_op1 = copy_rtx (operands[1]);
10416 operands[1] = new_op1;
10417 PUT_MODE (new_op1, QImode);
10418 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10419 GET_MODE (XEXP (new_op1, 0))));
10421 /* Make sure that (a) the CCmode we have for the flags is strong
10422 enough for the reversed compare or (b) we have a valid FP compare. */
10423 if (! ix86_comparison_operator (new_op1, VOIDmode))
10428 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10429 (eq:QI (match_operator 1 "ix86_comparison_operator"
10430 [(reg FLAGS_REG) (const_int 0)])
10433 [(set (match_dup 0) (match_dup 1))]
10435 rtx new_op1 = copy_rtx (operands[1]);
10436 operands[1] = new_op1;
10437 PUT_MODE (new_op1, QImode);
10438 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10439 GET_MODE (XEXP (new_op1, 0))));
10441 /* Make sure that (a) the CCmode we have for the flags is strong
10442 enough for the reversed compare or (b) we have a valid FP compare. */
10443 if (! ix86_comparison_operator (new_op1, VOIDmode))
10447 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10448 ;; subsequent logical operations are used to imitate conditional moves.
10449 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10452 (define_insn "setcc_<mode>_sse"
10453 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10454 (match_operator:MODEF 3 "sse_comparison_operator"
10455 [(match_operand:MODEF 1 "register_operand" "0,x")
10456 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10457 "SSE_FLOAT_MODE_P (<MODE>mode)"
10459 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10460 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10461 [(set_attr "isa" "noavx,avx")
10462 (set_attr "type" "ssecmp")
10463 (set_attr "length_immediate" "1")
10464 (set_attr "prefix" "orig,vex")
10465 (set_attr "mode" "<MODE>")])
10467 ;; Basic conditional jump instructions.
10468 ;; We ignore the overflow flag for signed branch instructions.
10470 (define_insn "*jcc_1"
10472 (if_then_else (match_operator 1 "ix86_comparison_operator"
10473 [(reg FLAGS_REG) (const_int 0)])
10474 (label_ref (match_operand 0))
10478 [(set_attr "type" "ibr")
10479 (set_attr "modrm" "0")
10480 (set (attr "length")
10481 (if_then_else (and (ge (minus (match_dup 0) (pc))
10483 (lt (minus (match_dup 0) (pc))
10488 (define_insn "*jcc_2"
10490 (if_then_else (match_operator 1 "ix86_comparison_operator"
10491 [(reg FLAGS_REG) (const_int 0)])
10493 (label_ref (match_operand 0))))]
10496 [(set_attr "type" "ibr")
10497 (set_attr "modrm" "0")
10498 (set (attr "length")
10499 (if_then_else (and (ge (minus (match_dup 0) (pc))
10501 (lt (minus (match_dup 0) (pc))
10506 ;; In general it is not safe to assume too much about CCmode registers,
10507 ;; so simplify-rtx stops when it sees a second one. Under certain
10508 ;; conditions this is safe on x86, so help combine not create
10516 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10517 [(reg FLAGS_REG) (const_int 0)])
10519 (label_ref (match_operand 1))
10523 (if_then_else (match_dup 0)
10524 (label_ref (match_dup 1))
10526 "PUT_MODE (operands[0], VOIDmode);")
10530 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10531 [(reg FLAGS_REG) (const_int 0)])
10533 (label_ref (match_operand 1))
10537 (if_then_else (match_dup 0)
10538 (label_ref (match_dup 1))
10541 rtx new_op0 = copy_rtx (operands[0]);
10542 operands[0] = new_op0;
10543 PUT_MODE (new_op0, VOIDmode);
10544 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10545 GET_MODE (XEXP (new_op0, 0))));
10547 /* Make sure that (a) the CCmode we have for the flags is strong
10548 enough for the reversed compare or (b) we have a valid FP compare. */
10549 if (! ix86_comparison_operator (new_op0, VOIDmode))
10553 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10554 ;; pass generates from shift insn with QImode operand. Actually, the mode
10555 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10556 ;; appropriate modulo of the bit offset value.
10558 (define_insn_and_split "*jcc_bt<mode>"
10560 (if_then_else (match_operator 0 "bt_comparison_operator"
10561 [(zero_extract:SWI48
10562 (match_operand:SWI48 1 "register_operand" "r")
10565 (match_operand:QI 2 "register_operand" "r")))
10567 (label_ref (match_operand 3))
10569 (clobber (reg:CC FLAGS_REG))]
10570 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10573 [(set (reg:CCC FLAGS_REG)
10575 (zero_extract:SWI48
10581 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10582 (label_ref (match_dup 3))
10585 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10587 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10590 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10591 ;; also for DImode, this is what combine produces.
10592 (define_insn_and_split "*jcc_bt<mode>_mask"
10594 (if_then_else (match_operator 0 "bt_comparison_operator"
10595 [(zero_extract:SWI48
10596 (match_operand:SWI48 1 "register_operand" "r")
10599 (match_operand:SI 2 "register_operand" "r")
10600 (match_operand:SI 3 "const_int_operand" "n")))])
10601 (label_ref (match_operand 4))
10603 (clobber (reg:CC FLAGS_REG))]
10604 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10605 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10606 == GET_MODE_BITSIZE (<MODE>mode)-1"
10609 [(set (reg:CCC FLAGS_REG)
10611 (zero_extract:SWI48
10617 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10618 (label_ref (match_dup 4))
10621 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10623 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10626 (define_insn_and_split "*jcc_btsi_1"
10628 (if_then_else (match_operator 0 "bt_comparison_operator"
10631 (match_operand:SI 1 "register_operand" "r")
10632 (match_operand:QI 2 "register_operand" "r"))
10635 (label_ref (match_operand 3))
10637 (clobber (reg:CC FLAGS_REG))]
10638 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10641 [(set (reg:CCC FLAGS_REG)
10649 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10650 (label_ref (match_dup 3))
10653 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10655 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10658 ;; avoid useless masking of bit offset operand
10659 (define_insn_and_split "*jcc_btsi_mask_1"
10662 (match_operator 0 "bt_comparison_operator"
10665 (match_operand:SI 1 "register_operand" "r")
10668 (match_operand:SI 2 "register_operand" "r")
10669 (match_operand:SI 3 "const_int_operand" "n")) 0))
10672 (label_ref (match_operand 4))
10674 (clobber (reg:CC FLAGS_REG))]
10675 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10676 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10679 [(set (reg:CCC FLAGS_REG)
10687 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10688 (label_ref (match_dup 4))
10690 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10692 ;; Define combination compare-and-branch fp compare instructions to help
10695 (define_insn "*jcc<mode>_0_i387"
10697 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
10698 [(match_operand:X87MODEF 1 "register_operand" "f")
10699 (match_operand:X87MODEF 2 "const0_operand")])
10700 (label_ref (match_operand 3))
10702 (clobber (reg:CCFP FPSR_REG))
10703 (clobber (reg:CCFP FLAGS_REG))
10704 (clobber (match_scratch:HI 4 "=a"))]
10705 "TARGET_80387 && !TARGET_CMOVE"
10708 (define_insn "*jcc<mode>_0_r_i387"
10710 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
10711 [(match_operand:X87MODEF 1 "register_operand" "f")
10712 (match_operand:X87MODEF 2 "const0_operand")])
10714 (label_ref (match_operand 3))))
10715 (clobber (reg:CCFP FPSR_REG))
10716 (clobber (reg:CCFP FLAGS_REG))
10717 (clobber (match_scratch:HI 4 "=a"))]
10718 "TARGET_80387 && !TARGET_CMOVE"
10721 (define_insn "*jccxf_i387"
10723 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
10724 [(match_operand:XF 1 "register_operand" "f")
10725 (match_operand:XF 2 "register_operand" "f")])
10726 (label_ref (match_operand 3))
10728 (clobber (reg:CCFP FPSR_REG))
10729 (clobber (reg:CCFP FLAGS_REG))
10730 (clobber (match_scratch:HI 4 "=a"))]
10731 "TARGET_80387 && !TARGET_CMOVE"
10734 (define_insn "*jccxf_r_i387"
10736 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
10737 [(match_operand:XF 1 "register_operand" "f")
10738 (match_operand:XF 2 "register_operand" "f")])
10740 (label_ref (match_operand 3))))
10741 (clobber (reg:CCFP FPSR_REG))
10742 (clobber (reg:CCFP FLAGS_REG))
10743 (clobber (match_scratch:HI 4 "=a"))]
10744 "TARGET_80387 && !TARGET_CMOVE"
10747 (define_insn "*jcc<mode>_i387"
10749 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
10750 [(match_operand:MODEF 1 "register_operand" "f")
10751 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
10752 (label_ref (match_operand 3))
10754 (clobber (reg:CCFP FPSR_REG))
10755 (clobber (reg:CCFP FLAGS_REG))
10756 (clobber (match_scratch:HI 4 "=a"))]
10757 "TARGET_80387 && !TARGET_CMOVE"
10760 (define_insn "*jcc<mode>_r_i387"
10762 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
10763 [(match_operand:MODEF 1 "register_operand" "f")
10764 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
10766 (label_ref (match_operand 3))))
10767 (clobber (reg:CCFP FPSR_REG))
10768 (clobber (reg:CCFP FLAGS_REG))
10769 (clobber (match_scratch:HI 4 "=a"))]
10770 "TARGET_80387 && !TARGET_CMOVE"
10773 (define_insn "*jccu<mode>_i387"
10775 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
10776 [(match_operand:X87MODEF 1 "register_operand" "f")
10777 (match_operand:X87MODEF 2 "register_operand" "f")])
10778 (label_ref (match_operand 3))
10780 (clobber (reg:CCFP FPSR_REG))
10781 (clobber (reg:CCFP FLAGS_REG))
10782 (clobber (match_scratch:HI 4 "=a"))]
10783 "TARGET_80387 && !TARGET_CMOVE"
10786 (define_insn "*jccu<mode>_r_i387"
10788 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
10789 [(match_operand:X87MODEF 1 "register_operand" "f")
10790 (match_operand:X87MODEF 2 "register_operand" "f")])
10792 (label_ref (match_operand 3))))
10793 (clobber (reg:CCFP FPSR_REG))
10794 (clobber (reg:CCFP FLAGS_REG))
10795 (clobber (match_scratch:HI 4 "=a"))]
10796 "TARGET_80387 && !TARGET_CMOVE"
10801 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10802 [(match_operand:X87MODEF 1 "register_operand")
10803 (match_operand:X87MODEF 2 "nonimmediate_operand")])
10805 (match_operand 4)))
10806 (clobber (reg:CCFP FPSR_REG))
10807 (clobber (reg:CCFP FLAGS_REG))]
10808 "TARGET_80387 && !TARGET_CMOVE
10809 && reload_completed"
10812 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10813 operands[3], operands[4], NULL_RTX, NULL_RTX);
10819 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10820 [(match_operand:X87MODEF 1 "register_operand")
10821 (match_operand:X87MODEF 2 "general_operand")])
10823 (match_operand 4)))
10824 (clobber (reg:CCFP FPSR_REG))
10825 (clobber (reg:CCFP FLAGS_REG))
10826 (clobber (match_scratch:HI 5))]
10827 "TARGET_80387 && !TARGET_CMOVE
10828 && reload_completed"
10831 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10832 operands[3], operands[4], operands[5], NULL_RTX);
10836 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
10837 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
10838 ;; with a precedence over other operators and is always put in the first
10839 ;; place. Swap condition and operands to match ficom instruction.
10841 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
10844 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
10845 [(match_operator:X87MODEF 1 "float_operator"
10846 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
10847 (match_operand:X87MODEF 3 "register_operand" "f,f")])
10848 (label_ref (match_operand 4))
10850 (clobber (reg:CCFP FPSR_REG))
10851 (clobber (reg:CCFP FLAGS_REG))
10852 (clobber (match_scratch:HI 5 "=a,a"))]
10853 "TARGET_80387 && !TARGET_CMOVE
10854 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
10855 || optimize_function_for_size_p (cfun))"
10858 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
10861 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
10862 [(match_operator:X87MODEF 1 "float_operator"
10863 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
10864 (match_operand:X87MODEF 3 "register_operand" "f,f")])
10866 (label_ref (match_operand 4))))
10867 (clobber (reg:CCFP FPSR_REG))
10868 (clobber (reg:CCFP FLAGS_REG))
10869 (clobber (match_scratch:HI 5 "=a,a"))]
10870 "TARGET_80387 && !TARGET_CMOVE
10871 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
10872 || optimize_function_for_size_p (cfun))"
10878 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
10879 [(match_operator:X87MODEF 1 "float_operator"
10880 [(match_operand:SWI24 2 "memory_operand")])
10881 (match_operand:X87MODEF 3 "register_operand")])
10883 (match_operand 5)))
10884 (clobber (reg:CCFP FPSR_REG))
10885 (clobber (reg:CCFP FLAGS_REG))
10886 (clobber (match_scratch:HI 6))]
10887 "TARGET_80387 && !TARGET_CMOVE
10888 && reload_completed"
10891 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
10892 gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
10893 operands[4], operands[5], operands[6], NULL_RTX);
10897 ;; %%% Kill this when reload knows how to do it.
10901 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
10902 [(match_operator:X87MODEF 1 "float_operator"
10903 [(match_operand:SWI24 2 "register_operand")])
10904 (match_operand:X87MODEF 3 "register_operand")])
10906 (match_operand 5)))
10907 (clobber (reg:CCFP FPSR_REG))
10908 (clobber (reg:CCFP FLAGS_REG))
10909 (clobber (match_scratch:HI 6))]
10910 "TARGET_80387 && !TARGET_CMOVE
10911 && reload_completed"
10914 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
10916 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
10917 gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]),
10918 operands[4], operands[5], operands[6], operands[2]);
10922 ;; Unconditional and other jump instructions
10924 (define_insn "jump"
10926 (label_ref (match_operand 0)))]
10929 [(set_attr "type" "ibr")
10930 (set (attr "length")
10931 (if_then_else (and (ge (minus (match_dup 0) (pc))
10933 (lt (minus (match_dup 0) (pc))
10937 (set_attr "modrm" "0")])
10939 (define_expand "indirect_jump"
10940 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
10944 operands[0] = convert_memory_address (word_mode, operands[0]);
10947 (define_insn "*indirect_jump"
10948 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))]
10951 [(set_attr "type" "ibr")
10952 (set_attr "length_immediate" "0")])
10954 (define_expand "tablejump"
10955 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
10956 (use (label_ref (match_operand 1)))])]
10959 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
10960 relative. Convert the relative address to an absolute address. */
10964 enum rtx_code code;
10966 /* We can't use @GOTOFF for text labels on VxWorks;
10967 see gotoff_operand. */
10968 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
10972 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
10974 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
10978 op1 = pic_offset_table_rtx;
10983 op0 = pic_offset_table_rtx;
10987 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
10992 operands[0] = convert_memory_address (word_mode, operands[0]);
10995 (define_insn "*tablejump_1"
10996 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))
10997 (use (label_ref (match_operand 1)))]
11000 [(set_attr "type" "ibr")
11001 (set_attr "length_immediate" "0")])
11003 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11006 [(set (reg FLAGS_REG) (match_operand 0))
11007 (set (match_operand:QI 1 "register_operand")
11008 (match_operator:QI 2 "ix86_comparison_operator"
11009 [(reg FLAGS_REG) (const_int 0)]))
11010 (set (match_operand 3 "q_regs_operand")
11011 (zero_extend (match_dup 1)))]
11012 "(peep2_reg_dead_p (3, operands[1])
11013 || operands_match_p (operands[1], operands[3]))
11014 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11015 [(set (match_dup 4) (match_dup 0))
11016 (set (strict_low_part (match_dup 5))
11019 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11020 operands[5] = gen_lowpart (QImode, operands[3]);
11021 ix86_expand_clear (operands[3]);
11025 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11026 (match_operand 4)])
11027 (set (match_operand:QI 1 "register_operand")
11028 (match_operator:QI 2 "ix86_comparison_operator"
11029 [(reg FLAGS_REG) (const_int 0)]))
11030 (set (match_operand 3 "q_regs_operand")
11031 (zero_extend (match_dup 1)))]
11032 "(peep2_reg_dead_p (3, operands[1])
11033 || operands_match_p (operands[1], operands[3]))
11034 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11035 [(parallel [(set (match_dup 5) (match_dup 0))
11037 (set (strict_low_part (match_dup 6))
11040 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11041 operands[6] = gen_lowpart (QImode, operands[3]);
11042 ix86_expand_clear (operands[3]);
11045 ;; Similar, but match zero extend with andsi3.
11048 [(set (reg FLAGS_REG) (match_operand 0))
11049 (set (match_operand:QI 1 "register_operand")
11050 (match_operator:QI 2 "ix86_comparison_operator"
11051 [(reg FLAGS_REG) (const_int 0)]))
11052 (parallel [(set (match_operand:SI 3 "q_regs_operand")
11053 (and:SI (match_dup 3) (const_int 255)))
11054 (clobber (reg:CC FLAGS_REG))])]
11055 "REGNO (operands[1]) == REGNO (operands[3])
11056 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11057 [(set (match_dup 4) (match_dup 0))
11058 (set (strict_low_part (match_dup 5))
11061 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11062 operands[5] = gen_lowpart (QImode, operands[3]);
11063 ix86_expand_clear (operands[3]);
11067 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11068 (match_operand 4)])
11069 (set (match_operand:QI 1 "register_operand")
11070 (match_operator:QI 2 "ix86_comparison_operator"
11071 [(reg FLAGS_REG) (const_int 0)]))
11072 (parallel [(set (match_operand 3 "q_regs_operand")
11073 (zero_extend (match_dup 1)))
11074 (clobber (reg:CC FLAGS_REG))])]
11075 "(peep2_reg_dead_p (3, operands[1])
11076 || operands_match_p (operands[1], operands[3]))
11077 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11078 [(parallel [(set (match_dup 5) (match_dup 0))
11080 (set (strict_low_part (match_dup 6))
11083 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11084 operands[6] = gen_lowpart (QImode, operands[3]);
11085 ix86_expand_clear (operands[3]);
11088 ;; Call instructions.
11090 ;; The predicates normally associated with named expanders are not properly
11091 ;; checked for calls. This is a bug in the generic code, but it isn't that
11092 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11094 ;; P6 processors will jump to the address after the decrement when %esp
11095 ;; is used as a call operand, so they will execute return address as a code.
11096 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11098 ;; Register constraint for call instruction.
11099 (define_mode_attr c [(SI "l") (DI "r")])
11101 ;; Call subroutine returning no value.
11103 (define_expand "call"
11104 [(call (match_operand:QI 0)
11106 (use (match_operand 2))]
11109 ix86_expand_call (NULL, operands[0], operands[1],
11110 operands[2], NULL, false);
11114 (define_expand "sibcall"
11115 [(call (match_operand:QI 0)
11117 (use (match_operand 2))]
11120 ix86_expand_call (NULL, operands[0], operands[1],
11121 operands[2], NULL, true);
11125 (define_insn "*call"
11126 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11127 (match_operand 1))]
11128 "!SIBLING_CALL_P (insn)"
11129 "* return ix86_output_call_insn (insn, operands[0]);"
11130 [(set_attr "type" "call")])
11132 (define_insn "*call_rex64_ms_sysv"
11133 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11135 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11136 (clobber (reg:TI XMM6_REG))
11137 (clobber (reg:TI XMM7_REG))
11138 (clobber (reg:TI XMM8_REG))
11139 (clobber (reg:TI XMM9_REG))
11140 (clobber (reg:TI XMM10_REG))
11141 (clobber (reg:TI XMM11_REG))
11142 (clobber (reg:TI XMM12_REG))
11143 (clobber (reg:TI XMM13_REG))
11144 (clobber (reg:TI XMM14_REG))
11145 (clobber (reg:TI XMM15_REG))
11146 (clobber (reg:DI SI_REG))
11147 (clobber (reg:DI DI_REG))]
11148 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11149 "* return ix86_output_call_insn (insn, operands[0]);"
11150 [(set_attr "type" "call")])
11152 (define_insn "*sibcall"
11153 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11154 (match_operand 1))]
11155 "SIBLING_CALL_P (insn)"
11156 "* return ix86_output_call_insn (insn, operands[0]);"
11157 [(set_attr "type" "call")])
11159 (define_expand "call_pop"
11160 [(parallel [(call (match_operand:QI 0)
11161 (match_operand:SI 1))
11162 (set (reg:SI SP_REG)
11163 (plus:SI (reg:SI SP_REG)
11164 (match_operand:SI 3)))])]
11167 ix86_expand_call (NULL, operands[0], operands[1],
11168 operands[2], operands[3], false);
11172 (define_insn "*call_pop"
11173 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11175 (set (reg:SI SP_REG)
11176 (plus:SI (reg:SI SP_REG)
11177 (match_operand:SI 2 "immediate_operand" "i")))]
11178 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11179 "* return ix86_output_call_insn (insn, operands[0]);"
11180 [(set_attr "type" "call")])
11182 (define_insn "*sibcall_pop"
11183 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11185 (set (reg:SI SP_REG)
11186 (plus:SI (reg:SI SP_REG)
11187 (match_operand:SI 2 "immediate_operand" "i")))]
11188 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11189 "* return ix86_output_call_insn (insn, operands[0]);"
11190 [(set_attr "type" "call")])
11192 ;; Call subroutine, returning value in operand 0
11194 (define_expand "call_value"
11195 [(set (match_operand 0)
11196 (call (match_operand:QI 1)
11197 (match_operand 2)))
11198 (use (match_operand 3))]
11201 ix86_expand_call (operands[0], operands[1], operands[2],
11202 operands[3], NULL, false);
11206 (define_expand "sibcall_value"
11207 [(set (match_operand 0)
11208 (call (match_operand:QI 1)
11209 (match_operand 2)))
11210 (use (match_operand 3))]
11213 ix86_expand_call (operands[0], operands[1], operands[2],
11214 operands[3], NULL, true);
11218 (define_insn "*call_value"
11219 [(set (match_operand 0)
11220 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11221 (match_operand 2)))]
11222 "!SIBLING_CALL_P (insn)"
11223 "* return ix86_output_call_insn (insn, operands[1]);"
11224 [(set_attr "type" "callv")])
11226 (define_insn "*sibcall_value"
11227 [(set (match_operand 0)
11228 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11229 (match_operand 2)))]
11230 "SIBLING_CALL_P (insn)"
11231 "* return ix86_output_call_insn (insn, operands[1]);"
11232 [(set_attr "type" "callv")])
11234 (define_insn "*call_value_rex64_ms_sysv"
11235 [(set (match_operand 0)
11236 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11237 (match_operand 2)))
11238 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11239 (clobber (reg:TI XMM6_REG))
11240 (clobber (reg:TI XMM7_REG))
11241 (clobber (reg:TI XMM8_REG))
11242 (clobber (reg:TI XMM9_REG))
11243 (clobber (reg:TI XMM10_REG))
11244 (clobber (reg:TI XMM11_REG))
11245 (clobber (reg:TI XMM12_REG))
11246 (clobber (reg:TI XMM13_REG))
11247 (clobber (reg:TI XMM14_REG))
11248 (clobber (reg:TI XMM15_REG))
11249 (clobber (reg:DI SI_REG))
11250 (clobber (reg:DI DI_REG))]
11251 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11252 "* return ix86_output_call_insn (insn, operands[1]);"
11253 [(set_attr "type" "callv")])
11255 (define_expand "call_value_pop"
11256 [(parallel [(set (match_operand 0)
11257 (call (match_operand:QI 1)
11258 (match_operand:SI 2)))
11259 (set (reg:SI SP_REG)
11260 (plus:SI (reg:SI SP_REG)
11261 (match_operand:SI 4)))])]
11264 ix86_expand_call (operands[0], operands[1], operands[2],
11265 operands[3], operands[4], false);
11269 (define_insn "*call_value_pop"
11270 [(set (match_operand 0)
11271 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11272 (match_operand 2)))
11273 (set (reg:SI SP_REG)
11274 (plus:SI (reg:SI SP_REG)
11275 (match_operand:SI 3 "immediate_operand" "i")))]
11276 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11277 "* return ix86_output_call_insn (insn, operands[1]);"
11278 [(set_attr "type" "callv")])
11280 (define_insn "*sibcall_value_pop"
11281 [(set (match_operand 0)
11282 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11283 (match_operand 2)))
11284 (set (reg:SI SP_REG)
11285 (plus:SI (reg:SI SP_REG)
11286 (match_operand:SI 3 "immediate_operand" "i")))]
11287 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11288 "* return ix86_output_call_insn (insn, operands[1]);"
11289 [(set_attr "type" "callv")])
11291 ;; Call subroutine returning any type.
11293 (define_expand "untyped_call"
11294 [(parallel [(call (match_operand 0)
11297 (match_operand 2)])]
11302 /* In order to give reg-stack an easier job in validating two
11303 coprocessor registers as containing a possible return value,
11304 simply pretend the untyped call returns a complex long double
11307 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11308 and should have the default ABI. */
11310 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11311 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11312 operands[0], const0_rtx,
11313 GEN_INT ((TARGET_64BIT
11314 ? (ix86_abi == SYSV_ABI
11315 ? X86_64_SSE_REGPARM_MAX
11316 : X86_64_MS_SSE_REGPARM_MAX)
11317 : X86_32_SSE_REGPARM_MAX)
11321 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11323 rtx set = XVECEXP (operands[2], 0, i);
11324 emit_move_insn (SET_DEST (set), SET_SRC (set));
11327 /* The optimizer does not know that the call sets the function value
11328 registers we stored in the result block. We avoid problems by
11329 claiming that all hard registers are used and clobbered at this
11331 emit_insn (gen_blockage ());
11336 ;; Prologue and epilogue instructions
11338 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11339 ;; all of memory. This blocks insns from being moved across this point.
11341 (define_insn "blockage"
11342 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11345 [(set_attr "length" "0")])
11347 ;; Do not schedule instructions accessing memory across this point.
11349 (define_expand "memory_blockage"
11350 [(set (match_dup 0)
11351 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11354 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11355 MEM_VOLATILE_P (operands[0]) = 1;
11358 (define_insn "*memory_blockage"
11359 [(set (match_operand:BLK 0)
11360 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11363 [(set_attr "length" "0")])
11365 ;; As USE insns aren't meaningful after reload, this is used instead
11366 ;; to prevent deleting instructions setting registers for PIC code
11367 (define_insn "prologue_use"
11368 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
11371 [(set_attr "length" "0")])
11373 ;; Insn emitted into the body of a function to return from a function.
11374 ;; This is only done if the function's epilogue is known to be simple.
11375 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11377 (define_expand "return"
11379 "ix86_can_use_return_insn_p ()"
11381 if (crtl->args.pops_args)
11383 rtx popc = GEN_INT (crtl->args.pops_args);
11384 emit_jump_insn (gen_simple_return_pop_internal (popc));
11389 ;; We need to disable this for TARGET_SEH, as otherwise
11390 ;; shrink-wrapped prologue gets enabled too. This might exceed
11391 ;; the maximum size of prologue in unwind information.
11393 (define_expand "simple_return"
11397 if (crtl->args.pops_args)
11399 rtx popc = GEN_INT (crtl->args.pops_args);
11400 emit_jump_insn (gen_simple_return_pop_internal (popc));
11405 (define_insn "simple_return_internal"
11409 [(set_attr "length" "1")
11410 (set_attr "atom_unit" "jeu")
11411 (set_attr "length_immediate" "0")
11412 (set_attr "modrm" "0")])
11414 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11415 ;; instruction Athlon and K8 have.
11417 (define_insn "simple_return_internal_long"
11419 (unspec [(const_int 0)] UNSPEC_REP)]
11422 [(set_attr "length" "2")
11423 (set_attr "atom_unit" "jeu")
11424 (set_attr "length_immediate" "0")
11425 (set_attr "prefix_rep" "1")
11426 (set_attr "modrm" "0")])
11428 (define_insn "simple_return_pop_internal"
11430 (use (match_operand:SI 0 "const_int_operand"))]
11433 [(set_attr "length" "3")
11434 (set_attr "atom_unit" "jeu")
11435 (set_attr "length_immediate" "2")
11436 (set_attr "modrm" "0")])
11438 (define_insn "simple_return_indirect_internal"
11440 (use (match_operand:SI 0 "register_operand" "r"))]
11443 [(set_attr "type" "ibr")
11444 (set_attr "length_immediate" "0")])
11450 [(set_attr "length" "1")
11451 (set_attr "length_immediate" "0")
11452 (set_attr "modrm" "0")])
11454 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11455 (define_insn "nops"
11456 [(unspec_volatile [(match_operand 0 "const_int_operand")]
11460 int num = INTVAL (operands[0]);
11462 gcc_assert (IN_RANGE (num, 1, 8));
11465 fputs ("\tnop\n", asm_out_file);
11469 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11470 (set_attr "length_immediate" "0")
11471 (set_attr "modrm" "0")])
11473 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11474 ;; branch prediction penalty for the third jump in a 16-byte
11478 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
11481 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11482 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11484 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11485 The align insn is used to avoid 3 jump instructions in the row to improve
11486 branch prediction and the benefits hardly outweigh the cost of extra 8
11487 nops on the average inserted by full alignment pseudo operation. */
11491 [(set_attr "length" "16")])
11493 (define_expand "prologue"
11496 "ix86_expand_prologue (); DONE;")
11498 (define_insn "set_got"
11499 [(set (match_operand:SI 0 "register_operand" "=r")
11500 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11501 (clobber (reg:CC FLAGS_REG))]
11503 "* return output_set_got (operands[0], NULL_RTX);"
11504 [(set_attr "type" "multi")
11505 (set_attr "length" "12")])
11507 (define_insn "set_got_labelled"
11508 [(set (match_operand:SI 0 "register_operand" "=r")
11509 (unspec:SI [(label_ref (match_operand 1))]
11511 (clobber (reg:CC FLAGS_REG))]
11513 "* return output_set_got (operands[0], operands[1]);"
11514 [(set_attr "type" "multi")
11515 (set_attr "length" "12")])
11517 (define_insn "set_got_rex64"
11518 [(set (match_operand:DI 0 "register_operand" "=r")
11519 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11521 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11522 [(set_attr "type" "lea")
11523 (set_attr "length_address" "4")
11524 (set_attr "mode" "DI")])
11526 (define_insn "set_rip_rex64"
11527 [(set (match_operand:DI 0 "register_operand" "=r")
11528 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
11530 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11531 [(set_attr "type" "lea")
11532 (set_attr "length_address" "4")
11533 (set_attr "mode" "DI")])
11535 (define_insn "set_got_offset_rex64"
11536 [(set (match_operand:DI 0 "register_operand" "=r")
11538 [(label_ref (match_operand 1))]
11539 UNSPEC_SET_GOT_OFFSET))]
11541 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11542 [(set_attr "type" "imov")
11543 (set_attr "length_immediate" "0")
11544 (set_attr "length_address" "8")
11545 (set_attr "mode" "DI")])
11547 (define_expand "epilogue"
11550 "ix86_expand_epilogue (1); DONE;")
11552 (define_expand "sibcall_epilogue"
11555 "ix86_expand_epilogue (0); DONE;")
11557 (define_expand "eh_return"
11558 [(use (match_operand 0 "register_operand"))]
11561 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11563 /* Tricky bit: we write the address of the handler to which we will
11564 be returning into someone else's stack frame, one word below the
11565 stack address we wish to restore. */
11566 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11567 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
11568 tmp = gen_rtx_MEM (Pmode, tmp);
11569 emit_move_insn (tmp, ra);
11571 emit_jump_insn (gen_eh_return_internal ());
11576 (define_insn_and_split "eh_return_internal"
11580 "epilogue_completed"
11582 "ix86_expand_epilogue (2); DONE;")
11584 (define_insn "leave"
11585 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11586 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11587 (clobber (mem:BLK (scratch)))]
11590 [(set_attr "type" "leave")])
11592 (define_insn "leave_rex64"
11593 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11594 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11595 (clobber (mem:BLK (scratch)))]
11598 [(set_attr "type" "leave")])
11600 ;; Handle -fsplit-stack.
11602 (define_expand "split_stack_prologue"
11606 ix86_expand_split_stack_prologue ();
11610 ;; In order to support the call/return predictor, we use a return
11611 ;; instruction which the middle-end doesn't see.
11612 (define_insn "split_stack_return"
11613 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
11614 UNSPECV_SPLIT_STACK_RETURN)]
11617 if (operands[0] == const0_rtx)
11622 [(set_attr "atom_unit" "jeu")
11623 (set_attr "modrm" "0")
11624 (set (attr "length")
11625 (if_then_else (match_operand:SI 0 "const0_operand")
11628 (set (attr "length_immediate")
11629 (if_then_else (match_operand:SI 0 "const0_operand")
11633 ;; If there are operand 0 bytes available on the stack, jump to
11636 (define_expand "split_stack_space_check"
11637 [(set (pc) (if_then_else
11638 (ltu (minus (reg SP_REG)
11639 (match_operand 0 "register_operand"))
11640 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11641 (label_ref (match_operand 1))
11645 rtx reg, size, limit;
11647 reg = gen_reg_rtx (Pmode);
11648 size = force_reg (Pmode, operands[0]);
11649 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11650 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11651 UNSPEC_STACK_CHECK);
11652 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11653 ix86_expand_branch (GEU, reg, limit, operands[1]);
11658 ;; Bit manipulation instructions.
11660 (define_expand "ffs<mode>2"
11661 [(set (match_dup 2) (const_int -1))
11662 (parallel [(set (match_dup 3) (match_dup 4))
11663 (set (match_operand:SWI48 0 "register_operand")
11665 (match_operand:SWI48 1 "nonimmediate_operand")))])
11666 (set (match_dup 0) (if_then_else:SWI48
11667 (eq (match_dup 3) (const_int 0))
11670 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11671 (clobber (reg:CC FLAGS_REG))])]
11674 enum machine_mode flags_mode;
11676 if (<MODE>mode == SImode && !TARGET_CMOVE)
11678 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11682 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
11684 operands[2] = gen_reg_rtx (<MODE>mode);
11685 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
11686 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
11689 (define_insn_and_split "ffssi2_no_cmove"
11690 [(set (match_operand:SI 0 "register_operand" "=r")
11691 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11692 (clobber (match_scratch:SI 2 "=&q"))
11693 (clobber (reg:CC FLAGS_REG))]
11696 "&& reload_completed"
11697 [(parallel [(set (match_dup 4) (match_dup 5))
11698 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11699 (set (strict_low_part (match_dup 3))
11700 (eq:QI (match_dup 4) (const_int 0)))
11701 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11702 (clobber (reg:CC FLAGS_REG))])
11703 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11704 (clobber (reg:CC FLAGS_REG))])
11705 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11706 (clobber (reg:CC FLAGS_REG))])]
11708 enum machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
11710 operands[3] = gen_lowpart (QImode, operands[2]);
11711 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
11712 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
11714 ix86_expand_clear (operands[2]);
11717 (define_insn "*tzcnt<mode>_1"
11718 [(set (reg:CCC FLAGS_REG)
11719 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11721 (set (match_operand:SWI48 0 "register_operand" "=r")
11722 (ctz:SWI48 (match_dup 1)))]
11724 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11725 [(set_attr "type" "alu1")
11726 (set_attr "prefix_0f" "1")
11727 (set_attr "prefix_rep" "1")
11728 (set_attr "btver2_decode" "double")
11729 (set_attr "mode" "<MODE>")])
11731 (define_insn "*bsf<mode>_1"
11732 [(set (reg:CCZ FLAGS_REG)
11733 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11735 (set (match_operand:SWI48 0 "register_operand" "=r")
11736 (ctz:SWI48 (match_dup 1)))]
11738 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11739 [(set_attr "type" "alu1")
11740 (set_attr "prefix_0f" "1")
11741 (set_attr "btver2_decode" "double")
11742 (set_attr "mode" "<MODE>")])
11744 (define_insn "ctz<mode>2"
11745 [(set (match_operand:SWI248 0 "register_operand" "=r")
11746 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11747 (clobber (reg:CC FLAGS_REG))]
11751 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11752 else if (optimize_function_for_size_p (cfun))
11754 else if (TARGET_GENERIC)
11755 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
11756 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
11758 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
11760 [(set_attr "type" "alu1")
11761 (set_attr "prefix_0f" "1")
11762 (set (attr "prefix_rep")
11764 (ior (match_test "TARGET_BMI")
11765 (and (not (match_test "optimize_function_for_size_p (cfun)"))
11766 (match_test "TARGET_GENERIC")))
11768 (const_string "0")))
11769 (set_attr "mode" "<MODE>")])
11771 (define_expand "clz<mode>2"
11773 [(set (match_operand:SWI248 0 "register_operand")
11776 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
11777 (clobber (reg:CC FLAGS_REG))])
11779 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
11780 (clobber (reg:CC FLAGS_REG))])]
11785 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
11788 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11791 (define_insn "clz<mode>2_lzcnt"
11792 [(set (match_operand:SWI248 0 "register_operand" "=r")
11793 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11794 (clobber (reg:CC FLAGS_REG))]
11796 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11797 [(set_attr "prefix_rep" "1")
11798 (set_attr "type" "bitmanip")
11799 (set_attr "mode" "<MODE>")])
11801 ;; BMI instructions.
11802 (define_insn "*bmi_andn_<mode>"
11803 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
11806 (match_operand:SWI48 1 "register_operand" "r,r"))
11807 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
11808 (clobber (reg:CC FLAGS_REG))]
11810 "andn\t{%2, %1, %0|%0, %1, %2}"
11811 [(set_attr "type" "bitmanip")
11812 (set_attr "btver2_decode" "direct, double")
11813 (set_attr "mode" "<MODE>")])
11815 (define_insn "bmi_bextr_<mode>"
11816 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
11817 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r,r")
11818 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")]
11820 (clobber (reg:CC FLAGS_REG))]
11822 "bextr\t{%2, %1, %0|%0, %1, %2}"
11823 [(set_attr "type" "bitmanip")
11824 (set_attr "btver2_decode" "direct, double")
11825 (set_attr "mode" "<MODE>")])
11827 (define_insn "*bmi_blsi_<mode>"
11828 [(set (match_operand:SWI48 0 "register_operand" "=r")
11831 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
11833 (clobber (reg:CC FLAGS_REG))]
11835 "blsi\t{%1, %0|%0, %1}"
11836 [(set_attr "type" "bitmanip")
11837 (set_attr "btver2_decode" "double")
11838 (set_attr "mode" "<MODE>")])
11840 (define_insn "*bmi_blsmsk_<mode>"
11841 [(set (match_operand:SWI48 0 "register_operand" "=r")
11844 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11847 (clobber (reg:CC FLAGS_REG))]
11849 "blsmsk\t{%1, %0|%0, %1}"
11850 [(set_attr "type" "bitmanip")
11851 (set_attr "btver2_decode" "double")
11852 (set_attr "mode" "<MODE>")])
11854 (define_insn "*bmi_blsr_<mode>"
11855 [(set (match_operand:SWI48 0 "register_operand" "=r")
11858 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11861 (clobber (reg:CC FLAGS_REG))]
11863 "blsr\t{%1, %0|%0, %1}"
11864 [(set_attr "type" "bitmanip")
11865 (set_attr "btver2_decode" "double")
11866 (set_attr "mode" "<MODE>")])
11868 ;; BMI2 instructions.
11869 (define_insn "bmi2_bzhi_<mode>3"
11870 [(set (match_operand:SWI48 0 "register_operand" "=r")
11871 (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
11872 (lshiftrt:SWI48 (const_int -1)
11873 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
11874 (clobber (reg:CC FLAGS_REG))]
11876 "bzhi\t{%2, %1, %0|%0, %1, %2}"
11877 [(set_attr "type" "bitmanip")
11878 (set_attr "prefix" "vex")
11879 (set_attr "mode" "<MODE>")])
11881 (define_insn "bmi2_pdep_<mode>3"
11882 [(set (match_operand:SWI48 0 "register_operand" "=r")
11883 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
11884 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
11887 "pdep\t{%2, %1, %0|%0, %1, %2}"
11888 [(set_attr "type" "bitmanip")
11889 (set_attr "prefix" "vex")
11890 (set_attr "mode" "<MODE>")])
11892 (define_insn "bmi2_pext_<mode>3"
11893 [(set (match_operand:SWI48 0 "register_operand" "=r")
11894 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
11895 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
11898 "pext\t{%2, %1, %0|%0, %1, %2}"
11899 [(set_attr "type" "bitmanip")
11900 (set_attr "prefix" "vex")
11901 (set_attr "mode" "<MODE>")])
11903 ;; TBM instructions.
11904 (define_insn "tbm_bextri_<mode>"
11905 [(set (match_operand:SWI48 0 "register_operand" "=r")
11906 (zero_extract:SWI48
11907 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11908 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
11909 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
11910 (clobber (reg:CC FLAGS_REG))]
11913 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
11914 return "bextr\t{%2, %1, %0|%0, %1, %2}";
11916 [(set_attr "type" "bitmanip")
11917 (set_attr "mode" "<MODE>")])
11919 (define_insn "*tbm_blcfill_<mode>"
11920 [(set (match_operand:SWI48 0 "register_operand" "=r")
11923 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11926 (clobber (reg:CC FLAGS_REG))]
11928 "blcfill\t{%1, %0|%0, %1}"
11929 [(set_attr "type" "bitmanip")
11930 (set_attr "mode" "<MODE>")])
11932 (define_insn "*tbm_blci_<mode>"
11933 [(set (match_operand:SWI48 0 "register_operand" "=r")
11937 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11940 (clobber (reg:CC FLAGS_REG))]
11942 "blci\t{%1, %0|%0, %1}"
11943 [(set_attr "type" "bitmanip")
11944 (set_attr "mode" "<MODE>")])
11946 (define_insn "*tbm_blcic_<mode>"
11947 [(set (match_operand:SWI48 0 "register_operand" "=r")
11950 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11954 (clobber (reg:CC FLAGS_REG))]
11956 "blcic\t{%1, %0|%0, %1}"
11957 [(set_attr "type" "bitmanip")
11958 (set_attr "mode" "<MODE>")])
11960 (define_insn "*tbm_blcmsk_<mode>"
11961 [(set (match_operand:SWI48 0 "register_operand" "=r")
11964 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11967 (clobber (reg:CC FLAGS_REG))]
11969 "blcmsk\t{%1, %0|%0, %1}"
11970 [(set_attr "type" "bitmanip")
11971 (set_attr "mode" "<MODE>")])
11973 (define_insn "*tbm_blcs_<mode>"
11974 [(set (match_operand:SWI48 0 "register_operand" "=r")
11977 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11980 (clobber (reg:CC FLAGS_REG))]
11982 "blcs\t{%1, %0|%0, %1}"
11983 [(set_attr "type" "bitmanip")
11984 (set_attr "mode" "<MODE>")])
11986 (define_insn "*tbm_blsfill_<mode>"
11987 [(set (match_operand:SWI48 0 "register_operand" "=r")
11990 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11993 (clobber (reg:CC FLAGS_REG))]
11995 "blsfill\t{%1, %0|%0, %1}"
11996 [(set_attr "type" "bitmanip")
11997 (set_attr "mode" "<MODE>")])
11999 (define_insn "*tbm_blsic_<mode>"
12000 [(set (match_operand:SWI48 0 "register_operand" "=r")
12003 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12007 (clobber (reg:CC FLAGS_REG))]
12009 "blsic\t{%1, %0|%0, %1}"
12010 [(set_attr "type" "bitmanip")
12011 (set_attr "mode" "<MODE>")])
12013 (define_insn "*tbm_t1mskc_<mode>"
12014 [(set (match_operand:SWI48 0 "register_operand" "=r")
12017 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12021 (clobber (reg:CC FLAGS_REG))]
12023 "t1mskc\t{%1, %0|%0, %1}"
12024 [(set_attr "type" "bitmanip")
12025 (set_attr "mode" "<MODE>")])
12027 (define_insn "*tbm_tzmsk_<mode>"
12028 [(set (match_operand:SWI48 0 "register_operand" "=r")
12031 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12035 (clobber (reg:CC FLAGS_REG))]
12037 "tzmsk\t{%1, %0|%0, %1}"
12038 [(set_attr "type" "bitmanip")
12039 (set_attr "mode" "<MODE>")])
12041 (define_insn "bsr_rex64"
12042 [(set (match_operand:DI 0 "register_operand" "=r")
12043 (minus:DI (const_int 63)
12044 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12045 (clobber (reg:CC FLAGS_REG))]
12047 "bsr{q}\t{%1, %0|%0, %1}"
12048 [(set_attr "type" "alu1")
12049 (set_attr "prefix_0f" "1")
12050 (set_attr "mode" "DI")])
12053 [(set (match_operand:SI 0 "register_operand" "=r")
12054 (minus:SI (const_int 31)
12055 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12056 (clobber (reg:CC FLAGS_REG))]
12058 "bsr{l}\t{%1, %0|%0, %1}"
12059 [(set_attr "type" "alu1")
12060 (set_attr "prefix_0f" "1")
12061 (set_attr "mode" "SI")])
12063 (define_insn "*bsrhi"
12064 [(set (match_operand:HI 0 "register_operand" "=r")
12065 (minus:HI (const_int 15)
12066 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12067 (clobber (reg:CC FLAGS_REG))]
12069 "bsr{w}\t{%1, %0|%0, %1}"
12070 [(set_attr "type" "alu1")
12071 (set_attr "prefix_0f" "1")
12072 (set_attr "mode" "HI")])
12074 (define_insn "popcount<mode>2"
12075 [(set (match_operand:SWI248 0 "register_operand" "=r")
12077 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12078 (clobber (reg:CC FLAGS_REG))]
12082 return "popcnt\t{%1, %0|%0, %1}";
12084 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12087 [(set_attr "prefix_rep" "1")
12088 (set_attr "type" "bitmanip")
12089 (set_attr "mode" "<MODE>")])
12091 (define_insn "*popcount<mode>2_cmp"
12092 [(set (reg FLAGS_REG)
12095 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12097 (set (match_operand:SWI248 0 "register_operand" "=r")
12098 (popcount:SWI248 (match_dup 1)))]
12099 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12102 return "popcnt\t{%1, %0|%0, %1}";
12104 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12107 [(set_attr "prefix_rep" "1")
12108 (set_attr "type" "bitmanip")
12109 (set_attr "mode" "<MODE>")])
12111 (define_insn "*popcountsi2_cmp_zext"
12112 [(set (reg FLAGS_REG)
12114 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12116 (set (match_operand:DI 0 "register_operand" "=r")
12117 (zero_extend:DI(popcount:SI (match_dup 1))))]
12118 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12121 return "popcnt\t{%1, %0|%0, %1}";
12123 return "popcnt{l}\t{%1, %0|%0, %1}";
12126 [(set_attr "prefix_rep" "1")
12127 (set_attr "type" "bitmanip")
12128 (set_attr "mode" "SI")])
12130 (define_expand "bswapdi2"
12131 [(set (match_operand:DI 0 "register_operand")
12132 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
12136 operands[1] = force_reg (DImode, operands[1]);
12139 (define_expand "bswapsi2"
12140 [(set (match_operand:SI 0 "register_operand")
12141 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
12146 else if (TARGET_BSWAP)
12147 operands[1] = force_reg (SImode, operands[1]);
12150 rtx x = operands[0];
12152 emit_move_insn (x, operands[1]);
12153 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12154 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12155 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12160 (define_insn "*bswap<mode>2_movbe"
12161 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12162 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12164 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12167 movbe\t{%1, %0|%0, %1}
12168 movbe\t{%1, %0|%0, %1}"
12169 [(set_attr "type" "bitmanip,imov,imov")
12170 (set_attr "modrm" "0,1,1")
12171 (set_attr "prefix_0f" "*,1,1")
12172 (set_attr "prefix_extra" "*,1,1")
12173 (set_attr "mode" "<MODE>")])
12175 (define_insn "*bswap<mode>2"
12176 [(set (match_operand:SWI48 0 "register_operand" "=r")
12177 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12180 [(set_attr "type" "bitmanip")
12181 (set_attr "modrm" "0")
12182 (set_attr "mode" "<MODE>")])
12184 (define_insn "*bswaphi_lowpart_1"
12185 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12186 (bswap:HI (match_dup 0)))
12187 (clobber (reg:CC FLAGS_REG))]
12188 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12190 xchg{b}\t{%h0, %b0|%b0, %h0}
12191 rol{w}\t{$8, %0|%0, 8}"
12192 [(set_attr "length" "2,4")
12193 (set_attr "mode" "QI,HI")])
12195 (define_insn "bswaphi_lowpart"
12196 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12197 (bswap:HI (match_dup 0)))
12198 (clobber (reg:CC FLAGS_REG))]
12200 "rol{w}\t{$8, %0|%0, 8}"
12201 [(set_attr "length" "4")
12202 (set_attr "mode" "HI")])
12204 (define_expand "paritydi2"
12205 [(set (match_operand:DI 0 "register_operand")
12206 (parity:DI (match_operand:DI 1 "register_operand")))]
12209 rtx scratch = gen_reg_rtx (QImode);
12212 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12213 NULL_RTX, operands[1]));
12215 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12216 gen_rtx_REG (CCmode, FLAGS_REG),
12218 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12221 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12224 rtx tmp = gen_reg_rtx (SImode);
12226 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12227 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12232 (define_expand "paritysi2"
12233 [(set (match_operand:SI 0 "register_operand")
12234 (parity:SI (match_operand:SI 1 "register_operand")))]
12237 rtx scratch = gen_reg_rtx (QImode);
12240 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12242 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12243 gen_rtx_REG (CCmode, FLAGS_REG),
12245 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12247 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12251 (define_insn_and_split "paritydi2_cmp"
12252 [(set (reg:CC FLAGS_REG)
12253 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12255 (clobber (match_scratch:DI 0 "=r"))
12256 (clobber (match_scratch:SI 1 "=&r"))
12257 (clobber (match_scratch:HI 2 "=Q"))]
12260 "&& reload_completed"
12262 [(set (match_dup 1)
12263 (xor:SI (match_dup 1) (match_dup 4)))
12264 (clobber (reg:CC FLAGS_REG))])
12266 [(set (reg:CC FLAGS_REG)
12267 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12268 (clobber (match_dup 1))
12269 (clobber (match_dup 2))])]
12271 operands[4] = gen_lowpart (SImode, operands[3]);
12275 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12276 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12279 operands[1] = gen_highpart (SImode, operands[3]);
12282 (define_insn_and_split "paritysi2_cmp"
12283 [(set (reg:CC FLAGS_REG)
12284 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12286 (clobber (match_scratch:SI 0 "=r"))
12287 (clobber (match_scratch:HI 1 "=&Q"))]
12290 "&& reload_completed"
12292 [(set (match_dup 1)
12293 (xor:HI (match_dup 1) (match_dup 3)))
12294 (clobber (reg:CC FLAGS_REG))])
12296 [(set (reg:CC FLAGS_REG)
12297 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12298 (clobber (match_dup 1))])]
12300 operands[3] = gen_lowpart (HImode, operands[2]);
12302 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12303 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12306 (define_insn "*parityhi2_cmp"
12307 [(set (reg:CC FLAGS_REG)
12308 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12310 (clobber (match_scratch:HI 0 "=Q"))]
12312 "xor{b}\t{%h0, %b0|%b0, %h0}"
12313 [(set_attr "length" "2")
12314 (set_attr "mode" "HI")])
12317 ;; Thread-local storage patterns for ELF.
12319 ;; Note that these code sequences must appear exactly as shown
12320 ;; in order to allow linker relaxation.
12322 (define_insn "*tls_global_dynamic_32_gnu"
12323 [(set (match_operand:SI 0 "register_operand" "=a")
12325 [(match_operand:SI 1 "register_operand" "b")
12326 (match_operand 2 "tls_symbolic_operand")
12327 (match_operand 3 "constant_call_address_operand" "z")]
12329 (clobber (match_scratch:SI 4 "=d"))
12330 (clobber (match_scratch:SI 5 "=c"))
12331 (clobber (reg:CC FLAGS_REG))]
12332 "!TARGET_64BIT && TARGET_GNU_TLS"
12335 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12336 if (TARGET_SUN_TLS)
12337 #ifdef HAVE_AS_IX86_TLSGDPLT
12338 return "call\t%a2@tlsgdplt";
12340 return "call\t%p3@plt";
12342 return "call\t%P3";
12344 [(set_attr "type" "multi")
12345 (set_attr "length" "12")])
12347 (define_expand "tls_global_dynamic_32"
12349 [(set (match_operand:SI 0 "register_operand")
12350 (unspec:SI [(match_operand:SI 2 "register_operand")
12351 (match_operand 1 "tls_symbolic_operand")
12352 (match_operand 3 "constant_call_address_operand")]
12354 (clobber (match_scratch:SI 4))
12355 (clobber (match_scratch:SI 5))
12356 (clobber (reg:CC FLAGS_REG))])])
12358 (define_insn "*tls_global_dynamic_64_<mode>"
12359 [(set (match_operand:P 0 "register_operand" "=a")
12361 (mem:QI (match_operand 2 "constant_call_address_operand" "z"))
12362 (match_operand 3)))
12363 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12368 fputs (ASM_BYTE "0x66\n", asm_out_file);
12370 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12371 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12372 fputs ("\trex64\n", asm_out_file);
12373 if (TARGET_SUN_TLS)
12374 return "call\t%p2@plt";
12375 return "call\t%P2";
12377 [(set_attr "type" "multi")
12378 (set (attr "length")
12379 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12381 (define_expand "tls_global_dynamic_64_<mode>"
12383 [(set (match_operand:P 0 "register_operand")
12385 (mem:QI (match_operand 2 "constant_call_address_operand"))
12387 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12391 (define_insn "*tls_local_dynamic_base_32_gnu"
12392 [(set (match_operand:SI 0 "register_operand" "=a")
12394 [(match_operand:SI 1 "register_operand" "b")
12395 (match_operand 2 "constant_call_address_operand" "z")]
12396 UNSPEC_TLS_LD_BASE))
12397 (clobber (match_scratch:SI 3 "=d"))
12398 (clobber (match_scratch:SI 4 "=c"))
12399 (clobber (reg:CC FLAGS_REG))]
12400 "!TARGET_64BIT && TARGET_GNU_TLS"
12403 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12404 if (TARGET_SUN_TLS)
12405 #ifdef HAVE_AS_IX86_TLSLDMPLT
12406 return "call\t%&@tlsldmplt";
12408 return "call\t%p2@plt";
12410 return "call\t%P2";
12412 [(set_attr "type" "multi")
12413 (set_attr "length" "11")])
12415 (define_expand "tls_local_dynamic_base_32"
12417 [(set (match_operand:SI 0 "register_operand")
12419 [(match_operand:SI 1 "register_operand")
12420 (match_operand 2 "constant_call_address_operand")]
12421 UNSPEC_TLS_LD_BASE))
12422 (clobber (match_scratch:SI 3))
12423 (clobber (match_scratch:SI 4))
12424 (clobber (reg:CC FLAGS_REG))])])
12426 (define_insn "*tls_local_dynamic_base_64_<mode>"
12427 [(set (match_operand:P 0 "register_operand" "=a")
12429 (mem:QI (match_operand 1 "constant_call_address_operand" "z"))
12430 (match_operand 2)))
12431 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12435 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12436 if (TARGET_SUN_TLS)
12437 return "call\t%p1@plt";
12438 return "call\t%P1";
12440 [(set_attr "type" "multi")
12441 (set_attr "length" "12")])
12443 (define_expand "tls_local_dynamic_base_64_<mode>"
12445 [(set (match_operand:P 0 "register_operand")
12447 (mem:QI (match_operand 1 "constant_call_address_operand"))
12449 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12452 ;; Local dynamic of a single variable is a lose. Show combine how
12453 ;; to convert that back to global dynamic.
12455 (define_insn_and_split "*tls_local_dynamic_32_once"
12456 [(set (match_operand:SI 0 "register_operand" "=a")
12458 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12459 (match_operand 2 "constant_call_address_operand" "z")]
12460 UNSPEC_TLS_LD_BASE)
12461 (const:SI (unspec:SI
12462 [(match_operand 3 "tls_symbolic_operand")]
12464 (clobber (match_scratch:SI 4 "=d"))
12465 (clobber (match_scratch:SI 5 "=c"))
12466 (clobber (reg:CC FLAGS_REG))]
12471 [(set (match_dup 0)
12472 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12474 (clobber (match_dup 4))
12475 (clobber (match_dup 5))
12476 (clobber (reg:CC FLAGS_REG))])])
12478 ;; Segment register for the thread base ptr load
12479 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12481 ;; Load and add the thread base pointer from %<tp_seg>:0.
12482 (define_insn "*load_tp_x32"
12483 [(set (match_operand:SI 0 "register_operand" "=r")
12484 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12486 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12487 [(set_attr "type" "imov")
12488 (set_attr "modrm" "0")
12489 (set_attr "length" "7")
12490 (set_attr "memory" "load")
12491 (set_attr "imm_disp" "false")])
12493 (define_insn "*load_tp_x32_zext"
12494 [(set (match_operand:DI 0 "register_operand" "=r")
12495 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12497 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12498 [(set_attr "type" "imov")
12499 (set_attr "modrm" "0")
12500 (set_attr "length" "7")
12501 (set_attr "memory" "load")
12502 (set_attr "imm_disp" "false")])
12504 (define_insn "*load_tp_<mode>"
12505 [(set (match_operand:P 0 "register_operand" "=r")
12506 (unspec:P [(const_int 0)] UNSPEC_TP))]
12508 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12509 [(set_attr "type" "imov")
12510 (set_attr "modrm" "0")
12511 (set_attr "length" "7")
12512 (set_attr "memory" "load")
12513 (set_attr "imm_disp" "false")])
12515 (define_insn "*add_tp_x32"
12516 [(set (match_operand:SI 0 "register_operand" "=r")
12517 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12518 (match_operand:SI 1 "register_operand" "0")))
12519 (clobber (reg:CC FLAGS_REG))]
12521 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12522 [(set_attr "type" "alu")
12523 (set_attr "modrm" "0")
12524 (set_attr "length" "7")
12525 (set_attr "memory" "load")
12526 (set_attr "imm_disp" "false")])
12528 (define_insn "*add_tp_x32_zext"
12529 [(set (match_operand:DI 0 "register_operand" "=r")
12531 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12532 (match_operand:SI 1 "register_operand" "0"))))
12533 (clobber (reg:CC FLAGS_REG))]
12535 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12536 [(set_attr "type" "alu")
12537 (set_attr "modrm" "0")
12538 (set_attr "length" "7")
12539 (set_attr "memory" "load")
12540 (set_attr "imm_disp" "false")])
12542 (define_insn "*add_tp_<mode>"
12543 [(set (match_operand:P 0 "register_operand" "=r")
12544 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12545 (match_operand:P 1 "register_operand" "0")))
12546 (clobber (reg:CC FLAGS_REG))]
12548 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12549 [(set_attr "type" "alu")
12550 (set_attr "modrm" "0")
12551 (set_attr "length" "7")
12552 (set_attr "memory" "load")
12553 (set_attr "imm_disp" "false")])
12555 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12556 ;; %rax as destination of the initial executable code sequence.
12557 (define_insn "tls_initial_exec_64_sun"
12558 [(set (match_operand:DI 0 "register_operand" "=a")
12560 [(match_operand 1 "tls_symbolic_operand")]
12561 UNSPEC_TLS_IE_SUN))
12562 (clobber (reg:CC FLAGS_REG))]
12563 "TARGET_64BIT && TARGET_SUN_TLS"
12566 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12567 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12569 [(set_attr "type" "multi")])
12571 ;; GNU2 TLS patterns can be split.
12573 (define_expand "tls_dynamic_gnu2_32"
12574 [(set (match_dup 3)
12575 (plus:SI (match_operand:SI 2 "register_operand")
12577 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
12580 [(set (match_operand:SI 0 "register_operand")
12581 (unspec:SI [(match_dup 1) (match_dup 3)
12582 (match_dup 2) (reg:SI SP_REG)]
12584 (clobber (reg:CC FLAGS_REG))])]
12585 "!TARGET_64BIT && TARGET_GNU2_TLS"
12587 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12588 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12591 (define_insn "*tls_dynamic_gnu2_lea_32"
12592 [(set (match_operand:SI 0 "register_operand" "=r")
12593 (plus:SI (match_operand:SI 1 "register_operand" "b")
12595 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
12596 UNSPEC_TLSDESC))))]
12597 "!TARGET_64BIT && TARGET_GNU2_TLS"
12598 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
12599 [(set_attr "type" "lea")
12600 (set_attr "mode" "SI")
12601 (set_attr "length" "6")
12602 (set_attr "length_address" "4")])
12604 (define_insn "*tls_dynamic_gnu2_call_32"
12605 [(set (match_operand:SI 0 "register_operand" "=a")
12606 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
12607 (match_operand:SI 2 "register_operand" "0")
12608 ;; we have to make sure %ebx still points to the GOT
12609 (match_operand:SI 3 "register_operand" "b")
12612 (clobber (reg:CC FLAGS_REG))]
12613 "!TARGET_64BIT && TARGET_GNU2_TLS"
12614 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12615 [(set_attr "type" "call")
12616 (set_attr "length" "2")
12617 (set_attr "length_address" "0")])
12619 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12620 [(set (match_operand:SI 0 "register_operand" "=&a")
12622 (unspec:SI [(match_operand 3 "tls_modbase_operand")
12623 (match_operand:SI 4)
12624 (match_operand:SI 2 "register_operand" "b")
12627 (const:SI (unspec:SI
12628 [(match_operand 1 "tls_symbolic_operand")]
12630 (clobber (reg:CC FLAGS_REG))]
12631 "!TARGET_64BIT && TARGET_GNU2_TLS"
12634 [(set (match_dup 0) (match_dup 5))]
12636 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12637 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12640 (define_expand "tls_dynamic_gnu2_64"
12641 [(set (match_dup 2)
12642 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
12645 [(set (match_operand:DI 0 "register_operand")
12646 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12648 (clobber (reg:CC FLAGS_REG))])]
12649 "TARGET_64BIT && TARGET_GNU2_TLS"
12651 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12652 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12655 (define_insn "*tls_dynamic_gnu2_lea_64"
12656 [(set (match_operand:DI 0 "register_operand" "=r")
12657 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
12659 "TARGET_64BIT && TARGET_GNU2_TLS"
12660 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
12661 [(set_attr "type" "lea")
12662 (set_attr "mode" "DI")
12663 (set_attr "length" "7")
12664 (set_attr "length_address" "4")])
12666 (define_insn "*tls_dynamic_gnu2_call_64"
12667 [(set (match_operand:DI 0 "register_operand" "=a")
12668 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
12669 (match_operand:DI 2 "register_operand" "0")
12672 (clobber (reg:CC FLAGS_REG))]
12673 "TARGET_64BIT && TARGET_GNU2_TLS"
12674 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12675 [(set_attr "type" "call")
12676 (set_attr "length" "2")
12677 (set_attr "length_address" "0")])
12679 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12680 [(set (match_operand:DI 0 "register_operand" "=&a")
12682 (unspec:DI [(match_operand 2 "tls_modbase_operand")
12683 (match_operand:DI 3)
12686 (const:DI (unspec:DI
12687 [(match_operand 1 "tls_symbolic_operand")]
12689 (clobber (reg:CC FLAGS_REG))]
12690 "TARGET_64BIT && TARGET_GNU2_TLS"
12693 [(set (match_dup 0) (match_dup 4))]
12695 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12696 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12699 ;; These patterns match the binary 387 instructions for addM3, subM3,
12700 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12701 ;; SFmode. The first is the normal insn, the second the same insn but
12702 ;; with one operand a conversion, and the third the same insn but with
12703 ;; the other operand a conversion. The conversion may be SFmode or
12704 ;; SImode if the target mode DFmode, but only SImode if the target mode
12707 ;; Gcc is slightly more smart about handling normal two address instructions
12708 ;; so use special patterns for add and mull.
12710 (define_insn "*fop_<mode>_comm_mixed"
12711 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12712 (match_operator:MODEF 3 "binary_fp_operator"
12713 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12714 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12715 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12716 && COMMUTATIVE_ARITH_P (operands[3])
12717 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12718 "* return output_387_binary_op (insn, operands);"
12719 [(set (attr "type")
12720 (if_then_else (eq_attr "alternative" "1,2")
12721 (if_then_else (match_operand:MODEF 3 "mult_operator")
12722 (const_string "ssemul")
12723 (const_string "sseadd"))
12724 (if_then_else (match_operand:MODEF 3 "mult_operator")
12725 (const_string "fmul")
12726 (const_string "fop"))))
12727 (set_attr "isa" "*,noavx,avx")
12728 (set_attr "prefix" "orig,orig,vex")
12729 (set_attr "mode" "<MODE>")])
12731 (define_insn "*fop_<mode>_comm_sse"
12732 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12733 (match_operator:MODEF 3 "binary_fp_operator"
12734 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12735 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12736 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12737 && COMMUTATIVE_ARITH_P (operands[3])
12738 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12739 "* return output_387_binary_op (insn, operands);"
12740 [(set (attr "type")
12741 (if_then_else (match_operand:MODEF 3 "mult_operator")
12742 (const_string "ssemul")
12743 (const_string "sseadd")))
12744 (set_attr "isa" "noavx,avx")
12745 (set_attr "prefix" "orig,vex")
12746 (set_attr "mode" "<MODE>")])
12748 (define_insn "*fop_<mode>_comm_i387"
12749 [(set (match_operand:MODEF 0 "register_operand" "=f")
12750 (match_operator:MODEF 3 "binary_fp_operator"
12751 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12752 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12753 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12754 && COMMUTATIVE_ARITH_P (operands[3])
12755 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12756 "* return output_387_binary_op (insn, operands);"
12757 [(set (attr "type")
12758 (if_then_else (match_operand:MODEF 3 "mult_operator")
12759 (const_string "fmul")
12760 (const_string "fop")))
12761 (set_attr "mode" "<MODE>")])
12763 (define_insn "*fop_<mode>_1_mixed"
12764 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
12765 (match_operator:MODEF 3 "binary_fp_operator"
12766 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
12767 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
12768 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12769 && !COMMUTATIVE_ARITH_P (operands[3])
12770 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12771 "* return output_387_binary_op (insn, operands);"
12772 [(set (attr "type")
12773 (cond [(and (eq_attr "alternative" "2,3")
12774 (match_operand:MODEF 3 "mult_operator"))
12775 (const_string "ssemul")
12776 (and (eq_attr "alternative" "2,3")
12777 (match_operand:MODEF 3 "div_operator"))
12778 (const_string "ssediv")
12779 (eq_attr "alternative" "2,3")
12780 (const_string "sseadd")
12781 (match_operand:MODEF 3 "mult_operator")
12782 (const_string "fmul")
12783 (match_operand:MODEF 3 "div_operator")
12784 (const_string "fdiv")
12786 (const_string "fop")))
12787 (set_attr "isa" "*,*,noavx,avx")
12788 (set_attr "prefix" "orig,orig,orig,vex")
12789 (set_attr "mode" "<MODE>")])
12791 (define_insn "*rcpsf2_sse"
12792 [(set (match_operand:SF 0 "register_operand" "=x")
12793 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12796 "%vrcpss\t{%1, %d0|%d0, %1}"
12797 [(set_attr "type" "sse")
12798 (set_attr "atom_sse_attr" "rcp")
12799 (set_attr "btver2_sse_attr" "rcp")
12800 (set_attr "prefix" "maybe_vex")
12801 (set_attr "mode" "SF")])
12803 (define_insn "*fop_<mode>_1_sse"
12804 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12805 (match_operator:MODEF 3 "binary_fp_operator"
12806 [(match_operand:MODEF 1 "register_operand" "0,x")
12807 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12808 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12809 && !COMMUTATIVE_ARITH_P (operands[3])"
12810 "* return output_387_binary_op (insn, operands);"
12811 [(set (attr "type")
12812 (cond [(match_operand:MODEF 3 "mult_operator")
12813 (const_string "ssemul")
12814 (match_operand:MODEF 3 "div_operator")
12815 (const_string "ssediv")
12817 (const_string "sseadd")))
12818 (set_attr "isa" "noavx,avx")
12819 (set_attr "prefix" "orig,vex")
12820 (set_attr "mode" "<MODE>")])
12822 ;; This pattern is not fully shadowed by the pattern above.
12823 (define_insn "*fop_<mode>_1_i387"
12824 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12825 (match_operator:MODEF 3 "binary_fp_operator"
12826 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12827 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12828 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12829 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12830 && !COMMUTATIVE_ARITH_P (operands[3])
12831 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12832 "* return output_387_binary_op (insn, operands);"
12833 [(set (attr "type")
12834 (cond [(match_operand:MODEF 3 "mult_operator")
12835 (const_string "fmul")
12836 (match_operand:MODEF 3 "div_operator")
12837 (const_string "fdiv")
12839 (const_string "fop")))
12840 (set_attr "mode" "<MODE>")])
12842 ;; ??? Add SSE splitters for these!
12843 (define_insn "*fop_<MODEF:mode>_2_i387"
12844 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12845 (match_operator:MODEF 3 "binary_fp_operator"
12847 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
12848 (match_operand:MODEF 2 "register_operand" "0,0")]))]
12849 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
12850 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12851 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12852 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12853 [(set (attr "type")
12854 (cond [(match_operand:MODEF 3 "mult_operator")
12855 (const_string "fmul")
12856 (match_operand:MODEF 3 "div_operator")
12857 (const_string "fdiv")
12859 (const_string "fop")))
12860 (set_attr "fp_int_src" "true")
12861 (set_attr "mode" "<SWI24:MODE>")])
12863 (define_insn "*fop_<MODEF:mode>_3_i387"
12864 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12865 (match_operator:MODEF 3 "binary_fp_operator"
12866 [(match_operand:MODEF 1 "register_operand" "0,0")
12868 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
12869 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
12870 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12871 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12872 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12873 [(set (attr "type")
12874 (cond [(match_operand:MODEF 3 "mult_operator")
12875 (const_string "fmul")
12876 (match_operand:MODEF 3 "div_operator")
12877 (const_string "fdiv")
12879 (const_string "fop")))
12880 (set_attr "fp_int_src" "true")
12881 (set_attr "mode" "<MODE>")])
12883 (define_insn "*fop_df_4_i387"
12884 [(set (match_operand:DF 0 "register_operand" "=f,f")
12885 (match_operator:DF 3 "binary_fp_operator"
12887 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12888 (match_operand:DF 2 "register_operand" "0,f")]))]
12889 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12890 && !(TARGET_SSE2 && TARGET_SSE_MATH)
12891 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12892 "* return output_387_binary_op (insn, operands);"
12893 [(set (attr "type")
12894 (cond [(match_operand:DF 3 "mult_operator")
12895 (const_string "fmul")
12896 (match_operand:DF 3 "div_operator")
12897 (const_string "fdiv")
12899 (const_string "fop")))
12900 (set_attr "mode" "SF")])
12902 (define_insn "*fop_df_5_i387"
12903 [(set (match_operand:DF 0 "register_operand" "=f,f")
12904 (match_operator:DF 3 "binary_fp_operator"
12905 [(match_operand:DF 1 "register_operand" "0,f")
12907 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12908 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12909 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12910 "* return output_387_binary_op (insn, operands);"
12911 [(set (attr "type")
12912 (cond [(match_operand:DF 3 "mult_operator")
12913 (const_string "fmul")
12914 (match_operand:DF 3 "div_operator")
12915 (const_string "fdiv")
12917 (const_string "fop")))
12918 (set_attr "mode" "SF")])
12920 (define_insn "*fop_df_6_i387"
12921 [(set (match_operand:DF 0 "register_operand" "=f,f")
12922 (match_operator:DF 3 "binary_fp_operator"
12924 (match_operand:SF 1 "register_operand" "0,f"))
12926 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12927 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12928 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12929 "* return output_387_binary_op (insn, operands);"
12930 [(set (attr "type")
12931 (cond [(match_operand:DF 3 "mult_operator")
12932 (const_string "fmul")
12933 (match_operand:DF 3 "div_operator")
12934 (const_string "fdiv")
12936 (const_string "fop")))
12937 (set_attr "mode" "SF")])
12939 (define_insn "*fop_xf_comm_i387"
12940 [(set (match_operand:XF 0 "register_operand" "=f")
12941 (match_operator:XF 3 "binary_fp_operator"
12942 [(match_operand:XF 1 "register_operand" "%0")
12943 (match_operand:XF 2 "register_operand" "f")]))]
12945 && COMMUTATIVE_ARITH_P (operands[3])"
12946 "* return output_387_binary_op (insn, operands);"
12947 [(set (attr "type")
12948 (if_then_else (match_operand:XF 3 "mult_operator")
12949 (const_string "fmul")
12950 (const_string "fop")))
12951 (set_attr "mode" "XF")])
12953 (define_insn "*fop_xf_1_i387"
12954 [(set (match_operand:XF 0 "register_operand" "=f,f")
12955 (match_operator:XF 3 "binary_fp_operator"
12956 [(match_operand:XF 1 "register_operand" "0,f")
12957 (match_operand:XF 2 "register_operand" "f,0")]))]
12959 && !COMMUTATIVE_ARITH_P (operands[3])"
12960 "* return output_387_binary_op (insn, operands);"
12961 [(set (attr "type")
12962 (cond [(match_operand:XF 3 "mult_operator")
12963 (const_string "fmul")
12964 (match_operand:XF 3 "div_operator")
12965 (const_string "fdiv")
12967 (const_string "fop")))
12968 (set_attr "mode" "XF")])
12970 (define_insn "*fop_xf_2_i387"
12971 [(set (match_operand:XF 0 "register_operand" "=f,f")
12972 (match_operator:XF 3 "binary_fp_operator"
12974 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
12975 (match_operand:XF 2 "register_operand" "0,0")]))]
12976 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12977 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12978 [(set (attr "type")
12979 (cond [(match_operand:XF 3 "mult_operator")
12980 (const_string "fmul")
12981 (match_operand:XF 3 "div_operator")
12982 (const_string "fdiv")
12984 (const_string "fop")))
12985 (set_attr "fp_int_src" "true")
12986 (set_attr "mode" "<MODE>")])
12988 (define_insn "*fop_xf_3_i387"
12989 [(set (match_operand:XF 0 "register_operand" "=f,f")
12990 (match_operator:XF 3 "binary_fp_operator"
12991 [(match_operand:XF 1 "register_operand" "0,0")
12993 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
12994 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12995 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12996 [(set (attr "type")
12997 (cond [(match_operand:XF 3 "mult_operator")
12998 (const_string "fmul")
12999 (match_operand:XF 3 "div_operator")
13000 (const_string "fdiv")
13002 (const_string "fop")))
13003 (set_attr "fp_int_src" "true")
13004 (set_attr "mode" "<MODE>")])
13006 (define_insn "*fop_xf_4_i387"
13007 [(set (match_operand:XF 0 "register_operand" "=f,f")
13008 (match_operator:XF 3 "binary_fp_operator"
13010 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13011 (match_operand:XF 2 "register_operand" "0,f")]))]
13013 "* return output_387_binary_op (insn, operands);"
13014 [(set (attr "type")
13015 (cond [(match_operand:XF 3 "mult_operator")
13016 (const_string "fmul")
13017 (match_operand:XF 3 "div_operator")
13018 (const_string "fdiv")
13020 (const_string "fop")))
13021 (set_attr "mode" "<MODE>")])
13023 (define_insn "*fop_xf_5_i387"
13024 [(set (match_operand:XF 0 "register_operand" "=f,f")
13025 (match_operator:XF 3 "binary_fp_operator"
13026 [(match_operand:XF 1 "register_operand" "0,f")
13028 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13030 "* return output_387_binary_op (insn, operands);"
13031 [(set (attr "type")
13032 (cond [(match_operand:XF 3 "mult_operator")
13033 (const_string "fmul")
13034 (match_operand:XF 3 "div_operator")
13035 (const_string "fdiv")
13037 (const_string "fop")))
13038 (set_attr "mode" "<MODE>")])
13040 (define_insn "*fop_xf_6_i387"
13041 [(set (match_operand:XF 0 "register_operand" "=f,f")
13042 (match_operator:XF 3 "binary_fp_operator"
13044 (match_operand:MODEF 1 "register_operand" "0,f"))
13046 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13048 "* return output_387_binary_op (insn, operands);"
13049 [(set (attr "type")
13050 (cond [(match_operand:XF 3 "mult_operator")
13051 (const_string "fmul")
13052 (match_operand:XF 3 "div_operator")
13053 (const_string "fdiv")
13055 (const_string "fop")))
13056 (set_attr "mode" "<MODE>")])
13059 [(set (match_operand 0 "register_operand")
13060 (match_operator 3 "binary_fp_operator"
13061 [(float (match_operand:SWI24 1 "register_operand"))
13062 (match_operand 2 "register_operand")]))]
13064 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13065 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13068 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13069 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13070 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13071 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13072 GET_MODE (operands[3]),
13075 ix86_free_from_memory (GET_MODE (operands[1]));
13080 [(set (match_operand 0 "register_operand")
13081 (match_operator 3 "binary_fp_operator"
13082 [(match_operand 1 "register_operand")
13083 (float (match_operand:SWI24 2 "register_operand"))]))]
13085 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13086 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13089 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13090 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13091 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13092 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13093 GET_MODE (operands[3]),
13096 ix86_free_from_memory (GET_MODE (operands[2]));
13100 ;; FPU special functions.
13102 ;; This pattern implements a no-op XFmode truncation for
13103 ;; all fancy i386 XFmode math functions.
13105 (define_insn "truncxf<mode>2_i387_noop_unspec"
13106 [(set (match_operand:MODEF 0 "register_operand" "=f")
13107 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13108 UNSPEC_TRUNC_NOOP))]
13109 "TARGET_USE_FANCY_MATH_387"
13110 "* return output_387_reg_move (insn, operands);"
13111 [(set_attr "type" "fmov")
13112 (set_attr "mode" "<MODE>")])
13114 (define_insn "sqrtxf2"
13115 [(set (match_operand:XF 0 "register_operand" "=f")
13116 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13117 "TARGET_USE_FANCY_MATH_387"
13119 [(set_attr "type" "fpspc")
13120 (set_attr "mode" "XF")
13121 (set_attr "athlon_decode" "direct")
13122 (set_attr "amdfam10_decode" "direct")
13123 (set_attr "bdver1_decode" "direct")])
13125 (define_insn "sqrt_extend<mode>xf2_i387"
13126 [(set (match_operand:XF 0 "register_operand" "=f")
13129 (match_operand:MODEF 1 "register_operand" "0"))))]
13130 "TARGET_USE_FANCY_MATH_387"
13132 [(set_attr "type" "fpspc")
13133 (set_attr "mode" "XF")
13134 (set_attr "athlon_decode" "direct")
13135 (set_attr "amdfam10_decode" "direct")
13136 (set_attr "bdver1_decode" "direct")])
13138 (define_insn "*rsqrtsf2_sse"
13139 [(set (match_operand:SF 0 "register_operand" "=x")
13140 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13143 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13144 [(set_attr "type" "sse")
13145 (set_attr "atom_sse_attr" "rcp")
13146 (set_attr "btver2_sse_attr" "rcp")
13147 (set_attr "prefix" "maybe_vex")
13148 (set_attr "mode" "SF")])
13150 (define_expand "rsqrtsf2"
13151 [(set (match_operand:SF 0 "register_operand")
13152 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
13156 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13160 (define_insn "*sqrt<mode>2_sse"
13161 [(set (match_operand:MODEF 0 "register_operand" "=x")
13163 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13164 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13165 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13166 [(set_attr "type" "sse")
13167 (set_attr "atom_sse_attr" "sqrt")
13168 (set_attr "btver2_sse_attr" "sqrt")
13169 (set_attr "prefix" "maybe_vex")
13170 (set_attr "mode" "<MODE>")
13171 (set_attr "athlon_decode" "*")
13172 (set_attr "amdfam10_decode" "*")
13173 (set_attr "bdver1_decode" "*")])
13175 (define_expand "sqrt<mode>2"
13176 [(set (match_operand:MODEF 0 "register_operand")
13178 (match_operand:MODEF 1 "nonimmediate_operand")))]
13179 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13180 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13182 if (<MODE>mode == SFmode
13184 && TARGET_RECIP_SQRT
13185 && !optimize_function_for_size_p (cfun)
13186 && flag_finite_math_only && !flag_trapping_math
13187 && flag_unsafe_math_optimizations)
13189 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13193 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13195 rtx op0 = gen_reg_rtx (XFmode);
13196 rtx op1 = force_reg (<MODE>mode, operands[1]);
13198 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13199 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13204 (define_insn "fpremxf4_i387"
13205 [(set (match_operand:XF 0 "register_operand" "=f")
13206 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13207 (match_operand:XF 3 "register_operand" "1")]
13209 (set (match_operand:XF 1 "register_operand" "=u")
13210 (unspec:XF [(match_dup 2) (match_dup 3)]
13212 (set (reg:CCFP FPSR_REG)
13213 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13215 "TARGET_USE_FANCY_MATH_387"
13217 [(set_attr "type" "fpspc")
13218 (set_attr "mode" "XF")])
13220 (define_expand "fmodxf3"
13221 [(use (match_operand:XF 0 "register_operand"))
13222 (use (match_operand:XF 1 "general_operand"))
13223 (use (match_operand:XF 2 "general_operand"))]
13224 "TARGET_USE_FANCY_MATH_387"
13226 rtx label = gen_label_rtx ();
13228 rtx op1 = gen_reg_rtx (XFmode);
13229 rtx op2 = gen_reg_rtx (XFmode);
13231 emit_move_insn (op2, operands[2]);
13232 emit_move_insn (op1, operands[1]);
13234 emit_label (label);
13235 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13236 ix86_emit_fp_unordered_jump (label);
13237 LABEL_NUSES (label) = 1;
13239 emit_move_insn (operands[0], op1);
13243 (define_expand "fmod<mode>3"
13244 [(use (match_operand:MODEF 0 "register_operand"))
13245 (use (match_operand:MODEF 1 "general_operand"))
13246 (use (match_operand:MODEF 2 "general_operand"))]
13247 "TARGET_USE_FANCY_MATH_387"
13249 rtx (*gen_truncxf) (rtx, rtx);
13251 rtx label = gen_label_rtx ();
13253 rtx op1 = gen_reg_rtx (XFmode);
13254 rtx op2 = gen_reg_rtx (XFmode);
13256 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13257 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13259 emit_label (label);
13260 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13261 ix86_emit_fp_unordered_jump (label);
13262 LABEL_NUSES (label) = 1;
13264 /* Truncate the result properly for strict SSE math. */
13265 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13266 && !TARGET_MIX_SSE_I387)
13267 gen_truncxf = gen_truncxf<mode>2;
13269 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13271 emit_insn (gen_truncxf (operands[0], op1));
13275 (define_insn "fprem1xf4_i387"
13276 [(set (match_operand:XF 0 "register_operand" "=f")
13277 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13278 (match_operand:XF 3 "register_operand" "1")]
13280 (set (match_operand:XF 1 "register_operand" "=u")
13281 (unspec:XF [(match_dup 2) (match_dup 3)]
13283 (set (reg:CCFP FPSR_REG)
13284 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13286 "TARGET_USE_FANCY_MATH_387"
13288 [(set_attr "type" "fpspc")
13289 (set_attr "mode" "XF")])
13291 (define_expand "remainderxf3"
13292 [(use (match_operand:XF 0 "register_operand"))
13293 (use (match_operand:XF 1 "general_operand"))
13294 (use (match_operand:XF 2 "general_operand"))]
13295 "TARGET_USE_FANCY_MATH_387"
13297 rtx label = gen_label_rtx ();
13299 rtx op1 = gen_reg_rtx (XFmode);
13300 rtx op2 = gen_reg_rtx (XFmode);
13302 emit_move_insn (op2, operands[2]);
13303 emit_move_insn (op1, operands[1]);
13305 emit_label (label);
13306 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13307 ix86_emit_fp_unordered_jump (label);
13308 LABEL_NUSES (label) = 1;
13310 emit_move_insn (operands[0], op1);
13314 (define_expand "remainder<mode>3"
13315 [(use (match_operand:MODEF 0 "register_operand"))
13316 (use (match_operand:MODEF 1 "general_operand"))
13317 (use (match_operand:MODEF 2 "general_operand"))]
13318 "TARGET_USE_FANCY_MATH_387"
13320 rtx (*gen_truncxf) (rtx, rtx);
13322 rtx label = gen_label_rtx ();
13324 rtx op1 = gen_reg_rtx (XFmode);
13325 rtx op2 = gen_reg_rtx (XFmode);
13327 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13328 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13330 emit_label (label);
13332 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13333 ix86_emit_fp_unordered_jump (label);
13334 LABEL_NUSES (label) = 1;
13336 /* Truncate the result properly for strict SSE math. */
13337 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13338 && !TARGET_MIX_SSE_I387)
13339 gen_truncxf = gen_truncxf<mode>2;
13341 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13343 emit_insn (gen_truncxf (operands[0], op1));
13347 (define_int_iterator SINCOS
13351 (define_int_attr sincos
13352 [(UNSPEC_SIN "sin")
13353 (UNSPEC_COS "cos")])
13355 (define_insn "*<sincos>xf2_i387"
13356 [(set (match_operand:XF 0 "register_operand" "=f")
13357 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13359 "TARGET_USE_FANCY_MATH_387
13360 && flag_unsafe_math_optimizations"
13362 [(set_attr "type" "fpspc")
13363 (set_attr "mode" "XF")])
13365 (define_insn "*<sincos>_extend<mode>xf2_i387"
13366 [(set (match_operand:XF 0 "register_operand" "=f")
13367 (unspec:XF [(float_extend:XF
13368 (match_operand:MODEF 1 "register_operand" "0"))]
13370 "TARGET_USE_FANCY_MATH_387
13371 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13372 || TARGET_MIX_SSE_I387)
13373 && flag_unsafe_math_optimizations"
13375 [(set_attr "type" "fpspc")
13376 (set_attr "mode" "XF")])
13378 ;; When sincos pattern is defined, sin and cos builtin functions will be
13379 ;; expanded to sincos pattern with one of its outputs left unused.
13380 ;; CSE pass will figure out if two sincos patterns can be combined,
13381 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13382 ;; depending on the unused output.
13384 (define_insn "sincosxf3"
13385 [(set (match_operand:XF 0 "register_operand" "=f")
13386 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13387 UNSPEC_SINCOS_COS))
13388 (set (match_operand:XF 1 "register_operand" "=u")
13389 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13390 "TARGET_USE_FANCY_MATH_387
13391 && flag_unsafe_math_optimizations"
13393 [(set_attr "type" "fpspc")
13394 (set_attr "mode" "XF")])
13397 [(set (match_operand:XF 0 "register_operand")
13398 (unspec:XF [(match_operand:XF 2 "register_operand")]
13399 UNSPEC_SINCOS_COS))
13400 (set (match_operand:XF 1 "register_operand")
13401 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13402 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13403 && can_create_pseudo_p ()"
13404 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13407 [(set (match_operand:XF 0 "register_operand")
13408 (unspec:XF [(match_operand:XF 2 "register_operand")]
13409 UNSPEC_SINCOS_COS))
13410 (set (match_operand:XF 1 "register_operand")
13411 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13412 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13413 && can_create_pseudo_p ()"
13414 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13416 (define_insn "sincos_extend<mode>xf3_i387"
13417 [(set (match_operand:XF 0 "register_operand" "=f")
13418 (unspec:XF [(float_extend:XF
13419 (match_operand:MODEF 2 "register_operand" "0"))]
13420 UNSPEC_SINCOS_COS))
13421 (set (match_operand:XF 1 "register_operand" "=u")
13422 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13423 "TARGET_USE_FANCY_MATH_387
13424 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13425 || TARGET_MIX_SSE_I387)
13426 && flag_unsafe_math_optimizations"
13428 [(set_attr "type" "fpspc")
13429 (set_attr "mode" "XF")])
13432 [(set (match_operand:XF 0 "register_operand")
13433 (unspec:XF [(float_extend:XF
13434 (match_operand:MODEF 2 "register_operand"))]
13435 UNSPEC_SINCOS_COS))
13436 (set (match_operand:XF 1 "register_operand")
13437 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13438 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13439 && can_create_pseudo_p ()"
13440 [(set (match_dup 1)
13441 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13444 [(set (match_operand:XF 0 "register_operand")
13445 (unspec:XF [(float_extend:XF
13446 (match_operand:MODEF 2 "register_operand"))]
13447 UNSPEC_SINCOS_COS))
13448 (set (match_operand:XF 1 "register_operand")
13449 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13450 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13451 && can_create_pseudo_p ()"
13452 [(set (match_dup 0)
13453 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13455 (define_expand "sincos<mode>3"
13456 [(use (match_operand:MODEF 0 "register_operand"))
13457 (use (match_operand:MODEF 1 "register_operand"))
13458 (use (match_operand:MODEF 2 "register_operand"))]
13459 "TARGET_USE_FANCY_MATH_387
13460 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13461 || TARGET_MIX_SSE_I387)
13462 && flag_unsafe_math_optimizations"
13464 rtx op0 = gen_reg_rtx (XFmode);
13465 rtx op1 = gen_reg_rtx (XFmode);
13467 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13468 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13469 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13473 (define_insn "fptanxf4_i387"
13474 [(set (match_operand:XF 0 "register_operand" "=f")
13475 (match_operand:XF 3 "const_double_operand" "F"))
13476 (set (match_operand:XF 1 "register_operand" "=u")
13477 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13479 "TARGET_USE_FANCY_MATH_387
13480 && flag_unsafe_math_optimizations
13481 && standard_80387_constant_p (operands[3]) == 2"
13483 [(set_attr "type" "fpspc")
13484 (set_attr "mode" "XF")])
13486 (define_insn "fptan_extend<mode>xf4_i387"
13487 [(set (match_operand:MODEF 0 "register_operand" "=f")
13488 (match_operand:MODEF 3 "const_double_operand" "F"))
13489 (set (match_operand:XF 1 "register_operand" "=u")
13490 (unspec:XF [(float_extend:XF
13491 (match_operand:MODEF 2 "register_operand" "0"))]
13493 "TARGET_USE_FANCY_MATH_387
13494 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13495 || TARGET_MIX_SSE_I387)
13496 && flag_unsafe_math_optimizations
13497 && standard_80387_constant_p (operands[3]) == 2"
13499 [(set_attr "type" "fpspc")
13500 (set_attr "mode" "XF")])
13502 (define_expand "tanxf2"
13503 [(use (match_operand:XF 0 "register_operand"))
13504 (use (match_operand:XF 1 "register_operand"))]
13505 "TARGET_USE_FANCY_MATH_387
13506 && flag_unsafe_math_optimizations"
13508 rtx one = gen_reg_rtx (XFmode);
13509 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13511 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13515 (define_expand "tan<mode>2"
13516 [(use (match_operand:MODEF 0 "register_operand"))
13517 (use (match_operand:MODEF 1 "register_operand"))]
13518 "TARGET_USE_FANCY_MATH_387
13519 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13520 || TARGET_MIX_SSE_I387)
13521 && flag_unsafe_math_optimizations"
13523 rtx op0 = gen_reg_rtx (XFmode);
13525 rtx one = gen_reg_rtx (<MODE>mode);
13526 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13528 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13529 operands[1], op2));
13530 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13534 (define_insn "*fpatanxf3_i387"
13535 [(set (match_operand:XF 0 "register_operand" "=f")
13536 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13537 (match_operand:XF 2 "register_operand" "u")]
13539 (clobber (match_scratch:XF 3 "=2"))]
13540 "TARGET_USE_FANCY_MATH_387
13541 && flag_unsafe_math_optimizations"
13543 [(set_attr "type" "fpspc")
13544 (set_attr "mode" "XF")])
13546 (define_insn "fpatan_extend<mode>xf3_i387"
13547 [(set (match_operand:XF 0 "register_operand" "=f")
13548 (unspec:XF [(float_extend:XF
13549 (match_operand:MODEF 1 "register_operand" "0"))
13551 (match_operand:MODEF 2 "register_operand" "u"))]
13553 (clobber (match_scratch:XF 3 "=2"))]
13554 "TARGET_USE_FANCY_MATH_387
13555 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13556 || TARGET_MIX_SSE_I387)
13557 && flag_unsafe_math_optimizations"
13559 [(set_attr "type" "fpspc")
13560 (set_attr "mode" "XF")])
13562 (define_expand "atan2xf3"
13563 [(parallel [(set (match_operand:XF 0 "register_operand")
13564 (unspec:XF [(match_operand:XF 2 "register_operand")
13565 (match_operand:XF 1 "register_operand")]
13567 (clobber (match_scratch:XF 3))])]
13568 "TARGET_USE_FANCY_MATH_387
13569 && flag_unsafe_math_optimizations")
13571 (define_expand "atan2<mode>3"
13572 [(use (match_operand:MODEF 0 "register_operand"))
13573 (use (match_operand:MODEF 1 "register_operand"))
13574 (use (match_operand:MODEF 2 "register_operand"))]
13575 "TARGET_USE_FANCY_MATH_387
13576 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13577 || TARGET_MIX_SSE_I387)
13578 && flag_unsafe_math_optimizations"
13580 rtx op0 = gen_reg_rtx (XFmode);
13582 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13583 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13587 (define_expand "atanxf2"
13588 [(parallel [(set (match_operand:XF 0 "register_operand")
13589 (unspec:XF [(match_dup 2)
13590 (match_operand:XF 1 "register_operand")]
13592 (clobber (match_scratch:XF 3))])]
13593 "TARGET_USE_FANCY_MATH_387
13594 && flag_unsafe_math_optimizations"
13596 operands[2] = gen_reg_rtx (XFmode);
13597 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13600 (define_expand "atan<mode>2"
13601 [(use (match_operand:MODEF 0 "register_operand"))
13602 (use (match_operand:MODEF 1 "register_operand"))]
13603 "TARGET_USE_FANCY_MATH_387
13604 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13605 || TARGET_MIX_SSE_I387)
13606 && flag_unsafe_math_optimizations"
13608 rtx op0 = gen_reg_rtx (XFmode);
13610 rtx op2 = gen_reg_rtx (<MODE>mode);
13611 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13613 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13614 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13618 (define_expand "asinxf2"
13619 [(set (match_dup 2)
13620 (mult:XF (match_operand:XF 1 "register_operand")
13622 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13623 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13624 (parallel [(set (match_operand:XF 0 "register_operand")
13625 (unspec:XF [(match_dup 5) (match_dup 1)]
13627 (clobber (match_scratch:XF 6))])]
13628 "TARGET_USE_FANCY_MATH_387
13629 && flag_unsafe_math_optimizations"
13633 if (optimize_insn_for_size_p ())
13636 for (i = 2; i < 6; i++)
13637 operands[i] = gen_reg_rtx (XFmode);
13639 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13642 (define_expand "asin<mode>2"
13643 [(use (match_operand:MODEF 0 "register_operand"))
13644 (use (match_operand:MODEF 1 "general_operand"))]
13645 "TARGET_USE_FANCY_MATH_387
13646 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13647 || TARGET_MIX_SSE_I387)
13648 && flag_unsafe_math_optimizations"
13650 rtx op0 = gen_reg_rtx (XFmode);
13651 rtx op1 = gen_reg_rtx (XFmode);
13653 if (optimize_insn_for_size_p ())
13656 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13657 emit_insn (gen_asinxf2 (op0, op1));
13658 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13662 (define_expand "acosxf2"
13663 [(set (match_dup 2)
13664 (mult:XF (match_operand:XF 1 "register_operand")
13666 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13667 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13668 (parallel [(set (match_operand:XF 0 "register_operand")
13669 (unspec:XF [(match_dup 1) (match_dup 5)]
13671 (clobber (match_scratch:XF 6))])]
13672 "TARGET_USE_FANCY_MATH_387
13673 && flag_unsafe_math_optimizations"
13677 if (optimize_insn_for_size_p ())
13680 for (i = 2; i < 6; i++)
13681 operands[i] = gen_reg_rtx (XFmode);
13683 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13686 (define_expand "acos<mode>2"
13687 [(use (match_operand:MODEF 0 "register_operand"))
13688 (use (match_operand:MODEF 1 "general_operand"))]
13689 "TARGET_USE_FANCY_MATH_387
13690 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13691 || TARGET_MIX_SSE_I387)
13692 && flag_unsafe_math_optimizations"
13694 rtx op0 = gen_reg_rtx (XFmode);
13695 rtx op1 = gen_reg_rtx (XFmode);
13697 if (optimize_insn_for_size_p ())
13700 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13701 emit_insn (gen_acosxf2 (op0, op1));
13702 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13706 (define_insn "fyl2xxf3_i387"
13707 [(set (match_operand:XF 0 "register_operand" "=f")
13708 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13709 (match_operand:XF 2 "register_operand" "u")]
13711 (clobber (match_scratch:XF 3 "=2"))]
13712 "TARGET_USE_FANCY_MATH_387
13713 && flag_unsafe_math_optimizations"
13715 [(set_attr "type" "fpspc")
13716 (set_attr "mode" "XF")])
13718 (define_insn "fyl2x_extend<mode>xf3_i387"
13719 [(set (match_operand:XF 0 "register_operand" "=f")
13720 (unspec:XF [(float_extend:XF
13721 (match_operand:MODEF 1 "register_operand" "0"))
13722 (match_operand:XF 2 "register_operand" "u")]
13724 (clobber (match_scratch:XF 3 "=2"))]
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 [(set_attr "type" "fpspc")
13731 (set_attr "mode" "XF")])
13733 (define_expand "logxf2"
13734 [(parallel [(set (match_operand:XF 0 "register_operand")
13735 (unspec:XF [(match_operand:XF 1 "register_operand")
13736 (match_dup 2)] UNSPEC_FYL2X))
13737 (clobber (match_scratch:XF 3))])]
13738 "TARGET_USE_FANCY_MATH_387
13739 && flag_unsafe_math_optimizations"
13741 operands[2] = gen_reg_rtx (XFmode);
13742 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13745 (define_expand "log<mode>2"
13746 [(use (match_operand:MODEF 0 "register_operand"))
13747 (use (match_operand:MODEF 1 "register_operand"))]
13748 "TARGET_USE_FANCY_MATH_387
13749 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13750 || TARGET_MIX_SSE_I387)
13751 && flag_unsafe_math_optimizations"
13753 rtx op0 = gen_reg_rtx (XFmode);
13755 rtx op2 = gen_reg_rtx (XFmode);
13756 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13758 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13759 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13763 (define_expand "log10xf2"
13764 [(parallel [(set (match_operand:XF 0 "register_operand")
13765 (unspec:XF [(match_operand:XF 1 "register_operand")
13766 (match_dup 2)] UNSPEC_FYL2X))
13767 (clobber (match_scratch:XF 3))])]
13768 "TARGET_USE_FANCY_MATH_387
13769 && flag_unsafe_math_optimizations"
13771 operands[2] = gen_reg_rtx (XFmode);
13772 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13775 (define_expand "log10<mode>2"
13776 [(use (match_operand:MODEF 0 "register_operand"))
13777 (use (match_operand:MODEF 1 "register_operand"))]
13778 "TARGET_USE_FANCY_MATH_387
13779 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13780 || TARGET_MIX_SSE_I387)
13781 && flag_unsafe_math_optimizations"
13783 rtx op0 = gen_reg_rtx (XFmode);
13785 rtx op2 = gen_reg_rtx (XFmode);
13786 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13788 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13789 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13793 (define_expand "log2xf2"
13794 [(parallel [(set (match_operand:XF 0 "register_operand")
13795 (unspec:XF [(match_operand:XF 1 "register_operand")
13796 (match_dup 2)] UNSPEC_FYL2X))
13797 (clobber (match_scratch:XF 3))])]
13798 "TARGET_USE_FANCY_MATH_387
13799 && flag_unsafe_math_optimizations"
13801 operands[2] = gen_reg_rtx (XFmode);
13802 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13805 (define_expand "log2<mode>2"
13806 [(use (match_operand:MODEF 0 "register_operand"))
13807 (use (match_operand:MODEF 1 "register_operand"))]
13808 "TARGET_USE_FANCY_MATH_387
13809 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13810 || TARGET_MIX_SSE_I387)
13811 && flag_unsafe_math_optimizations"
13813 rtx op0 = gen_reg_rtx (XFmode);
13815 rtx op2 = gen_reg_rtx (XFmode);
13816 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13818 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13819 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13823 (define_insn "fyl2xp1xf3_i387"
13824 [(set (match_operand:XF 0 "register_operand" "=f")
13825 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13826 (match_operand:XF 2 "register_operand" "u")]
13828 (clobber (match_scratch:XF 3 "=2"))]
13829 "TARGET_USE_FANCY_MATH_387
13830 && flag_unsafe_math_optimizations"
13832 [(set_attr "type" "fpspc")
13833 (set_attr "mode" "XF")])
13835 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13836 [(set (match_operand:XF 0 "register_operand" "=f")
13837 (unspec:XF [(float_extend:XF
13838 (match_operand:MODEF 1 "register_operand" "0"))
13839 (match_operand:XF 2 "register_operand" "u")]
13841 (clobber (match_scratch:XF 3 "=2"))]
13842 "TARGET_USE_FANCY_MATH_387
13843 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13844 || TARGET_MIX_SSE_I387)
13845 && flag_unsafe_math_optimizations"
13847 [(set_attr "type" "fpspc")
13848 (set_attr "mode" "XF")])
13850 (define_expand "log1pxf2"
13851 [(use (match_operand:XF 0 "register_operand"))
13852 (use (match_operand:XF 1 "register_operand"))]
13853 "TARGET_USE_FANCY_MATH_387
13854 && flag_unsafe_math_optimizations"
13856 if (optimize_insn_for_size_p ())
13859 ix86_emit_i387_log1p (operands[0], operands[1]);
13863 (define_expand "log1p<mode>2"
13864 [(use (match_operand:MODEF 0 "register_operand"))
13865 (use (match_operand:MODEF 1 "register_operand"))]
13866 "TARGET_USE_FANCY_MATH_387
13867 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13868 || TARGET_MIX_SSE_I387)
13869 && flag_unsafe_math_optimizations"
13873 if (optimize_insn_for_size_p ())
13876 op0 = gen_reg_rtx (XFmode);
13878 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13880 ix86_emit_i387_log1p (op0, operands[1]);
13881 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13885 (define_insn "fxtractxf3_i387"
13886 [(set (match_operand:XF 0 "register_operand" "=f")
13887 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13888 UNSPEC_XTRACT_FRACT))
13889 (set (match_operand:XF 1 "register_operand" "=u")
13890 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13891 "TARGET_USE_FANCY_MATH_387
13892 && flag_unsafe_math_optimizations"
13894 [(set_attr "type" "fpspc")
13895 (set_attr "mode" "XF")])
13897 (define_insn "fxtract_extend<mode>xf3_i387"
13898 [(set (match_operand:XF 0 "register_operand" "=f")
13899 (unspec:XF [(float_extend:XF
13900 (match_operand:MODEF 2 "register_operand" "0"))]
13901 UNSPEC_XTRACT_FRACT))
13902 (set (match_operand:XF 1 "register_operand" "=u")
13903 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13904 "TARGET_USE_FANCY_MATH_387
13905 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13906 || TARGET_MIX_SSE_I387)
13907 && flag_unsafe_math_optimizations"
13909 [(set_attr "type" "fpspc")
13910 (set_attr "mode" "XF")])
13912 (define_expand "logbxf2"
13913 [(parallel [(set (match_dup 2)
13914 (unspec:XF [(match_operand:XF 1 "register_operand")]
13915 UNSPEC_XTRACT_FRACT))
13916 (set (match_operand:XF 0 "register_operand")
13917 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13918 "TARGET_USE_FANCY_MATH_387
13919 && flag_unsafe_math_optimizations"
13920 "operands[2] = gen_reg_rtx (XFmode);")
13922 (define_expand "logb<mode>2"
13923 [(use (match_operand:MODEF 0 "register_operand"))
13924 (use (match_operand:MODEF 1 "register_operand"))]
13925 "TARGET_USE_FANCY_MATH_387
13926 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13927 || TARGET_MIX_SSE_I387)
13928 && flag_unsafe_math_optimizations"
13930 rtx op0 = gen_reg_rtx (XFmode);
13931 rtx op1 = gen_reg_rtx (XFmode);
13933 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13934 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13938 (define_expand "ilogbxf2"
13939 [(use (match_operand:SI 0 "register_operand"))
13940 (use (match_operand:XF 1 "register_operand"))]
13941 "TARGET_USE_FANCY_MATH_387
13942 && flag_unsafe_math_optimizations"
13946 if (optimize_insn_for_size_p ())
13949 op0 = gen_reg_rtx (XFmode);
13950 op1 = gen_reg_rtx (XFmode);
13952 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13953 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13957 (define_expand "ilogb<mode>2"
13958 [(use (match_operand:SI 0 "register_operand"))
13959 (use (match_operand:MODEF 1 "register_operand"))]
13960 "TARGET_USE_FANCY_MATH_387
13961 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13962 || TARGET_MIX_SSE_I387)
13963 && flag_unsafe_math_optimizations"
13967 if (optimize_insn_for_size_p ())
13970 op0 = gen_reg_rtx (XFmode);
13971 op1 = gen_reg_rtx (XFmode);
13973 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13974 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13978 (define_insn "*f2xm1xf2_i387"
13979 [(set (match_operand:XF 0 "register_operand" "=f")
13980 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13982 "TARGET_USE_FANCY_MATH_387
13983 && flag_unsafe_math_optimizations"
13985 [(set_attr "type" "fpspc")
13986 (set_attr "mode" "XF")])
13988 (define_insn "*fscalexf4_i387"
13989 [(set (match_operand:XF 0 "register_operand" "=f")
13990 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13991 (match_operand:XF 3 "register_operand" "1")]
13992 UNSPEC_FSCALE_FRACT))
13993 (set (match_operand:XF 1 "register_operand" "=u")
13994 (unspec:XF [(match_dup 2) (match_dup 3)]
13995 UNSPEC_FSCALE_EXP))]
13996 "TARGET_USE_FANCY_MATH_387
13997 && flag_unsafe_math_optimizations"
13999 [(set_attr "type" "fpspc")
14000 (set_attr "mode" "XF")])
14002 (define_expand "expNcorexf3"
14003 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14004 (match_operand:XF 2 "register_operand")))
14005 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14006 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14007 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14008 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14009 (parallel [(set (match_operand:XF 0 "register_operand")
14010 (unspec:XF [(match_dup 8) (match_dup 4)]
14011 UNSPEC_FSCALE_FRACT))
14013 (unspec:XF [(match_dup 8) (match_dup 4)]
14014 UNSPEC_FSCALE_EXP))])]
14015 "TARGET_USE_FANCY_MATH_387
14016 && flag_unsafe_math_optimizations"
14020 if (optimize_insn_for_size_p ())
14023 for (i = 3; i < 10; i++)
14024 operands[i] = gen_reg_rtx (XFmode);
14026 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14029 (define_expand "expxf2"
14030 [(use (match_operand:XF 0 "register_operand"))
14031 (use (match_operand:XF 1 "register_operand"))]
14032 "TARGET_USE_FANCY_MATH_387
14033 && flag_unsafe_math_optimizations"
14037 if (optimize_insn_for_size_p ())
14040 op2 = gen_reg_rtx (XFmode);
14041 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14043 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14047 (define_expand "exp<mode>2"
14048 [(use (match_operand:MODEF 0 "register_operand"))
14049 (use (match_operand:MODEF 1 "general_operand"))]
14050 "TARGET_USE_FANCY_MATH_387
14051 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14052 || TARGET_MIX_SSE_I387)
14053 && flag_unsafe_math_optimizations"
14057 if (optimize_insn_for_size_p ())
14060 op0 = gen_reg_rtx (XFmode);
14061 op1 = gen_reg_rtx (XFmode);
14063 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14064 emit_insn (gen_expxf2 (op0, op1));
14065 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14069 (define_expand "exp10xf2"
14070 [(use (match_operand:XF 0 "register_operand"))
14071 (use (match_operand:XF 1 "register_operand"))]
14072 "TARGET_USE_FANCY_MATH_387
14073 && flag_unsafe_math_optimizations"
14077 if (optimize_insn_for_size_p ())
14080 op2 = gen_reg_rtx (XFmode);
14081 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14083 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14087 (define_expand "exp10<mode>2"
14088 [(use (match_operand:MODEF 0 "register_operand"))
14089 (use (match_operand:MODEF 1 "general_operand"))]
14090 "TARGET_USE_FANCY_MATH_387
14091 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14092 || TARGET_MIX_SSE_I387)
14093 && flag_unsafe_math_optimizations"
14097 if (optimize_insn_for_size_p ())
14100 op0 = gen_reg_rtx (XFmode);
14101 op1 = gen_reg_rtx (XFmode);
14103 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14104 emit_insn (gen_exp10xf2 (op0, op1));
14105 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14109 (define_expand "exp2xf2"
14110 [(use (match_operand:XF 0 "register_operand"))
14111 (use (match_operand:XF 1 "register_operand"))]
14112 "TARGET_USE_FANCY_MATH_387
14113 && flag_unsafe_math_optimizations"
14117 if (optimize_insn_for_size_p ())
14120 op2 = gen_reg_rtx (XFmode);
14121 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14123 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14127 (define_expand "exp2<mode>2"
14128 [(use (match_operand:MODEF 0 "register_operand"))
14129 (use (match_operand:MODEF 1 "general_operand"))]
14130 "TARGET_USE_FANCY_MATH_387
14131 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14132 || TARGET_MIX_SSE_I387)
14133 && flag_unsafe_math_optimizations"
14137 if (optimize_insn_for_size_p ())
14140 op0 = gen_reg_rtx (XFmode);
14141 op1 = gen_reg_rtx (XFmode);
14143 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14144 emit_insn (gen_exp2xf2 (op0, op1));
14145 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14149 (define_expand "expm1xf2"
14150 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14152 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14153 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14154 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14155 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14156 (parallel [(set (match_dup 7)
14157 (unspec:XF [(match_dup 6) (match_dup 4)]
14158 UNSPEC_FSCALE_FRACT))
14160 (unspec:XF [(match_dup 6) (match_dup 4)]
14161 UNSPEC_FSCALE_EXP))])
14162 (parallel [(set (match_dup 10)
14163 (unspec:XF [(match_dup 9) (match_dup 8)]
14164 UNSPEC_FSCALE_FRACT))
14165 (set (match_dup 11)
14166 (unspec:XF [(match_dup 9) (match_dup 8)]
14167 UNSPEC_FSCALE_EXP))])
14168 (set (match_dup 12) (minus:XF (match_dup 10)
14169 (float_extend:XF (match_dup 13))))
14170 (set (match_operand:XF 0 "register_operand")
14171 (plus:XF (match_dup 12) (match_dup 7)))]
14172 "TARGET_USE_FANCY_MATH_387
14173 && flag_unsafe_math_optimizations"
14177 if (optimize_insn_for_size_p ())
14180 for (i = 2; i < 13; i++)
14181 operands[i] = gen_reg_rtx (XFmode);
14184 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14186 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14189 (define_expand "expm1<mode>2"
14190 [(use (match_operand:MODEF 0 "register_operand"))
14191 (use (match_operand:MODEF 1 "general_operand"))]
14192 "TARGET_USE_FANCY_MATH_387
14193 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14194 || TARGET_MIX_SSE_I387)
14195 && flag_unsafe_math_optimizations"
14199 if (optimize_insn_for_size_p ())
14202 op0 = gen_reg_rtx (XFmode);
14203 op1 = gen_reg_rtx (XFmode);
14205 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14206 emit_insn (gen_expm1xf2 (op0, op1));
14207 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14211 (define_expand "ldexpxf3"
14212 [(set (match_dup 3)
14213 (float:XF (match_operand:SI 2 "register_operand")))
14214 (parallel [(set (match_operand:XF 0 " register_operand")
14215 (unspec:XF [(match_operand:XF 1 "register_operand")
14217 UNSPEC_FSCALE_FRACT))
14219 (unspec:XF [(match_dup 1) (match_dup 3)]
14220 UNSPEC_FSCALE_EXP))])]
14221 "TARGET_USE_FANCY_MATH_387
14222 && flag_unsafe_math_optimizations"
14224 if (optimize_insn_for_size_p ())
14227 operands[3] = gen_reg_rtx (XFmode);
14228 operands[4] = gen_reg_rtx (XFmode);
14231 (define_expand "ldexp<mode>3"
14232 [(use (match_operand:MODEF 0 "register_operand"))
14233 (use (match_operand:MODEF 1 "general_operand"))
14234 (use (match_operand:SI 2 "register_operand"))]
14235 "TARGET_USE_FANCY_MATH_387
14236 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14237 || TARGET_MIX_SSE_I387)
14238 && flag_unsafe_math_optimizations"
14242 if (optimize_insn_for_size_p ())
14245 op0 = gen_reg_rtx (XFmode);
14246 op1 = gen_reg_rtx (XFmode);
14248 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14249 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14250 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14254 (define_expand "scalbxf3"
14255 [(parallel [(set (match_operand:XF 0 " register_operand")
14256 (unspec:XF [(match_operand:XF 1 "register_operand")
14257 (match_operand:XF 2 "register_operand")]
14258 UNSPEC_FSCALE_FRACT))
14260 (unspec:XF [(match_dup 1) (match_dup 2)]
14261 UNSPEC_FSCALE_EXP))])]
14262 "TARGET_USE_FANCY_MATH_387
14263 && flag_unsafe_math_optimizations"
14265 if (optimize_insn_for_size_p ())
14268 operands[3] = gen_reg_rtx (XFmode);
14271 (define_expand "scalb<mode>3"
14272 [(use (match_operand:MODEF 0 "register_operand"))
14273 (use (match_operand:MODEF 1 "general_operand"))
14274 (use (match_operand:MODEF 2 "general_operand"))]
14275 "TARGET_USE_FANCY_MATH_387
14276 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14277 || TARGET_MIX_SSE_I387)
14278 && flag_unsafe_math_optimizations"
14282 if (optimize_insn_for_size_p ())
14285 op0 = gen_reg_rtx (XFmode);
14286 op1 = gen_reg_rtx (XFmode);
14287 op2 = gen_reg_rtx (XFmode);
14289 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14290 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14291 emit_insn (gen_scalbxf3 (op0, op1, op2));
14292 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14296 (define_expand "significandxf2"
14297 [(parallel [(set (match_operand:XF 0 "register_operand")
14298 (unspec:XF [(match_operand:XF 1 "register_operand")]
14299 UNSPEC_XTRACT_FRACT))
14301 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14302 "TARGET_USE_FANCY_MATH_387
14303 && flag_unsafe_math_optimizations"
14304 "operands[2] = gen_reg_rtx (XFmode);")
14306 (define_expand "significand<mode>2"
14307 [(use (match_operand:MODEF 0 "register_operand"))
14308 (use (match_operand:MODEF 1 "register_operand"))]
14309 "TARGET_USE_FANCY_MATH_387
14310 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14311 || TARGET_MIX_SSE_I387)
14312 && flag_unsafe_math_optimizations"
14314 rtx op0 = gen_reg_rtx (XFmode);
14315 rtx op1 = gen_reg_rtx (XFmode);
14317 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14318 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14323 (define_insn "sse4_1_round<mode>2"
14324 [(set (match_operand:MODEF 0 "register_operand" "=x")
14325 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14326 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14329 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14330 [(set_attr "type" "ssecvt")
14331 (set_attr "prefix_extra" "1")
14332 (set_attr "prefix" "maybe_vex")
14333 (set_attr "mode" "<MODE>")])
14335 (define_insn "rintxf2"
14336 [(set (match_operand:XF 0 "register_operand" "=f")
14337 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14339 "TARGET_USE_FANCY_MATH_387
14340 && flag_unsafe_math_optimizations"
14342 [(set_attr "type" "fpspc")
14343 (set_attr "mode" "XF")])
14345 (define_expand "rint<mode>2"
14346 [(use (match_operand:MODEF 0 "register_operand"))
14347 (use (match_operand:MODEF 1 "register_operand"))]
14348 "(TARGET_USE_FANCY_MATH_387
14349 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14350 || TARGET_MIX_SSE_I387)
14351 && flag_unsafe_math_optimizations)
14352 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14353 && !flag_trapping_math)"
14355 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14356 && !flag_trapping_math)
14359 emit_insn (gen_sse4_1_round<mode>2
14360 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14361 else if (optimize_insn_for_size_p ())
14364 ix86_expand_rint (operands[0], operands[1]);
14368 rtx op0 = gen_reg_rtx (XFmode);
14369 rtx op1 = gen_reg_rtx (XFmode);
14371 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14372 emit_insn (gen_rintxf2 (op0, op1));
14374 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14379 (define_expand "round<mode>2"
14380 [(match_operand:X87MODEF 0 "register_operand")
14381 (match_operand:X87MODEF 1 "nonimmediate_operand")]
14382 "(TARGET_USE_FANCY_MATH_387
14383 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14384 || TARGET_MIX_SSE_I387)
14385 && flag_unsafe_math_optimizations)
14386 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14387 && !flag_trapping_math && !flag_rounding_math)"
14389 if (optimize_insn_for_size_p ())
14392 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14393 && !flag_trapping_math && !flag_rounding_math)
14397 operands[1] = force_reg (<MODE>mode, operands[1]);
14398 ix86_expand_round_sse4 (operands[0], operands[1]);
14400 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14401 ix86_expand_round (operands[0], operands[1]);
14403 ix86_expand_rounddf_32 (operands[0], operands[1]);
14407 operands[1] = force_reg (<MODE>mode, operands[1]);
14408 ix86_emit_i387_round (operands[0], operands[1]);
14413 (define_insn_and_split "*fistdi2_1"
14414 [(set (match_operand:DI 0 "nonimmediate_operand")
14415 (unspec:DI [(match_operand:XF 1 "register_operand")]
14417 "TARGET_USE_FANCY_MATH_387
14418 && can_create_pseudo_p ()"
14423 if (memory_operand (operands[0], VOIDmode))
14424 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14427 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14428 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14433 [(set_attr "type" "fpspc")
14434 (set_attr "mode" "DI")])
14436 (define_insn "fistdi2"
14437 [(set (match_operand:DI 0 "memory_operand" "=m")
14438 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14440 (clobber (match_scratch:XF 2 "=&1f"))]
14441 "TARGET_USE_FANCY_MATH_387"
14442 "* return output_fix_trunc (insn, operands, false);"
14443 [(set_attr "type" "fpspc")
14444 (set_attr "mode" "DI")])
14446 (define_insn "fistdi2_with_temp"
14447 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14448 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14450 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14451 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14452 "TARGET_USE_FANCY_MATH_387"
14454 [(set_attr "type" "fpspc")
14455 (set_attr "mode" "DI")])
14458 [(set (match_operand:DI 0 "register_operand")
14459 (unspec:DI [(match_operand:XF 1 "register_operand")]
14461 (clobber (match_operand:DI 2 "memory_operand"))
14462 (clobber (match_scratch 3))]
14464 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14465 (clobber (match_dup 3))])
14466 (set (match_dup 0) (match_dup 2))])
14469 [(set (match_operand:DI 0 "memory_operand")
14470 (unspec:DI [(match_operand:XF 1 "register_operand")]
14472 (clobber (match_operand:DI 2 "memory_operand"))
14473 (clobber (match_scratch 3))]
14475 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14476 (clobber (match_dup 3))])])
14478 (define_insn_and_split "*fist<mode>2_1"
14479 [(set (match_operand:SWI24 0 "register_operand")
14480 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14482 "TARGET_USE_FANCY_MATH_387
14483 && can_create_pseudo_p ()"
14488 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14489 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14493 [(set_attr "type" "fpspc")
14494 (set_attr "mode" "<MODE>")])
14496 (define_insn "fist<mode>2"
14497 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14498 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14500 "TARGET_USE_FANCY_MATH_387"
14501 "* return output_fix_trunc (insn, operands, false);"
14502 [(set_attr "type" "fpspc")
14503 (set_attr "mode" "<MODE>")])
14505 (define_insn "fist<mode>2_with_temp"
14506 [(set (match_operand:SWI24 0 "register_operand" "=r")
14507 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14509 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14510 "TARGET_USE_FANCY_MATH_387"
14512 [(set_attr "type" "fpspc")
14513 (set_attr "mode" "<MODE>")])
14516 [(set (match_operand:SWI24 0 "register_operand")
14517 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14519 (clobber (match_operand:SWI24 2 "memory_operand"))]
14521 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14522 (set (match_dup 0) (match_dup 2))])
14525 [(set (match_operand:SWI24 0 "memory_operand")
14526 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14528 (clobber (match_operand:SWI24 2 "memory_operand"))]
14530 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14532 (define_expand "lrintxf<mode>2"
14533 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
14534 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
14536 "TARGET_USE_FANCY_MATH_387")
14538 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
14539 [(set (match_operand:SWI48 0 "nonimmediate_operand")
14540 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
14541 UNSPEC_FIX_NOTRUNC))]
14542 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
14544 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14545 [(match_operand:SWI248x 0 "nonimmediate_operand")
14546 (match_operand:X87MODEF 1 "register_operand")]
14547 "(TARGET_USE_FANCY_MATH_387
14548 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14549 || TARGET_MIX_SSE_I387)
14550 && flag_unsafe_math_optimizations)
14551 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14552 && <SWI248x:MODE>mode != HImode
14553 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14554 && !flag_trapping_math && !flag_rounding_math)"
14556 if (optimize_insn_for_size_p ())
14559 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14560 && <SWI248x:MODE>mode != HImode
14561 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14562 && !flag_trapping_math && !flag_rounding_math)
14563 ix86_expand_lround (operands[0], operands[1]);
14565 ix86_emit_i387_round (operands[0], operands[1]);
14569 (define_int_iterator FRNDINT_ROUNDING
14570 [UNSPEC_FRNDINT_FLOOR
14571 UNSPEC_FRNDINT_CEIL
14572 UNSPEC_FRNDINT_TRUNC])
14574 (define_int_iterator FIST_ROUNDING
14578 ;; Base name for define_insn
14579 (define_int_attr rounding_insn
14580 [(UNSPEC_FRNDINT_FLOOR "floor")
14581 (UNSPEC_FRNDINT_CEIL "ceil")
14582 (UNSPEC_FRNDINT_TRUNC "btrunc")
14583 (UNSPEC_FIST_FLOOR "floor")
14584 (UNSPEC_FIST_CEIL "ceil")])
14586 (define_int_attr rounding
14587 [(UNSPEC_FRNDINT_FLOOR "floor")
14588 (UNSPEC_FRNDINT_CEIL "ceil")
14589 (UNSPEC_FRNDINT_TRUNC "trunc")
14590 (UNSPEC_FIST_FLOOR "floor")
14591 (UNSPEC_FIST_CEIL "ceil")])
14593 (define_int_attr ROUNDING
14594 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
14595 (UNSPEC_FRNDINT_CEIL "CEIL")
14596 (UNSPEC_FRNDINT_TRUNC "TRUNC")
14597 (UNSPEC_FIST_FLOOR "FLOOR")
14598 (UNSPEC_FIST_CEIL "CEIL")])
14600 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14601 (define_insn_and_split "frndintxf2_<rounding>"
14602 [(set (match_operand:XF 0 "register_operand")
14603 (unspec:XF [(match_operand:XF 1 "register_operand")]
14605 (clobber (reg:CC FLAGS_REG))]
14606 "TARGET_USE_FANCY_MATH_387
14607 && flag_unsafe_math_optimizations
14608 && can_create_pseudo_p ()"
14613 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
14615 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14616 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
14618 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
14619 operands[2], operands[3]));
14622 [(set_attr "type" "frndint")
14623 (set_attr "i387_cw" "<rounding>")
14624 (set_attr "mode" "XF")])
14626 (define_insn "frndintxf2_<rounding>_i387"
14627 [(set (match_operand:XF 0 "register_operand" "=f")
14628 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14630 (use (match_operand:HI 2 "memory_operand" "m"))
14631 (use (match_operand:HI 3 "memory_operand" "m"))]
14632 "TARGET_USE_FANCY_MATH_387
14633 && flag_unsafe_math_optimizations"
14634 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14635 [(set_attr "type" "frndint")
14636 (set_attr "i387_cw" "<rounding>")
14637 (set_attr "mode" "XF")])
14639 (define_expand "<rounding_insn>xf2"
14640 [(parallel [(set (match_operand:XF 0 "register_operand")
14641 (unspec:XF [(match_operand:XF 1 "register_operand")]
14643 (clobber (reg:CC FLAGS_REG))])]
14644 "TARGET_USE_FANCY_MATH_387
14645 && flag_unsafe_math_optimizations
14646 && !optimize_insn_for_size_p ()")
14648 (define_expand "<rounding_insn><mode>2"
14649 [(parallel [(set (match_operand:MODEF 0 "register_operand")
14650 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
14652 (clobber (reg:CC FLAGS_REG))])]
14653 "(TARGET_USE_FANCY_MATH_387
14654 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14655 || TARGET_MIX_SSE_I387)
14656 && flag_unsafe_math_optimizations)
14657 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14658 && !flag_trapping_math)"
14660 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14661 && !flag_trapping_math)
14664 emit_insn (gen_sse4_1_round<mode>2
14665 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
14666 else if (optimize_insn_for_size_p ())
14668 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14670 if (ROUND_<ROUNDING> == ROUND_FLOOR)
14671 ix86_expand_floorceil (operands[0], operands[1], true);
14672 else if (ROUND_<ROUNDING> == ROUND_CEIL)
14673 ix86_expand_floorceil (operands[0], operands[1], false);
14674 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
14675 ix86_expand_trunc (operands[0], operands[1]);
14677 gcc_unreachable ();
14681 if (ROUND_<ROUNDING> == ROUND_FLOOR)
14682 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
14683 else if (ROUND_<ROUNDING> == ROUND_CEIL)
14684 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
14685 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
14686 ix86_expand_truncdf_32 (operands[0], operands[1]);
14688 gcc_unreachable ();
14695 if (optimize_insn_for_size_p ())
14698 op0 = gen_reg_rtx (XFmode);
14699 op1 = gen_reg_rtx (XFmode);
14700 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14701 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
14703 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14708 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14709 (define_insn_and_split "frndintxf2_mask_pm"
14710 [(set (match_operand:XF 0 "register_operand")
14711 (unspec:XF [(match_operand:XF 1 "register_operand")]
14712 UNSPEC_FRNDINT_MASK_PM))
14713 (clobber (reg:CC FLAGS_REG))]
14714 "TARGET_USE_FANCY_MATH_387
14715 && flag_unsafe_math_optimizations
14716 && can_create_pseudo_p ()"
14721 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
14723 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14724 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
14726 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
14727 operands[2], operands[3]));
14730 [(set_attr "type" "frndint")
14731 (set_attr "i387_cw" "mask_pm")
14732 (set_attr "mode" "XF")])
14734 (define_insn "frndintxf2_mask_pm_i387"
14735 [(set (match_operand:XF 0 "register_operand" "=f")
14736 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14737 UNSPEC_FRNDINT_MASK_PM))
14738 (use (match_operand:HI 2 "memory_operand" "m"))
14739 (use (match_operand:HI 3 "memory_operand" "m"))]
14740 "TARGET_USE_FANCY_MATH_387
14741 && flag_unsafe_math_optimizations"
14742 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
14743 [(set_attr "type" "frndint")
14744 (set_attr "i387_cw" "mask_pm")
14745 (set_attr "mode" "XF")])
14747 (define_expand "nearbyintxf2"
14748 [(parallel [(set (match_operand:XF 0 "register_operand")
14749 (unspec:XF [(match_operand:XF 1 "register_operand")]
14750 UNSPEC_FRNDINT_MASK_PM))
14751 (clobber (reg:CC FLAGS_REG))])]
14752 "TARGET_USE_FANCY_MATH_387
14753 && flag_unsafe_math_optimizations")
14755 (define_expand "nearbyint<mode>2"
14756 [(use (match_operand:MODEF 0 "register_operand"))
14757 (use (match_operand:MODEF 1 "register_operand"))]
14758 "TARGET_USE_FANCY_MATH_387
14759 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14760 || TARGET_MIX_SSE_I387)
14761 && flag_unsafe_math_optimizations"
14763 rtx op0 = gen_reg_rtx (XFmode);
14764 rtx op1 = gen_reg_rtx (XFmode);
14766 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14767 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
14769 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14773 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14774 (define_insn_and_split "*fist<mode>2_<rounding>_1"
14775 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
14776 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
14778 (clobber (reg:CC FLAGS_REG))]
14779 "TARGET_USE_FANCY_MATH_387
14780 && flag_unsafe_math_optimizations
14781 && can_create_pseudo_p ()"
14786 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
14788 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14789 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
14790 if (memory_operand (operands[0], VOIDmode))
14791 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
14792 operands[2], operands[3]));
14795 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14796 emit_insn (gen_fist<mode>2_<rounding>_with_temp
14797 (operands[0], operands[1], operands[2],
14798 operands[3], operands[4]));
14802 [(set_attr "type" "fistp")
14803 (set_attr "i387_cw" "<rounding>")
14804 (set_attr "mode" "<MODE>")])
14806 (define_insn "fistdi2_<rounding>"
14807 [(set (match_operand:DI 0 "memory_operand" "=m")
14808 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14810 (use (match_operand:HI 2 "memory_operand" "m"))
14811 (use (match_operand:HI 3 "memory_operand" "m"))
14812 (clobber (match_scratch:XF 4 "=&1f"))]
14813 "TARGET_USE_FANCY_MATH_387
14814 && flag_unsafe_math_optimizations"
14815 "* return output_fix_trunc (insn, operands, false);"
14816 [(set_attr "type" "fistp")
14817 (set_attr "i387_cw" "<rounding>")
14818 (set_attr "mode" "DI")])
14820 (define_insn "fistdi2_<rounding>_with_temp"
14821 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14822 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14824 (use (match_operand:HI 2 "memory_operand" "m,m"))
14825 (use (match_operand:HI 3 "memory_operand" "m,m"))
14826 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14827 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14828 "TARGET_USE_FANCY_MATH_387
14829 && flag_unsafe_math_optimizations"
14831 [(set_attr "type" "fistp")
14832 (set_attr "i387_cw" "<rounding>")
14833 (set_attr "mode" "DI")])
14836 [(set (match_operand:DI 0 "register_operand")
14837 (unspec:DI [(match_operand:XF 1 "register_operand")]
14839 (use (match_operand:HI 2 "memory_operand"))
14840 (use (match_operand:HI 3 "memory_operand"))
14841 (clobber (match_operand:DI 4 "memory_operand"))
14842 (clobber (match_scratch 5))]
14844 [(parallel [(set (match_dup 4)
14845 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
14846 (use (match_dup 2))
14847 (use (match_dup 3))
14848 (clobber (match_dup 5))])
14849 (set (match_dup 0) (match_dup 4))])
14852 [(set (match_operand:DI 0 "memory_operand")
14853 (unspec:DI [(match_operand:XF 1 "register_operand")]
14855 (use (match_operand:HI 2 "memory_operand"))
14856 (use (match_operand:HI 3 "memory_operand"))
14857 (clobber (match_operand:DI 4 "memory_operand"))
14858 (clobber (match_scratch 5))]
14860 [(parallel [(set (match_dup 0)
14861 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
14862 (use (match_dup 2))
14863 (use (match_dup 3))
14864 (clobber (match_dup 5))])])
14866 (define_insn "fist<mode>2_<rounding>"
14867 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14868 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14870 (use (match_operand:HI 2 "memory_operand" "m"))
14871 (use (match_operand:HI 3 "memory_operand" "m"))]
14872 "TARGET_USE_FANCY_MATH_387
14873 && flag_unsafe_math_optimizations"
14874 "* return output_fix_trunc (insn, operands, false);"
14875 [(set_attr "type" "fistp")
14876 (set_attr "i387_cw" "<rounding>")
14877 (set_attr "mode" "<MODE>")])
14879 (define_insn "fist<mode>2_<rounding>_with_temp"
14880 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
14881 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
14883 (use (match_operand:HI 2 "memory_operand" "m,m"))
14884 (use (match_operand:HI 3 "memory_operand" "m,m"))
14885 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
14886 "TARGET_USE_FANCY_MATH_387
14887 && flag_unsafe_math_optimizations"
14889 [(set_attr "type" "fistp")
14890 (set_attr "i387_cw" "<rounding>")
14891 (set_attr "mode" "<MODE>")])
14894 [(set (match_operand:SWI24 0 "register_operand")
14895 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14897 (use (match_operand:HI 2 "memory_operand"))
14898 (use (match_operand:HI 3 "memory_operand"))
14899 (clobber (match_operand:SWI24 4 "memory_operand"))]
14901 [(parallel [(set (match_dup 4)
14902 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
14903 (use (match_dup 2))
14904 (use (match_dup 3))])
14905 (set (match_dup 0) (match_dup 4))])
14908 [(set (match_operand:SWI24 0 "memory_operand")
14909 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14911 (use (match_operand:HI 2 "memory_operand"))
14912 (use (match_operand:HI 3 "memory_operand"))
14913 (clobber (match_operand:SWI24 4 "memory_operand"))]
14915 [(parallel [(set (match_dup 0)
14916 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
14917 (use (match_dup 2))
14918 (use (match_dup 3))])])
14920 (define_expand "l<rounding_insn>xf<mode>2"
14921 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
14922 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
14924 (clobber (reg:CC FLAGS_REG))])]
14925 "TARGET_USE_FANCY_MATH_387
14926 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14927 && flag_unsafe_math_optimizations")
14929 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
14930 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
14931 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
14933 (clobber (reg:CC FLAGS_REG))])]
14934 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14935 && !flag_trapping_math"
14937 if (TARGET_64BIT && optimize_insn_for_size_p ())
14940 if (ROUND_<ROUNDING> == ROUND_FLOOR)
14941 ix86_expand_lfloorceil (operands[0], operands[1], true);
14942 else if (ROUND_<ROUNDING> == ROUND_CEIL)
14943 ix86_expand_lfloorceil (operands[0], operands[1], false);
14945 gcc_unreachable ();
14950 (define_insn "fxam<mode>2_i387"
14951 [(set (match_operand:HI 0 "register_operand" "=a")
14953 [(match_operand:X87MODEF 1 "register_operand" "f")]
14955 "TARGET_USE_FANCY_MATH_387"
14956 "fxam\n\tfnstsw\t%0"
14957 [(set_attr "type" "multi")
14958 (set_attr "length" "4")
14959 (set_attr "unit" "i387")
14960 (set_attr "mode" "<MODE>")])
14962 (define_insn_and_split "fxam<mode>2_i387_with_temp"
14963 [(set (match_operand:HI 0 "register_operand")
14965 [(match_operand:MODEF 1 "memory_operand")]
14967 "TARGET_USE_FANCY_MATH_387
14968 && can_create_pseudo_p ()"
14971 [(set (match_dup 2)(match_dup 1))
14973 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
14975 operands[2] = gen_reg_rtx (<MODE>mode);
14977 MEM_VOLATILE_P (operands[1]) = 1;
14979 [(set_attr "type" "multi")
14980 (set_attr "unit" "i387")
14981 (set_attr "mode" "<MODE>")])
14983 (define_expand "isinfxf2"
14984 [(use (match_operand:SI 0 "register_operand"))
14985 (use (match_operand:XF 1 "register_operand"))]
14986 "TARGET_USE_FANCY_MATH_387
14987 && TARGET_C99_FUNCTIONS"
14989 rtx mask = GEN_INT (0x45);
14990 rtx val = GEN_INT (0x05);
14994 rtx scratch = gen_reg_rtx (HImode);
14995 rtx res = gen_reg_rtx (QImode);
14997 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
14999 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15000 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15001 cond = gen_rtx_fmt_ee (EQ, QImode,
15002 gen_rtx_REG (CCmode, FLAGS_REG),
15004 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15005 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15009 (define_expand "isinf<mode>2"
15010 [(use (match_operand:SI 0 "register_operand"))
15011 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15012 "TARGET_USE_FANCY_MATH_387
15013 && TARGET_C99_FUNCTIONS
15014 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15016 rtx mask = GEN_INT (0x45);
15017 rtx val = GEN_INT (0x05);
15021 rtx scratch = gen_reg_rtx (HImode);
15022 rtx res = gen_reg_rtx (QImode);
15024 /* Remove excess precision by forcing value through memory. */
15025 if (memory_operand (operands[1], VOIDmode))
15026 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15029 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15031 emit_move_insn (temp, operands[1]);
15032 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15035 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15036 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15037 cond = gen_rtx_fmt_ee (EQ, QImode,
15038 gen_rtx_REG (CCmode, FLAGS_REG),
15040 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15041 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15045 (define_expand "signbitxf2"
15046 [(use (match_operand:SI 0 "register_operand"))
15047 (use (match_operand:XF 1 "register_operand"))]
15048 "TARGET_USE_FANCY_MATH_387"
15050 rtx scratch = gen_reg_rtx (HImode);
15052 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15053 emit_insn (gen_andsi3 (operands[0],
15054 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15058 (define_insn "movmsk_df"
15059 [(set (match_operand:SI 0 "register_operand" "=r")
15061 [(match_operand:DF 1 "register_operand" "x")]
15063 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15064 "%vmovmskpd\t{%1, %0|%0, %1}"
15065 [(set_attr "type" "ssemov")
15066 (set_attr "prefix" "maybe_vex")
15067 (set_attr "mode" "DF")])
15069 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15070 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15071 (define_expand "signbitdf2"
15072 [(use (match_operand:SI 0 "register_operand"))
15073 (use (match_operand:DF 1 "register_operand"))]
15074 "TARGET_USE_FANCY_MATH_387
15075 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15077 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15079 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15080 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15084 rtx scratch = gen_reg_rtx (HImode);
15086 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15087 emit_insn (gen_andsi3 (operands[0],
15088 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15093 (define_expand "signbitsf2"
15094 [(use (match_operand:SI 0 "register_operand"))
15095 (use (match_operand:SF 1 "register_operand"))]
15096 "TARGET_USE_FANCY_MATH_387
15097 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15099 rtx scratch = gen_reg_rtx (HImode);
15101 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15102 emit_insn (gen_andsi3 (operands[0],
15103 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15107 ;; Block operation instructions
15110 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15113 [(set_attr "length" "1")
15114 (set_attr "length_immediate" "0")
15115 (set_attr "modrm" "0")])
15117 (define_expand "movmem<mode>"
15118 [(use (match_operand:BLK 0 "memory_operand"))
15119 (use (match_operand:BLK 1 "memory_operand"))
15120 (use (match_operand:SWI48 2 "nonmemory_operand"))
15121 (use (match_operand:SWI48 3 "const_int_operand"))
15122 (use (match_operand:SI 4 "const_int_operand"))
15123 (use (match_operand:SI 5 "const_int_operand"))]
15126 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15127 operands[4], operands[5]))
15133 ;; Most CPUs don't like single string operations
15134 ;; Handle this case here to simplify previous expander.
15136 (define_expand "strmov"
15137 [(set (match_dup 4) (match_operand 3 "memory_operand"))
15138 (set (match_operand 1 "memory_operand") (match_dup 4))
15139 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
15140 (clobber (reg:CC FLAGS_REG))])
15141 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
15142 (clobber (reg:CC FLAGS_REG))])]
15145 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15147 /* If .md ever supports :P for Pmode, these can be directly
15148 in the pattern above. */
15149 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15150 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15152 /* Can't use this if the user has appropriated esi or edi. */
15153 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15154 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15156 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15157 operands[2], operands[3],
15158 operands[5], operands[6]));
15162 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15165 (define_expand "strmov_singleop"
15166 [(parallel [(set (match_operand 1 "memory_operand")
15167 (match_operand 3 "memory_operand"))
15168 (set (match_operand 0 "register_operand")
15170 (set (match_operand 2 "register_operand")
15171 (match_operand 5))])]
15173 "ix86_current_function_needs_cld = 1;")
15175 (define_insn "*strmovdi_rex_1"
15176 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15177 (mem:DI (match_operand:P 3 "register_operand" "1")))
15178 (set (match_operand:P 0 "register_operand" "=D")
15179 (plus:P (match_dup 2)
15181 (set (match_operand:P 1 "register_operand" "=S")
15182 (plus:P (match_dup 3)
15185 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15187 [(set_attr "type" "str")
15188 (set_attr "memory" "both")
15189 (set_attr "mode" "DI")])
15191 (define_insn "*strmovsi_1"
15192 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15193 (mem:SI (match_operand:P 3 "register_operand" "1")))
15194 (set (match_operand:P 0 "register_operand" "=D")
15195 (plus:P (match_dup 2)
15197 (set (match_operand:P 1 "register_operand" "=S")
15198 (plus:P (match_dup 3)
15200 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15202 [(set_attr "type" "str")
15203 (set_attr "memory" "both")
15204 (set_attr "mode" "SI")])
15206 (define_insn "*strmovhi_1"
15207 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15208 (mem:HI (match_operand:P 3 "register_operand" "1")))
15209 (set (match_operand:P 0 "register_operand" "=D")
15210 (plus:P (match_dup 2)
15212 (set (match_operand:P 1 "register_operand" "=S")
15213 (plus:P (match_dup 3)
15215 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15217 [(set_attr "type" "str")
15218 (set_attr "memory" "both")
15219 (set_attr "mode" "HI")])
15221 (define_insn "*strmovqi_1"
15222 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15223 (mem:QI (match_operand:P 3 "register_operand" "1")))
15224 (set (match_operand:P 0 "register_operand" "=D")
15225 (plus:P (match_dup 2)
15227 (set (match_operand:P 1 "register_operand" "=S")
15228 (plus:P (match_dup 3)
15230 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15232 [(set_attr "type" "str")
15233 (set_attr "memory" "both")
15234 (set (attr "prefix_rex")
15236 (match_test "<P:MODE>mode == DImode")
15238 (const_string "*")))
15239 (set_attr "mode" "QI")])
15241 (define_expand "rep_mov"
15242 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
15243 (set (match_operand 0 "register_operand")
15245 (set (match_operand 2 "register_operand")
15247 (set (match_operand 1 "memory_operand")
15248 (match_operand 3 "memory_operand"))
15249 (use (match_dup 4))])]
15251 "ix86_current_function_needs_cld = 1;")
15253 (define_insn "*rep_movdi_rex64"
15254 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15255 (set (match_operand:P 0 "register_operand" "=D")
15256 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15258 (match_operand:P 3 "register_operand" "0")))
15259 (set (match_operand:P 1 "register_operand" "=S")
15260 (plus:P (ashift:P (match_dup 5) (const_int 3))
15261 (match_operand:P 4 "register_operand" "1")))
15262 (set (mem:BLK (match_dup 3))
15263 (mem:BLK (match_dup 4)))
15264 (use (match_dup 5))]
15266 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15268 [(set_attr "type" "str")
15269 (set_attr "prefix_rep" "1")
15270 (set_attr "memory" "both")
15271 (set_attr "mode" "DI")])
15273 (define_insn "*rep_movsi"
15274 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15275 (set (match_operand:P 0 "register_operand" "=D")
15276 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15278 (match_operand:P 3 "register_operand" "0")))
15279 (set (match_operand:P 1 "register_operand" "=S")
15280 (plus:P (ashift:P (match_dup 5) (const_int 2))
15281 (match_operand:P 4 "register_operand" "1")))
15282 (set (mem:BLK (match_dup 3))
15283 (mem:BLK (match_dup 4)))
15284 (use (match_dup 5))]
15285 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15286 "%^rep{%;} movs{l|d}"
15287 [(set_attr "type" "str")
15288 (set_attr "prefix_rep" "1")
15289 (set_attr "memory" "both")
15290 (set_attr "mode" "SI")])
15292 (define_insn "*rep_movqi"
15293 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15294 (set (match_operand:P 0 "register_operand" "=D")
15295 (plus:P (match_operand:P 3 "register_operand" "0")
15296 (match_operand:P 5 "register_operand" "2")))
15297 (set (match_operand:P 1 "register_operand" "=S")
15298 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15299 (set (mem:BLK (match_dup 3))
15300 (mem:BLK (match_dup 4)))
15301 (use (match_dup 5))]
15302 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15304 [(set_attr "type" "str")
15305 (set_attr "prefix_rep" "1")
15306 (set_attr "memory" "both")
15307 (set_attr "mode" "QI")])
15309 (define_expand "setmem<mode>"
15310 [(use (match_operand:BLK 0 "memory_operand"))
15311 (use (match_operand:SWI48 1 "nonmemory_operand"))
15312 (use (match_operand:QI 2 "nonmemory_operand"))
15313 (use (match_operand 3 "const_int_operand"))
15314 (use (match_operand:SI 4 "const_int_operand"))
15315 (use (match_operand:SI 5 "const_int_operand"))]
15318 if (ix86_expand_setmem (operands[0], operands[1],
15319 operands[2], operands[3],
15320 operands[4], operands[5]))
15326 ;; Most CPUs don't like single string operations
15327 ;; Handle this case here to simplify previous expander.
15329 (define_expand "strset"
15330 [(set (match_operand 1 "memory_operand")
15331 (match_operand 2 "register_operand"))
15332 (parallel [(set (match_operand 0 "register_operand")
15334 (clobber (reg:CC FLAGS_REG))])]
15337 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15338 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15340 /* If .md ever supports :P for Pmode, this can be directly
15341 in the pattern above. */
15342 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15343 GEN_INT (GET_MODE_SIZE (GET_MODE
15345 /* Can't use this if the user has appropriated eax or edi. */
15346 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15347 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15349 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15355 (define_expand "strset_singleop"
15356 [(parallel [(set (match_operand 1 "memory_operand")
15357 (match_operand 2 "register_operand"))
15358 (set (match_operand 0 "register_operand")
15360 (unspec [(const_int 0)] UNSPEC_STOS)])]
15362 "ix86_current_function_needs_cld = 1;")
15364 (define_insn "*strsetdi_rex_1"
15365 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
15366 (match_operand:DI 2 "register_operand" "a"))
15367 (set (match_operand:P 0 "register_operand" "=D")
15368 (plus:P (match_dup 1)
15370 (unspec [(const_int 0)] UNSPEC_STOS)]
15372 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15374 [(set_attr "type" "str")
15375 (set_attr "memory" "store")
15376 (set_attr "mode" "DI")])
15378 (define_insn "*strsetsi_1"
15379 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15380 (match_operand:SI 2 "register_operand" "a"))
15381 (set (match_operand:P 0 "register_operand" "=D")
15382 (plus:P (match_dup 1)
15384 (unspec [(const_int 0)] UNSPEC_STOS)]
15385 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15387 [(set_attr "type" "str")
15388 (set_attr "memory" "store")
15389 (set_attr "mode" "SI")])
15391 (define_insn "*strsethi_1"
15392 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15393 (match_operand:HI 2 "register_operand" "a"))
15394 (set (match_operand:P 0 "register_operand" "=D")
15395 (plus:P (match_dup 1)
15397 (unspec [(const_int 0)] UNSPEC_STOS)]
15398 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15400 [(set_attr "type" "str")
15401 (set_attr "memory" "store")
15402 (set_attr "mode" "HI")])
15404 (define_insn "*strsetqi_1"
15405 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15406 (match_operand:QI 2 "register_operand" "a"))
15407 (set (match_operand:P 0 "register_operand" "=D")
15408 (plus:P (match_dup 1)
15410 (unspec [(const_int 0)] UNSPEC_STOS)]
15411 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15413 [(set_attr "type" "str")
15414 (set_attr "memory" "store")
15415 (set (attr "prefix_rex")
15417 (match_test "<P:MODE>mode == DImode")
15419 (const_string "*")))
15420 (set_attr "mode" "QI")])
15422 (define_expand "rep_stos"
15423 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
15424 (set (match_operand 0 "register_operand")
15426 (set (match_operand 2 "memory_operand") (const_int 0))
15427 (use (match_operand 3 "register_operand"))
15428 (use (match_dup 1))])]
15430 "ix86_current_function_needs_cld = 1;")
15432 (define_insn "*rep_stosdi_rex64"
15433 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15434 (set (match_operand:P 0 "register_operand" "=D")
15435 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15437 (match_operand:P 3 "register_operand" "0")))
15438 (set (mem:BLK (match_dup 3))
15440 (use (match_operand:DI 2 "register_operand" "a"))
15441 (use (match_dup 4))]
15443 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15445 [(set_attr "type" "str")
15446 (set_attr "prefix_rep" "1")
15447 (set_attr "memory" "store")
15448 (set_attr "mode" "DI")])
15450 (define_insn "*rep_stossi"
15451 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15452 (set (match_operand:P 0 "register_operand" "=D")
15453 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15455 (match_operand:P 3 "register_operand" "0")))
15456 (set (mem:BLK (match_dup 3))
15458 (use (match_operand:SI 2 "register_operand" "a"))
15459 (use (match_dup 4))]
15460 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15461 "%^rep{%;} stos{l|d}"
15462 [(set_attr "type" "str")
15463 (set_attr "prefix_rep" "1")
15464 (set_attr "memory" "store")
15465 (set_attr "mode" "SI")])
15467 (define_insn "*rep_stosqi"
15468 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15469 (set (match_operand:P 0 "register_operand" "=D")
15470 (plus:P (match_operand:P 3 "register_operand" "0")
15471 (match_operand:P 4 "register_operand" "1")))
15472 (set (mem:BLK (match_dup 3))
15474 (use (match_operand:QI 2 "register_operand" "a"))
15475 (use (match_dup 4))]
15476 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15478 [(set_attr "type" "str")
15479 (set_attr "prefix_rep" "1")
15480 (set_attr "memory" "store")
15481 (set (attr "prefix_rex")
15483 (match_test "<P:MODE>mode == DImode")
15485 (const_string "*")))
15486 (set_attr "mode" "QI")])
15488 (define_expand "cmpstrnsi"
15489 [(set (match_operand:SI 0 "register_operand")
15490 (compare:SI (match_operand:BLK 1 "general_operand")
15491 (match_operand:BLK 2 "general_operand")))
15492 (use (match_operand 3 "general_operand"))
15493 (use (match_operand 4 "immediate_operand"))]
15496 rtx addr1, addr2, out, outlow, count, countreg, align;
15498 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15501 /* Can't use this if the user has appropriated ecx, esi or edi. */
15502 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
15507 out = gen_reg_rtx (SImode);
15509 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
15510 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
15511 if (addr1 != XEXP (operands[1], 0))
15512 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15513 if (addr2 != XEXP (operands[2], 0))
15514 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15516 count = operands[3];
15517 countreg = ix86_zero_extend_to_Pmode (count);
15519 /* %%% Iff we are testing strict equality, we can use known alignment
15520 to good advantage. This may be possible with combine, particularly
15521 once cc0 is dead. */
15522 align = operands[4];
15524 if (CONST_INT_P (count))
15526 if (INTVAL (count) == 0)
15528 emit_move_insn (operands[0], const0_rtx);
15531 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15532 operands[1], operands[2]));
15536 rtx (*gen_cmp) (rtx, rtx);
15538 gen_cmp = (TARGET_64BIT
15539 ? gen_cmpdi_1 : gen_cmpsi_1);
15541 emit_insn (gen_cmp (countreg, countreg));
15542 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15543 operands[1], operands[2]));
15546 outlow = gen_lowpart (QImode, out);
15547 emit_insn (gen_cmpintqi (outlow));
15548 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15550 if (operands[0] != out)
15551 emit_move_insn (operands[0], out);
15556 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15558 (define_expand "cmpintqi"
15559 [(set (match_dup 1)
15560 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15562 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15563 (parallel [(set (match_operand:QI 0 "register_operand")
15564 (minus:QI (match_dup 1)
15566 (clobber (reg:CC FLAGS_REG))])]
15569 operands[1] = gen_reg_rtx (QImode);
15570 operands[2] = gen_reg_rtx (QImode);
15573 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15574 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
15576 (define_expand "cmpstrnqi_nz_1"
15577 [(parallel [(set (reg:CC FLAGS_REG)
15578 (compare:CC (match_operand 4 "memory_operand")
15579 (match_operand 5 "memory_operand")))
15580 (use (match_operand 2 "register_operand"))
15581 (use (match_operand:SI 3 "immediate_operand"))
15582 (clobber (match_operand 0 "register_operand"))
15583 (clobber (match_operand 1 "register_operand"))
15584 (clobber (match_dup 2))])]
15586 "ix86_current_function_needs_cld = 1;")
15588 (define_insn "*cmpstrnqi_nz_1"
15589 [(set (reg:CC FLAGS_REG)
15590 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15591 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
15592 (use (match_operand:P 6 "register_operand" "2"))
15593 (use (match_operand:SI 3 "immediate_operand" "i"))
15594 (clobber (match_operand:P 0 "register_operand" "=S"))
15595 (clobber (match_operand:P 1 "register_operand" "=D"))
15596 (clobber (match_operand:P 2 "register_operand" "=c"))]
15597 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15599 [(set_attr "type" "str")
15600 (set_attr "mode" "QI")
15601 (set (attr "prefix_rex")
15603 (match_test "<P:MODE>mode == DImode")
15605 (const_string "*")))
15606 (set_attr "prefix_rep" "1")])
15608 ;; The same, but the count is not known to not be zero.
15610 (define_expand "cmpstrnqi_1"
15611 [(parallel [(set (reg:CC FLAGS_REG)
15612 (if_then_else:CC (ne (match_operand 2 "register_operand")
15614 (compare:CC (match_operand 4 "memory_operand")
15615 (match_operand 5 "memory_operand"))
15617 (use (match_operand:SI 3 "immediate_operand"))
15618 (use (reg:CC FLAGS_REG))
15619 (clobber (match_operand 0 "register_operand"))
15620 (clobber (match_operand 1 "register_operand"))
15621 (clobber (match_dup 2))])]
15623 "ix86_current_function_needs_cld = 1;")
15625 (define_insn "*cmpstrnqi_1"
15626 [(set (reg:CC FLAGS_REG)
15627 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
15629 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15630 (mem:BLK (match_operand:P 5 "register_operand" "1")))
15632 (use (match_operand:SI 3 "immediate_operand" "i"))
15633 (use (reg:CC FLAGS_REG))
15634 (clobber (match_operand:P 0 "register_operand" "=S"))
15635 (clobber (match_operand:P 1 "register_operand" "=D"))
15636 (clobber (match_operand:P 2 "register_operand" "=c"))]
15637 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15639 [(set_attr "type" "str")
15640 (set_attr "mode" "QI")
15641 (set (attr "prefix_rex")
15643 (match_test "<P:MODE>mode == DImode")
15645 (const_string "*")))
15646 (set_attr "prefix_rep" "1")])
15648 (define_expand "strlen<mode>"
15649 [(set (match_operand:P 0 "register_operand")
15650 (unspec:P [(match_operand:BLK 1 "general_operand")
15651 (match_operand:QI 2 "immediate_operand")
15652 (match_operand 3 "immediate_operand")]
15656 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15662 (define_expand "strlenqi_1"
15663 [(parallel [(set (match_operand 0 "register_operand")
15665 (clobber (match_operand 1 "register_operand"))
15666 (clobber (reg:CC FLAGS_REG))])]
15668 "ix86_current_function_needs_cld = 1;")
15670 (define_insn "*strlenqi_1"
15671 [(set (match_operand:P 0 "register_operand" "=&c")
15672 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
15673 (match_operand:QI 2 "register_operand" "a")
15674 (match_operand:P 3 "immediate_operand" "i")
15675 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
15676 (clobber (match_operand:P 1 "register_operand" "=D"))
15677 (clobber (reg:CC FLAGS_REG))]
15678 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15679 "%^repnz{%;} scasb"
15680 [(set_attr "type" "str")
15681 (set_attr "mode" "QI")
15682 (set (attr "prefix_rex")
15684 (match_test "<P:MODE>mode == DImode")
15686 (const_string "*")))
15687 (set_attr "prefix_rep" "1")])
15689 ;; Peephole optimizations to clean up after cmpstrn*. This should be
15690 ;; handled in combine, but it is not currently up to the task.
15691 ;; When used for their truth value, the cmpstrn* expanders generate
15700 ;; The intermediate three instructions are unnecessary.
15702 ;; This one handles cmpstrn*_nz_1...
15705 (set (reg:CC FLAGS_REG)
15706 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
15707 (mem:BLK (match_operand 5 "register_operand"))))
15708 (use (match_operand 6 "register_operand"))
15709 (use (match_operand:SI 3 "immediate_operand"))
15710 (clobber (match_operand 0 "register_operand"))
15711 (clobber (match_operand 1 "register_operand"))
15712 (clobber (match_operand 2 "register_operand"))])
15713 (set (match_operand:QI 7 "register_operand")
15714 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15715 (set (match_operand:QI 8 "register_operand")
15716 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15717 (set (reg FLAGS_REG)
15718 (compare (match_dup 7) (match_dup 8)))
15720 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15722 (set (reg:CC FLAGS_REG)
15723 (compare:CC (mem:BLK (match_dup 4))
15724 (mem:BLK (match_dup 5))))
15725 (use (match_dup 6))
15726 (use (match_dup 3))
15727 (clobber (match_dup 0))
15728 (clobber (match_dup 1))
15729 (clobber (match_dup 2))])])
15731 ;; ...and this one handles cmpstrn*_1.
15734 (set (reg:CC FLAGS_REG)
15735 (if_then_else:CC (ne (match_operand 6 "register_operand")
15737 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
15738 (mem:BLK (match_operand 5 "register_operand")))
15740 (use (match_operand:SI 3 "immediate_operand"))
15741 (use (reg:CC FLAGS_REG))
15742 (clobber (match_operand 0 "register_operand"))
15743 (clobber (match_operand 1 "register_operand"))
15744 (clobber (match_operand 2 "register_operand"))])
15745 (set (match_operand:QI 7 "register_operand")
15746 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15747 (set (match_operand:QI 8 "register_operand")
15748 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15749 (set (reg FLAGS_REG)
15750 (compare (match_dup 7) (match_dup 8)))
15752 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15754 (set (reg:CC FLAGS_REG)
15755 (if_then_else:CC (ne (match_dup 6)
15757 (compare:CC (mem:BLK (match_dup 4))
15758 (mem:BLK (match_dup 5)))
15760 (use (match_dup 3))
15761 (use (reg:CC FLAGS_REG))
15762 (clobber (match_dup 0))
15763 (clobber (match_dup 1))
15764 (clobber (match_dup 2))])])
15766 ;; Conditional move instructions.
15768 (define_expand "mov<mode>cc"
15769 [(set (match_operand:SWIM 0 "register_operand")
15770 (if_then_else:SWIM (match_operand 1 "comparison_operator")
15771 (match_operand:SWIM 2 "<general_operand>")
15772 (match_operand:SWIM 3 "<general_operand>")))]
15774 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
15776 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
15777 ;; the register first winds up with `sbbl $0,reg', which is also weird.
15778 ;; So just document what we're doing explicitly.
15780 (define_expand "x86_mov<mode>cc_0_m1"
15782 [(set (match_operand:SWI48 0 "register_operand")
15783 (if_then_else:SWI48
15784 (match_operator:SWI48 2 "ix86_carry_flag_operator"
15785 [(match_operand 1 "flags_reg_operand")
15789 (clobber (reg:CC FLAGS_REG))])])
15791 (define_insn "*x86_mov<mode>cc_0_m1"
15792 [(set (match_operand:SWI48 0 "register_operand" "=r")
15793 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15794 [(reg FLAGS_REG) (const_int 0)])
15797 (clobber (reg:CC FLAGS_REG))]
15799 "sbb{<imodesuffix>}\t%0, %0"
15800 ; Since we don't have the proper number of operands for an alu insn,
15801 ; fill in all the blanks.
15802 [(set_attr "type" "alu")
15803 (set_attr "use_carry" "1")
15804 (set_attr "pent_pair" "pu")
15805 (set_attr "memory" "none")
15806 (set_attr "imm_disp" "false")
15807 (set_attr "mode" "<MODE>")
15808 (set_attr "length_immediate" "0")])
15810 (define_insn "*x86_mov<mode>cc_0_m1_se"
15811 [(set (match_operand:SWI48 0 "register_operand" "=r")
15812 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15813 [(reg FLAGS_REG) (const_int 0)])
15816 (clobber (reg:CC FLAGS_REG))]
15818 "sbb{<imodesuffix>}\t%0, %0"
15819 [(set_attr "type" "alu")
15820 (set_attr "use_carry" "1")
15821 (set_attr "pent_pair" "pu")
15822 (set_attr "memory" "none")
15823 (set_attr "imm_disp" "false")
15824 (set_attr "mode" "<MODE>")
15825 (set_attr "length_immediate" "0")])
15827 (define_insn "*x86_mov<mode>cc_0_m1_neg"
15828 [(set (match_operand:SWI48 0 "register_operand" "=r")
15829 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15830 [(reg FLAGS_REG) (const_int 0)])))
15831 (clobber (reg:CC FLAGS_REG))]
15833 "sbb{<imodesuffix>}\t%0, %0"
15834 [(set_attr "type" "alu")
15835 (set_attr "use_carry" "1")
15836 (set_attr "pent_pair" "pu")
15837 (set_attr "memory" "none")
15838 (set_attr "imm_disp" "false")
15839 (set_attr "mode" "<MODE>")
15840 (set_attr "length_immediate" "0")])
15842 (define_insn "*mov<mode>cc_noc"
15843 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
15844 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
15845 [(reg FLAGS_REG) (const_int 0)])
15846 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
15847 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
15848 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
15850 cmov%O2%C1\t{%2, %0|%0, %2}
15851 cmov%O2%c1\t{%3, %0|%0, %3}"
15852 [(set_attr "type" "icmov")
15853 (set_attr "mode" "<MODE>")])
15855 ;; Don't do conditional moves with memory inputs. This splitter helps
15856 ;; register starved x86_32 by forcing inputs into registers before reload.
15858 [(set (match_operand:SWI248 0 "register_operand")
15859 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
15860 [(reg FLAGS_REG) (const_int 0)])
15861 (match_operand:SWI248 2 "nonimmediate_operand")
15862 (match_operand:SWI248 3 "nonimmediate_operand")))]
15863 "!TARGET_64BIT && TARGET_CMOVE
15864 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
15865 && (MEM_P (operands[2]) || MEM_P (operands[3]))
15866 && can_create_pseudo_p ()
15867 && optimize_insn_for_speed_p ()"
15868 [(set (match_dup 0)
15869 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
15871 if (MEM_P (operands[2]))
15872 operands[2] = force_reg (<MODE>mode, operands[2]);
15873 if (MEM_P (operands[3]))
15874 operands[3] = force_reg (<MODE>mode, operands[3]);
15877 (define_insn "*movqicc_noc"
15878 [(set (match_operand:QI 0 "register_operand" "=r,r")
15879 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
15880 [(reg FLAGS_REG) (const_int 0)])
15881 (match_operand:QI 2 "register_operand" "r,0")
15882 (match_operand:QI 3 "register_operand" "0,r")))]
15883 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
15885 [(set_attr "type" "icmov")
15886 (set_attr "mode" "QI")])
15889 [(set (match_operand:SWI12 0 "register_operand")
15890 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
15891 [(reg FLAGS_REG) (const_int 0)])
15892 (match_operand:SWI12 2 "register_operand")
15893 (match_operand:SWI12 3 "register_operand")))]
15894 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
15895 && reload_completed"
15896 [(set (match_dup 0)
15897 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
15899 operands[0] = gen_lowpart (SImode, operands[0]);
15900 operands[2] = gen_lowpart (SImode, operands[2]);
15901 operands[3] = gen_lowpart (SImode, operands[3]);
15904 ;; Don't do conditional moves with memory inputs
15906 [(match_scratch:SWI248 2 "r")
15907 (set (match_operand:SWI248 0 "register_operand")
15908 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
15909 [(reg FLAGS_REG) (const_int 0)])
15911 (match_operand:SWI248 3 "memory_operand")))]
15912 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
15913 && optimize_insn_for_speed_p ()"
15914 [(set (match_dup 2) (match_dup 3))
15916 (if_then_else:SWI248 (match_dup 1) (match_dup 0) (match_dup 2)))])
15919 [(match_scratch:SWI248 2 "r")
15920 (set (match_operand:SWI248 0 "register_operand")
15921 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
15922 [(reg FLAGS_REG) (const_int 0)])
15923 (match_operand:SWI248 3 "memory_operand")
15925 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
15926 && optimize_insn_for_speed_p ()"
15927 [(set (match_dup 2) (match_dup 3))
15929 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 0)))])
15931 (define_expand "mov<mode>cc"
15932 [(set (match_operand:X87MODEF 0 "register_operand")
15933 (if_then_else:X87MODEF
15934 (match_operand 1 "comparison_operator")
15935 (match_operand:X87MODEF 2 "register_operand")
15936 (match_operand:X87MODEF 3 "register_operand")))]
15937 "(TARGET_80387 && TARGET_CMOVE)
15938 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15939 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
15941 (define_insn "*movxfcc_1"
15942 [(set (match_operand:XF 0 "register_operand" "=f,f")
15943 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
15944 [(reg FLAGS_REG) (const_int 0)])
15945 (match_operand:XF 2 "register_operand" "f,0")
15946 (match_operand:XF 3 "register_operand" "0,f")))]
15947 "TARGET_80387 && TARGET_CMOVE"
15949 fcmov%F1\t{%2, %0|%0, %2}
15950 fcmov%f1\t{%3, %0|%0, %3}"
15951 [(set_attr "type" "fcmov")
15952 (set_attr "mode" "XF")])
15954 (define_insn "*movdfcc_1_rex64"
15955 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
15956 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
15957 [(reg FLAGS_REG) (const_int 0)])
15958 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
15959 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
15960 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
15961 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
15963 fcmov%F1\t{%2, %0|%0, %2}
15964 fcmov%f1\t{%3, %0|%0, %3}
15965 cmov%O2%C1\t{%2, %0|%0, %2}
15966 cmov%O2%c1\t{%3, %0|%0, %3}"
15967 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
15968 (set_attr "mode" "DF,DF,DI,DI")])
15970 (define_insn "*movdfcc_1"
15971 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
15972 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
15973 [(reg FLAGS_REG) (const_int 0)])
15974 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
15975 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
15976 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
15977 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
15979 fcmov%F1\t{%2, %0|%0, %2}
15980 fcmov%f1\t{%3, %0|%0, %3}
15983 [(set_attr "type" "fcmov,fcmov,multi,multi")
15984 (set_attr "mode" "DF,DF,DI,DI")])
15987 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
15988 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
15989 [(reg FLAGS_REG) (const_int 0)])
15990 (match_operand:DF 2 "nonimmediate_operand")
15991 (match_operand:DF 3 "nonimmediate_operand")))]
15992 "!TARGET_64BIT && reload_completed"
15993 [(set (match_dup 2)
15994 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
15996 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
15998 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
15999 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16002 (define_insn "*movsfcc_1_387"
16003 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16004 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16005 [(reg FLAGS_REG) (const_int 0)])
16006 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16007 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16008 "TARGET_80387 && TARGET_CMOVE
16009 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16011 fcmov%F1\t{%2, %0|%0, %2}
16012 fcmov%f1\t{%3, %0|%0, %3}
16013 cmov%O2%C1\t{%2, %0|%0, %2}
16014 cmov%O2%c1\t{%3, %0|%0, %3}"
16015 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16016 (set_attr "mode" "SF,SF,SI,SI")])
16018 ;; Don't do conditional moves with memory inputs. This splitter helps
16019 ;; register starved x86_32 by forcing inputs into registers before reload.
16021 [(set (match_operand:MODEF 0 "register_operand")
16022 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
16023 [(reg FLAGS_REG) (const_int 0)])
16024 (match_operand:MODEF 2 "nonimmediate_operand")
16025 (match_operand:MODEF 3 "nonimmediate_operand")))]
16026 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16027 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16028 && (MEM_P (operands[2]) || MEM_P (operands[3]))
16029 && can_create_pseudo_p ()
16030 && optimize_insn_for_speed_p ()"
16031 [(set (match_dup 0)
16032 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
16034 if (MEM_P (operands[2]))
16035 operands[2] = force_reg (<MODE>mode, operands[2]);
16036 if (MEM_P (operands[3]))
16037 operands[3] = force_reg (<MODE>mode, operands[3]);
16040 ;; Don't do conditional moves with memory inputs
16042 [(match_scratch:MODEF 2 "r")
16043 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16044 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16045 [(reg FLAGS_REG) (const_int 0)])
16047 (match_operand:MODEF 3 "memory_operand")))]
16048 "(<MODE>mode != DFmode || TARGET_64BIT)
16049 && TARGET_80387 && TARGET_CMOVE
16050 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16051 && optimize_insn_for_speed_p ()"
16052 [(set (match_dup 2) (match_dup 3))
16054 (if_then_else:MODEF (match_dup 1) (match_dup 0) (match_dup 2)))])
16057 [(match_scratch:MODEF 2 "r")
16058 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16059 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16060 [(reg FLAGS_REG) (const_int 0)])
16061 (match_operand:MODEF 3 "memory_operand")
16063 "(<MODE>mode != DFmode || TARGET_64BIT)
16064 && TARGET_80387 && TARGET_CMOVE
16065 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16066 && optimize_insn_for_speed_p ()"
16067 [(set (match_dup 2) (match_dup 3))
16069 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 0)))])
16071 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16072 ;; the scalar versions to have only XMM registers as operands.
16074 ;; XOP conditional move
16075 (define_insn "*xop_pcmov_<mode>"
16076 [(set (match_operand:MODEF 0 "register_operand" "=x")
16077 (if_then_else:MODEF
16078 (match_operand:MODEF 1 "register_operand" "x")
16079 (match_operand:MODEF 2 "register_operand" "x")
16080 (match_operand:MODEF 3 "register_operand" "x")))]
16082 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16083 [(set_attr "type" "sse4arg")])
16085 ;; These versions of the min/max patterns are intentionally ignorant of
16086 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16087 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16088 ;; are undefined in this condition, we're certain this is correct.
16090 (define_insn "<code><mode>3"
16091 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16093 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16094 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16095 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16097 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16098 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16099 [(set_attr "isa" "noavx,avx")
16100 (set_attr "prefix" "orig,vex")
16101 (set_attr "type" "sseadd")
16102 (set_attr "mode" "<MODE>")])
16104 ;; These versions of the min/max patterns implement exactly the operations
16105 ;; min = (op1 < op2 ? op1 : op2)
16106 ;; max = (!(op1 < op2) ? op1 : op2)
16107 ;; Their operands are not commutative, and thus they may be used in the
16108 ;; presence of -0.0 and NaN.
16110 (define_int_iterator IEEE_MAXMIN
16114 (define_int_attr ieee_maxmin
16115 [(UNSPEC_IEEE_MAX "max")
16116 (UNSPEC_IEEE_MIN "min")])
16118 (define_insn "*ieee_s<ieee_maxmin><mode>3"
16119 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16121 [(match_operand:MODEF 1 "register_operand" "0,x")
16122 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16124 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16126 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
16127 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16128 [(set_attr "isa" "noavx,avx")
16129 (set_attr "prefix" "orig,vex")
16130 (set_attr "type" "sseadd")
16131 (set_attr "mode" "<MODE>")])
16133 ;; Make two stack loads independent:
16135 ;; fld %st(0) -> fld bb
16136 ;; fmul bb fmul %st(1), %st
16138 ;; Actually we only match the last two instructions for simplicity.
16140 [(set (match_operand 0 "fp_register_operand")
16141 (match_operand 1 "fp_register_operand"))
16143 (match_operator 2 "binary_fp_operator"
16145 (match_operand 3 "memory_operand")]))]
16146 "REGNO (operands[0]) != REGNO (operands[1])"
16147 [(set (match_dup 0) (match_dup 3))
16148 (set (match_dup 0) (match_dup 4))]
16150 ;; The % modifier is not operational anymore in peephole2's, so we have to
16151 ;; swap the operands manually in the case of addition and multiplication.
16155 if (COMMUTATIVE_ARITH_P (operands[2]))
16156 op0 = operands[0], op1 = operands[1];
16158 op0 = operands[1], op1 = operands[0];
16160 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16161 GET_MODE (operands[2]),
16165 ;; Conditional addition patterns
16166 (define_expand "add<mode>cc"
16167 [(match_operand:SWI 0 "register_operand")
16168 (match_operand 1 "ordered_comparison_operator")
16169 (match_operand:SWI 2 "register_operand")
16170 (match_operand:SWI 3 "const_int_operand")]
16172 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16174 ;; Misc patterns (?)
16176 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16177 ;; Otherwise there will be nothing to keep
16179 ;; [(set (reg ebp) (reg esp))]
16180 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16181 ;; (clobber (eflags)]
16182 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16184 ;; in proper program order.
16186 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16187 [(set (match_operand:P 0 "register_operand" "=r,r")
16188 (plus:P (match_operand:P 1 "register_operand" "0,r")
16189 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16190 (clobber (reg:CC FLAGS_REG))
16191 (clobber (mem:BLK (scratch)))]
16194 switch (get_attr_type (insn))
16197 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16200 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16201 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16202 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16204 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16207 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16208 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16211 [(set (attr "type")
16212 (cond [(and (eq_attr "alternative" "0")
16213 (not (match_test "TARGET_OPT_AGU")))
16214 (const_string "alu")
16215 (match_operand:<MODE> 2 "const0_operand")
16216 (const_string "imov")
16218 (const_string "lea")))
16219 (set (attr "length_immediate")
16220 (cond [(eq_attr "type" "imov")
16222 (and (eq_attr "type" "alu")
16223 (match_operand 2 "const128_operand"))
16226 (const_string "*")))
16227 (set_attr "mode" "<MODE>")])
16229 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16230 [(set (match_operand:P 0 "register_operand" "=r")
16231 (minus:P (match_operand:P 1 "register_operand" "0")
16232 (match_operand:P 2 "register_operand" "r")))
16233 (clobber (reg:CC FLAGS_REG))
16234 (clobber (mem:BLK (scratch)))]
16236 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16237 [(set_attr "type" "alu")
16238 (set_attr "mode" "<MODE>")])
16240 (define_insn "allocate_stack_worker_probe_<mode>"
16241 [(set (match_operand:P 0 "register_operand" "=a")
16242 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16243 UNSPECV_STACK_PROBE))
16244 (clobber (reg:CC FLAGS_REG))]
16245 "ix86_target_stack_probe ()"
16246 "call\t___chkstk_ms"
16247 [(set_attr "type" "multi")
16248 (set_attr "length" "5")])
16250 (define_expand "allocate_stack"
16251 [(match_operand 0 "register_operand")
16252 (match_operand 1 "general_operand")]
16253 "ix86_target_stack_probe ()"
16257 #ifndef CHECK_STACK_LIMIT
16258 #define CHECK_STACK_LIMIT 0
16261 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16262 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16266 rtx (*insn) (rtx, rtx);
16268 x = copy_to_mode_reg (Pmode, operands[1]);
16270 insn = (TARGET_64BIT
16271 ? gen_allocate_stack_worker_probe_di
16272 : gen_allocate_stack_worker_probe_si);
16274 emit_insn (insn (x, x));
16277 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16278 stack_pointer_rtx, 0, OPTAB_DIRECT);
16280 if (x != stack_pointer_rtx)
16281 emit_move_insn (stack_pointer_rtx, x);
16283 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16287 ;; Use IOR for stack probes, this is shorter.
16288 (define_expand "probe_stack"
16289 [(match_operand 0 "memory_operand")]
16292 rtx (*gen_ior3) (rtx, rtx, rtx);
16294 gen_ior3 = (GET_MODE (operands[0]) == DImode
16295 ? gen_iordi3 : gen_iorsi3);
16297 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16301 (define_insn "adjust_stack_and_probe<mode>"
16302 [(set (match_operand:P 0 "register_operand" "=r")
16303 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16304 UNSPECV_PROBE_STACK_RANGE))
16305 (set (reg:P SP_REG)
16306 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16307 (clobber (reg:CC FLAGS_REG))
16308 (clobber (mem:BLK (scratch)))]
16310 "* return output_adjust_stack_and_probe (operands[0]);"
16311 [(set_attr "type" "multi")])
16313 (define_insn "probe_stack_range<mode>"
16314 [(set (match_operand:P 0 "register_operand" "=r")
16315 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16316 (match_operand:P 2 "const_int_operand" "n")]
16317 UNSPECV_PROBE_STACK_RANGE))
16318 (clobber (reg:CC FLAGS_REG))]
16320 "* return output_probe_stack_range (operands[0], operands[2]);"
16321 [(set_attr "type" "multi")])
16323 (define_expand "builtin_setjmp_receiver"
16324 [(label_ref (match_operand 0))]
16325 "!TARGET_64BIT && flag_pic"
16331 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16332 rtx label_rtx = gen_label_rtx ();
16333 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16334 xops[0] = xops[1] = picreg;
16335 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16336 ix86_expand_binary_operator (MINUS, SImode, xops);
16340 emit_insn (gen_set_got (pic_offset_table_rtx));
16344 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16347 [(set (match_operand 0 "register_operand")
16348 (match_operator 3 "promotable_binary_operator"
16349 [(match_operand 1 "register_operand")
16350 (match_operand 2 "aligned_operand")]))
16351 (clobber (reg:CC FLAGS_REG))]
16352 "! TARGET_PARTIAL_REG_STALL && reload_completed
16353 && ((GET_MODE (operands[0]) == HImode
16354 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16355 /* ??? next two lines just !satisfies_constraint_K (...) */
16356 || !CONST_INT_P (operands[2])
16357 || satisfies_constraint_K (operands[2])))
16358 || (GET_MODE (operands[0]) == QImode
16359 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16360 [(parallel [(set (match_dup 0)
16361 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16362 (clobber (reg:CC FLAGS_REG))])]
16364 operands[0] = gen_lowpart (SImode, operands[0]);
16365 operands[1] = gen_lowpart (SImode, operands[1]);
16366 if (GET_CODE (operands[3]) != ASHIFT)
16367 operands[2] = gen_lowpart (SImode, operands[2]);
16368 PUT_MODE (operands[3], SImode);
16371 ; Promote the QImode tests, as i386 has encoding of the AND
16372 ; instruction with 32-bit sign-extended immediate and thus the
16373 ; instruction size is unchanged, except in the %eax case for
16374 ; which it is increased by one byte, hence the ! optimize_size.
16376 [(set (match_operand 0 "flags_reg_operand")
16377 (match_operator 2 "compare_operator"
16378 [(and (match_operand 3 "aligned_operand")
16379 (match_operand 4 "const_int_operand"))
16381 (set (match_operand 1 "register_operand")
16382 (and (match_dup 3) (match_dup 4)))]
16383 "! TARGET_PARTIAL_REG_STALL && reload_completed
16384 && optimize_insn_for_speed_p ()
16385 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16386 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16387 /* Ensure that the operand will remain sign-extended immediate. */
16388 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16389 [(parallel [(set (match_dup 0)
16390 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16393 (and:SI (match_dup 3) (match_dup 4)))])]
16396 = gen_int_mode (INTVAL (operands[4])
16397 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16398 operands[1] = gen_lowpart (SImode, operands[1]);
16399 operands[3] = gen_lowpart (SImode, operands[3]);
16402 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16403 ; the TEST instruction with 32-bit sign-extended immediate and thus
16404 ; the instruction size would at least double, which is not what we
16405 ; want even with ! optimize_size.
16407 [(set (match_operand 0 "flags_reg_operand")
16408 (match_operator 1 "compare_operator"
16409 [(and (match_operand:HI 2 "aligned_operand")
16410 (match_operand:HI 3 "const_int_operand"))
16412 "! TARGET_PARTIAL_REG_STALL && reload_completed
16413 && ! TARGET_FAST_PREFIX
16414 && optimize_insn_for_speed_p ()
16415 /* Ensure that the operand will remain sign-extended immediate. */
16416 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16417 [(set (match_dup 0)
16418 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16422 = gen_int_mode (INTVAL (operands[3])
16423 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16424 operands[2] = gen_lowpart (SImode, operands[2]);
16428 [(set (match_operand 0 "register_operand")
16429 (neg (match_operand 1 "register_operand")))
16430 (clobber (reg:CC FLAGS_REG))]
16431 "! TARGET_PARTIAL_REG_STALL && reload_completed
16432 && (GET_MODE (operands[0]) == HImode
16433 || (GET_MODE (operands[0]) == QImode
16434 && (TARGET_PROMOTE_QImode
16435 || optimize_insn_for_size_p ())))"
16436 [(parallel [(set (match_dup 0)
16437 (neg:SI (match_dup 1)))
16438 (clobber (reg:CC FLAGS_REG))])]
16440 operands[0] = gen_lowpart (SImode, operands[0]);
16441 operands[1] = gen_lowpart (SImode, operands[1]);
16445 [(set (match_operand 0 "register_operand")
16446 (not (match_operand 1 "register_operand")))]
16447 "! TARGET_PARTIAL_REG_STALL && reload_completed
16448 && (GET_MODE (operands[0]) == HImode
16449 || (GET_MODE (operands[0]) == QImode
16450 && (TARGET_PROMOTE_QImode
16451 || optimize_insn_for_size_p ())))"
16452 [(set (match_dup 0)
16453 (not:SI (match_dup 1)))]
16455 operands[0] = gen_lowpart (SImode, operands[0]);
16456 operands[1] = gen_lowpart (SImode, operands[1]);
16459 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16460 ;; transform a complex memory operation into two memory to register operations.
16462 ;; Don't push memory operands
16464 [(set (match_operand:SWI 0 "push_operand")
16465 (match_operand:SWI 1 "memory_operand"))
16466 (match_scratch:SWI 2 "<r>")]
16467 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16468 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16469 [(set (match_dup 2) (match_dup 1))
16470 (set (match_dup 0) (match_dup 2))])
16472 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16475 [(set (match_operand:SF 0 "push_operand")
16476 (match_operand:SF 1 "memory_operand"))
16477 (match_scratch:SF 2 "r")]
16478 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16479 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16480 [(set (match_dup 2) (match_dup 1))
16481 (set (match_dup 0) (match_dup 2))])
16483 ;; Don't move an immediate directly to memory when the instruction
16484 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
16486 [(match_scratch:SWI124 1 "<r>")
16487 (set (match_operand:SWI124 0 "memory_operand")
16489 "optimize_insn_for_speed_p ()
16490 && ((<MODE>mode == HImode
16491 && TARGET_LCP_STALL)
16492 || (!TARGET_USE_MOV0
16493 && TARGET_SPLIT_LONG_MOVES
16494 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
16495 && peep2_regno_dead_p (0, FLAGS_REG)"
16496 [(parallel [(set (match_dup 2) (const_int 0))
16497 (clobber (reg:CC FLAGS_REG))])
16498 (set (match_dup 0) (match_dup 1))]
16499 "operands[2] = gen_lowpart (SImode, operands[1]);")
16502 [(match_scratch:SWI124 2 "<r>")
16503 (set (match_operand:SWI124 0 "memory_operand")
16504 (match_operand:SWI124 1 "immediate_operand"))]
16505 "optimize_insn_for_speed_p ()
16506 && ((<MODE>mode == HImode
16507 && TARGET_LCP_STALL)
16508 || (TARGET_SPLIT_LONG_MOVES
16509 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
16510 [(set (match_dup 2) (match_dup 1))
16511 (set (match_dup 0) (match_dup 2))])
16513 ;; Don't compare memory with zero, load and use a test instead.
16515 [(set (match_operand 0 "flags_reg_operand")
16516 (match_operator 1 "compare_operator"
16517 [(match_operand:SI 2 "memory_operand")
16519 (match_scratch:SI 3 "r")]
16520 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16521 [(set (match_dup 3) (match_dup 2))
16522 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16524 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16525 ;; Don't split NOTs with a displacement operand, because resulting XOR
16526 ;; will not be pairable anyway.
16528 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16529 ;; represented using a modRM byte. The XOR replacement is long decoded,
16530 ;; so this split helps here as well.
16532 ;; Note: Can't do this as a regular split because we can't get proper
16533 ;; lifetime information then.
16536 [(set (match_operand:SWI124 0 "nonimmediate_operand")
16537 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
16538 "optimize_insn_for_speed_p ()
16539 && ((TARGET_NOT_UNPAIRABLE
16540 && (!MEM_P (operands[0])
16541 || !memory_displacement_operand (operands[0], <MODE>mode)))
16542 || (TARGET_NOT_VECTORMODE
16543 && long_memory_operand (operands[0], <MODE>mode)))
16544 && peep2_regno_dead_p (0, FLAGS_REG)"
16545 [(parallel [(set (match_dup 0)
16546 (xor:SWI124 (match_dup 1) (const_int -1)))
16547 (clobber (reg:CC FLAGS_REG))])])
16549 ;; Non pairable "test imm, reg" instructions can be translated to
16550 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16551 ;; byte opcode instead of two, have a short form for byte operands),
16552 ;; so do it for other CPUs as well. Given that the value was dead,
16553 ;; this should not create any new dependencies. Pass on the sub-word
16554 ;; versions if we're concerned about partial register stalls.
16557 [(set (match_operand 0 "flags_reg_operand")
16558 (match_operator 1 "compare_operator"
16559 [(and:SI (match_operand:SI 2 "register_operand")
16560 (match_operand:SI 3 "immediate_operand"))
16562 "ix86_match_ccmode (insn, CCNOmode)
16563 && (true_regnum (operands[2]) != AX_REG
16564 || satisfies_constraint_K (operands[3]))
16565 && peep2_reg_dead_p (1, operands[2])"
16567 [(set (match_dup 0)
16568 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16571 (and:SI (match_dup 2) (match_dup 3)))])])
16573 ;; We don't need to handle HImode case, because it will be promoted to SImode
16574 ;; on ! TARGET_PARTIAL_REG_STALL
16577 [(set (match_operand 0 "flags_reg_operand")
16578 (match_operator 1 "compare_operator"
16579 [(and:QI (match_operand:QI 2 "register_operand")
16580 (match_operand:QI 3 "immediate_operand"))
16582 "! TARGET_PARTIAL_REG_STALL
16583 && ix86_match_ccmode (insn, CCNOmode)
16584 && true_regnum (operands[2]) != AX_REG
16585 && peep2_reg_dead_p (1, operands[2])"
16587 [(set (match_dup 0)
16588 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16591 (and:QI (match_dup 2) (match_dup 3)))])])
16594 [(set (match_operand 0 "flags_reg_operand")
16595 (match_operator 1 "compare_operator"
16598 (match_operand 2 "ext_register_operand")
16601 (match_operand 3 "const_int_operand"))
16603 "! TARGET_PARTIAL_REG_STALL
16604 && ix86_match_ccmode (insn, CCNOmode)
16605 && true_regnum (operands[2]) != AX_REG
16606 && peep2_reg_dead_p (1, operands[2])"
16607 [(parallel [(set (match_dup 0)
16616 (set (zero_extract:SI (match_dup 2)
16624 (match_dup 3)))])])
16626 ;; Don't do logical operations with memory inputs.
16628 [(match_scratch:SI 2 "r")
16629 (parallel [(set (match_operand:SI 0 "register_operand")
16630 (match_operator:SI 3 "arith_or_logical_operator"
16632 (match_operand:SI 1 "memory_operand")]))
16633 (clobber (reg:CC FLAGS_REG))])]
16634 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
16635 [(set (match_dup 2) (match_dup 1))
16636 (parallel [(set (match_dup 0)
16637 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16638 (clobber (reg:CC FLAGS_REG))])])
16641 [(match_scratch:SI 2 "r")
16642 (parallel [(set (match_operand:SI 0 "register_operand")
16643 (match_operator:SI 3 "arith_or_logical_operator"
16644 [(match_operand:SI 1 "memory_operand")
16646 (clobber (reg:CC FLAGS_REG))])]
16647 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
16648 [(set (match_dup 2) (match_dup 1))
16649 (parallel [(set (match_dup 0)
16650 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16651 (clobber (reg:CC FLAGS_REG))])])
16653 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
16654 ;; refers to the destination of the load!
16657 [(set (match_operand:SI 0 "register_operand")
16658 (match_operand:SI 1 "register_operand"))
16659 (parallel [(set (match_dup 0)
16660 (match_operator:SI 3 "commutative_operator"
16662 (match_operand:SI 2 "memory_operand")]))
16663 (clobber (reg:CC FLAGS_REG))])]
16664 "REGNO (operands[0]) != REGNO (operands[1])
16665 && GENERAL_REGNO_P (REGNO (operands[0]))
16666 && GENERAL_REGNO_P (REGNO (operands[1]))"
16667 [(set (match_dup 0) (match_dup 4))
16668 (parallel [(set (match_dup 0)
16669 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16670 (clobber (reg:CC FLAGS_REG))])]
16671 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
16674 [(set (match_operand 0 "register_operand")
16675 (match_operand 1 "register_operand"))
16677 (match_operator 3 "commutative_operator"
16679 (match_operand 2 "memory_operand")]))]
16680 "REGNO (operands[0]) != REGNO (operands[1])
16681 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
16682 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
16683 [(set (match_dup 0) (match_dup 2))
16685 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
16687 ; Don't do logical operations with memory outputs
16689 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16690 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
16691 ; the same decoder scheduling characteristics as the original.
16694 [(match_scratch:SI 2 "r")
16695 (parallel [(set (match_operand:SI 0 "memory_operand")
16696 (match_operator:SI 3 "arith_or_logical_operator"
16698 (match_operand:SI 1 "nonmemory_operand")]))
16699 (clobber (reg:CC FLAGS_REG))])]
16700 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16701 /* Do not split stack checking probes. */
16702 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16703 [(set (match_dup 2) (match_dup 0))
16704 (parallel [(set (match_dup 2)
16705 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16706 (clobber (reg:CC FLAGS_REG))])
16707 (set (match_dup 0) (match_dup 2))])
16710 [(match_scratch:SI 2 "r")
16711 (parallel [(set (match_operand:SI 0 "memory_operand")
16712 (match_operator:SI 3 "arith_or_logical_operator"
16713 [(match_operand:SI 1 "nonmemory_operand")
16715 (clobber (reg:CC FLAGS_REG))])]
16716 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16717 /* Do not split stack checking probes. */
16718 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16719 [(set (match_dup 2) (match_dup 0))
16720 (parallel [(set (match_dup 2)
16721 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16722 (clobber (reg:CC FLAGS_REG))])
16723 (set (match_dup 0) (match_dup 2))])
16725 ;; Attempt to use arith or logical operations with memory outputs with
16726 ;; setting of flags.
16728 [(set (match_operand:SWI 0 "register_operand")
16729 (match_operand:SWI 1 "memory_operand"))
16730 (parallel [(set (match_dup 0)
16731 (match_operator:SWI 3 "plusminuslogic_operator"
16733 (match_operand:SWI 2 "<nonmemory_operand>")]))
16734 (clobber (reg:CC FLAGS_REG))])
16735 (set (match_dup 1) (match_dup 0))
16736 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16737 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16738 && peep2_reg_dead_p (4, operands[0])
16739 && !reg_overlap_mentioned_p (operands[0], operands[1])
16740 && (<MODE>mode != QImode
16741 || immediate_operand (operands[2], QImode)
16742 || q_regs_operand (operands[2], QImode))
16743 && ix86_match_ccmode (peep2_next_insn (3),
16744 (GET_CODE (operands[3]) == PLUS
16745 || GET_CODE (operands[3]) == MINUS)
16746 ? CCGOCmode : CCNOmode)"
16747 [(parallel [(set (match_dup 4) (match_dup 5))
16748 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
16749 (match_dup 2)]))])]
16751 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
16752 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16753 copy_rtx (operands[1]),
16754 copy_rtx (operands[2]));
16755 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
16756 operands[5], const0_rtx);
16760 [(parallel [(set (match_operand:SWI 0 "register_operand")
16761 (match_operator:SWI 2 "plusminuslogic_operator"
16763 (match_operand:SWI 1 "memory_operand")]))
16764 (clobber (reg:CC FLAGS_REG))])
16765 (set (match_dup 1) (match_dup 0))
16766 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16767 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16768 && GET_CODE (operands[2]) != MINUS
16769 && peep2_reg_dead_p (3, operands[0])
16770 && !reg_overlap_mentioned_p (operands[0], operands[1])
16771 && ix86_match_ccmode (peep2_next_insn (2),
16772 GET_CODE (operands[2]) == PLUS
16773 ? CCGOCmode : CCNOmode)"
16774 [(parallel [(set (match_dup 3) (match_dup 4))
16775 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
16776 (match_dup 0)]))])]
16778 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
16779 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
16780 copy_rtx (operands[1]),
16781 copy_rtx (operands[0]));
16782 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
16783 operands[4], const0_rtx);
16787 [(set (match_operand:SWI12 0 "register_operand")
16788 (match_operand:SWI12 1 "memory_operand"))
16789 (parallel [(set (match_operand:SI 4 "register_operand")
16790 (match_operator:SI 3 "plusminuslogic_operator"
16792 (match_operand:SI 2 "nonmemory_operand")]))
16793 (clobber (reg:CC FLAGS_REG))])
16794 (set (match_dup 1) (match_dup 0))
16795 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16796 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16797 && REG_P (operands[0]) && REG_P (operands[4])
16798 && REGNO (operands[0]) == REGNO (operands[4])
16799 && peep2_reg_dead_p (4, operands[0])
16800 && (<MODE>mode != QImode
16801 || immediate_operand (operands[2], SImode)
16802 || q_regs_operand (operands[2], SImode))
16803 && !reg_overlap_mentioned_p (operands[0], operands[1])
16804 && ix86_match_ccmode (peep2_next_insn (3),
16805 (GET_CODE (operands[3]) == PLUS
16806 || GET_CODE (operands[3]) == MINUS)
16807 ? CCGOCmode : CCNOmode)"
16808 [(parallel [(set (match_dup 4) (match_dup 5))
16809 (set (match_dup 1) (match_dup 6))])]
16811 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
16812 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
16813 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16814 copy_rtx (operands[1]), operands[2]);
16815 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
16816 operands[5], const0_rtx);
16817 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16818 copy_rtx (operands[1]),
16819 copy_rtx (operands[2]));
16822 ;; Attempt to always use XOR for zeroing registers.
16824 [(set (match_operand 0 "register_operand")
16825 (match_operand 1 "const0_operand"))]
16826 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
16827 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16828 && GENERAL_REG_P (operands[0])
16829 && peep2_regno_dead_p (0, FLAGS_REG)"
16830 [(parallel [(set (match_dup 0) (const_int 0))
16831 (clobber (reg:CC FLAGS_REG))])]
16832 "operands[0] = gen_lowpart (word_mode, operands[0]);")
16835 [(set (strict_low_part (match_operand 0 "register_operand"))
16837 "(GET_MODE (operands[0]) == QImode
16838 || GET_MODE (operands[0]) == HImode)
16839 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16840 && peep2_regno_dead_p (0, FLAGS_REG)"
16841 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
16842 (clobber (reg:CC FLAGS_REG))])])
16844 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
16846 [(set (match_operand:SWI248 0 "register_operand")
16848 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
16849 && peep2_regno_dead_p (0, FLAGS_REG)"
16850 [(parallel [(set (match_dup 0) (const_int -1))
16851 (clobber (reg:CC FLAGS_REG))])]
16853 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
16854 operands[0] = gen_lowpart (SImode, operands[0]);
16857 ;; Attempt to convert simple lea to add/shift.
16858 ;; These can be created by move expanders.
16859 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
16860 ;; relevant lea instructions were already split.
16863 [(set (match_operand:SWI48 0 "register_operand")
16864 (plus:SWI48 (match_dup 0)
16865 (match_operand:SWI48 1 "<nonmemory_operand>")))]
16867 && peep2_regno_dead_p (0, FLAGS_REG)"
16868 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
16869 (clobber (reg:CC FLAGS_REG))])])
16872 [(set (match_operand:SWI48 0 "register_operand")
16873 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
16876 && peep2_regno_dead_p (0, FLAGS_REG)"
16877 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
16878 (clobber (reg:CC FLAGS_REG))])])
16881 [(set (match_operand:DI 0 "register_operand")
16883 (plus:SI (match_operand:SI 1 "register_operand")
16884 (match_operand:SI 2 "nonmemory_operand"))))]
16885 "TARGET_64BIT && !TARGET_OPT_AGU
16886 && REGNO (operands[0]) == REGNO (operands[1])
16887 && peep2_regno_dead_p (0, FLAGS_REG)"
16888 [(parallel [(set (match_dup 0)
16889 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
16890 (clobber (reg:CC FLAGS_REG))])])
16893 [(set (match_operand:DI 0 "register_operand")
16895 (plus:SI (match_operand:SI 1 "nonmemory_operand")
16896 (match_operand:SI 2 "register_operand"))))]
16897 "TARGET_64BIT && !TARGET_OPT_AGU
16898 && REGNO (operands[0]) == REGNO (operands[2])
16899 && peep2_regno_dead_p (0, FLAGS_REG)"
16900 [(parallel [(set (match_dup 0)
16901 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
16902 (clobber (reg:CC FLAGS_REG))])])
16905 [(set (match_operand:SWI48 0 "register_operand")
16906 (mult:SWI48 (match_dup 0)
16907 (match_operand:SWI48 1 "const_int_operand")))]
16908 "exact_log2 (INTVAL (operands[1])) >= 0
16909 && peep2_regno_dead_p (0, FLAGS_REG)"
16910 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
16911 (clobber (reg:CC FLAGS_REG))])]
16912 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
16915 [(set (match_operand:DI 0 "register_operand")
16917 (mult:SI (match_operand:SI 1 "register_operand")
16918 (match_operand:SI 2 "const_int_operand"))))]
16920 && exact_log2 (INTVAL (operands[2])) >= 0
16921 && REGNO (operands[0]) == REGNO (operands[1])
16922 && peep2_regno_dead_p (0, FLAGS_REG)"
16923 [(parallel [(set (match_dup 0)
16924 (zero_extend (ashift:SI (match_dup 1) (match_dup 2))))
16925 (clobber (reg:CC FLAGS_REG))])]
16926 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
16928 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
16929 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
16930 ;; On many CPUs it is also faster, since special hardware to avoid esp
16931 ;; dependencies is present.
16933 ;; While some of these conversions may be done using splitters, we use
16934 ;; peepholes in order to allow combine_stack_adjustments pass to see
16935 ;; nonobfuscated RTL.
16937 ;; Convert prologue esp subtractions to push.
16938 ;; We need register to push. In order to keep verify_flow_info happy we have
16940 ;; - use scratch and clobber it in order to avoid dependencies
16941 ;; - use already live register
16942 ;; We can't use the second way right now, since there is no reliable way how to
16943 ;; verify that given register is live. First choice will also most likely in
16944 ;; fewer dependencies. On the place of esp adjustments it is very likely that
16945 ;; call clobbered registers are dead. We may want to use base pointer as an
16946 ;; alternative when no register is available later.
16949 [(match_scratch:W 1 "r")
16950 (parallel [(set (reg:P SP_REG)
16951 (plus:P (reg:P SP_REG)
16952 (match_operand:P 0 "const_int_operand")))
16953 (clobber (reg:CC FLAGS_REG))
16954 (clobber (mem:BLK (scratch)))])]
16955 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16956 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
16957 [(clobber (match_dup 1))
16958 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16959 (clobber (mem:BLK (scratch)))])])
16962 [(match_scratch:W 1 "r")
16963 (parallel [(set (reg:P SP_REG)
16964 (plus:P (reg:P SP_REG)
16965 (match_operand:P 0 "const_int_operand")))
16966 (clobber (reg:CC FLAGS_REG))
16967 (clobber (mem:BLK (scratch)))])]
16968 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16969 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
16970 [(clobber (match_dup 1))
16971 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16972 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16973 (clobber (mem:BLK (scratch)))])])
16975 ;; Convert esp subtractions to push.
16977 [(match_scratch:W 1 "r")
16978 (parallel [(set (reg:P SP_REG)
16979 (plus:P (reg:P SP_REG)
16980 (match_operand:P 0 "const_int_operand")))
16981 (clobber (reg:CC FLAGS_REG))])]
16982 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16983 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
16984 [(clobber (match_dup 1))
16985 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
16988 [(match_scratch:W 1 "r")
16989 (parallel [(set (reg:P SP_REG)
16990 (plus:P (reg:P SP_REG)
16991 (match_operand:P 0 "const_int_operand")))
16992 (clobber (reg:CC FLAGS_REG))])]
16993 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16994 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
16995 [(clobber (match_dup 1))
16996 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16997 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
16999 ;; Convert epilogue deallocator to pop.
17001 [(match_scratch:W 1 "r")
17002 (parallel [(set (reg:P SP_REG)
17003 (plus:P (reg:P SP_REG)
17004 (match_operand:P 0 "const_int_operand")))
17005 (clobber (reg:CC FLAGS_REG))
17006 (clobber (mem:BLK (scratch)))])]
17007 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17008 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17009 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17010 (clobber (mem:BLK (scratch)))])])
17012 ;; Two pops case is tricky, since pop causes dependency
17013 ;; on destination register. We use two registers if available.
17015 [(match_scratch:W 1 "r")
17016 (match_scratch:W 2 "r")
17017 (parallel [(set (reg:P SP_REG)
17018 (plus:P (reg:P SP_REG)
17019 (match_operand:P 0 "const_int_operand")))
17020 (clobber (reg:CC FLAGS_REG))
17021 (clobber (mem:BLK (scratch)))])]
17022 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17023 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17024 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17025 (clobber (mem:BLK (scratch)))])
17026 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17029 [(match_scratch:W 1 "r")
17030 (parallel [(set (reg:P SP_REG)
17031 (plus:P (reg:P SP_REG)
17032 (match_operand:P 0 "const_int_operand")))
17033 (clobber (reg:CC FLAGS_REG))
17034 (clobber (mem:BLK (scratch)))])]
17035 "optimize_insn_for_size_p ()
17036 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17037 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17038 (clobber (mem:BLK (scratch)))])
17039 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17041 ;; Convert esp additions to pop.
17043 [(match_scratch:W 1 "r")
17044 (parallel [(set (reg:P SP_REG)
17045 (plus:P (reg:P SP_REG)
17046 (match_operand:P 0 "const_int_operand")))
17047 (clobber (reg:CC FLAGS_REG))])]
17048 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17049 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17051 ;; Two pops case is tricky, since pop causes dependency
17052 ;; on destination register. We use two registers if available.
17054 [(match_scratch:W 1 "r")
17055 (match_scratch:W 2 "r")
17056 (parallel [(set (reg:P SP_REG)
17057 (plus:P (reg:P SP_REG)
17058 (match_operand:P 0 "const_int_operand")))
17059 (clobber (reg:CC FLAGS_REG))])]
17060 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17061 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17062 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17065 [(match_scratch:W 1 "r")
17066 (parallel [(set (reg:P SP_REG)
17067 (plus:P (reg:P SP_REG)
17068 (match_operand:P 0 "const_int_operand")))
17069 (clobber (reg:CC FLAGS_REG))])]
17070 "optimize_insn_for_size_p ()
17071 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17072 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17073 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17075 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17076 ;; required and register dies. Similarly for 128 to -128.
17078 [(set (match_operand 0 "flags_reg_operand")
17079 (match_operator 1 "compare_operator"
17080 [(match_operand 2 "register_operand")
17081 (match_operand 3 "const_int_operand")]))]
17082 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17083 && incdec_operand (operands[3], GET_MODE (operands[3])))
17084 || (!TARGET_FUSE_CMP_AND_BRANCH
17085 && INTVAL (operands[3]) == 128))
17086 && ix86_match_ccmode (insn, CCGCmode)
17087 && peep2_reg_dead_p (1, operands[2])"
17088 [(parallel [(set (match_dup 0)
17089 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17090 (clobber (match_dup 2))])])
17092 ;; Convert imul by three, five and nine into lea
17095 [(set (match_operand:SWI48 0 "register_operand")
17096 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
17097 (match_operand:SWI48 2 "const359_operand")))
17098 (clobber (reg:CC FLAGS_REG))])]
17099 "!TARGET_PARTIAL_REG_STALL
17100 || <MODE>mode == SImode
17101 || optimize_function_for_size_p (cfun)"
17102 [(set (match_dup 0)
17103 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17105 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17109 [(set (match_operand:SWI48 0 "register_operand")
17110 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17111 (match_operand:SWI48 2 "const359_operand")))
17112 (clobber (reg:CC FLAGS_REG))])]
17113 "optimize_insn_for_speed_p ()
17114 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17115 [(set (match_dup 0) (match_dup 1))
17117 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17119 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17121 ;; imul $32bit_imm, mem, reg is vector decoded, while
17122 ;; imul $32bit_imm, reg, reg is direct decoded.
17124 [(match_scratch:SWI48 3 "r")
17125 (parallel [(set (match_operand:SWI48 0 "register_operand")
17126 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
17127 (match_operand:SWI48 2 "immediate_operand")))
17128 (clobber (reg:CC FLAGS_REG))])]
17129 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17130 && !satisfies_constraint_K (operands[2])"
17131 [(set (match_dup 3) (match_dup 1))
17132 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17133 (clobber (reg:CC FLAGS_REG))])])
17136 [(match_scratch:SI 3 "r")
17137 (parallel [(set (match_operand:DI 0 "register_operand")
17139 (mult:SI (match_operand:SI 1 "memory_operand")
17140 (match_operand:SI 2 "immediate_operand"))))
17141 (clobber (reg:CC FLAGS_REG))])]
17143 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17144 && !satisfies_constraint_K (operands[2])"
17145 [(set (match_dup 3) (match_dup 1))
17146 (parallel [(set (match_dup 0)
17147 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17148 (clobber (reg:CC FLAGS_REG))])])
17150 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17151 ;; Convert it into imul reg, reg
17152 ;; It would be better to force assembler to encode instruction using long
17153 ;; immediate, but there is apparently no way to do so.
17155 [(parallel [(set (match_operand:SWI248 0 "register_operand")
17157 (match_operand:SWI248 1 "nonimmediate_operand")
17158 (match_operand:SWI248 2 "const_int_operand")))
17159 (clobber (reg:CC FLAGS_REG))])
17160 (match_scratch:SWI248 3 "r")]
17161 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17162 && satisfies_constraint_K (operands[2])"
17163 [(set (match_dup 3) (match_dup 2))
17164 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17165 (clobber (reg:CC FLAGS_REG))])]
17167 if (!rtx_equal_p (operands[0], operands[1]))
17168 emit_move_insn (operands[0], operands[1]);
17171 ;; After splitting up read-modify operations, array accesses with memory
17172 ;; operands might end up in form:
17174 ;; movl 4(%esp), %edx
17176 ;; instead of pre-splitting:
17178 ;; addl 4(%esp), %eax
17180 ;; movl 4(%esp), %edx
17181 ;; leal (%edx,%eax,4), %eax
17184 [(match_scratch:W 5 "r")
17185 (parallel [(set (match_operand 0 "register_operand")
17186 (ashift (match_operand 1 "register_operand")
17187 (match_operand 2 "const_int_operand")))
17188 (clobber (reg:CC FLAGS_REG))])
17189 (parallel [(set (match_operand 3 "register_operand")
17190 (plus (match_dup 0)
17191 (match_operand 4 "x86_64_general_operand")))
17192 (clobber (reg:CC FLAGS_REG))])]
17193 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17194 /* Validate MODE for lea. */
17195 && ((!TARGET_PARTIAL_REG_STALL
17196 && (GET_MODE (operands[0]) == QImode
17197 || GET_MODE (operands[0]) == HImode))
17198 || GET_MODE (operands[0]) == SImode
17199 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17200 && (rtx_equal_p (operands[0], operands[3])
17201 || peep2_reg_dead_p (2, operands[0]))
17202 /* We reorder load and the shift. */
17203 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17204 [(set (match_dup 5) (match_dup 4))
17205 (set (match_dup 0) (match_dup 1))]
17207 enum machine_mode op1mode = GET_MODE (operands[1]);
17208 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17209 int scale = 1 << INTVAL (operands[2]);
17210 rtx index = gen_lowpart (word_mode, operands[1]);
17211 rtx base = gen_lowpart (word_mode, operands[5]);
17212 rtx dest = gen_lowpart (mode, operands[3]);
17214 operands[1] = gen_rtx_PLUS (word_mode, base,
17215 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
17216 operands[5] = base;
17217 if (mode != word_mode)
17218 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17219 if (op1mode != word_mode)
17220 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17221 operands[0] = dest;
17224 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17225 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17226 ;; caught for use by garbage collectors and the like. Using an insn that
17227 ;; maps to SIGILL makes it more likely the program will rightfully die.
17228 ;; Keeping with tradition, "6" is in honor of #UD.
17229 (define_insn "trap"
17230 [(trap_if (const_int 1) (const_int 6))]
17232 { return ASM_SHORT "0x0b0f"; }
17233 [(set_attr "length" "2")])
17235 (define_expand "prefetch"
17236 [(prefetch (match_operand 0 "address_operand")
17237 (match_operand:SI 1 "const_int_operand")
17238 (match_operand:SI 2 "const_int_operand"))]
17239 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17241 int rw = INTVAL (operands[1]);
17242 int locality = INTVAL (operands[2]);
17244 gcc_assert (rw == 0 || rw == 1);
17245 gcc_assert (IN_RANGE (locality, 0, 3));
17247 if (TARGET_PRFCHW && rw)
17248 operands[2] = GEN_INT (3);
17249 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17250 supported by SSE counterpart or the SSE prefetch is not available
17251 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17253 else if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17254 operands[2] = GEN_INT (3);
17256 operands[1] = const0_rtx;
17259 (define_insn "*prefetch_sse"
17260 [(prefetch (match_operand 0 "address_operand" "p")
17262 (match_operand:SI 1 "const_int_operand"))]
17263 "TARGET_PREFETCH_SSE"
17265 static const char * const patterns[4] = {
17266 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17269 int locality = INTVAL (operands[1]);
17270 gcc_assert (IN_RANGE (locality, 0, 3));
17272 return patterns[locality];
17274 [(set_attr "type" "sse")
17275 (set_attr "atom_sse_attr" "prefetch")
17276 (set (attr "length_address")
17277 (symbol_ref "memory_address_length (operands[0], false)"))
17278 (set_attr "memory" "none")])
17280 (define_insn "*prefetch_3dnow"
17281 [(prefetch (match_operand 0 "address_operand" "p")
17282 (match_operand:SI 1 "const_int_operand" "n")
17284 "TARGET_3DNOW || TARGET_PRFCHW"
17286 if (INTVAL (operands[1]) == 0)
17287 return "prefetch\t%a0";
17289 return "prefetchw\t%a0";
17291 [(set_attr "type" "mmx")
17292 (set (attr "length_address")
17293 (symbol_ref "memory_address_length (operands[0], false)"))
17294 (set_attr "memory" "none")])
17296 (define_expand "stack_protect_set"
17297 [(match_operand 0 "memory_operand")
17298 (match_operand 1 "memory_operand")]
17299 "!TARGET_HAS_BIONIC"
17301 rtx (*insn)(rtx, rtx);
17303 #ifdef TARGET_THREAD_SSP_OFFSET
17304 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17305 insn = (TARGET_LP64
17306 ? gen_stack_tls_protect_set_di
17307 : gen_stack_tls_protect_set_si);
17309 insn = (TARGET_LP64
17310 ? gen_stack_protect_set_di
17311 : gen_stack_protect_set_si);
17314 emit_insn (insn (operands[0], operands[1]));
17318 (define_insn "stack_protect_set_<mode>"
17319 [(set (match_operand:PTR 0 "memory_operand" "=m")
17320 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17322 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17323 (clobber (reg:CC FLAGS_REG))]
17324 "!TARGET_HAS_BIONIC"
17325 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17326 [(set_attr "type" "multi")])
17328 (define_insn "stack_tls_protect_set_<mode>"
17329 [(set (match_operand:PTR 0 "memory_operand" "=m")
17330 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17331 UNSPEC_SP_TLS_SET))
17332 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17333 (clobber (reg:CC FLAGS_REG))]
17335 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17336 [(set_attr "type" "multi")])
17338 (define_expand "stack_protect_test"
17339 [(match_operand 0 "memory_operand")
17340 (match_operand 1 "memory_operand")
17342 "!TARGET_HAS_BIONIC"
17344 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17346 rtx (*insn)(rtx, rtx, rtx);
17348 #ifdef TARGET_THREAD_SSP_OFFSET
17349 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17350 insn = (TARGET_LP64
17351 ? gen_stack_tls_protect_test_di
17352 : gen_stack_tls_protect_test_si);
17354 insn = (TARGET_LP64
17355 ? gen_stack_protect_test_di
17356 : gen_stack_protect_test_si);
17359 emit_insn (insn (flags, operands[0], operands[1]));
17361 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17362 flags, const0_rtx, operands[2]));
17366 (define_insn "stack_protect_test_<mode>"
17367 [(set (match_operand:CCZ 0 "flags_reg_operand")
17368 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17369 (match_operand:PTR 2 "memory_operand" "m")]
17371 (clobber (match_scratch:PTR 3 "=&r"))]
17372 "!TARGET_HAS_BIONIC"
17373 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17374 [(set_attr "type" "multi")])
17376 (define_insn "stack_tls_protect_test_<mode>"
17377 [(set (match_operand:CCZ 0 "flags_reg_operand")
17378 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17379 (match_operand:PTR 2 "const_int_operand" "i")]
17380 UNSPEC_SP_TLS_TEST))
17381 (clobber (match_scratch:PTR 3 "=r"))]
17383 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17384 [(set_attr "type" "multi")])
17386 (define_insn "sse4_2_crc32<mode>"
17387 [(set (match_operand:SI 0 "register_operand" "=r")
17389 [(match_operand:SI 1 "register_operand" "0")
17390 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17392 "TARGET_SSE4_2 || TARGET_CRC32"
17393 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17394 [(set_attr "type" "sselog1")
17395 (set_attr "prefix_rep" "1")
17396 (set_attr "prefix_extra" "1")
17397 (set (attr "prefix_data16")
17398 (if_then_else (match_operand:HI 2)
17400 (const_string "*")))
17401 (set (attr "prefix_rex")
17402 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
17404 (const_string "*")))
17405 (set_attr "mode" "SI")])
17407 (define_insn "sse4_2_crc32di"
17408 [(set (match_operand:DI 0 "register_operand" "=r")
17410 [(match_operand:DI 1 "register_operand" "0")
17411 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17413 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17414 "crc32{q}\t{%2, %0|%0, %2}"
17415 [(set_attr "type" "sselog1")
17416 (set_attr "prefix_rep" "1")
17417 (set_attr "prefix_extra" "1")
17418 (set_attr "mode" "DI")])
17420 (define_insn "rdpmc"
17421 [(set (match_operand:DI 0 "register_operand" "=A")
17422 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17426 [(set_attr "type" "other")
17427 (set_attr "length" "2")])
17429 (define_insn "rdpmc_rex64"
17430 [(set (match_operand:DI 0 "register_operand" "=a")
17431 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17433 (set (match_operand:DI 1 "register_operand" "=d")
17434 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
17437 [(set_attr "type" "other")
17438 (set_attr "length" "2")])
17440 (define_insn "rdtsc"
17441 [(set (match_operand:DI 0 "register_operand" "=A")
17442 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17445 [(set_attr "type" "other")
17446 (set_attr "length" "2")])
17448 (define_insn "rdtsc_rex64"
17449 [(set (match_operand:DI 0 "register_operand" "=a")
17450 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17451 (set (match_operand:DI 1 "register_operand" "=d")
17452 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17455 [(set_attr "type" "other")
17456 (set_attr "length" "2")])
17458 (define_insn "rdtscp"
17459 [(set (match_operand:DI 0 "register_operand" "=A")
17460 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17461 (set (match_operand:SI 1 "register_operand" "=c")
17462 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17465 [(set_attr "type" "other")
17466 (set_attr "length" "3")])
17468 (define_insn "rdtscp_rex64"
17469 [(set (match_operand:DI 0 "register_operand" "=a")
17470 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17471 (set (match_operand:DI 1 "register_operand" "=d")
17472 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17473 (set (match_operand:SI 2 "register_operand" "=c")
17474 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17477 [(set_attr "type" "other")
17478 (set_attr "length" "3")])
17480 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17482 ;; FXSR, XSAVE and XSAVEOPT instructions
17484 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17486 (define_insn "fxsave"
17487 [(set (match_operand:BLK 0 "memory_operand" "=m")
17488 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
17491 [(set_attr "type" "other")
17492 (set_attr "memory" "store")
17493 (set (attr "length")
17494 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17496 (define_insn "fxsave64"
17497 [(set (match_operand:BLK 0 "memory_operand" "=m")
17498 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
17499 "TARGET_64BIT && TARGET_FXSR"
17501 [(set_attr "type" "other")
17502 (set_attr "memory" "store")
17503 (set (attr "length")
17504 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17506 (define_insn "fxrstor"
17507 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
17511 [(set_attr "type" "other")
17512 (set_attr "memory" "load")
17513 (set (attr "length")
17514 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17516 (define_insn "fxrstor64"
17517 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
17518 UNSPECV_FXRSTOR64)]
17519 "TARGET_64BIT && TARGET_FXSR"
17521 [(set_attr "type" "other")
17522 (set_attr "memory" "load")
17523 (set (attr "length")
17524 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17526 (define_int_iterator ANY_XSAVE
17528 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")])
17530 (define_int_iterator ANY_XSAVE64
17532 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")])
17534 (define_int_attr xsave
17535 [(UNSPECV_XSAVE "xsave")
17536 (UNSPECV_XSAVE64 "xsave64")
17537 (UNSPECV_XSAVEOPT "xsaveopt")
17538 (UNSPECV_XSAVEOPT64 "xsaveopt64")])
17540 (define_insn "<xsave>"
17541 [(set (match_operand:BLK 0 "memory_operand" "=m")
17542 (unspec_volatile:BLK
17543 [(match_operand:DI 1 "register_operand" "A")]
17545 "!TARGET_64BIT && TARGET_XSAVE"
17547 [(set_attr "type" "other")
17548 (set_attr "memory" "store")
17549 (set (attr "length")
17550 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17552 (define_insn "<xsave>_rex64"
17553 [(set (match_operand:BLK 0 "memory_operand" "=m")
17554 (unspec_volatile:BLK
17555 [(match_operand:SI 1 "register_operand" "a")
17556 (match_operand:SI 2 "register_operand" "d")]
17558 "TARGET_64BIT && TARGET_XSAVE"
17560 [(set_attr "type" "other")
17561 (set_attr "memory" "store")
17562 (set (attr "length")
17563 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17565 (define_insn "<xsave>"
17566 [(set (match_operand:BLK 0 "memory_operand" "=m")
17567 (unspec_volatile:BLK
17568 [(match_operand:SI 1 "register_operand" "a")
17569 (match_operand:SI 2 "register_operand" "d")]
17571 "TARGET_64BIT && TARGET_XSAVE"
17573 [(set_attr "type" "other")
17574 (set_attr "memory" "store")
17575 (set (attr "length")
17576 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17578 (define_insn "xrstor"
17579 [(unspec_volatile:BLK
17580 [(match_operand:BLK 0 "memory_operand" "m")
17581 (match_operand:DI 1 "register_operand" "A")]
17583 "!TARGET_64BIT && TARGET_XSAVE"
17585 [(set_attr "type" "other")
17586 (set_attr "memory" "load")
17587 (set (attr "length")
17588 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17590 (define_insn "xrstor_rex64"
17591 [(unspec_volatile:BLK
17592 [(match_operand:BLK 0 "memory_operand" "m")
17593 (match_operand:SI 1 "register_operand" "a")
17594 (match_operand:SI 2 "register_operand" "d")]
17596 "TARGET_64BIT && TARGET_XSAVE"
17598 [(set_attr "type" "other")
17599 (set_attr "memory" "load")
17600 (set (attr "length")
17601 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17603 (define_insn "xrstor64"
17604 [(unspec_volatile:BLK
17605 [(match_operand:BLK 0 "memory_operand" "m")
17606 (match_operand:SI 1 "register_operand" "a")
17607 (match_operand:SI 2 "register_operand" "d")]
17609 "TARGET_64BIT && TARGET_XSAVE"
17611 [(set_attr "type" "other")
17612 (set_attr "memory" "load")
17613 (set (attr "length")
17614 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17616 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17618 ;; LWP instructions
17620 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17622 (define_expand "lwp_llwpcb"
17623 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17624 UNSPECV_LLWP_INTRINSIC)]
17627 (define_insn "*lwp_llwpcb<mode>1"
17628 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17629 UNSPECV_LLWP_INTRINSIC)]
17632 [(set_attr "type" "lwp")
17633 (set_attr "mode" "<MODE>")
17634 (set_attr "length" "5")])
17636 (define_expand "lwp_slwpcb"
17637 [(set (match_operand 0 "register_operand" "=r")
17638 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17643 insn = (Pmode == DImode
17645 : gen_lwp_slwpcbsi);
17647 emit_insn (insn (operands[0]));
17651 (define_insn "lwp_slwpcb<mode>"
17652 [(set (match_operand:P 0 "register_operand" "=r")
17653 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17656 [(set_attr "type" "lwp")
17657 (set_attr "mode" "<MODE>")
17658 (set_attr "length" "5")])
17660 (define_expand "lwp_lwpval<mode>3"
17661 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
17662 (match_operand:SI 2 "nonimmediate_operand" "rm")
17663 (match_operand:SI 3 "const_int_operand" "i")]
17664 UNSPECV_LWPVAL_INTRINSIC)]
17666 ;; Avoid unused variable warning.
17667 "(void) operands[0];")
17669 (define_insn "*lwp_lwpval<mode>3_1"
17670 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
17671 (match_operand:SI 1 "nonimmediate_operand" "rm")
17672 (match_operand:SI 2 "const_int_operand" "i")]
17673 UNSPECV_LWPVAL_INTRINSIC)]
17675 "lwpval\t{%2, %1, %0|%0, %1, %2}"
17676 [(set_attr "type" "lwp")
17677 (set_attr "mode" "<MODE>")
17678 (set (attr "length")
17679 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17681 (define_expand "lwp_lwpins<mode>3"
17682 [(set (reg:CCC FLAGS_REG)
17683 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
17684 (match_operand:SI 2 "nonimmediate_operand" "rm")
17685 (match_operand:SI 3 "const_int_operand" "i")]
17686 UNSPECV_LWPINS_INTRINSIC))
17687 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
17688 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
17691 (define_insn "*lwp_lwpins<mode>3_1"
17692 [(set (reg:CCC FLAGS_REG)
17693 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
17694 (match_operand:SI 1 "nonimmediate_operand" "rm")
17695 (match_operand:SI 2 "const_int_operand" "i")]
17696 UNSPECV_LWPINS_INTRINSIC))]
17698 "lwpins\t{%2, %1, %0|%0, %1, %2}"
17699 [(set_attr "type" "lwp")
17700 (set_attr "mode" "<MODE>")
17701 (set (attr "length")
17702 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17704 (define_int_iterator RDFSGSBASE
17708 (define_int_iterator WRFSGSBASE
17712 (define_int_attr fsgs
17713 [(UNSPECV_RDFSBASE "fs")
17714 (UNSPECV_RDGSBASE "gs")
17715 (UNSPECV_WRFSBASE "fs")
17716 (UNSPECV_WRGSBASE "gs")])
17718 (define_insn "rd<fsgs>base<mode>"
17719 [(set (match_operand:SWI48 0 "register_operand" "=r")
17720 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
17721 "TARGET_64BIT && TARGET_FSGSBASE"
17723 [(set_attr "type" "other")
17724 (set_attr "prefix_extra" "2")])
17726 (define_insn "wr<fsgs>base<mode>"
17727 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17729 "TARGET_64BIT && TARGET_FSGSBASE"
17731 [(set_attr "type" "other")
17732 (set_attr "prefix_extra" "2")])
17734 (define_insn "rdrand<mode>_1"
17735 [(set (match_operand:SWI248 0 "register_operand" "=r")
17736 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
17737 (set (reg:CCC FLAGS_REG)
17738 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
17741 [(set_attr "type" "other")
17742 (set_attr "prefix_extra" "1")])
17744 (define_insn "rdseed<mode>_1"
17745 [(set (match_operand:SWI248 0 "register_operand" "=r")
17746 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
17747 (set (reg:CCC FLAGS_REG)
17748 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
17751 [(set_attr "type" "other")
17752 (set_attr "prefix_extra" "1")])
17754 (define_expand "pause"
17755 [(set (match_dup 0)
17756 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
17759 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
17760 MEM_VOLATILE_P (operands[0]) = 1;
17763 ;; Use "rep; nop", instead of "pause", to support older assemblers.
17764 ;; They have the same encoding.
17765 (define_insn "*pause"
17766 [(set (match_operand:BLK 0)
17767 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
17770 [(set_attr "length" "2")
17771 (set_attr "memory" "unknown")])
17773 (define_expand "xbegin"
17774 [(set (match_operand:SI 0 "register_operand")
17775 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
17778 rtx label = gen_label_rtx ();
17780 /* xbegin is emitted as jump_insn, so reload won't be able
17781 to reload its operand. Force the value into AX hard register. */
17782 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
17783 emit_move_insn (ax_reg, constm1_rtx);
17785 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
17787 emit_label (label);
17788 LABEL_NUSES (label) = 1;
17790 emit_move_insn (operands[0], ax_reg);
17795 (define_insn "xbegin_1"
17797 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
17799 (label_ref (match_operand 1))
17801 (set (match_operand:SI 0 "register_operand" "+a")
17802 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
17805 [(set_attr "type" "other")
17806 (set_attr "length" "6")])
17808 (define_insn "xend"
17809 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
17812 [(set_attr "type" "other")
17813 (set_attr "length" "3")])
17815 (define_insn "xabort"
17816 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
17820 [(set_attr "type" "other")
17821 (set_attr "length" "3")])
17823 (define_expand "xtest"
17824 [(set (match_operand:QI 0 "register_operand")
17825 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
17828 emit_insn (gen_xtest_1 ());
17830 ix86_expand_setcc (operands[0], NE,
17831 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
17835 (define_insn "xtest_1"
17836 [(set (reg:CCZ FLAGS_REG)
17837 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
17840 [(set_attr "type" "other")
17841 (set_attr "length" "3")])
17845 (include "sync.md")