1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>. */
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;; The special asm out single letter directives following a '%' are:
30 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; F,f -- likewise, but for floating-point.
34 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
36 ;; R -- print the prefix for register names.
37 ;; z -- print the opcode suffix for the size of the current operand.
38 ;; Z -- likewise, with special suffixes for x87 instructions.
39 ;; * -- print a star (in certain assembler syntax)
40 ;; A -- print an absolute memory reference.
41 ;; E -- print address with DImode register names if TARGET_64BIT.
42 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
43 ;; s -- print a shift double count, followed by the assemblers argument
45 ;; b -- print the QImode name of the register for the indicated operand.
46 ;; %b0 would print %al if operands[0] is reg 0.
47 ;; w -- likewise, print the HImode name of the register.
48 ;; k -- likewise, print the SImode name of the register.
49 ;; q -- likewise, print the DImode name of the register.
50 ;; x -- likewise, print the V4SFmode name of the register.
51 ;; t -- likewise, print the V8SFmode name of the register.
52 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
53 ;; y -- print "st(0)" instead of "st" as a register.
54 ;; d -- print duplicated register operand for AVX instruction.
55 ;; D -- print condition for SSE cmp instruction.
56 ;; P -- if PIC, print an @PLT suffix.
57 ;; p -- print raw symbol name.
58 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
59 ;; & -- print some in-use local-dynamic symbol name.
60 ;; H -- print a memory address offset by 8; used for sse high-parts
61 ;; Y -- print condition for XOP pcom* instruction.
62 ;; + -- print a branch hint as 'cs' or 'ds' prefix
63 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
64 ;; ~ -- print "i" if TARGET_AVX2, "f" otherwise.
65 ;; @ -- print a segment register of thread base pointer load
66 ;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
68 (define_c_enum "unspec" [
69 ;; Relocation specifiers
80 UNSPEC_MACHOPIC_OFFSET
90 UNSPEC_MEMORY_BLOCKAGE
100 ;; Other random patterns
109 UNSPEC_LD_MPIC ; load_macho_picbase
111 UNSPEC_DIV_ALREADY_SPLIT
112 UNSPEC_MS_TO_SYSV_CALL
113 UNSPEC_CALL_NEEDS_VZEROUPPER
118 ;; For SSE/MMX support:
126 ;; Generic math support
128 UNSPEC_IEEE_MIN ; not commutative
129 UNSPEC_IEEE_MAX ; not commutative
131 ;; x87 Floating point
147 UNSPEC_FRNDINT_MASK_PM
151 ;; x87 Double output FP
178 ;; For RDRAND support
189 (define_c_enum "unspecv" [
192 UNSPECV_PROBE_STACK_RANGE
195 UNSPECV_SPLIT_STACK_RETURN
201 UNSPECV_LLWP_INTRINSIC
202 UNSPECV_SLWP_INTRINSIC
203 UNSPECV_LWPVAL_INTRINSIC
204 UNSPECV_LWPINS_INTRINSIC
217 ;; Constants to represent rounding modes in the ROUND instruction
226 ;; Constants to represent pcomtrue/pcomfalse variants
236 ;; Constants used in the XOP pperm instruction
238 [(PPERM_SRC 0x00) /* copy source */
239 (PPERM_INVERT 0x20) /* invert source */
240 (PPERM_REVERSE 0x40) /* bit reverse source */
241 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
242 (PPERM_ZERO 0x80) /* all 0's */
243 (PPERM_ONES 0xa0) /* all 1's */
244 (PPERM_SIGN 0xc0) /* propagate sign bit */
245 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
246 (PPERM_SRC1 0x00) /* use first source byte */
247 (PPERM_SRC2 0x10) /* use second source byte */
250 ;; Registers by name.
303 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
306 ;; In C guard expressions, put expressions which may be compile-time
307 ;; constants first. This allows for better optimization. For
308 ;; example, write "TARGET_64BIT && reload_completed", not
309 ;; "reload_completed && TARGET_64BIT".
313 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
314 atom,generic64,amdfam10,bdver1,bdver2,btver1"
315 (const (symbol_ref "ix86_schedule")))
317 ;; A basic instruction type. Refinements due to arguments to be
318 ;; provided in other attributes.
321 alu,alu1,negnot,imov,imovx,lea,
322 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,imul,imulx,idiv,
323 icmp,test,ibr,setcc,icmov,
324 push,pop,call,callv,leave,
326 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
327 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
328 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
329 ssemuladd,sse4arg,lwp,
330 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
331 (const_string "other"))
333 ;; Main data type used by the insn
335 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
336 (const_string "unknown"))
338 ;; The CPU unit operations uses.
339 (define_attr "unit" "integer,i387,sse,mmx,unknown"
340 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
341 (const_string "i387")
342 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
343 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
344 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
346 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
348 (eq_attr "type" "other")
349 (const_string "unknown")]
350 (const_string "integer")))
352 ;; The (bounding maximum) length of an instruction immediate.
353 (define_attr "length_immediate" ""
354 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
357 (eq_attr "unit" "i387,sse,mmx")
359 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
360 rotate,rotatex,rotate1,imul,icmp,push,pop")
361 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
362 (eq_attr "type" "imov,test")
363 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
364 (eq_attr "type" "call")
365 (if_then_else (match_operand 0 "constant_call_address_operand")
368 (eq_attr "type" "callv")
369 (if_then_else (match_operand 1 "constant_call_address_operand")
372 ;; We don't know the size before shorten_branches. Expect
373 ;; the instruction to fit for better scheduling.
374 (eq_attr "type" "ibr")
377 (symbol_ref "/* Update immediate_length and other attributes! */
378 gcc_unreachable (),1")))
380 ;; The (bounding maximum) length of an instruction address.
381 (define_attr "length_address" ""
382 (cond [(eq_attr "type" "str,other,multi,fxch")
384 (and (eq_attr "type" "call")
385 (match_operand 0 "constant_call_address_operand"))
387 (and (eq_attr "type" "callv")
388 (match_operand 1 "constant_call_address_operand"))
391 (symbol_ref "ix86_attr_length_address_default (insn)")))
393 ;; Set when length prefix is used.
394 (define_attr "prefix_data16" ""
395 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
397 (eq_attr "mode" "HI")
399 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
404 ;; Set when string REP prefix is used.
405 (define_attr "prefix_rep" ""
406 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
408 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
413 ;; Set when 0f opcode prefix is used.
414 (define_attr "prefix_0f" ""
416 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
417 (eq_attr "unit" "sse,mmx"))
421 ;; Set when REX opcode prefix is used.
422 (define_attr "prefix_rex" ""
423 (cond [(not (match_test "TARGET_64BIT"))
425 (and (eq_attr "mode" "DI")
426 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
427 (eq_attr "unit" "!mmx")))
429 (and (eq_attr "mode" "QI")
430 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
432 (match_test "x86_extended_reg_mentioned_p (insn)")
434 (and (eq_attr "type" "imovx")
435 (match_operand:QI 1 "ext_QIreg_operand"))
440 ;; There are also additional prefixes in 3DNOW, SSSE3.
441 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
442 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
443 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
444 (define_attr "prefix_extra" ""
445 (cond [(eq_attr "type" "ssemuladd,sse4arg")
447 (eq_attr "type" "sseiadd1,ssecvt1")
452 ;; Prefix used: original, VEX or maybe VEX.
453 (define_attr "prefix" "orig,vex,maybe_vex"
454 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
456 (const_string "orig")))
458 ;; VEX W bit is used.
459 (define_attr "prefix_vex_w" "" (const_int 0))
461 ;; The length of VEX prefix
462 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
463 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
464 ;; still prefix_0f 1, with prefix_extra 1.
465 (define_attr "length_vex" ""
466 (if_then_else (and (eq_attr "prefix_0f" "1")
467 (eq_attr "prefix_extra" "0"))
468 (if_then_else (eq_attr "prefix_vex_w" "1")
469 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
470 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
471 (if_then_else (eq_attr "prefix_vex_w" "1")
472 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
473 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
475 ;; Set when modrm byte is used.
476 (define_attr "modrm" ""
477 (cond [(eq_attr "type" "str,leave")
479 (eq_attr "unit" "i387")
481 (and (eq_attr "type" "incdec")
482 (and (not (match_test "TARGET_64BIT"))
483 (ior (match_operand:SI 1 "register_operand")
484 (match_operand:HI 1 "register_operand"))))
486 (and (eq_attr "type" "push")
487 (not (match_operand 1 "memory_operand")))
489 (and (eq_attr "type" "pop")
490 (not (match_operand 0 "memory_operand")))
492 (and (eq_attr "type" "imov")
493 (and (not (eq_attr "mode" "DI"))
494 (ior (and (match_operand 0 "register_operand")
495 (match_operand 1 "immediate_operand"))
496 (ior (and (match_operand 0 "ax_reg_operand")
497 (match_operand 1 "memory_displacement_only_operand"))
498 (and (match_operand 0 "memory_displacement_only_operand")
499 (match_operand 1 "ax_reg_operand"))))))
501 (and (eq_attr "type" "call")
502 (match_operand 0 "constant_call_address_operand"))
504 (and (eq_attr "type" "callv")
505 (match_operand 1 "constant_call_address_operand"))
507 (and (eq_attr "type" "alu,alu1,icmp,test")
508 (match_operand 0 "ax_reg_operand"))
509 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
513 ;; The (bounding maximum) length of an instruction in bytes.
514 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
515 ;; Later we may want to split them and compute proper length as for
517 (define_attr "length" ""
518 (cond [(eq_attr "type" "other,multi,fistp,frndint")
520 (eq_attr "type" "fcmp")
522 (eq_attr "unit" "i387")
524 (plus (attr "prefix_data16")
525 (attr "length_address")))
526 (ior (eq_attr "prefix" "vex")
527 (and (eq_attr "prefix" "maybe_vex")
528 (match_test "TARGET_AVX")))
529 (plus (attr "length_vex")
530 (plus (attr "length_immediate")
532 (attr "length_address"))))]
533 (plus (plus (attr "modrm")
534 (plus (attr "prefix_0f")
535 (plus (attr "prefix_rex")
536 (plus (attr "prefix_extra")
538 (plus (attr "prefix_rep")
539 (plus (attr "prefix_data16")
540 (plus (attr "length_immediate")
541 (attr "length_address")))))))
543 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
544 ;; `store' if there is a simple memory reference therein, or `unknown'
545 ;; if the instruction is complex.
547 (define_attr "memory" "none,load,store,both,unknown"
548 (cond [(eq_attr "type" "other,multi,str,lwp")
549 (const_string "unknown")
550 (eq_attr "type" "lea,fcmov,fpspc")
551 (const_string "none")
552 (eq_attr "type" "fistp,leave")
553 (const_string "both")
554 (eq_attr "type" "frndint")
555 (const_string "load")
556 (eq_attr "type" "push")
557 (if_then_else (match_operand 1 "memory_operand")
558 (const_string "both")
559 (const_string "store"))
560 (eq_attr "type" "pop")
561 (if_then_else (match_operand 0 "memory_operand")
562 (const_string "both")
563 (const_string "load"))
564 (eq_attr "type" "setcc")
565 (if_then_else (match_operand 0 "memory_operand")
566 (const_string "store")
567 (const_string "none"))
568 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
569 (if_then_else (ior (match_operand 0 "memory_operand")
570 (match_operand 1 "memory_operand"))
571 (const_string "load")
572 (const_string "none"))
573 (eq_attr "type" "ibr")
574 (if_then_else (match_operand 0 "memory_operand")
575 (const_string "load")
576 (const_string "none"))
577 (eq_attr "type" "call")
578 (if_then_else (match_operand 0 "constant_call_address_operand")
579 (const_string "none")
580 (const_string "load"))
581 (eq_attr "type" "callv")
582 (if_then_else (match_operand 1 "constant_call_address_operand")
583 (const_string "none")
584 (const_string "load"))
585 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
586 (match_operand 1 "memory_operand"))
587 (const_string "both")
588 (and (match_operand 0 "memory_operand")
589 (match_operand 1 "memory_operand"))
590 (const_string "both")
591 (match_operand 0 "memory_operand")
592 (const_string "store")
593 (match_operand 1 "memory_operand")
594 (const_string "load")
596 "!alu1,negnot,ishift1,
597 imov,imovx,icmp,test,bitmanip,
599 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
600 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
601 (match_operand 2 "memory_operand"))
602 (const_string "load")
603 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
604 (match_operand 3 "memory_operand"))
605 (const_string "load")
607 (const_string "none")))
609 ;; Indicates if an instruction has both an immediate and a displacement.
611 (define_attr "imm_disp" "false,true,unknown"
612 (cond [(eq_attr "type" "other,multi")
613 (const_string "unknown")
614 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
615 (and (match_operand 0 "memory_displacement_operand")
616 (match_operand 1 "immediate_operand")))
617 (const_string "true")
618 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
619 (and (match_operand 0 "memory_displacement_operand")
620 (match_operand 2 "immediate_operand")))
621 (const_string "true")
623 (const_string "false")))
625 ;; Indicates if an FP operation has an integer source.
627 (define_attr "fp_int_src" "false,true"
628 (const_string "false"))
630 ;; Defines rounding mode of an FP operation.
632 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
633 (const_string "any"))
635 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
636 (define_attr "use_carry" "0,1" (const_string "0"))
638 ;; Define attribute to indicate unaligned ssemov insns
639 (define_attr "movu" "0,1" (const_string "0"))
641 ;; Used to control the "enabled" attribute on a per-instruction basis.
642 (define_attr "isa" "base,sse2,sse2_noavx,sse3,sse4,sse4_noavx,noavx,avx,avx2,noavx2,bmi2"
643 (const_string "base"))
645 (define_attr "enabled" ""
646 (cond [(eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
647 (eq_attr "isa" "sse2_noavx")
648 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
649 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
650 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
651 (eq_attr "isa" "sse4_noavx")
652 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
653 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
654 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
655 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
656 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
657 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
661 ;; Describe a user's asm statement.
662 (define_asm_attributes
663 [(set_attr "length" "128")
664 (set_attr "type" "multi")])
666 (define_code_iterator plusminus [plus minus])
668 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
670 ;; Base name for define_insn
671 (define_code_attr plusminus_insn
672 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
673 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
675 ;; Base name for insn mnemonic.
676 (define_code_attr plusminus_mnemonic
677 [(plus "add") (ss_plus "adds") (us_plus "addus")
678 (minus "sub") (ss_minus "subs") (us_minus "subus")])
679 (define_code_attr plusminus_carry_mnemonic
680 [(plus "adc") (minus "sbb")])
682 ;; Mark commutative operators as such in constraints.
683 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
684 (minus "") (ss_minus "") (us_minus "")])
686 ;; Mapping of max and min
687 (define_code_iterator maxmin [smax smin umax umin])
689 ;; Mapping of signed max and min
690 (define_code_iterator smaxmin [smax smin])
692 ;; Mapping of unsigned max and min
693 (define_code_iterator umaxmin [umax umin])
695 ;; Base name for integer and FP insn mnemonic
696 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
697 (umax "maxu") (umin "minu")])
698 (define_code_attr maxmin_float [(smax "max") (smin "min")])
700 ;; Mapping of logic operators
701 (define_code_iterator any_logic [and ior xor])
702 (define_code_iterator any_or [ior xor])
704 ;; Base name for insn mnemonic.
705 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
707 ;; Mapping of logic-shift operators
708 (define_code_iterator any_lshift [ashift lshiftrt])
710 ;; Mapping of shift-right operators
711 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
713 ;; Base name for define_insn
714 (define_code_attr shift_insn
715 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
717 ;; Base name for insn mnemonic.
718 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
719 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
721 ;; Mapping of rotate operators
722 (define_code_iterator any_rotate [rotate rotatert])
724 ;; Base name for define_insn
725 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
727 ;; Base name for insn mnemonic.
728 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
730 ;; Mapping of abs neg operators
731 (define_code_iterator absneg [abs neg])
733 ;; Base name for x87 insn mnemonic.
734 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
736 ;; Used in signed and unsigned widening multiplications.
737 (define_code_iterator any_extend [sign_extend zero_extend])
739 ;; Prefix for insn menmonic.
740 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
742 ;; Prefix for define_insn
743 (define_code_attr u [(sign_extend "") (zero_extend "u")])
744 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
746 ;; All integer modes.
747 (define_mode_iterator SWI1248x [QI HI SI DI])
749 ;; All integer modes without QImode.
750 (define_mode_iterator SWI248x [HI SI DI])
752 ;; All integer modes without QImode and HImode.
753 (define_mode_iterator SWI48x [SI DI])
755 ;; All integer modes without SImode and DImode.
756 (define_mode_iterator SWI12 [QI HI])
758 ;; All integer modes without DImode.
759 (define_mode_iterator SWI124 [QI HI SI])
761 ;; All integer modes without QImode and DImode.
762 (define_mode_iterator SWI24 [HI SI])
764 ;; Single word integer modes.
765 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
767 ;; Single word integer modes without QImode.
768 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
770 ;; Single word integer modes without QImode and HImode.
771 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
773 ;; All math-dependant single and double word integer modes.
774 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
775 (HI "TARGET_HIMODE_MATH")
776 SI DI (TI "TARGET_64BIT")])
778 ;; Math-dependant single word integer modes.
779 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
780 (HI "TARGET_HIMODE_MATH")
781 SI (DI "TARGET_64BIT")])
783 ;; Math-dependant integer modes without DImode.
784 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
785 (HI "TARGET_HIMODE_MATH")
788 ;; Math-dependant single word integer modes without QImode.
789 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
790 SI (DI "TARGET_64BIT")])
792 ;; Double word integer modes.
793 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
794 (TI "TARGET_64BIT")])
796 ;; Double word integer modes as mode attribute.
797 (define_mode_attr DWI [(SI "DI") (DI "TI")])
798 (define_mode_attr dwi [(SI "di") (DI "ti")])
800 ;; Half mode for double word integer modes.
801 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
802 (DI "TARGET_64BIT")])
804 ;; Instruction suffix for integer modes.
805 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
807 ;; Pointer size prefix for integer modes (Intel asm dialect)
808 (define_mode_attr iptrsize [(QI "BYTE")
813 ;; Register class for integer modes.
814 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
816 ;; Immediate operand constraint for integer modes.
817 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
819 ;; General operand constraint for word modes.
820 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
822 ;; Immediate operand constraint for double integer modes.
823 (define_mode_attr di [(SI "nF") (DI "e")])
825 ;; Immediate operand constraint for shifts.
826 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
828 ;; General operand predicate for integer modes.
829 (define_mode_attr general_operand
830 [(QI "general_operand")
831 (HI "general_operand")
832 (SI "x86_64_general_operand")
833 (DI "x86_64_general_operand")
834 (TI "x86_64_general_operand")])
836 ;; General sign/zero extend operand predicate for integer modes.
837 (define_mode_attr general_szext_operand
838 [(QI "general_operand")
839 (HI "general_operand")
840 (SI "x86_64_szext_general_operand")
841 (DI "x86_64_szext_general_operand")])
843 ;; Immediate operand predicate for integer modes.
844 (define_mode_attr immediate_operand
845 [(QI "immediate_operand")
846 (HI "immediate_operand")
847 (SI "x86_64_immediate_operand")
848 (DI "x86_64_immediate_operand")])
850 ;; Nonmemory operand predicate for integer modes.
851 (define_mode_attr nonmemory_operand
852 [(QI "nonmemory_operand")
853 (HI "nonmemory_operand")
854 (SI "x86_64_nonmemory_operand")
855 (DI "x86_64_nonmemory_operand")])
857 ;; Operand predicate for shifts.
858 (define_mode_attr shift_operand
859 [(QI "nonimmediate_operand")
860 (HI "nonimmediate_operand")
861 (SI "nonimmediate_operand")
862 (DI "shiftdi_operand")
863 (TI "register_operand")])
865 ;; Operand predicate for shift argument.
866 (define_mode_attr shift_immediate_operand
867 [(QI "const_1_to_31_operand")
868 (HI "const_1_to_31_operand")
869 (SI "const_1_to_31_operand")
870 (DI "const_1_to_63_operand")])
872 ;; Input operand predicate for arithmetic left shifts.
873 (define_mode_attr ashl_input_operand
874 [(QI "nonimmediate_operand")
875 (HI "nonimmediate_operand")
876 (SI "nonimmediate_operand")
877 (DI "ashldi_input_operand")
878 (TI "reg_or_pm1_operand")])
880 ;; SSE and x87 SFmode and DFmode floating point modes
881 (define_mode_iterator MODEF [SF DF])
883 ;; All x87 floating point modes
884 (define_mode_iterator X87MODEF [SF DF XF])
886 ;; SSE instruction suffix for various modes
887 (define_mode_attr ssemodesuffix
889 (V8SF "ps") (V4DF "pd")
890 (V4SF "ps") (V2DF "pd")
891 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
892 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
894 ;; SSE vector suffix for floating point modes
895 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
897 ;; SSE vector mode corresponding to a scalar mode
898 (define_mode_attr ssevecmode
899 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
901 ;; Instruction suffix for REX 64bit operators.
902 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
904 ;; This mode iterator allows :P to be used for patterns that operate on
905 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
906 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
908 ;; This mode iterator allows :W to be used for patterns that operate on
909 ;; word_mode sized quantities.
910 (define_mode_iterator W
911 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
913 ;; This mode iterator allows :PTR to be used for patterns that operate on
914 ;; ptr_mode sized quantities.
915 (define_mode_iterator PTR
916 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
918 ;; Scheduling descriptions
920 (include "pentium.md")
923 (include "athlon.md")
924 (include "bdver1.md")
930 ;; Operand and operator predicates and constraints
932 (include "predicates.md")
933 (include "constraints.md")
936 ;; Compare and branch/compare and store instructions.
938 (define_expand "cbranch<mode>4"
939 [(set (reg:CC FLAGS_REG)
940 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
941 (match_operand:SDWIM 2 "<general_operand>")))
942 (set (pc) (if_then_else
943 (match_operator 0 "ordered_comparison_operator"
944 [(reg:CC FLAGS_REG) (const_int 0)])
945 (label_ref (match_operand 3))
949 if (MEM_P (operands[1]) && MEM_P (operands[2]))
950 operands[1] = force_reg (<MODE>mode, operands[1]);
951 ix86_expand_branch (GET_CODE (operands[0]),
952 operands[1], operands[2], operands[3]);
956 (define_expand "cstore<mode>4"
957 [(set (reg:CC FLAGS_REG)
958 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
959 (match_operand:SWIM 3 "<general_operand>")))
960 (set (match_operand:QI 0 "register_operand")
961 (match_operator 1 "ordered_comparison_operator"
962 [(reg:CC FLAGS_REG) (const_int 0)]))]
965 if (MEM_P (operands[2]) && MEM_P (operands[3]))
966 operands[2] = force_reg (<MODE>mode, operands[2]);
967 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
968 operands[2], operands[3]);
972 (define_expand "cmp<mode>_1"
973 [(set (reg:CC FLAGS_REG)
974 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
975 (match_operand:SWI48 1 "<general_operand>")))])
977 (define_insn "*cmp<mode>_ccno_1"
978 [(set (reg FLAGS_REG)
979 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
980 (match_operand:SWI 1 "const0_operand")))]
981 "ix86_match_ccmode (insn, CCNOmode)"
983 test{<imodesuffix>}\t%0, %0
984 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
985 [(set_attr "type" "test,icmp")
986 (set_attr "length_immediate" "0,1")
987 (set_attr "mode" "<MODE>")])
989 (define_insn "*cmp<mode>_1"
990 [(set (reg FLAGS_REG)
991 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
992 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
993 "ix86_match_ccmode (insn, CCmode)"
994 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
995 [(set_attr "type" "icmp")
996 (set_attr "mode" "<MODE>")])
998 (define_insn "*cmp<mode>_minus_1"
999 [(set (reg FLAGS_REG)
1001 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1002 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1004 "ix86_match_ccmode (insn, CCGOCmode)"
1005 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1006 [(set_attr "type" "icmp")
1007 (set_attr "mode" "<MODE>")])
1009 (define_insn "*cmpqi_ext_1"
1010 [(set (reg FLAGS_REG)
1012 (match_operand:QI 0 "general_operand" "Qm")
1015 (match_operand 1 "ext_register_operand" "Q")
1017 (const_int 8)) 0)))]
1018 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1019 "cmp{b}\t{%h1, %0|%0, %h1}"
1020 [(set_attr "type" "icmp")
1021 (set_attr "mode" "QI")])
1023 (define_insn "*cmpqi_ext_1_rex64"
1024 [(set (reg FLAGS_REG)
1026 (match_operand:QI 0 "register_operand" "Q")
1029 (match_operand 1 "ext_register_operand" "Q")
1031 (const_int 8)) 0)))]
1032 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1033 "cmp{b}\t{%h1, %0|%0, %h1}"
1034 [(set_attr "type" "icmp")
1035 (set_attr "mode" "QI")])
1037 (define_insn "*cmpqi_ext_2"
1038 [(set (reg FLAGS_REG)
1042 (match_operand 0 "ext_register_operand" "Q")
1045 (match_operand:QI 1 "const0_operand")))]
1046 "ix86_match_ccmode (insn, CCNOmode)"
1048 [(set_attr "type" "test")
1049 (set_attr "length_immediate" "0")
1050 (set_attr "mode" "QI")])
1052 (define_expand "cmpqi_ext_3"
1053 [(set (reg:CC FLAGS_REG)
1057 (match_operand 0 "ext_register_operand")
1060 (match_operand:QI 1 "immediate_operand")))])
1062 (define_insn "*cmpqi_ext_3_insn"
1063 [(set (reg FLAGS_REG)
1067 (match_operand 0 "ext_register_operand" "Q")
1070 (match_operand:QI 1 "general_operand" "Qmn")))]
1071 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1072 "cmp{b}\t{%1, %h0|%h0, %1}"
1073 [(set_attr "type" "icmp")
1074 (set_attr "modrm" "1")
1075 (set_attr "mode" "QI")])
1077 (define_insn "*cmpqi_ext_3_insn_rex64"
1078 [(set (reg FLAGS_REG)
1082 (match_operand 0 "ext_register_operand" "Q")
1085 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1086 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1087 "cmp{b}\t{%1, %h0|%h0, %1}"
1088 [(set_attr "type" "icmp")
1089 (set_attr "modrm" "1")
1090 (set_attr "mode" "QI")])
1092 (define_insn "*cmpqi_ext_4"
1093 [(set (reg FLAGS_REG)
1097 (match_operand 0 "ext_register_operand" "Q")
1102 (match_operand 1 "ext_register_operand" "Q")
1104 (const_int 8)) 0)))]
1105 "ix86_match_ccmode (insn, CCmode)"
1106 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1107 [(set_attr "type" "icmp")
1108 (set_attr "mode" "QI")])
1110 ;; These implement float point compares.
1111 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1112 ;; which would allow mix and match FP modes on the compares. Which is what
1113 ;; the old patterns did, but with many more of them.
1115 (define_expand "cbranchxf4"
1116 [(set (reg:CC FLAGS_REG)
1117 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1118 (match_operand:XF 2 "nonmemory_operand")))
1119 (set (pc) (if_then_else
1120 (match_operator 0 "ix86_fp_comparison_operator"
1123 (label_ref (match_operand 3))
1127 ix86_expand_branch (GET_CODE (operands[0]),
1128 operands[1], operands[2], operands[3]);
1132 (define_expand "cstorexf4"
1133 [(set (reg:CC FLAGS_REG)
1134 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1135 (match_operand:XF 3 "nonmemory_operand")))
1136 (set (match_operand:QI 0 "register_operand")
1137 (match_operator 1 "ix86_fp_comparison_operator"
1142 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1143 operands[2], operands[3]);
1147 (define_expand "cbranch<mode>4"
1148 [(set (reg:CC FLAGS_REG)
1149 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1150 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1151 (set (pc) (if_then_else
1152 (match_operator 0 "ix86_fp_comparison_operator"
1155 (label_ref (match_operand 3))
1157 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1159 ix86_expand_branch (GET_CODE (operands[0]),
1160 operands[1], operands[2], operands[3]);
1164 (define_expand "cstore<mode>4"
1165 [(set (reg:CC FLAGS_REG)
1166 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1167 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1168 (set (match_operand:QI 0 "register_operand")
1169 (match_operator 1 "ix86_fp_comparison_operator"
1172 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1174 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1175 operands[2], operands[3]);
1179 (define_expand "cbranchcc4"
1180 [(set (pc) (if_then_else
1181 (match_operator 0 "comparison_operator"
1182 [(match_operand 1 "flags_reg_operand")
1183 (match_operand 2 "const0_operand")])
1184 (label_ref (match_operand 3))
1188 ix86_expand_branch (GET_CODE (operands[0]),
1189 operands[1], operands[2], operands[3]);
1193 (define_expand "cstorecc4"
1194 [(set (match_operand:QI 0 "register_operand")
1195 (match_operator 1 "comparison_operator"
1196 [(match_operand 2 "flags_reg_operand")
1197 (match_operand 3 "const0_operand")]))]
1200 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1201 operands[2], operands[3]);
1206 ;; FP compares, step 1:
1207 ;; Set the FP condition codes.
1209 ;; CCFPmode compare with exceptions
1210 ;; CCFPUmode compare with no exceptions
1212 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1213 ;; used to manage the reg stack popping would not be preserved.
1215 (define_insn "*cmpfp_0"
1216 [(set (match_operand:HI 0 "register_operand" "=a")
1219 (match_operand 1 "register_operand" "f")
1220 (match_operand 2 "const0_operand"))]
1222 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1223 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1224 "* return output_fp_compare (insn, operands, false, false);"
1225 [(set_attr "type" "multi")
1226 (set_attr "unit" "i387")
1228 (cond [(match_operand:SF 1)
1230 (match_operand:DF 1)
1233 (const_string "XF")))])
1235 (define_insn_and_split "*cmpfp_0_cc"
1236 [(set (reg:CCFP FLAGS_REG)
1238 (match_operand 1 "register_operand" "f")
1239 (match_operand 2 "const0_operand")))
1240 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1241 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1242 && TARGET_SAHF && !TARGET_CMOVE
1243 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1245 "&& reload_completed"
1248 [(compare:CCFP (match_dup 1)(match_dup 2))]
1250 (set (reg:CC FLAGS_REG)
1251 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1253 [(set_attr "type" "multi")
1254 (set_attr "unit" "i387")
1256 (cond [(match_operand:SF 1)
1258 (match_operand:DF 1)
1261 (const_string "XF")))])
1263 (define_insn "*cmpfp_xf"
1264 [(set (match_operand:HI 0 "register_operand" "=a")
1267 (match_operand:XF 1 "register_operand" "f")
1268 (match_operand:XF 2 "register_operand" "f"))]
1271 "* return output_fp_compare (insn, operands, false, false);"
1272 [(set_attr "type" "multi")
1273 (set_attr "unit" "i387")
1274 (set_attr "mode" "XF")])
1276 (define_insn_and_split "*cmpfp_xf_cc"
1277 [(set (reg:CCFP FLAGS_REG)
1279 (match_operand:XF 1 "register_operand" "f")
1280 (match_operand:XF 2 "register_operand" "f")))
1281 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1283 && TARGET_SAHF && !TARGET_CMOVE"
1285 "&& reload_completed"
1288 [(compare:CCFP (match_dup 1)(match_dup 2))]
1290 (set (reg:CC FLAGS_REG)
1291 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1293 [(set_attr "type" "multi")
1294 (set_attr "unit" "i387")
1295 (set_attr "mode" "XF")])
1297 (define_insn "*cmpfp_<mode>"
1298 [(set (match_operand:HI 0 "register_operand" "=a")
1301 (match_operand:MODEF 1 "register_operand" "f")
1302 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1305 "* return output_fp_compare (insn, operands, false, false);"
1306 [(set_attr "type" "multi")
1307 (set_attr "unit" "i387")
1308 (set_attr "mode" "<MODE>")])
1310 (define_insn_and_split "*cmpfp_<mode>_cc"
1311 [(set (reg:CCFP FLAGS_REG)
1313 (match_operand:MODEF 1 "register_operand" "f")
1314 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1315 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1317 && TARGET_SAHF && !TARGET_CMOVE"
1319 "&& reload_completed"
1322 [(compare:CCFP (match_dup 1)(match_dup 2))]
1324 (set (reg:CC FLAGS_REG)
1325 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1327 [(set_attr "type" "multi")
1328 (set_attr "unit" "i387")
1329 (set_attr "mode" "<MODE>")])
1331 (define_insn "*cmpfp_u"
1332 [(set (match_operand:HI 0 "register_operand" "=a")
1335 (match_operand 1 "register_operand" "f")
1336 (match_operand 2 "register_operand" "f"))]
1338 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1339 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1340 "* return output_fp_compare (insn, operands, false, true);"
1341 [(set_attr "type" "multi")
1342 (set_attr "unit" "i387")
1344 (cond [(match_operand:SF 1)
1346 (match_operand:DF 1)
1349 (const_string "XF")))])
1351 (define_insn_and_split "*cmpfp_u_cc"
1352 [(set (reg:CCFPU FLAGS_REG)
1354 (match_operand 1 "register_operand" "f")
1355 (match_operand 2 "register_operand" "f")))
1356 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1357 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1358 && TARGET_SAHF && !TARGET_CMOVE
1359 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1361 "&& reload_completed"
1364 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1366 (set (reg:CC FLAGS_REG)
1367 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1369 [(set_attr "type" "multi")
1370 (set_attr "unit" "i387")
1372 (cond [(match_operand:SF 1)
1374 (match_operand:DF 1)
1377 (const_string "XF")))])
1379 (define_insn "*cmpfp_<mode>"
1380 [(set (match_operand:HI 0 "register_operand" "=a")
1383 (match_operand 1 "register_operand" "f")
1384 (match_operator 3 "float_operator"
1385 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1387 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1388 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1389 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1390 "* return output_fp_compare (insn, operands, false, false);"
1391 [(set_attr "type" "multi")
1392 (set_attr "unit" "i387")
1393 (set_attr "fp_int_src" "true")
1394 (set_attr "mode" "<MODE>")])
1396 (define_insn_and_split "*cmpfp_<mode>_cc"
1397 [(set (reg:CCFP FLAGS_REG)
1399 (match_operand 1 "register_operand" "f")
1400 (match_operator 3 "float_operator"
1401 [(match_operand:SWI24 2 "memory_operand" "m")])))
1402 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1403 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1404 && TARGET_SAHF && !TARGET_CMOVE
1405 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1406 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1408 "&& reload_completed"
1413 (match_op_dup 3 [(match_dup 2)]))]
1415 (set (reg:CC FLAGS_REG)
1416 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1418 [(set_attr "type" "multi")
1419 (set_attr "unit" "i387")
1420 (set_attr "fp_int_src" "true")
1421 (set_attr "mode" "<MODE>")])
1423 ;; FP compares, step 2
1424 ;; Move the fpsw to ax.
1426 (define_insn "x86_fnstsw_1"
1427 [(set (match_operand:HI 0 "register_operand" "=a")
1428 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1431 [(set (attr "length")
1432 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1433 (set_attr "mode" "SI")
1434 (set_attr "unit" "i387")])
1436 ;; FP compares, step 3
1437 ;; Get ax into flags, general case.
1439 (define_insn "x86_sahf_1"
1440 [(set (reg:CC FLAGS_REG)
1441 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1445 #ifndef HAVE_AS_IX86_SAHF
1447 return ASM_BYTE "0x9e";
1452 [(set_attr "length" "1")
1453 (set_attr "athlon_decode" "vector")
1454 (set_attr "amdfam10_decode" "direct")
1455 (set_attr "bdver1_decode" "direct")
1456 (set_attr "mode" "SI")])
1458 ;; Pentium Pro can do steps 1 through 3 in one go.
1459 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1460 ;; (these i387 instructions set flags directly)
1461 (define_insn "*cmpfp_i_mixed"
1462 [(set (reg:CCFP FLAGS_REG)
1463 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1464 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1465 "TARGET_MIX_SSE_I387
1466 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1467 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1468 "* return output_fp_compare (insn, operands, true, false);"
1469 [(set_attr "type" "fcmp,ssecomi")
1470 (set_attr "prefix" "orig,maybe_vex")
1472 (if_then_else (match_operand:SF 1)
1474 (const_string "DF")))
1475 (set (attr "prefix_rep")
1476 (if_then_else (eq_attr "type" "ssecomi")
1478 (const_string "*")))
1479 (set (attr "prefix_data16")
1480 (cond [(eq_attr "type" "fcmp")
1482 (eq_attr "mode" "DF")
1485 (const_string "0")))
1486 (set_attr "athlon_decode" "vector")
1487 (set_attr "amdfam10_decode" "direct")
1488 (set_attr "bdver1_decode" "double")])
1490 (define_insn "*cmpfp_i_sse"
1491 [(set (reg:CCFP FLAGS_REG)
1492 (compare:CCFP (match_operand 0 "register_operand" "x")
1493 (match_operand 1 "nonimmediate_operand" "xm")))]
1495 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1496 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1497 "* return output_fp_compare (insn, operands, true, false);"
1498 [(set_attr "type" "ssecomi")
1499 (set_attr "prefix" "maybe_vex")
1501 (if_then_else (match_operand:SF 1)
1503 (const_string "DF")))
1504 (set_attr "prefix_rep" "0")
1505 (set (attr "prefix_data16")
1506 (if_then_else (eq_attr "mode" "DF")
1508 (const_string "0")))
1509 (set_attr "athlon_decode" "vector")
1510 (set_attr "amdfam10_decode" "direct")
1511 (set_attr "bdver1_decode" "double")])
1513 (define_insn "*cmpfp_i_i387"
1514 [(set (reg:CCFP FLAGS_REG)
1515 (compare:CCFP (match_operand 0 "register_operand" "f")
1516 (match_operand 1 "register_operand" "f")))]
1517 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1519 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1520 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1521 "* return output_fp_compare (insn, operands, true, false);"
1522 [(set_attr "type" "fcmp")
1524 (cond [(match_operand:SF 1)
1526 (match_operand:DF 1)
1529 (const_string "XF")))
1530 (set_attr "athlon_decode" "vector")
1531 (set_attr "amdfam10_decode" "direct")
1532 (set_attr "bdver1_decode" "double")])
1534 (define_insn "*cmpfp_iu_mixed"
1535 [(set (reg:CCFPU FLAGS_REG)
1536 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1537 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1538 "TARGET_MIX_SSE_I387
1539 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1540 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1541 "* return output_fp_compare (insn, operands, true, true);"
1542 [(set_attr "type" "fcmp,ssecomi")
1543 (set_attr "prefix" "orig,maybe_vex")
1545 (if_then_else (match_operand:SF 1)
1547 (const_string "DF")))
1548 (set (attr "prefix_rep")
1549 (if_then_else (eq_attr "type" "ssecomi")
1551 (const_string "*")))
1552 (set (attr "prefix_data16")
1553 (cond [(eq_attr "type" "fcmp")
1555 (eq_attr "mode" "DF")
1558 (const_string "0")))
1559 (set_attr "athlon_decode" "vector")
1560 (set_attr "amdfam10_decode" "direct")
1561 (set_attr "bdver1_decode" "double")])
1563 (define_insn "*cmpfp_iu_sse"
1564 [(set (reg:CCFPU FLAGS_REG)
1565 (compare:CCFPU (match_operand 0 "register_operand" "x")
1566 (match_operand 1 "nonimmediate_operand" "xm")))]
1568 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1569 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1570 "* return output_fp_compare (insn, operands, true, true);"
1571 [(set_attr "type" "ssecomi")
1572 (set_attr "prefix" "maybe_vex")
1574 (if_then_else (match_operand:SF 1)
1576 (const_string "DF")))
1577 (set_attr "prefix_rep" "0")
1578 (set (attr "prefix_data16")
1579 (if_then_else (eq_attr "mode" "DF")
1581 (const_string "0")))
1582 (set_attr "athlon_decode" "vector")
1583 (set_attr "amdfam10_decode" "direct")
1584 (set_attr "bdver1_decode" "double")])
1586 (define_insn "*cmpfp_iu_387"
1587 [(set (reg:CCFPU FLAGS_REG)
1588 (compare:CCFPU (match_operand 0 "register_operand" "f")
1589 (match_operand 1 "register_operand" "f")))]
1590 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1592 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1593 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1594 "* return output_fp_compare (insn, operands, true, true);"
1595 [(set_attr "type" "fcmp")
1597 (cond [(match_operand:SF 1)
1599 (match_operand:DF 1)
1602 (const_string "XF")))
1603 (set_attr "athlon_decode" "vector")
1604 (set_attr "amdfam10_decode" "direct")
1605 (set_attr "bdver1_decode" "direct")])
1607 ;; Push/pop instructions.
1609 (define_insn "*push<mode>2"
1610 [(set (match_operand:DWI 0 "push_operand" "=<")
1611 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1614 [(set_attr "type" "multi")
1615 (set_attr "mode" "<MODE>")])
1618 [(set (match_operand:TI 0 "push_operand")
1619 (match_operand:TI 1 "general_operand"))]
1620 "TARGET_64BIT && reload_completed
1621 && !SSE_REG_P (operands[1])"
1623 "ix86_split_long_move (operands); DONE;")
1625 (define_insn "*pushdi2_rex64"
1626 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1627 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1632 [(set_attr "type" "push,multi")
1633 (set_attr "mode" "DI")])
1635 ;; Convert impossible pushes of immediate to existing instructions.
1636 ;; First try to get scratch register and go through it. In case this
1637 ;; fails, push sign extended lower part first and then overwrite
1638 ;; upper part by 32bit move.
1640 [(match_scratch:DI 2 "r")
1641 (set (match_operand:DI 0 "push_operand")
1642 (match_operand:DI 1 "immediate_operand"))]
1643 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1644 && !x86_64_immediate_operand (operands[1], DImode)"
1645 [(set (match_dup 2) (match_dup 1))
1646 (set (match_dup 0) (match_dup 2))])
1648 ;; We need to define this as both peepholer and splitter for case
1649 ;; peephole2 pass is not run.
1650 ;; "&& 1" is needed to keep it from matching the previous pattern.
1652 [(set (match_operand:DI 0 "push_operand")
1653 (match_operand:DI 1 "immediate_operand"))]
1654 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1655 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1656 [(set (match_dup 0) (match_dup 1))
1657 (set (match_dup 2) (match_dup 3))]
1659 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1661 operands[1] = gen_lowpart (DImode, operands[2]);
1662 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1667 [(set (match_operand:DI 0 "push_operand")
1668 (match_operand:DI 1 "immediate_operand"))]
1669 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1670 ? epilogue_completed : reload_completed)
1671 && !symbolic_operand (operands[1], DImode)
1672 && !x86_64_immediate_operand (operands[1], DImode)"
1673 [(set (match_dup 0) (match_dup 1))
1674 (set (match_dup 2) (match_dup 3))]
1676 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1678 operands[1] = gen_lowpart (DImode, operands[2]);
1679 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1684 [(set (match_operand:DI 0 "push_operand")
1685 (match_operand:DI 1 "general_operand"))]
1686 "!TARGET_64BIT && reload_completed
1687 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1689 "ix86_split_long_move (operands); DONE;")
1691 (define_insn "*pushsi2"
1692 [(set (match_operand:SI 0 "push_operand" "=<")
1693 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1696 [(set_attr "type" "push")
1697 (set_attr "mode" "SI")])
1699 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1700 ;; "push a byte/word". But actually we use pushl, which has the effect
1701 ;; of rounding the amount pushed up to a word.
1703 ;; For TARGET_64BIT we always round up to 8 bytes.
1704 (define_insn "*push<mode>2_rex64"
1705 [(set (match_operand:SWI124 0 "push_operand" "=X")
1706 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1709 [(set_attr "type" "push")
1710 (set_attr "mode" "DI")])
1712 (define_insn "*push<mode>2"
1713 [(set (match_operand:SWI12 0 "push_operand" "=X")
1714 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1717 [(set_attr "type" "push")
1718 (set_attr "mode" "SI")])
1720 (define_insn "*push<mode>2_prologue"
1721 [(set (match_operand:W 0 "push_operand" "=<")
1722 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1723 (clobber (mem:BLK (scratch)))]
1725 "push{<imodesuffix>}\t%1"
1726 [(set_attr "type" "push")
1727 (set_attr "mode" "<MODE>")])
1729 (define_insn "*pop<mode>1"
1730 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1731 (match_operand:W 1 "pop_operand" ">"))]
1733 "pop{<imodesuffix>}\t%0"
1734 [(set_attr "type" "pop")
1735 (set_attr "mode" "<MODE>")])
1737 (define_insn "*pop<mode>1_epilogue"
1738 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1739 (match_operand:W 1 "pop_operand" ">"))
1740 (clobber (mem:BLK (scratch)))]
1742 "pop{<imodesuffix>}\t%0"
1743 [(set_attr "type" "pop")
1744 (set_attr "mode" "<MODE>")])
1746 ;; Move instructions.
1748 (define_expand "movoi"
1749 [(set (match_operand:OI 0 "nonimmediate_operand")
1750 (match_operand:OI 1 "general_operand"))]
1752 "ix86_expand_move (OImode, operands); DONE;")
1754 (define_expand "movti"
1755 [(set (match_operand:TI 0 "nonimmediate_operand")
1756 (match_operand:TI 1 "nonimmediate_operand"))]
1757 "TARGET_64BIT || TARGET_SSE"
1760 ix86_expand_move (TImode, operands);
1761 else if (push_operand (operands[0], TImode))
1762 ix86_expand_push (TImode, operands[1]);
1764 ix86_expand_vector_move (TImode, operands);
1768 ;; This expands to what emit_move_complex would generate if we didn't
1769 ;; have a movti pattern. Having this avoids problems with reload on
1770 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1771 ;; to have around all the time.
1772 (define_expand "movcdi"
1773 [(set (match_operand:CDI 0 "nonimmediate_operand")
1774 (match_operand:CDI 1 "general_operand"))]
1777 if (push_operand (operands[0], CDImode))
1778 emit_move_complex_push (CDImode, operands[0], operands[1]);
1780 emit_move_complex_parts (operands[0], operands[1]);
1784 (define_expand "mov<mode>"
1785 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1786 (match_operand:SWI1248x 1 "general_operand"))]
1788 "ix86_expand_move (<MODE>mode, operands); DONE;")
1790 (define_insn "*mov<mode>_xor"
1791 [(set (match_operand:SWI48 0 "register_operand" "=r")
1792 (match_operand:SWI48 1 "const0_operand"))
1793 (clobber (reg:CC FLAGS_REG))]
1796 [(set_attr "type" "alu1")
1797 (set_attr "mode" "SI")
1798 (set_attr "length_immediate" "0")])
1800 (define_insn "*mov<mode>_or"
1801 [(set (match_operand:SWI48 0 "register_operand" "=r")
1802 (match_operand:SWI48 1 "const_int_operand"))
1803 (clobber (reg:CC FLAGS_REG))]
1805 && operands[1] == constm1_rtx"
1806 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1807 [(set_attr "type" "alu1")
1808 (set_attr "mode" "<MODE>")
1809 (set_attr "length_immediate" "1")])
1811 (define_insn "*movoi_internal_avx"
1812 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1813 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1814 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1816 switch (which_alternative)
1819 return standard_sse_constant_opcode (insn, operands[1]);
1822 if (misaligned_operand (operands[0], OImode)
1823 || misaligned_operand (operands[1], OImode))
1824 return "vmovdqu\t{%1, %0|%0, %1}";
1826 return "vmovdqa\t{%1, %0|%0, %1}";
1831 [(set_attr "type" "sselog1,ssemov,ssemov")
1832 (set_attr "prefix" "vex")
1833 (set_attr "mode" "OI")])
1835 (define_insn "*movti_internal_rex64"
1836 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1837 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1838 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1840 switch (which_alternative)
1846 return standard_sse_constant_opcode (insn, operands[1]);
1849 /* TDmode values are passed as TImode on the stack. Moving them
1850 to stack may result in unaligned memory access. */
1851 if (misaligned_operand (operands[0], TImode)
1852 || misaligned_operand (operands[1], TImode))
1854 if (get_attr_mode (insn) == MODE_V4SF)
1855 return "%vmovups\t{%1, %0|%0, %1}";
1857 return "%vmovdqu\t{%1, %0|%0, %1}";
1861 if (get_attr_mode (insn) == MODE_V4SF)
1862 return "%vmovaps\t{%1, %0|%0, %1}";
1864 return "%vmovdqa\t{%1, %0|%0, %1}";
1870 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1871 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1873 (cond [(eq_attr "alternative" "2,3")
1875 (match_test "optimize_function_for_size_p (cfun)")
1876 (const_string "V4SF")
1877 (const_string "TI"))
1878 (eq_attr "alternative" "4")
1880 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
1881 (match_test "optimize_function_for_size_p (cfun)"))
1882 (const_string "V4SF")
1883 (const_string "TI"))]
1884 (const_string "DI")))])
1887 [(set (match_operand:TI 0 "nonimmediate_operand")
1888 (match_operand:TI 1 "general_operand"))]
1890 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1892 "ix86_split_long_move (operands); DONE;")
1894 (define_insn "*movti_internal_sse"
1895 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1896 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1897 "TARGET_SSE && !TARGET_64BIT
1898 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1900 switch (which_alternative)
1903 return standard_sse_constant_opcode (insn, operands[1]);
1906 /* TDmode values are passed as TImode on the stack. Moving them
1907 to stack may result in unaligned memory access. */
1908 if (misaligned_operand (operands[0], TImode)
1909 || misaligned_operand (operands[1], TImode))
1911 if (get_attr_mode (insn) == MODE_V4SF)
1912 return "%vmovups\t{%1, %0|%0, %1}";
1914 return "%vmovdqu\t{%1, %0|%0, %1}";
1918 if (get_attr_mode (insn) == MODE_V4SF)
1919 return "%vmovaps\t{%1, %0|%0, %1}";
1921 return "%vmovdqa\t{%1, %0|%0, %1}";
1927 [(set_attr "type" "sselog1,ssemov,ssemov")
1928 (set_attr "prefix" "maybe_vex")
1930 (cond [(ior (not (match_test "TARGET_SSE2"))
1931 (match_test "optimize_function_for_size_p (cfun)"))
1932 (const_string "V4SF")
1933 (and (eq_attr "alternative" "2")
1934 (match_test "TARGET_SSE_TYPELESS_STORES"))
1935 (const_string "V4SF")]
1936 (const_string "TI")))])
1938 (define_insn "*movdi_internal_rex64"
1939 [(set (match_operand:DI 0 "nonimmediate_operand"
1940 "=r,r ,r,m ,!o,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1941 (match_operand:DI 1 "general_operand"
1942 "Z ,rem,i,re,n ,C ,*y ,m ,*Ym,r ,C ,*x,*x,m ,*Yi,r ,*Ym,*x"))]
1943 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1945 switch (get_attr_type (insn))
1948 if (SSE_REG_P (operands[0]))
1949 return "movq2dq\t{%1, %0|%0, %1}";
1951 return "movdq2q\t{%1, %0|%0, %1}";
1954 if (get_attr_mode (insn) == MODE_TI)
1955 return "%vmovdqa\t{%1, %0|%0, %1}";
1956 /* Handle broken assemblers that require movd instead of movq. */
1957 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1958 return "%vmovd\t{%1, %0|%0, %1}";
1960 return "%vmovq\t{%1, %0|%0, %1}";
1963 /* Handle broken assemblers that require movd instead of movq. */
1964 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1965 return "movd\t{%1, %0|%0, %1}";
1967 return "movq\t{%1, %0|%0, %1}";
1970 return standard_sse_constant_opcode (insn, operands[1]);
1973 return "pxor\t%0, %0";
1979 return "lea{q}\t{%E1, %0|%0, %E1}";
1982 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1983 if (get_attr_mode (insn) == MODE_SI)
1984 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1985 else if (which_alternative == 2)
1986 return "movabs{q}\t{%1, %0|%0, %1}";
1987 else if (ix86_use_lea_for_mov (insn, operands))
1988 return "lea{q}\t{%E1, %0|%0, %E1}";
1990 return "mov{q}\t{%1, %0|%0, %1}";
1994 (cond [(eq_attr "alternative" "4")
1995 (const_string "multi")
1996 (eq_attr "alternative" "5")
1997 (const_string "mmx")
1998 (eq_attr "alternative" "6,7,8,9")
1999 (const_string "mmxmov")
2000 (eq_attr "alternative" "10")
2001 (const_string "sselog1")
2002 (eq_attr "alternative" "11,12,13,14,15")
2003 (const_string "ssemov")
2004 (eq_attr "alternative" "16,17")
2005 (const_string "ssecvt")
2006 (match_operand 1 "pic_32bit_operand")
2007 (const_string "lea")
2009 (const_string "imov")))
2012 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2014 (const_string "*")))
2015 (set (attr "length_immediate")
2017 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2019 (const_string "*")))
2020 (set (attr "prefix_rex")
2021 (if_then_else (eq_attr "alternative" "8,9")
2023 (const_string "*")))
2024 (set (attr "prefix_data16")
2025 (if_then_else (eq_attr "alternative" "11")
2027 (const_string "*")))
2028 (set (attr "prefix")
2029 (if_then_else (eq_attr "alternative" "10,11,12,13,14,15")
2030 (const_string "maybe_vex")
2031 (const_string "orig")))
2032 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,TI,DI,TI,DI,DI,DI,DI,DI")])
2034 ;; Reload patterns to support multi-word load/store
2035 ;; with non-offsetable address.
2036 (define_expand "reload_noff_store"
2037 [(parallel [(match_operand 0 "memory_operand" "=m")
2038 (match_operand 1 "register_operand" "r")
2039 (match_operand:DI 2 "register_operand" "=&r")])]
2042 rtx mem = operands[0];
2043 rtx addr = XEXP (mem, 0);
2045 emit_move_insn (operands[2], addr);
2046 mem = replace_equiv_address_nv (mem, operands[2]);
2048 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
2052 (define_expand "reload_noff_load"
2053 [(parallel [(match_operand 0 "register_operand" "=r")
2054 (match_operand 1 "memory_operand" "m")
2055 (match_operand:DI 2 "register_operand" "=r")])]
2058 rtx mem = operands[1];
2059 rtx addr = XEXP (mem, 0);
2061 emit_move_insn (operands[2], addr);
2062 mem = replace_equiv_address_nv (mem, operands[2]);
2064 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
2068 ;; Convert impossible stores of immediate to existing instructions.
2069 ;; First try to get scratch register and go through it. In case this
2070 ;; fails, move by 32bit parts.
2072 [(match_scratch:DI 2 "r")
2073 (set (match_operand:DI 0 "memory_operand")
2074 (match_operand:DI 1 "immediate_operand"))]
2075 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2076 && !x86_64_immediate_operand (operands[1], DImode)"
2077 [(set (match_dup 2) (match_dup 1))
2078 (set (match_dup 0) (match_dup 2))])
2080 ;; We need to define this as both peepholer and splitter for case
2081 ;; peephole2 pass is not run.
2082 ;; "&& 1" is needed to keep it from matching the previous pattern.
2084 [(set (match_operand:DI 0 "memory_operand")
2085 (match_operand:DI 1 "immediate_operand"))]
2086 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2087 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2088 [(set (match_dup 2) (match_dup 3))
2089 (set (match_dup 4) (match_dup 5))]
2090 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2093 [(set (match_operand:DI 0 "memory_operand")
2094 (match_operand:DI 1 "immediate_operand"))]
2095 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2096 ? epilogue_completed : reload_completed)
2097 && !symbolic_operand (operands[1], DImode)
2098 && !x86_64_immediate_operand (operands[1], DImode)"
2099 [(set (match_dup 2) (match_dup 3))
2100 (set (match_dup 4) (match_dup 5))]
2101 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2103 (define_insn "*movdi_internal"
2104 [(set (match_operand:DI 0 "nonimmediate_operand"
2105 "=r ,o ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym")
2106 (match_operand:DI 1 "general_operand"
2107 "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))]
2108 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2110 switch (get_attr_type (insn))
2113 if (SSE_REG_P (operands[0]))
2114 return "movq2dq\t{%1, %0|%0, %1}";
2116 return "movdq2q\t{%1, %0|%0, %1}";
2119 switch (get_attr_mode (insn))
2122 return "%vmovdqa\t{%1, %0|%0, %1}";
2124 return "%vmovq\t{%1, %0|%0, %1}";
2126 return "movaps\t{%1, %0|%0, %1}";
2128 return "movlps\t{%1, %0|%0, %1}";
2134 return "movq\t{%1, %0|%0, %1}";
2137 return standard_sse_constant_opcode (insn, operands[1]);
2140 return "pxor\t%0, %0";
2150 (cond [(eq_attr "alternative" "5,6,7,8,13,14")
2151 (const_string "sse2")
2152 (eq_attr "alternative" "9,10,11,12")
2153 (const_string "noavx")
2155 (const_string "*")))
2157 (cond [(eq_attr "alternative" "0,1")
2158 (const_string "multi")
2159 (eq_attr "alternative" "2")
2160 (const_string "mmx")
2161 (eq_attr "alternative" "3,4")
2162 (const_string "mmxmov")
2163 (eq_attr "alternative" "5,9")
2164 (const_string "sselog1")
2165 (eq_attr "alternative" "13,14")
2166 (const_string "ssecvt")
2168 (const_string "ssemov")))
2169 (set (attr "prefix")
2170 (if_then_else (eq_attr "alternative" "5,6,7,8")
2171 (const_string "maybe_vex")
2172 (const_string "orig")))
2173 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")])
2176 [(set (match_operand:DI 0 "nonimmediate_operand")
2177 (match_operand:DI 1 "general_operand"))]
2178 "!TARGET_64BIT && reload_completed
2179 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2180 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2182 "ix86_split_long_move (operands); DONE;")
2184 (define_insn "*movsi_internal"
2185 [(set (match_operand:SI 0 "nonimmediate_operand"
2186 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2187 (match_operand:SI 1 "general_operand"
2188 "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2189 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2191 switch (get_attr_type (insn))
2194 return standard_sse_constant_opcode (insn, operands[1]);
2197 switch (get_attr_mode (insn))
2200 return "%vmovdqa\t{%1, %0|%0, %1}";
2202 return "%vmovaps\t{%1, %0|%0, %1}";
2204 return "%vmovd\t{%1, %0|%0, %1}";
2206 return "%vmovss\t{%1, %0|%0, %1}";
2212 return "pxor\t%0, %0";
2215 if (get_attr_mode (insn) == MODE_DI)
2216 return "movq\t{%1, %0|%0, %1}";
2217 return "movd\t{%1, %0|%0, %1}";
2220 return "lea{l}\t{%E1, %0|%0, %E1}";
2223 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2224 if (ix86_use_lea_for_mov (insn, operands))
2225 return "lea{l}\t{%E1, %0|%0, %E1}";
2227 return "mov{l}\t{%1, %0|%0, %1}";
2231 (cond [(eq_attr "alternative" "2")
2232 (const_string "mmx")
2233 (eq_attr "alternative" "3,4,5")
2234 (const_string "mmxmov")
2235 (eq_attr "alternative" "6")
2236 (const_string "sselog1")
2237 (eq_attr "alternative" "7,8,9,10,11")
2238 (const_string "ssemov")
2239 (match_operand 1 "pic_32bit_operand")
2240 (const_string "lea")
2242 (const_string "imov")))
2243 (set (attr "prefix")
2244 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2245 (const_string "orig")
2246 (const_string "maybe_vex")))
2247 (set (attr "prefix_data16")
2248 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2250 (const_string "*")))
2252 (cond [(eq_attr "alternative" "2,3")
2254 (eq_attr "alternative" "6,7")
2256 (not (match_test "TARGET_SSE2"))
2257 (const_string "V4SF")
2258 (const_string "TI"))
2259 (and (eq_attr "alternative" "8,9,10,11")
2260 (not (match_test "TARGET_SSE2")))
2263 (const_string "SI")))])
2265 (define_insn "*movhi_internal"
2266 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2267 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2268 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2270 switch (get_attr_type (insn))
2273 /* movzwl is faster than movw on p2 due to partial word stalls,
2274 though not as fast as an aligned movl. */
2275 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2277 if (get_attr_mode (insn) == MODE_SI)
2278 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2280 return "mov{w}\t{%1, %0|%0, %1}";
2284 (cond [(match_test "optimize_function_for_size_p (cfun)")
2285 (const_string "imov")
2286 (and (eq_attr "alternative" "0")
2287 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2288 (not (match_test "TARGET_HIMODE_MATH"))))
2289 (const_string "imov")
2290 (and (eq_attr "alternative" "1,2")
2291 (match_operand:HI 1 "aligned_operand"))
2292 (const_string "imov")
2293 (and (match_test "TARGET_MOVX")
2294 (eq_attr "alternative" "0,2"))
2295 (const_string "imovx")
2297 (const_string "imov")))
2299 (cond [(eq_attr "type" "imovx")
2301 (and (eq_attr "alternative" "1,2")
2302 (match_operand:HI 1 "aligned_operand"))
2304 (and (eq_attr "alternative" "0")
2305 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2306 (not (match_test "TARGET_HIMODE_MATH"))))
2309 (const_string "HI")))])
2311 ;; Situation is quite tricky about when to choose full sized (SImode) move
2312 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2313 ;; partial register dependency machines (such as AMD Athlon), where QImode
2314 ;; moves issue extra dependency and for partial register stalls machines
2315 ;; that don't use QImode patterns (and QImode move cause stall on the next
2318 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2319 ;; register stall machines with, where we use QImode instructions, since
2320 ;; partial register stall can be caused there. Then we use movzx.
2321 (define_insn "*movqi_internal"
2322 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2323 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2324 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2326 switch (get_attr_type (insn))
2329 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2330 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2332 if (get_attr_mode (insn) == MODE_SI)
2333 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2335 return "mov{b}\t{%1, %0|%0, %1}";
2339 (cond [(and (eq_attr "alternative" "5")
2340 (not (match_operand:QI 1 "aligned_operand")))
2341 (const_string "imovx")
2342 (match_test "optimize_function_for_size_p (cfun)")
2343 (const_string "imov")
2344 (and (eq_attr "alternative" "3")
2345 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2346 (not (match_test "TARGET_QIMODE_MATH"))))
2347 (const_string "imov")
2348 (eq_attr "alternative" "3,5")
2349 (const_string "imovx")
2350 (and (match_test "TARGET_MOVX")
2351 (eq_attr "alternative" "2"))
2352 (const_string "imovx")
2354 (const_string "imov")))
2356 (cond [(eq_attr "alternative" "3,4,5")
2358 (eq_attr "alternative" "6")
2360 (eq_attr "type" "imovx")
2362 (and (eq_attr "type" "imov")
2363 (and (eq_attr "alternative" "0,1")
2364 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2365 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2366 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2368 ;; Avoid partial register stalls when not using QImode arithmetic
2369 (and (eq_attr "type" "imov")
2370 (and (eq_attr "alternative" "0,1")
2371 (and (match_test "TARGET_PARTIAL_REG_STALL")
2372 (not (match_test "TARGET_QIMODE_MATH")))))
2375 (const_string "QI")))])
2377 ;; Stores and loads of ax to arbitrary constant address.
2378 ;; We fake an second form of instruction to force reload to load address
2379 ;; into register when rax is not available
2380 (define_insn "*movabs<mode>_1"
2381 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2382 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2383 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2385 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2386 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2387 [(set_attr "type" "imov")
2388 (set_attr "modrm" "0,*")
2389 (set_attr "length_address" "8,0")
2390 (set_attr "length_immediate" "0,*")
2391 (set_attr "memory" "store")
2392 (set_attr "mode" "<MODE>")])
2394 (define_insn "*movabs<mode>_2"
2395 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2396 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2397 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2399 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2400 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2401 [(set_attr "type" "imov")
2402 (set_attr "modrm" "0,*")
2403 (set_attr "length_address" "8,0")
2404 (set_attr "length_immediate" "0")
2405 (set_attr "memory" "load")
2406 (set_attr "mode" "<MODE>")])
2408 (define_insn "*swap<mode>"
2409 [(set (match_operand:SWI48 0 "register_operand" "+r")
2410 (match_operand:SWI48 1 "register_operand" "+r"))
2414 "xchg{<imodesuffix>}\t%1, %0"
2415 [(set_attr "type" "imov")
2416 (set_attr "mode" "<MODE>")
2417 (set_attr "pent_pair" "np")
2418 (set_attr "athlon_decode" "vector")
2419 (set_attr "amdfam10_decode" "double")
2420 (set_attr "bdver1_decode" "double")])
2422 (define_insn "*swap<mode>_1"
2423 [(set (match_operand:SWI12 0 "register_operand" "+r")
2424 (match_operand:SWI12 1 "register_operand" "+r"))
2427 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2429 [(set_attr "type" "imov")
2430 (set_attr "mode" "SI")
2431 (set_attr "pent_pair" "np")
2432 (set_attr "athlon_decode" "vector")
2433 (set_attr "amdfam10_decode" "double")
2434 (set_attr "bdver1_decode" "double")])
2436 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2437 ;; is disabled for AMDFAM10
2438 (define_insn "*swap<mode>_2"
2439 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2440 (match_operand:SWI12 1 "register_operand" "+<r>"))
2443 "TARGET_PARTIAL_REG_STALL"
2444 "xchg{<imodesuffix>}\t%1, %0"
2445 [(set_attr "type" "imov")
2446 (set_attr "mode" "<MODE>")
2447 (set_attr "pent_pair" "np")
2448 (set_attr "athlon_decode" "vector")])
2450 (define_expand "movstrict<mode>"
2451 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2452 (match_operand:SWI12 1 "general_operand"))]
2455 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2457 if (GET_CODE (operands[0]) == SUBREG
2458 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2460 /* Don't generate memory->memory moves, go through a register */
2461 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2462 operands[1] = force_reg (<MODE>mode, operands[1]);
2465 (define_insn "*movstrict<mode>_1"
2466 [(set (strict_low_part
2467 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2468 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2469 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2470 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2471 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2472 [(set_attr "type" "imov")
2473 (set_attr "mode" "<MODE>")])
2475 (define_insn "*movstrict<mode>_xor"
2476 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2477 (match_operand:SWI12 1 "const0_operand"))
2478 (clobber (reg:CC FLAGS_REG))]
2480 "xor{<imodesuffix>}\t%0, %0"
2481 [(set_attr "type" "alu1")
2482 (set_attr "mode" "<MODE>")
2483 (set_attr "length_immediate" "0")])
2485 (define_insn "*mov<mode>_extv_1"
2486 [(set (match_operand:SWI24 0 "register_operand" "=R")
2487 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2491 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2492 [(set_attr "type" "imovx")
2493 (set_attr "mode" "SI")])
2495 (define_insn "*movqi_extv_1_rex64"
2496 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2497 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2502 switch (get_attr_type (insn))
2505 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2507 return "mov{b}\t{%h1, %0|%0, %h1}";
2511 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand"))
2512 (match_test "TARGET_MOVX"))
2513 (const_string "imovx")
2514 (const_string "imov")))
2516 (if_then_else (eq_attr "type" "imovx")
2518 (const_string "QI")))])
2520 (define_insn "*movqi_extv_1"
2521 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2522 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2527 switch (get_attr_type (insn))
2530 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2532 return "mov{b}\t{%h1, %0|%0, %h1}";
2536 (if_then_else (and (match_operand:QI 0 "register_operand")
2537 (ior (not (match_operand:QI 0 "QIreg_operand"))
2538 (match_test "TARGET_MOVX")))
2539 (const_string "imovx")
2540 (const_string "imov")))
2542 (if_then_else (eq_attr "type" "imovx")
2544 (const_string "QI")))])
2546 (define_insn "*mov<mode>_extzv_1"
2547 [(set (match_operand:SWI48 0 "register_operand" "=R")
2548 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2552 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2553 [(set_attr "type" "imovx")
2554 (set_attr "mode" "SI")])
2556 (define_insn "*movqi_extzv_2_rex64"
2557 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2559 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2564 switch (get_attr_type (insn))
2567 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2569 return "mov{b}\t{%h1, %0|%0, %h1}";
2573 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand"))
2574 (match_test "TARGET_MOVX"))
2575 (const_string "imovx")
2576 (const_string "imov")))
2578 (if_then_else (eq_attr "type" "imovx")
2580 (const_string "QI")))])
2582 (define_insn "*movqi_extzv_2"
2583 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2585 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2590 switch (get_attr_type (insn))
2593 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2595 return "mov{b}\t{%h1, %0|%0, %h1}";
2599 (if_then_else (and (match_operand:QI 0 "register_operand")
2600 (ior (not (match_operand:QI 0 "QIreg_operand"))
2601 (match_test "TARGET_MOVX")))
2602 (const_string "imovx")
2603 (const_string "imov")))
2605 (if_then_else (eq_attr "type" "imovx")
2607 (const_string "QI")))])
2609 (define_expand "mov<mode>_insv_1"
2610 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand")
2613 (match_operand:SWI48 1 "nonmemory_operand"))])
2615 (define_insn "*mov<mode>_insv_1_rex64"
2616 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2619 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2621 "mov{b}\t{%b1, %h0|%h0, %b1}"
2622 [(set_attr "type" "imov")
2623 (set_attr "mode" "QI")])
2625 (define_insn "*movsi_insv_1"
2626 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2629 (match_operand:SI 1 "general_operand" "Qmn"))]
2631 "mov{b}\t{%b1, %h0|%h0, %b1}"
2632 [(set_attr "type" "imov")
2633 (set_attr "mode" "QI")])
2635 (define_insn "*movqi_insv_2"
2636 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2639 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2642 "mov{b}\t{%h1, %h0|%h0, %h1}"
2643 [(set_attr "type" "imov")
2644 (set_attr "mode" "QI")])
2646 ;; Floating point push instructions.
2648 (define_insn "*pushtf"
2649 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2650 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2653 /* This insn should be already split before reg-stack. */
2656 [(set_attr "type" "multi")
2657 (set_attr "unit" "sse,*,*")
2658 (set_attr "mode" "TF,SI,SI")])
2660 ;; %%% Kill this when call knows how to work this out.
2662 [(set (match_operand:TF 0 "push_operand")
2663 (match_operand:TF 1 "sse_reg_operand"))]
2664 "TARGET_SSE2 && reload_completed"
2665 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2666 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2668 (define_insn "*pushxf"
2669 [(set (match_operand:XF 0 "push_operand" "=<,<")
2670 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2671 "optimize_function_for_speed_p (cfun)"
2673 /* This insn should be already split before reg-stack. */
2676 [(set_attr "type" "multi")
2677 (set_attr "unit" "i387,*")
2678 (set_attr "mode" "XF,SI")])
2680 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2681 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2682 ;; Pushing using integer instructions is longer except for constants
2683 ;; and direct memory references (assuming that any given constant is pushed
2684 ;; only once, but this ought to be handled elsewhere).
2686 (define_insn "*pushxf_nointeger"
2687 [(set (match_operand:XF 0 "push_operand" "=<,<")
2688 (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2689 "optimize_function_for_size_p (cfun)"
2691 /* This insn should be already split before reg-stack. */
2694 [(set_attr "type" "multi")
2695 (set_attr "unit" "i387,*")
2696 (set_attr "mode" "XF,SI")])
2698 ;; %%% Kill this when call knows how to work this out.
2700 [(set (match_operand:XF 0 "push_operand")
2701 (match_operand:XF 1 "fp_register_operand"))]
2703 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2704 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2705 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2707 (define_insn "*pushdf_rex64"
2708 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2709 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
2712 /* This insn should be already split before reg-stack. */
2715 [(set_attr "type" "multi")
2716 (set_attr "unit" "i387,*,*")
2717 (set_attr "mode" "DF,DI,DF")])
2719 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2720 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2721 ;; On the average, pushdf using integers can be still shorter.
2723 (define_insn "*pushdf"
2724 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2725 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
2728 /* This insn should be already split before reg-stack. */
2731 [(set_attr "isa" "*,*,sse2")
2732 (set_attr "type" "multi")
2733 (set_attr "unit" "i387,*,*")
2734 (set_attr "mode" "DF,DI,DF")])
2736 ;; %%% Kill this when call knows how to work this out.
2738 [(set (match_operand:DF 0 "push_operand")
2739 (match_operand:DF 1 "any_fp_register_operand"))]
2741 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2742 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2744 (define_insn "*pushsf_rex64"
2745 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2746 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2749 /* Anything else should be already split before reg-stack. */
2750 gcc_assert (which_alternative == 1);
2751 return "push{q}\t%q1";
2753 [(set_attr "type" "multi,push,multi")
2754 (set_attr "unit" "i387,*,*")
2755 (set_attr "mode" "SF,DI,SF")])
2757 (define_insn "*pushsf"
2758 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2759 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2762 /* Anything else should be already split before reg-stack. */
2763 gcc_assert (which_alternative == 1);
2764 return "push{l}\t%1";
2766 [(set_attr "type" "multi,push,multi")
2767 (set_attr "unit" "i387,*,*")
2768 (set_attr "mode" "SF,SI,SF")])
2770 ;; %%% Kill this when call knows how to work this out.
2772 [(set (match_operand:SF 0 "push_operand")
2773 (match_operand:SF 1 "any_fp_register_operand"))]
2775 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2776 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2777 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2780 [(set (match_operand:SF 0 "push_operand")
2781 (match_operand:SF 1 "memory_operand"))]
2783 && (operands[2] = find_constant_src (insn))"
2784 [(set (match_dup 0) (match_dup 2))])
2787 [(set (match_operand 0 "push_operand")
2788 (match_operand 1 "general_operand"))]
2790 && (GET_MODE (operands[0]) == TFmode
2791 || GET_MODE (operands[0]) == XFmode
2792 || GET_MODE (operands[0]) == DFmode)
2793 && !ANY_FP_REG_P (operands[1])"
2795 "ix86_split_long_move (operands); DONE;")
2797 ;; Floating point move instructions.
2799 (define_expand "movtf"
2800 [(set (match_operand:TF 0 "nonimmediate_operand")
2801 (match_operand:TF 1 "nonimmediate_operand"))]
2804 ix86_expand_move (TFmode, operands);
2808 (define_expand "mov<mode>"
2809 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2810 (match_operand:X87MODEF 1 "general_operand"))]
2812 "ix86_expand_move (<MODE>mode, operands); DONE;")
2814 (define_insn "*movtf_internal"
2815 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o")
2816 (match_operand:TF 1 "general_operand" "xm,x,C,*roF,F*r"))]
2818 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2819 && (!can_create_pseudo_p ()
2820 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2821 || GET_CODE (operands[1]) != CONST_DOUBLE
2822 || (optimize_function_for_size_p (cfun)
2823 && standard_sse_constant_p (operands[1])
2824 && !memory_operand (operands[0], TFmode))
2825 || (!TARGET_MEMORY_MISMATCH_STALL
2826 && memory_operand (operands[0], TFmode)))"
2828 switch (which_alternative)
2832 /* Handle misaligned load/store since we
2833 don't have movmisaligntf pattern. */
2834 if (misaligned_operand (operands[0], TFmode)
2835 || misaligned_operand (operands[1], TFmode))
2837 if (get_attr_mode (insn) == MODE_V4SF)
2838 return "%vmovups\t{%1, %0|%0, %1}";
2840 return "%vmovdqu\t{%1, %0|%0, %1}";
2844 if (get_attr_mode (insn) == MODE_V4SF)
2845 return "%vmovaps\t{%1, %0|%0, %1}";
2847 return "%vmovdqa\t{%1, %0|%0, %1}";
2851 return standard_sse_constant_opcode (insn, operands[1]);
2861 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2862 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2864 (cond [(eq_attr "alternative" "0,2")
2866 (match_test "optimize_function_for_size_p (cfun)")
2867 (const_string "V4SF")
2868 (const_string "TI"))
2869 (eq_attr "alternative" "1")
2871 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
2872 (match_test "optimize_function_for_size_p (cfun)"))
2873 (const_string "V4SF")
2874 (const_string "TI"))]
2875 (const_string "DI")))])
2877 ;; Possible store forwarding (partial memory) stall in alternative 4.
2878 (define_insn "*movxf_internal"
2879 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2880 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,FYx*r"))]
2881 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2882 && (!can_create_pseudo_p ()
2883 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2884 || GET_CODE (operands[1]) != CONST_DOUBLE
2885 || (optimize_function_for_size_p (cfun)
2886 && standard_80387_constant_p (operands[1]) > 0
2887 && !memory_operand (operands[0], XFmode))
2888 || (!TARGET_MEMORY_MISMATCH_STALL
2889 && memory_operand (operands[0], XFmode)))"
2891 switch (which_alternative)
2895 return output_387_reg_move (insn, operands);
2898 return standard_80387_constant_opcode (operands[1]);
2908 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2909 (set_attr "mode" "XF,XF,XF,SI,SI")])
2911 (define_insn "*movdf_internal_rex64"
2912 [(set (match_operand:DF 0 "nonimmediate_operand"
2913 "=f,m,f,?r,?m,?r,!o,x,x,x,m,Yi,r ")
2914 (match_operand:DF 1 "general_operand"
2915 "fm,f,G,rm,r ,F ,F ,C,x,m,x,r ,Yi"))]
2916 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2917 && (!can_create_pseudo_p ()
2918 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2919 || GET_CODE (operands[1]) != CONST_DOUBLE
2920 || (optimize_function_for_size_p (cfun)
2921 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2922 && standard_80387_constant_p (operands[1]) > 0)
2923 || (TARGET_SSE2 && TARGET_SSE_MATH
2924 && standard_sse_constant_p (operands[1]))))
2925 || memory_operand (operands[0], DFmode))"
2927 switch (which_alternative)
2931 return output_387_reg_move (insn, operands);
2934 return standard_80387_constant_opcode (operands[1]);
2938 return "mov{q}\t{%1, %0|%0, %1}";
2941 return "movabs{q}\t{%1, %0|%0, %1}";
2947 return standard_sse_constant_opcode (insn, operands[1]);
2952 switch (get_attr_mode (insn))
2955 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2956 return "%vmovapd\t{%1, %0|%0, %1}";
2958 return "%vmovaps\t{%1, %0|%0, %1}";
2961 return "%vmovq\t{%1, %0|%0, %1}";
2963 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2964 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2965 return "%vmovsd\t{%1, %0|%0, %1}";
2967 return "%vmovlpd\t{%1, %d0|%d0, %1}";
2969 return "%vmovlps\t{%1, %d0|%d0, %1}";
2976 /* Handle broken assemblers that require movd instead of movq. */
2977 return "%vmovd\t{%1, %0|%0, %1}";
2984 (cond [(eq_attr "alternative" "0,1,2")
2985 (const_string "fmov")
2986 (eq_attr "alternative" "3,4,5")
2987 (const_string "imov")
2988 (eq_attr "alternative" "6")
2989 (const_string "multi")
2990 (eq_attr "alternative" "7")
2991 (const_string "sselog1")
2993 (const_string "ssemov")))
2996 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2998 (const_string "*")))
2999 (set (attr "length_immediate")
3001 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3003 (const_string "*")))
3004 (set (attr "prefix")
3005 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3006 (const_string "orig")
3007 (const_string "maybe_vex")))
3008 (set (attr "prefix_data16")
3009 (if_then_else (eq_attr "mode" "V1DF")
3011 (const_string "*")))
3013 (cond [(eq_attr "alternative" "0,1,2")
3015 (eq_attr "alternative" "3,4,5,6,11,12")
3018 /* xorps is one byte shorter. */
3019 (eq_attr "alternative" "7")
3020 (cond [(match_test "optimize_function_for_size_p (cfun)")
3021 (const_string "V4SF")
3022 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3025 (const_string "V2DF"))
3027 /* For architectures resolving dependencies on
3028 whole SSE registers use APD move to break dependency
3029 chains, otherwise use short move to avoid extra work.
3031 movaps encodes one byte shorter. */
3032 (eq_attr "alternative" "8")
3034 [(match_test "optimize_function_for_size_p (cfun)")
3035 (const_string "V4SF")
3036 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3037 (const_string "V2DF")
3039 (const_string "DF"))
3040 /* For architectures resolving dependencies on register
3041 parts we may avoid extra work to zero out upper part
3043 (eq_attr "alternative" "9")
3045 (match_test "TARGET_SSE_SPLIT_REGS")
3046 (const_string "V1DF")
3047 (const_string "DF"))
3049 (const_string "DF")))])
3051 ;; Possible store forwarding (partial memory) stall in alternative 4.
3052 (define_insn "*movdf_internal"
3053 [(set (match_operand:DF 0 "nonimmediate_operand"
3054 "=f,m,f,?Yd*r ,!o ,x,x,x,m,*x,*x,*x,m")
3055 (match_operand:DF 1 "general_operand"
3056 "fm,f,G,Yd*roF,FYd*r,C,x,m,x,C ,*x,m ,*x"))]
3057 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3058 && (!can_create_pseudo_p ()
3059 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3060 || GET_CODE (operands[1]) != CONST_DOUBLE
3061 || (optimize_function_for_size_p (cfun)
3062 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3063 && standard_80387_constant_p (operands[1]) > 0)
3064 || (TARGET_SSE2 && TARGET_SSE_MATH
3065 && standard_sse_constant_p (operands[1])))
3066 && !memory_operand (operands[0], DFmode))
3067 || (!TARGET_MEMORY_MISMATCH_STALL
3068 && memory_operand (operands[0], DFmode)))"
3070 switch (which_alternative)
3074 return output_387_reg_move (insn, operands);
3077 return standard_80387_constant_opcode (operands[1]);
3085 return standard_sse_constant_opcode (insn, operands[1]);
3093 switch (get_attr_mode (insn))
3096 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3097 return "%vmovapd\t{%1, %0|%0, %1}";
3099 return "%vmovaps\t{%1, %0|%0, %1}";
3102 return "%vmovq\t{%1, %0|%0, %1}";
3104 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3105 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3106 return "%vmovsd\t{%1, %0|%0, %1}";
3108 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3110 return "%vmovlps\t{%1, %d0|%d0, %1}";
3120 (if_then_else (eq_attr "alternative" "5,6,7,8")
3121 (const_string "sse2")
3122 (const_string "*")))
3124 (cond [(eq_attr "alternative" "0,1,2")
3125 (const_string "fmov")
3126 (eq_attr "alternative" "3,4")
3127 (const_string "multi")
3128 (eq_attr "alternative" "5,9")
3129 (const_string "sselog1")
3131 (const_string "ssemov")))
3132 (set (attr "prefix")
3133 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3134 (const_string "orig")
3135 (const_string "maybe_vex")))
3136 (set (attr "prefix_data16")
3137 (if_then_else (eq_attr "mode" "V1DF")
3139 (const_string "*")))
3141 (cond [(eq_attr "alternative" "0,1,2")
3143 (eq_attr "alternative" "3,4")
3146 /* For SSE1, we have many fewer alternatives. */
3147 (not (match_test "TARGET_SSE2"))
3149 (eq_attr "alternative" "5,6,9,10")
3150 (const_string "V4SF")
3151 (const_string "V2SF"))
3153 /* xorps is one byte shorter. */
3154 (eq_attr "alternative" "5,9")
3155 (cond [(match_test "optimize_function_for_size_p (cfun)")
3156 (const_string "V4SF")
3157 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3160 (const_string "V2DF"))
3162 /* For architectures resolving dependencies on
3163 whole SSE registers use APD move to break dependency
3164 chains, otherwise use short move to avoid extra work.
3166 movaps encodes one byte shorter. */
3167 (eq_attr "alternative" "6,10")
3169 [(match_test "optimize_function_for_size_p (cfun)")
3170 (const_string "V4SF")
3171 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3172 (const_string "V2DF")
3174 (const_string "DF"))
3175 /* For architectures resolving dependencies on register
3176 parts we may avoid extra work to zero out upper part
3178 (eq_attr "alternative" "7,11")
3180 (match_test "TARGET_SSE_SPLIT_REGS")
3181 (const_string "V1DF")
3182 (const_string "DF"))
3184 (const_string "DF")))])
3186 (define_insn "*movsf_internal"
3187 [(set (match_operand:SF 0 "nonimmediate_operand"
3188 "=f,m,f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3189 (match_operand:SF 1 "general_operand"
3190 "fm,f,G,rmF,Fr,C,x,m,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3191 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3192 && (!can_create_pseudo_p ()
3193 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3194 || GET_CODE (operands[1]) != CONST_DOUBLE
3195 || (optimize_function_for_size_p (cfun)
3196 && ((!TARGET_SSE_MATH
3197 && standard_80387_constant_p (operands[1]) > 0)
3199 && standard_sse_constant_p (operands[1]))))
3200 || memory_operand (operands[0], SFmode))"
3202 switch (which_alternative)
3206 return output_387_reg_move (insn, operands);
3209 return standard_80387_constant_opcode (operands[1]);
3213 return "mov{l}\t{%1, %0|%0, %1}";
3216 return standard_sse_constant_opcode (insn, operands[1]);
3219 if (get_attr_mode (insn) == MODE_V4SF)
3220 return "%vmovaps\t{%1, %0|%0, %1}";
3222 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3226 return "%vmovss\t{%1, %0|%0, %1}";
3232 return "movd\t{%1, %0|%0, %1}";
3235 return "movq\t{%1, %0|%0, %1}";
3239 return "%vmovd\t{%1, %0|%0, %1}";
3246 (cond [(eq_attr "alternative" "0,1,2")
3247 (const_string "fmov")
3248 (eq_attr "alternative" "3,4")
3249 (const_string "multi")
3250 (eq_attr "alternative" "5")
3251 (const_string "sselog1")
3252 (eq_attr "alternative" "9,10,11,14,15")
3253 (const_string "mmxmov")
3255 (const_string "ssemov")))
3256 (set (attr "prefix")
3257 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3258 (const_string "maybe_vex")
3259 (const_string "orig")))
3261 (cond [(eq_attr "alternative" "3,4,9,10")
3263 (eq_attr "alternative" "5")
3265 (and (and (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3266 (match_test "TARGET_SSE2"))
3267 (not (match_test "optimize_function_for_size_p (cfun)")))
3269 (const_string "V4SF"))
3270 /* For architectures resolving dependencies on
3271 whole SSE registers use APS move to break dependency
3272 chains, otherwise use short move to avoid extra work.
3274 Do the same for architectures resolving dependencies on
3275 the parts. While in DF mode it is better to always handle
3276 just register parts, the SF mode is different due to lack
3277 of instructions to load just part of the register. It is
3278 better to maintain the whole registers in single format
3279 to avoid problems on using packed logical operations. */
3280 (eq_attr "alternative" "6")
3282 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3283 (match_test "TARGET_SSE_SPLIT_REGS"))
3284 (const_string "V4SF")
3285 (const_string "SF"))
3286 (eq_attr "alternative" "11")
3287 (const_string "DI")]
3288 (const_string "SF")))])
3291 [(set (match_operand 0 "any_fp_register_operand")
3292 (match_operand 1 "memory_operand"))]
3294 && (GET_MODE (operands[0]) == TFmode
3295 || GET_MODE (operands[0]) == XFmode
3296 || GET_MODE (operands[0]) == DFmode
3297 || GET_MODE (operands[0]) == SFmode)
3298 && (operands[2] = find_constant_src (insn))"
3299 [(set (match_dup 0) (match_dup 2))]
3301 rtx c = operands[2];
3302 int r = REGNO (operands[0]);
3304 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3305 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3310 [(set (match_operand 0 "any_fp_register_operand")
3311 (float_extend (match_operand 1 "memory_operand")))]
3313 && (GET_MODE (operands[0]) == TFmode
3314 || GET_MODE (operands[0]) == XFmode
3315 || GET_MODE (operands[0]) == DFmode)
3316 && (operands[2] = find_constant_src (insn))"
3317 [(set (match_dup 0) (match_dup 2))]
3319 rtx c = operands[2];
3320 int r = REGNO (operands[0]);
3322 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3323 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3327 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3329 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3330 (match_operand:X87MODEF 1 "immediate_operand"))]
3332 && (standard_80387_constant_p (operands[1]) == 8
3333 || standard_80387_constant_p (operands[1]) == 9)"
3334 [(set (match_dup 0)(match_dup 1))
3336 (neg:X87MODEF (match_dup 0)))]
3340 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3341 if (real_isnegzero (&r))
3342 operands[1] = CONST0_RTX (<MODE>mode);
3344 operands[1] = CONST1_RTX (<MODE>mode);
3348 [(set (match_operand 0 "nonimmediate_operand")
3349 (match_operand 1 "general_operand"))]
3351 && (GET_MODE (operands[0]) == TFmode
3352 || GET_MODE (operands[0]) == XFmode
3353 || GET_MODE (operands[0]) == DFmode)
3354 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3356 "ix86_split_long_move (operands); DONE;")
3358 (define_insn "swapxf"
3359 [(set (match_operand:XF 0 "register_operand" "+f")
3360 (match_operand:XF 1 "register_operand" "+f"))
3365 if (STACK_TOP_P (operands[0]))
3370 [(set_attr "type" "fxch")
3371 (set_attr "mode" "XF")])
3373 (define_insn "*swap<mode>"
3374 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3375 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3378 "TARGET_80387 || reload_completed"
3380 if (STACK_TOP_P (operands[0]))
3385 [(set_attr "type" "fxch")
3386 (set_attr "mode" "<MODE>")])
3388 ;; Zero extension instructions
3390 (define_expand "zero_extendsidi2"
3391 [(set (match_operand:DI 0 "nonimmediate_operand")
3392 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3394 (define_insn "*zero_extendsidi2_rex64"
3395 [(set (match_operand:DI 0 "nonimmediate_operand"
3396 "=r ,o,?*Ym,?*y,?*Yi,!*x")
3398 (match_operand:SI 1 "x86_64_zext_general_operand"
3399 "rmWz,0,r ,m ,r ,m*x")))]
3402 mov{l}\t{%1, %k0|%k0, %1}
3404 movd\t{%1, %0|%0, %1}
3405 movd\t{%1, %0|%0, %1}
3406 %vmovd\t{%1, %0|%0, %1}
3407 %vmovd\t{%1, %0|%0, %1}"
3408 [(set_attr "isa" "*,*,*,*,*,sse2")
3409 (set_attr "type" "imovx,multi,mmxmov,mmxmov,ssemov,ssemov")
3410 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3411 (set_attr "prefix_0f" "0,*,*,*,*,*")
3412 (set_attr "mode" "SI,SI,DI,DI,TI,TI")])
3414 (define_insn "*zero_extendsidi2"
3415 [(set (match_operand:DI 0 "nonimmediate_operand"
3416 "=ro,?r,?o,?*Ym,?*y,?*Yi,!*x")
3417 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand"
3418 "0 ,rm,r ,r ,m ,r ,m*x")))]
3424 movd\t{%1, %0|%0, %1}
3425 movd\t{%1, %0|%0, %1}
3426 %vmovd\t{%1, %0|%0, %1}
3427 %vmovd\t{%1, %0|%0, %1}"
3428 [(set_attr "isa" "*,*,*,*,*,*,sse2")
3429 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3430 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3431 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3434 [(set (match_operand:DI 0 "memory_operand")
3435 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3437 [(set (match_dup 4) (const_int 0))]
3438 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3441 [(set (match_operand:DI 0 "register_operand")
3442 (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3443 "!TARGET_64BIT && reload_completed
3444 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3445 && true_regnum (operands[0]) == true_regnum (operands[1])"
3446 [(set (match_dup 4) (const_int 0))]
3447 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3450 [(set (match_operand:DI 0 "nonimmediate_operand")
3451 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3452 "!TARGET_64BIT && reload_completed
3453 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3454 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3455 [(set (match_dup 3) (match_dup 1))
3456 (set (match_dup 4) (const_int 0))]
3457 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3459 (define_insn "zero_extend<mode>di2"
3460 [(set (match_operand:DI 0 "register_operand" "=r")
3462 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3464 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3465 [(set_attr "type" "imovx")
3466 (set_attr "mode" "SI")])
3468 (define_expand "zero_extend<mode>si2"
3469 [(set (match_operand:SI 0 "register_operand")
3470 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3473 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3475 operands[1] = force_reg (<MODE>mode, operands[1]);
3476 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3481 (define_insn_and_split "zero_extend<mode>si2_and"
3482 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3484 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3485 (clobber (reg:CC FLAGS_REG))]
3486 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3488 "&& reload_completed"
3489 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3490 (clobber (reg:CC FLAGS_REG))])]
3492 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3494 ix86_expand_clear (operands[0]);
3496 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3497 emit_insn (gen_movstrict<mode>
3498 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3502 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3504 [(set_attr "type" "alu1")
3505 (set_attr "mode" "SI")])
3507 (define_insn "*zero_extend<mode>si2"
3508 [(set (match_operand:SI 0 "register_operand" "=r")
3510 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3511 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3512 "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3513 [(set_attr "type" "imovx")
3514 (set_attr "mode" "SI")])
3516 (define_expand "zero_extendqihi2"
3517 [(set (match_operand:HI 0 "register_operand")
3518 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3521 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3523 operands[1] = force_reg (QImode, operands[1]);
3524 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3529 (define_insn_and_split "zero_extendqihi2_and"
3530 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3531 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3532 (clobber (reg:CC FLAGS_REG))]
3533 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3535 "&& reload_completed"
3536 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3537 (clobber (reg:CC FLAGS_REG))])]
3539 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3541 ix86_expand_clear (operands[0]);
3543 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3544 emit_insn (gen_movstrictqi
3545 (gen_lowpart (QImode, operands[0]), operands[1]));
3549 operands[0] = gen_lowpart (SImode, operands[0]);
3551 [(set_attr "type" "alu1")
3552 (set_attr "mode" "SI")])
3554 ; zero extend to SImode to avoid partial register stalls
3555 (define_insn "*zero_extendqihi2"
3556 [(set (match_operand:HI 0 "register_operand" "=r")
3557 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3558 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3559 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3560 [(set_attr "type" "imovx")
3561 (set_attr "mode" "SI")])
3563 ;; Sign extension instructions
3565 (define_expand "extendsidi2"
3566 [(set (match_operand:DI 0 "register_operand")
3567 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3572 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3577 (define_insn "*extendsidi2_rex64"
3578 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3579 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3583 movs{lq|x}\t{%1, %0|%0, %1}"
3584 [(set_attr "type" "imovx")
3585 (set_attr "mode" "DI")
3586 (set_attr "prefix_0f" "0")
3587 (set_attr "modrm" "0,1")])
3589 (define_insn "extendsidi2_1"
3590 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3591 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3592 (clobber (reg:CC FLAGS_REG))
3593 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3597 ;; Extend to memory case when source register does die.
3599 [(set (match_operand:DI 0 "memory_operand")
3600 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3601 (clobber (reg:CC FLAGS_REG))
3602 (clobber (match_operand:SI 2 "register_operand"))]
3604 && dead_or_set_p (insn, operands[1])
3605 && !reg_mentioned_p (operands[1], operands[0]))"
3606 [(set (match_dup 3) (match_dup 1))
3607 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3608 (clobber (reg:CC FLAGS_REG))])
3609 (set (match_dup 4) (match_dup 1))]
3610 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3612 ;; Extend to memory case when source register does not die.
3614 [(set (match_operand:DI 0 "memory_operand")
3615 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3616 (clobber (reg:CC FLAGS_REG))
3617 (clobber (match_operand:SI 2 "register_operand"))]
3621 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3623 emit_move_insn (operands[3], operands[1]);
3625 /* Generate a cltd if possible and doing so it profitable. */
3626 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3627 && true_regnum (operands[1]) == AX_REG
3628 && true_regnum (operands[2]) == DX_REG)
3630 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3634 emit_move_insn (operands[2], operands[1]);
3635 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3637 emit_move_insn (operands[4], operands[2]);
3641 ;; Extend to register case. Optimize case where source and destination
3642 ;; registers match and cases where we can use cltd.
3644 [(set (match_operand:DI 0 "register_operand")
3645 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3646 (clobber (reg:CC FLAGS_REG))
3647 (clobber (match_scratch:SI 2))]
3651 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3653 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3654 emit_move_insn (operands[3], operands[1]);
3656 /* Generate a cltd if possible and doing so it profitable. */
3657 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3658 && true_regnum (operands[3]) == AX_REG
3659 && true_regnum (operands[4]) == DX_REG)
3661 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3665 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3666 emit_move_insn (operands[4], operands[1]);
3668 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3672 (define_insn "extend<mode>di2"
3673 [(set (match_operand:DI 0 "register_operand" "=r")
3675 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3677 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3678 [(set_attr "type" "imovx")
3679 (set_attr "mode" "DI")])
3681 (define_insn "extendhisi2"
3682 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3683 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3686 switch (get_attr_prefix_0f (insn))
3689 return "{cwtl|cwde}";
3691 return "movs{wl|x}\t{%1, %0|%0, %1}";
3694 [(set_attr "type" "imovx")
3695 (set_attr "mode" "SI")
3696 (set (attr "prefix_0f")
3697 ;; movsx is short decodable while cwtl is vector decoded.
3698 (if_then_else (and (eq_attr "cpu" "!k6")
3699 (eq_attr "alternative" "0"))
3701 (const_string "1")))
3703 (if_then_else (eq_attr "prefix_0f" "0")
3705 (const_string "1")))])
3707 (define_insn "*extendhisi2_zext"
3708 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3711 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3714 switch (get_attr_prefix_0f (insn))
3717 return "{cwtl|cwde}";
3719 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3722 [(set_attr "type" "imovx")
3723 (set_attr "mode" "SI")
3724 (set (attr "prefix_0f")
3725 ;; movsx is short decodable while cwtl is vector decoded.
3726 (if_then_else (and (eq_attr "cpu" "!k6")
3727 (eq_attr "alternative" "0"))
3729 (const_string "1")))
3731 (if_then_else (eq_attr "prefix_0f" "0")
3733 (const_string "1")))])
3735 (define_insn "extendqisi2"
3736 [(set (match_operand:SI 0 "register_operand" "=r")
3737 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3739 "movs{bl|x}\t{%1, %0|%0, %1}"
3740 [(set_attr "type" "imovx")
3741 (set_attr "mode" "SI")])
3743 (define_insn "*extendqisi2_zext"
3744 [(set (match_operand:DI 0 "register_operand" "=r")
3746 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3748 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3749 [(set_attr "type" "imovx")
3750 (set_attr "mode" "SI")])
3752 (define_insn "extendqihi2"
3753 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3754 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3757 switch (get_attr_prefix_0f (insn))
3760 return "{cbtw|cbw}";
3762 return "movs{bw|x}\t{%1, %0|%0, %1}";
3765 [(set_attr "type" "imovx")
3766 (set_attr "mode" "HI")
3767 (set (attr "prefix_0f")
3768 ;; movsx is short decodable while cwtl is vector decoded.
3769 (if_then_else (and (eq_attr "cpu" "!k6")
3770 (eq_attr "alternative" "0"))
3772 (const_string "1")))
3774 (if_then_else (eq_attr "prefix_0f" "0")
3776 (const_string "1")))])
3778 ;; Conversions between float and double.
3780 ;; These are all no-ops in the model used for the 80387.
3781 ;; So just emit moves.
3783 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3785 [(set (match_operand:DF 0 "push_operand")
3786 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3788 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3789 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3792 [(set (match_operand:XF 0 "push_operand")
3793 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3795 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3796 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3797 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3799 (define_expand "extendsfdf2"
3800 [(set (match_operand:DF 0 "nonimmediate_operand")
3801 (float_extend:DF (match_operand:SF 1 "general_operand")))]
3802 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3804 /* ??? Needed for compress_float_constant since all fp constants
3805 are TARGET_LEGITIMATE_CONSTANT_P. */
3806 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3808 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3809 && standard_80387_constant_p (operands[1]) > 0)
3811 operands[1] = simplify_const_unary_operation
3812 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3813 emit_move_insn_1 (operands[0], operands[1]);
3816 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3820 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3822 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3824 We do the conversion post reload to avoid producing of 128bit spills
3825 that might lead to ICE on 32bit target. The sequence unlikely combine
3828 [(set (match_operand:DF 0 "register_operand")
3830 (match_operand:SF 1 "nonimmediate_operand")))]
3831 "TARGET_USE_VECTOR_FP_CONVERTS
3832 && optimize_insn_for_speed_p ()
3833 && reload_completed && SSE_REG_P (operands[0])"
3838 (parallel [(const_int 0) (const_int 1)]))))]
3840 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3841 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3842 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3843 Try to avoid move when unpacking can be done in source. */
3844 if (REG_P (operands[1]))
3846 /* If it is unsafe to overwrite upper half of source, we need
3847 to move to destination and unpack there. */
3848 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3849 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3850 && true_regnum (operands[0]) != true_regnum (operands[1]))
3852 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3853 emit_move_insn (tmp, operands[1]);
3856 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3857 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3861 emit_insn (gen_vec_setv4sf_0 (operands[3],
3862 CONST0_RTX (V4SFmode), operands[1]));
3865 (define_insn "*extendsfdf2_mixed"
3866 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3868 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3869 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3871 switch (which_alternative)
3875 return output_387_reg_move (insn, operands);
3878 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3884 [(set_attr "type" "fmov,fmov,ssecvt")
3885 (set_attr "prefix" "orig,orig,maybe_vex")
3886 (set_attr "mode" "SF,XF,DF")])
3888 (define_insn "*extendsfdf2_sse"
3889 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3890 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3891 "TARGET_SSE2 && TARGET_SSE_MATH"
3892 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3893 [(set_attr "type" "ssecvt")
3894 (set_attr "prefix" "maybe_vex")
3895 (set_attr "mode" "DF")])
3897 (define_insn "*extendsfdf2_i387"
3898 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3899 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3901 "* return output_387_reg_move (insn, operands);"
3902 [(set_attr "type" "fmov")
3903 (set_attr "mode" "SF,XF")])
3905 (define_expand "extend<mode>xf2"
3906 [(set (match_operand:XF 0 "nonimmediate_operand")
3907 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
3910 /* ??? Needed for compress_float_constant since all fp constants
3911 are TARGET_LEGITIMATE_CONSTANT_P. */
3912 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3914 if (standard_80387_constant_p (operands[1]) > 0)
3916 operands[1] = simplify_const_unary_operation
3917 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3918 emit_move_insn_1 (operands[0], operands[1]);
3921 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3925 (define_insn "*extend<mode>xf2_i387"
3926 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3928 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3930 "* return output_387_reg_move (insn, operands);"
3931 [(set_attr "type" "fmov")
3932 (set_attr "mode" "<MODE>,XF")])
3934 ;; %%% This seems bad bad news.
3935 ;; This cannot output into an f-reg because there is no way to be sure
3936 ;; of truncating in that case. Otherwise this is just like a simple move
3937 ;; insn. So we pretend we can output to a reg in order to get better
3938 ;; register preferencing, but we really use a stack slot.
3940 ;; Conversion from DFmode to SFmode.
3942 (define_expand "truncdfsf2"
3943 [(set (match_operand:SF 0 "nonimmediate_operand")
3945 (match_operand:DF 1 "nonimmediate_operand")))]
3946 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3948 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3950 else if (flag_unsafe_math_optimizations)
3954 enum ix86_stack_slot slot = (virtuals_instantiated
3957 rtx temp = assign_386_stack_local (SFmode, slot);
3958 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3963 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
3965 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3967 We do the conversion post reload to avoid producing of 128bit spills
3968 that might lead to ICE on 32bit target. The sequence unlikely combine
3971 [(set (match_operand:SF 0 "register_operand")
3973 (match_operand:DF 1 "nonimmediate_operand")))]
3974 "TARGET_USE_VECTOR_FP_CONVERTS
3975 && optimize_insn_for_speed_p ()
3976 && reload_completed && SSE_REG_P (operands[0])"
3979 (float_truncate:V2SF
3983 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3984 operands[3] = CONST0_RTX (V2SFmode);
3985 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
3986 /* Use movsd for loading from memory, unpcklpd for registers.
3987 Try to avoid move when unpacking can be done in source, or SSE3
3988 movddup is available. */
3989 if (REG_P (operands[1]))
3992 && true_regnum (operands[0]) != true_regnum (operands[1])
3993 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3994 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
3996 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
3997 emit_move_insn (tmp, operands[1]);
4000 else if (!TARGET_SSE3)
4001 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4002 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4005 emit_insn (gen_sse2_loadlpd (operands[4],
4006 CONST0_RTX (V2DFmode), operands[1]));
4009 (define_expand "truncdfsf2_with_temp"
4010 [(parallel [(set (match_operand:SF 0)
4011 (float_truncate:SF (match_operand:DF 1)))
4012 (clobber (match_operand:SF 2))])])
4014 (define_insn "*truncdfsf_fast_mixed"
4015 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4017 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4018 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4020 switch (which_alternative)
4023 return output_387_reg_move (insn, operands);
4025 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4030 [(set_attr "type" "fmov,ssecvt")
4031 (set_attr "prefix" "orig,maybe_vex")
4032 (set_attr "mode" "SF")])
4034 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4035 ;; because nothing we do here is unsafe.
4036 (define_insn "*truncdfsf_fast_sse"
4037 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4039 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4040 "TARGET_SSE2 && TARGET_SSE_MATH"
4041 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4042 [(set_attr "type" "ssecvt")
4043 (set_attr "prefix" "maybe_vex")
4044 (set_attr "mode" "SF")])
4046 (define_insn "*truncdfsf_fast_i387"
4047 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4049 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4050 "TARGET_80387 && flag_unsafe_math_optimizations"
4051 "* return output_387_reg_move (insn, operands);"
4052 [(set_attr "type" "fmov")
4053 (set_attr "mode" "SF")])
4055 (define_insn "*truncdfsf_mixed"
4056 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4058 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4059 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4060 "TARGET_MIX_SSE_I387"
4062 switch (which_alternative)
4065 return output_387_reg_move (insn, operands);
4067 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4073 [(set_attr "isa" "*,sse2,*,*,*")
4074 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4075 (set_attr "unit" "*,*,i387,i387,i387")
4076 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4077 (set_attr "mode" "SF")])
4079 (define_insn "*truncdfsf_i387"
4080 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4082 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4083 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4086 switch (which_alternative)
4089 return output_387_reg_move (insn, operands);
4095 [(set_attr "type" "fmov,multi,multi,multi")
4096 (set_attr "unit" "*,i387,i387,i387")
4097 (set_attr "mode" "SF")])
4099 (define_insn "*truncdfsf2_i387_1"
4100 [(set (match_operand:SF 0 "memory_operand" "=m")
4102 (match_operand:DF 1 "register_operand" "f")))]
4104 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4105 && !TARGET_MIX_SSE_I387"
4106 "* return output_387_reg_move (insn, operands);"
4107 [(set_attr "type" "fmov")
4108 (set_attr "mode" "SF")])
4111 [(set (match_operand:SF 0 "register_operand")
4113 (match_operand:DF 1 "fp_register_operand")))
4114 (clobber (match_operand 2))]
4116 [(set (match_dup 2) (match_dup 1))
4117 (set (match_dup 0) (match_dup 2))]
4118 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4120 ;; Conversion from XFmode to {SF,DF}mode
4122 (define_expand "truncxf<mode>2"
4123 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4124 (float_truncate:MODEF
4125 (match_operand:XF 1 "register_operand")))
4126 (clobber (match_dup 2))])]
4129 if (flag_unsafe_math_optimizations)
4131 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4132 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4133 if (reg != operands[0])
4134 emit_move_insn (operands[0], reg);
4139 enum ix86_stack_slot slot = (virtuals_instantiated
4142 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4146 (define_insn "*truncxfsf2_mixed"
4147 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4149 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4150 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4153 gcc_assert (!which_alternative);
4154 return output_387_reg_move (insn, operands);
4156 [(set_attr "type" "fmov,multi,multi,multi")
4157 (set_attr "unit" "*,i387,i387,i387")
4158 (set_attr "mode" "SF")])
4160 (define_insn "*truncxfdf2_mixed"
4161 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4163 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4164 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4167 gcc_assert (!which_alternative);
4168 return output_387_reg_move (insn, operands);
4170 [(set_attr "isa" "*,*,sse2,*")
4171 (set_attr "type" "fmov,multi,multi,multi")
4172 (set_attr "unit" "*,i387,i387,i387")
4173 (set_attr "mode" "DF")])
4175 (define_insn "truncxf<mode>2_i387_noop"
4176 [(set (match_operand:MODEF 0 "register_operand" "=f")
4177 (float_truncate:MODEF
4178 (match_operand:XF 1 "register_operand" "f")))]
4179 "TARGET_80387 && flag_unsafe_math_optimizations"
4180 "* return output_387_reg_move (insn, operands);"
4181 [(set_attr "type" "fmov")
4182 (set_attr "mode" "<MODE>")])
4184 (define_insn "*truncxf<mode>2_i387"
4185 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4186 (float_truncate:MODEF
4187 (match_operand:XF 1 "register_operand" "f")))]
4189 "* return output_387_reg_move (insn, operands);"
4190 [(set_attr "type" "fmov")
4191 (set_attr "mode" "<MODE>")])
4194 [(set (match_operand:MODEF 0 "register_operand")
4195 (float_truncate:MODEF
4196 (match_operand:XF 1 "register_operand")))
4197 (clobber (match_operand:MODEF 2 "memory_operand"))]
4198 "TARGET_80387 && reload_completed"
4199 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4200 (set (match_dup 0) (match_dup 2))])
4203 [(set (match_operand:MODEF 0 "memory_operand")
4204 (float_truncate:MODEF
4205 (match_operand:XF 1 "register_operand")))
4206 (clobber (match_operand:MODEF 2 "memory_operand"))]
4208 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4210 ;; Signed conversion to DImode.
4212 (define_expand "fix_truncxfdi2"
4213 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4214 (fix:DI (match_operand:XF 1 "register_operand")))
4215 (clobber (reg:CC FLAGS_REG))])]
4220 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4225 (define_expand "fix_trunc<mode>di2"
4226 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4227 (fix:DI (match_operand:MODEF 1 "register_operand")))
4228 (clobber (reg:CC FLAGS_REG))])]
4229 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4232 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4234 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4237 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4239 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4240 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4241 if (out != operands[0])
4242 emit_move_insn (operands[0], out);
4247 ;; Signed conversion to SImode.
4249 (define_expand "fix_truncxfsi2"
4250 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4251 (fix:SI (match_operand:XF 1 "register_operand")))
4252 (clobber (reg:CC FLAGS_REG))])]
4257 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4262 (define_expand "fix_trunc<mode>si2"
4263 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4264 (fix:SI (match_operand:MODEF 1 "register_operand")))
4265 (clobber (reg:CC FLAGS_REG))])]
4266 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4269 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4271 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4274 if (SSE_FLOAT_MODE_P (<MODE>mode))
4276 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4277 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4278 if (out != operands[0])
4279 emit_move_insn (operands[0], out);
4284 ;; Signed conversion to HImode.
4286 (define_expand "fix_trunc<mode>hi2"
4287 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4288 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4289 (clobber (reg:CC FLAGS_REG))])]
4291 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4295 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4300 ;; Unsigned conversion to SImode.
4302 (define_expand "fixuns_trunc<mode>si2"
4304 [(set (match_operand:SI 0 "register_operand")
4306 (match_operand:MODEF 1 "nonimmediate_operand")))
4308 (clobber (match_scratch:<ssevecmode> 3))
4309 (clobber (match_scratch:<ssevecmode> 4))])]
4310 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4312 enum machine_mode mode = <MODE>mode;
4313 enum machine_mode vecmode = <ssevecmode>mode;
4314 REAL_VALUE_TYPE TWO31r;
4317 if (optimize_insn_for_size_p ())
4320 real_ldexp (&TWO31r, &dconst1, 31);
4321 two31 = const_double_from_real_value (TWO31r, mode);
4322 two31 = ix86_build_const_vector (vecmode, true, two31);
4323 operands[2] = force_reg (vecmode, two31);
4326 (define_insn_and_split "*fixuns_trunc<mode>_1"
4327 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4329 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4330 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4331 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4332 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4333 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4334 && optimize_function_for_speed_p (cfun)"
4336 "&& reload_completed"
4339 ix86_split_convert_uns_si_sse (operands);
4343 ;; Unsigned conversion to HImode.
4344 ;; Without these patterns, we'll try the unsigned SI conversion which
4345 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4347 (define_expand "fixuns_trunc<mode>hi2"
4349 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4350 (set (match_operand:HI 0 "nonimmediate_operand")
4351 (subreg:HI (match_dup 2) 0))]
4352 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4353 "operands[2] = gen_reg_rtx (SImode);")
4355 ;; When SSE is available, it is always faster to use it!
4356 (define_insn "fix_trunc<mode>di_sse"
4357 [(set (match_operand:DI 0 "register_operand" "=r,r")
4358 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4359 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4360 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4361 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4362 [(set_attr "type" "sseicvt")
4363 (set_attr "prefix" "maybe_vex")
4364 (set_attr "prefix_rex" "1")
4365 (set_attr "mode" "<MODE>")
4366 (set_attr "athlon_decode" "double,vector")
4367 (set_attr "amdfam10_decode" "double,double")
4368 (set_attr "bdver1_decode" "double,double")])
4370 (define_insn "fix_trunc<mode>si_sse"
4371 [(set (match_operand:SI 0 "register_operand" "=r,r")
4372 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4373 "SSE_FLOAT_MODE_P (<MODE>mode)
4374 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4375 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4376 [(set_attr "type" "sseicvt")
4377 (set_attr "prefix" "maybe_vex")
4378 (set_attr "mode" "<MODE>")
4379 (set_attr "athlon_decode" "double,vector")
4380 (set_attr "amdfam10_decode" "double,double")
4381 (set_attr "bdver1_decode" "double,double")])
4383 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4385 [(set (match_operand:MODEF 0 "register_operand")
4386 (match_operand:MODEF 1 "memory_operand"))
4387 (set (match_operand:SWI48x 2 "register_operand")
4388 (fix:SWI48x (match_dup 0)))]
4389 "TARGET_SHORTEN_X87_SSE
4390 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4391 && peep2_reg_dead_p (2, operands[0])"
4392 [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4394 ;; Avoid vector decoded forms of the instruction.
4396 [(match_scratch:DF 2 "x")
4397 (set (match_operand:SWI48x 0 "register_operand")
4398 (fix:SWI48x (match_operand:DF 1 "memory_operand")))]
4399 "TARGET_SSE2 && TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4400 [(set (match_dup 2) (match_dup 1))
4401 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4404 [(match_scratch:SF 2 "x")
4405 (set (match_operand:SWI48x 0 "register_operand")
4406 (fix:SWI48x (match_operand:SF 1 "memory_operand")))]
4407 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4408 [(set (match_dup 2) (match_dup 1))
4409 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4411 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4412 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4413 (fix:SWI248x (match_operand 1 "register_operand")))]
4414 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4416 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4417 && (TARGET_64BIT || <MODE>mode != DImode))
4419 && can_create_pseudo_p ()"
4424 if (memory_operand (operands[0], VOIDmode))
4425 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4428 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4429 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4435 [(set_attr "type" "fisttp")
4436 (set_attr "mode" "<MODE>")])
4438 (define_insn "fix_trunc<mode>_i387_fisttp"
4439 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4440 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4441 (clobber (match_scratch:XF 2 "=&1f"))]
4442 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4444 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4445 && (TARGET_64BIT || <MODE>mode != DImode))
4446 && TARGET_SSE_MATH)"
4447 "* return output_fix_trunc (insn, operands, true);"
4448 [(set_attr "type" "fisttp")
4449 (set_attr "mode" "<MODE>")])
4451 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4452 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4453 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4454 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4455 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4456 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4458 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4459 && (TARGET_64BIT || <MODE>mode != DImode))
4460 && TARGET_SSE_MATH)"
4462 [(set_attr "type" "fisttp")
4463 (set_attr "mode" "<MODE>")])
4466 [(set (match_operand:SWI248x 0 "register_operand")
4467 (fix:SWI248x (match_operand 1 "register_operand")))
4468 (clobber (match_operand:SWI248x 2 "memory_operand"))
4469 (clobber (match_scratch 3))]
4471 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4472 (clobber (match_dup 3))])
4473 (set (match_dup 0) (match_dup 2))])
4476 [(set (match_operand:SWI248x 0 "memory_operand")
4477 (fix:SWI248x (match_operand 1 "register_operand")))
4478 (clobber (match_operand:SWI248x 2 "memory_operand"))
4479 (clobber (match_scratch 3))]
4481 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4482 (clobber (match_dup 3))])])
4484 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4485 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4486 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4487 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4488 ;; function in i386.c.
4489 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4490 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4491 (fix:SWI248x (match_operand 1 "register_operand")))
4492 (clobber (reg:CC FLAGS_REG))]
4493 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4495 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4496 && (TARGET_64BIT || <MODE>mode != DImode))
4497 && can_create_pseudo_p ()"
4502 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4504 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4505 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4506 if (memory_operand (operands[0], VOIDmode))
4507 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4508 operands[2], operands[3]));
4511 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4512 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4513 operands[2], operands[3],
4518 [(set_attr "type" "fistp")
4519 (set_attr "i387_cw" "trunc")
4520 (set_attr "mode" "<MODE>")])
4522 (define_insn "fix_truncdi_i387"
4523 [(set (match_operand:DI 0 "memory_operand" "=m")
4524 (fix:DI (match_operand 1 "register_operand" "f")))
4525 (use (match_operand:HI 2 "memory_operand" "m"))
4526 (use (match_operand:HI 3 "memory_operand" "m"))
4527 (clobber (match_scratch:XF 4 "=&1f"))]
4528 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4530 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4531 "* return output_fix_trunc (insn, operands, false);"
4532 [(set_attr "type" "fistp")
4533 (set_attr "i387_cw" "trunc")
4534 (set_attr "mode" "DI")])
4536 (define_insn "fix_truncdi_i387_with_temp"
4537 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4538 (fix:DI (match_operand 1 "register_operand" "f,f")))
4539 (use (match_operand:HI 2 "memory_operand" "m,m"))
4540 (use (match_operand:HI 3 "memory_operand" "m,m"))
4541 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4542 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4543 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4545 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4547 [(set_attr "type" "fistp")
4548 (set_attr "i387_cw" "trunc")
4549 (set_attr "mode" "DI")])
4552 [(set (match_operand:DI 0 "register_operand")
4553 (fix:DI (match_operand 1 "register_operand")))
4554 (use (match_operand:HI 2 "memory_operand"))
4555 (use (match_operand:HI 3 "memory_operand"))
4556 (clobber (match_operand:DI 4 "memory_operand"))
4557 (clobber (match_scratch 5))]
4559 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4562 (clobber (match_dup 5))])
4563 (set (match_dup 0) (match_dup 4))])
4566 [(set (match_operand:DI 0 "memory_operand")
4567 (fix:DI (match_operand 1 "register_operand")))
4568 (use (match_operand:HI 2 "memory_operand"))
4569 (use (match_operand:HI 3 "memory_operand"))
4570 (clobber (match_operand:DI 4 "memory_operand"))
4571 (clobber (match_scratch 5))]
4573 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4576 (clobber (match_dup 5))])])
4578 (define_insn "fix_trunc<mode>_i387"
4579 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4580 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4581 (use (match_operand:HI 2 "memory_operand" "m"))
4582 (use (match_operand:HI 3 "memory_operand" "m"))]
4583 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4585 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4586 "* return output_fix_trunc (insn, operands, false);"
4587 [(set_attr "type" "fistp")
4588 (set_attr "i387_cw" "trunc")
4589 (set_attr "mode" "<MODE>")])
4591 (define_insn "fix_trunc<mode>_i387_with_temp"
4592 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4593 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4594 (use (match_operand:HI 2 "memory_operand" "m,m"))
4595 (use (match_operand:HI 3 "memory_operand" "m,m"))
4596 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4597 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4599 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4601 [(set_attr "type" "fistp")
4602 (set_attr "i387_cw" "trunc")
4603 (set_attr "mode" "<MODE>")])
4606 [(set (match_operand:SWI24 0 "register_operand")
4607 (fix:SWI24 (match_operand 1 "register_operand")))
4608 (use (match_operand:HI 2 "memory_operand"))
4609 (use (match_operand:HI 3 "memory_operand"))
4610 (clobber (match_operand:SWI24 4 "memory_operand"))]
4612 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4614 (use (match_dup 3))])
4615 (set (match_dup 0) (match_dup 4))])
4618 [(set (match_operand:SWI24 0 "memory_operand")
4619 (fix:SWI24 (match_operand 1 "register_operand")))
4620 (use (match_operand:HI 2 "memory_operand"))
4621 (use (match_operand:HI 3 "memory_operand"))
4622 (clobber (match_operand:SWI24 4 "memory_operand"))]
4624 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4626 (use (match_dup 3))])])
4628 (define_insn "x86_fnstcw_1"
4629 [(set (match_operand:HI 0 "memory_operand" "=m")
4630 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4633 [(set (attr "length")
4634 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4635 (set_attr "mode" "HI")
4636 (set_attr "unit" "i387")
4637 (set_attr "bdver1_decode" "vector")])
4639 (define_insn "x86_fldcw_1"
4640 [(set (reg:HI FPCR_REG)
4641 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4644 [(set (attr "length")
4645 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4646 (set_attr "mode" "HI")
4647 (set_attr "unit" "i387")
4648 (set_attr "athlon_decode" "vector")
4649 (set_attr "amdfam10_decode" "vector")
4650 (set_attr "bdver1_decode" "vector")])
4652 ;; Conversion between fixed point and floating point.
4654 ;; Even though we only accept memory inputs, the backend _really_
4655 ;; wants to be able to do this between registers.
4657 (define_expand "floathi<mode>2"
4658 [(set (match_operand:X87MODEF 0 "register_operand")
4659 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand")))]
4661 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4662 || TARGET_MIX_SSE_I387)")
4664 ;; Pre-reload splitter to add memory clobber to the pattern.
4665 (define_insn_and_split "*floathi<mode>2_1"
4666 [(set (match_operand:X87MODEF 0 "register_operand")
4667 (float:X87MODEF (match_operand:HI 1 "register_operand")))]
4669 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4670 || TARGET_MIX_SSE_I387)
4671 && can_create_pseudo_p ()"
4674 [(parallel [(set (match_dup 0)
4675 (float:X87MODEF (match_dup 1)))
4676 (clobber (match_dup 2))])]
4677 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4679 (define_insn "*floathi<mode>2_i387_with_temp"
4680 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4681 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4682 (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4684 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4685 || TARGET_MIX_SSE_I387)"
4687 [(set_attr "type" "fmov,multi")
4688 (set_attr "mode" "<MODE>")
4689 (set_attr "unit" "*,i387")
4690 (set_attr "fp_int_src" "true")])
4692 (define_insn "*floathi<mode>2_i387"
4693 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4694 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4696 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4697 || TARGET_MIX_SSE_I387)"
4699 [(set_attr "type" "fmov")
4700 (set_attr "mode" "<MODE>")
4701 (set_attr "fp_int_src" "true")])
4704 [(set (match_operand:X87MODEF 0 "register_operand")
4705 (float:X87MODEF (match_operand:HI 1 "register_operand")))
4706 (clobber (match_operand:HI 2 "memory_operand"))]
4708 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4709 || TARGET_MIX_SSE_I387)
4710 && reload_completed"
4711 [(set (match_dup 2) (match_dup 1))
4712 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4715 [(set (match_operand:X87MODEF 0 "register_operand")
4716 (float:X87MODEF (match_operand:HI 1 "memory_operand")))
4717 (clobber (match_operand:HI 2 "memory_operand"))]
4719 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4720 || TARGET_MIX_SSE_I387)
4721 && reload_completed"
4722 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4724 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4725 [(set (match_operand:X87MODEF 0 "register_operand")
4727 (match_operand:SWI48x 1 "nonimmediate_operand")))]
4729 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4730 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4732 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4733 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4734 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4736 rtx reg = gen_reg_rtx (XFmode);
4737 rtx (*insn)(rtx, rtx);
4739 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4741 if (<X87MODEF:MODE>mode == SFmode)
4742 insn = gen_truncxfsf2;
4743 else if (<X87MODEF:MODE>mode == DFmode)
4744 insn = gen_truncxfdf2;
4748 emit_insn (insn (operands[0], reg));
4753 ;; Pre-reload splitter to add memory clobber to the pattern.
4754 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4755 [(set (match_operand:X87MODEF 0 "register_operand")
4756 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))]
4758 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4759 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4760 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4761 || TARGET_MIX_SSE_I387))
4762 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4763 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4764 && ((<SWI48x:MODE>mode == SImode
4765 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4766 && optimize_function_for_speed_p (cfun)
4767 && flag_trapping_math)
4768 || !(TARGET_INTER_UNIT_CONVERSIONS
4769 || optimize_function_for_size_p (cfun)))))
4770 && can_create_pseudo_p ()"
4773 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4774 (clobber (match_dup 2))])]
4776 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4778 /* Avoid store forwarding (partial memory) stall penalty
4779 by passing DImode value through XMM registers. */
4780 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4781 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4782 && optimize_function_for_speed_p (cfun))
4784 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4791 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4792 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4794 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4795 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4796 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4797 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4799 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4800 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4801 (set_attr "unit" "*,i387,*,*,*")
4802 (set_attr "athlon_decode" "*,*,double,direct,double")
4803 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4804 (set_attr "bdver1_decode" "*,*,double,direct,double")
4805 (set_attr "fp_int_src" "true")])
4807 (define_insn "*floatsi<mode>2_vector_mixed"
4808 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4809 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4810 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4811 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4815 [(set_attr "type" "fmov,sseicvt")
4816 (set_attr "mode" "<MODE>,<ssevecmode>")
4817 (set_attr "unit" "i387,*")
4818 (set_attr "athlon_decode" "*,direct")
4819 (set_attr "amdfam10_decode" "*,double")
4820 (set_attr "bdver1_decode" "*,direct")
4821 (set_attr "fp_int_src" "true")])
4823 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4824 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4826 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4827 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4828 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4829 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4831 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4832 (set_attr "mode" "<MODEF:MODE>")
4833 (set_attr "unit" "*,i387,*,*")
4834 (set_attr "athlon_decode" "*,*,double,direct")
4835 (set_attr "amdfam10_decode" "*,*,vector,double")
4836 (set_attr "bdver1_decode" "*,*,double,direct")
4837 (set_attr "fp_int_src" "true")])
4840 [(set (match_operand:MODEF 0 "register_operand")
4841 (float:MODEF (match_operand:SWI48x 1 "register_operand")))
4842 (clobber (match_operand:SWI48x 2 "memory_operand"))]
4843 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4844 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4845 && TARGET_INTER_UNIT_CONVERSIONS
4847 && (SSE_REG_P (operands[0])
4848 || (GET_CODE (operands[0]) == SUBREG
4849 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4850 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4853 [(set (match_operand:MODEF 0 "register_operand")
4854 (float:MODEF (match_operand:SWI48x 1 "register_operand")))
4855 (clobber (match_operand:SWI48x 2 "memory_operand"))]
4856 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4857 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4858 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4860 && (SSE_REG_P (operands[0])
4861 || (GET_CODE (operands[0]) == SUBREG
4862 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4863 [(set (match_dup 2) (match_dup 1))
4864 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4866 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4867 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4869 (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4870 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4871 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4872 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4875 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4876 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4877 [(set_attr "type" "fmov,sseicvt,sseicvt")
4878 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4879 (set_attr "mode" "<MODEF:MODE>")
4880 (set (attr "prefix_rex")
4882 (and (eq_attr "prefix" "maybe_vex")
4883 (match_test "<SWI48x:MODE>mode == DImode"))
4885 (const_string "*")))
4886 (set_attr "unit" "i387,*,*")
4887 (set_attr "athlon_decode" "*,double,direct")
4888 (set_attr "amdfam10_decode" "*,vector,double")
4889 (set_attr "bdver1_decode" "*,double,direct")
4890 (set_attr "fp_int_src" "true")])
4892 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4893 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4895 (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4896 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4897 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4898 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4901 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4902 [(set_attr "type" "fmov,sseicvt")
4903 (set_attr "prefix" "orig,maybe_vex")
4904 (set_attr "mode" "<MODEF:MODE>")
4905 (set (attr "prefix_rex")
4907 (and (eq_attr "prefix" "maybe_vex")
4908 (match_test "<SWI48x:MODE>mode == DImode"))
4910 (const_string "*")))
4911 (set_attr "athlon_decode" "*,direct")
4912 (set_attr "amdfam10_decode" "*,double")
4913 (set_attr "bdver1_decode" "*,direct")
4914 (set_attr "fp_int_src" "true")])
4916 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4917 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4919 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4920 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4921 "TARGET_SSE2 && TARGET_SSE_MATH
4922 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4924 [(set_attr "type" "sseicvt")
4925 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4926 (set_attr "athlon_decode" "double,direct,double")
4927 (set_attr "amdfam10_decode" "vector,double,double")
4928 (set_attr "bdver1_decode" "double,direct,double")
4929 (set_attr "fp_int_src" "true")])
4931 (define_insn "*floatsi<mode>2_vector_sse"
4932 [(set (match_operand:MODEF 0 "register_operand" "=x")
4933 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4934 "TARGET_SSE2 && TARGET_SSE_MATH
4935 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4937 [(set_attr "type" "sseicvt")
4938 (set_attr "mode" "<MODE>")
4939 (set_attr "athlon_decode" "direct")
4940 (set_attr "amdfam10_decode" "double")
4941 (set_attr "bdver1_decode" "direct")
4942 (set_attr "fp_int_src" "true")])
4945 [(set (match_operand:MODEF 0 "register_operand")
4946 (float:MODEF (match_operand:SI 1 "register_operand")))
4947 (clobber (match_operand:SI 2 "memory_operand"))]
4948 "TARGET_SSE2 && TARGET_SSE_MATH
4949 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4951 && (SSE_REG_P (operands[0])
4952 || (GET_CODE (operands[0]) == SUBREG
4953 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4956 rtx op1 = operands[1];
4958 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4960 if (GET_CODE (op1) == SUBREG)
4961 op1 = SUBREG_REG (op1);
4963 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
4965 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4966 emit_insn (gen_sse2_loadld (operands[4],
4967 CONST0_RTX (V4SImode), operands[1]));
4969 /* We can ignore possible trapping value in the
4970 high part of SSE register for non-trapping math. */
4971 else if (SSE_REG_P (op1) && !flag_trapping_math)
4972 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4975 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4976 emit_move_insn (operands[2], operands[1]);
4977 emit_insn (gen_sse2_loadld (operands[4],
4978 CONST0_RTX (V4SImode), operands[2]));
4980 if (<ssevecmode>mode == V4SFmode)
4981 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4983 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4988 [(set (match_operand:MODEF 0 "register_operand")
4989 (float:MODEF (match_operand:SI 1 "memory_operand")))
4990 (clobber (match_operand:SI 2 "memory_operand"))]
4991 "TARGET_SSE2 && TARGET_SSE_MATH
4992 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4994 && (SSE_REG_P (operands[0])
4995 || (GET_CODE (operands[0]) == SUBREG
4996 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4999 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5001 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5003 emit_insn (gen_sse2_loadld (operands[4],
5004 CONST0_RTX (V4SImode), operands[1]));
5005 if (<ssevecmode>mode == V4SFmode)
5006 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5008 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5013 [(set (match_operand:MODEF 0 "register_operand")
5014 (float:MODEF (match_operand:SI 1 "register_operand")))]
5015 "TARGET_SSE2 && TARGET_SSE_MATH
5016 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5018 && (SSE_REG_P (operands[0])
5019 || (GET_CODE (operands[0]) == SUBREG
5020 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5023 rtx op1 = operands[1];
5025 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5027 if (GET_CODE (op1) == SUBREG)
5028 op1 = SUBREG_REG (op1);
5030 if (GENERAL_REG_P (op1))
5032 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5033 if (TARGET_INTER_UNIT_MOVES)
5034 emit_insn (gen_sse2_loadld (operands[4],
5035 CONST0_RTX (V4SImode), operands[1]));
5038 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5040 emit_insn (gen_sse2_loadld (operands[4],
5041 CONST0_RTX (V4SImode), operands[5]));
5042 ix86_free_from_memory (GET_MODE (operands[1]));
5045 /* We can ignore possible trapping value in the
5046 high part of SSE register for non-trapping math. */
5047 else if (SSE_REG_P (op1) && !flag_trapping_math)
5048 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5051 if (<ssevecmode>mode == V4SFmode)
5052 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5054 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5059 [(set (match_operand:MODEF 0 "register_operand")
5060 (float:MODEF (match_operand:SI 1 "memory_operand")))]
5061 "TARGET_SSE2 && TARGET_SSE_MATH
5062 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5064 && (SSE_REG_P (operands[0])
5065 || (GET_CODE (operands[0]) == SUBREG
5066 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5069 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5071 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5073 emit_insn (gen_sse2_loadld (operands[4],
5074 CONST0_RTX (V4SImode), operands[1]));
5075 if (<ssevecmode>mode == V4SFmode)
5076 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5078 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5082 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5083 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5085 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5086 (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5087 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5088 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5090 [(set_attr "type" "sseicvt")
5091 (set_attr "mode" "<MODEF:MODE>")
5092 (set_attr "athlon_decode" "double,direct")
5093 (set_attr "amdfam10_decode" "vector,double")
5094 (set_attr "bdver1_decode" "double,direct")
5095 (set_attr "fp_int_src" "true")])
5097 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5098 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5100 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5101 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5102 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5103 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5104 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5105 [(set_attr "type" "sseicvt")
5106 (set_attr "prefix" "maybe_vex")
5107 (set_attr "mode" "<MODEF:MODE>")
5108 (set (attr "prefix_rex")
5110 (and (eq_attr "prefix" "maybe_vex")
5111 (match_test "<SWI48x:MODE>mode == DImode"))
5113 (const_string "*")))
5114 (set_attr "athlon_decode" "double,direct")
5115 (set_attr "amdfam10_decode" "vector,double")
5116 (set_attr "bdver1_decode" "double,direct")
5117 (set_attr "fp_int_src" "true")])
5120 [(set (match_operand:MODEF 0 "register_operand")
5121 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand")))
5122 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5123 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5124 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5125 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5127 && (SSE_REG_P (operands[0])
5128 || (GET_CODE (operands[0]) == SUBREG
5129 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5130 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5132 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5133 [(set (match_operand:MODEF 0 "register_operand" "=x")
5135 (match_operand:SWI48x 1 "memory_operand" "m")))]
5136 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5137 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5138 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5139 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5140 [(set_attr "type" "sseicvt")
5141 (set_attr "prefix" "maybe_vex")
5142 (set_attr "mode" "<MODEF:MODE>")
5143 (set (attr "prefix_rex")
5145 (and (eq_attr "prefix" "maybe_vex")
5146 (match_test "<SWI48x:MODE>mode == DImode"))
5148 (const_string "*")))
5149 (set_attr "athlon_decode" "direct")
5150 (set_attr "amdfam10_decode" "double")
5151 (set_attr "bdver1_decode" "direct")
5152 (set_attr "fp_int_src" "true")])
5155 [(set (match_operand:MODEF 0 "register_operand")
5156 (float:MODEF (match_operand:SWI48x 1 "register_operand")))
5157 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5158 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5159 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5160 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5162 && (SSE_REG_P (operands[0])
5163 || (GET_CODE (operands[0]) == SUBREG
5164 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5165 [(set (match_dup 2) (match_dup 1))
5166 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5169 [(set (match_operand:MODEF 0 "register_operand")
5170 (float:MODEF (match_operand:SWI48x 1 "memory_operand")))
5171 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5172 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5173 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5175 && (SSE_REG_P (operands[0])
5176 || (GET_CODE (operands[0]) == SUBREG
5177 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5178 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5180 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5181 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5183 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5184 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5186 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5190 [(set_attr "type" "fmov,multi")
5191 (set_attr "mode" "<X87MODEF:MODE>")
5192 (set_attr "unit" "*,i387")
5193 (set_attr "fp_int_src" "true")])
5195 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5196 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5198 (match_operand:SWI48x 1 "memory_operand" "m")))]
5200 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5202 [(set_attr "type" "fmov")
5203 (set_attr "mode" "<X87MODEF:MODE>")
5204 (set_attr "fp_int_src" "true")])
5207 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5208 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))
5209 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5211 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5212 && reload_completed"
5213 [(set (match_dup 2) (match_dup 1))
5214 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5217 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5218 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand")))
5219 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5221 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5222 && reload_completed"
5223 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5225 ;; Avoid store forwarding (partial memory) stall penalty
5226 ;; by passing DImode value through XMM registers. */
5228 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5229 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5231 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5232 (clobber (match_scratch:V4SI 3 "=X,x"))
5233 (clobber (match_scratch:V4SI 4 "=X,x"))
5234 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5235 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5236 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5237 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5239 [(set_attr "type" "multi")
5240 (set_attr "mode" "<X87MODEF:MODE>")
5241 (set_attr "unit" "i387")
5242 (set_attr "fp_int_src" "true")])
5245 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5246 (float:X87MODEF (match_operand:DI 1 "register_operand")))
5247 (clobber (match_scratch:V4SI 3))
5248 (clobber (match_scratch:V4SI 4))
5249 (clobber (match_operand:DI 2 "memory_operand"))]
5250 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5251 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5252 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5253 && reload_completed"
5254 [(set (match_dup 2) (match_dup 3))
5255 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5257 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5258 Assemble the 64-bit DImode value in an xmm register. */
5259 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5260 gen_rtx_SUBREG (SImode, operands[1], 0)));
5261 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5262 gen_rtx_SUBREG (SImode, operands[1], 4)));
5263 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5266 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5270 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5271 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5272 (clobber (match_scratch:V4SI 3))
5273 (clobber (match_scratch:V4SI 4))
5274 (clobber (match_operand:DI 2 "memory_operand"))]
5275 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5276 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5277 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5278 && reload_completed"
5279 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5281 ;; Avoid store forwarding (partial memory) stall penalty by extending
5282 ;; SImode value to DImode through XMM register instead of pushing two
5283 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5284 ;; targets benefit from this optimization. Also note that fild
5285 ;; loads from memory only.
5287 (define_insn "*floatunssi<mode>2_1"
5288 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5289 (unsigned_float:X87MODEF
5290 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5291 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5292 (clobber (match_scratch:SI 3 "=X,x"))]
5294 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5297 [(set_attr "type" "multi")
5298 (set_attr "mode" "<MODE>")])
5301 [(set (match_operand:X87MODEF 0 "register_operand")
5302 (unsigned_float:X87MODEF
5303 (match_operand:SI 1 "register_operand")))
5304 (clobber (match_operand:DI 2 "memory_operand"))
5305 (clobber (match_scratch:SI 3))]
5307 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5309 && reload_completed"
5310 [(set (match_dup 2) (match_dup 1))
5312 (float:X87MODEF (match_dup 2)))]
5313 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5316 [(set (match_operand:X87MODEF 0 "register_operand")
5317 (unsigned_float:X87MODEF
5318 (match_operand:SI 1 "memory_operand")))
5319 (clobber (match_operand:DI 2 "memory_operand"))
5320 (clobber (match_scratch:SI 3))]
5322 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5324 && reload_completed"
5325 [(set (match_dup 2) (match_dup 3))
5327 (float:X87MODEF (match_dup 2)))]
5329 emit_move_insn (operands[3], operands[1]);
5330 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5333 (define_expand "floatunssi<mode>2"
5335 [(set (match_operand:X87MODEF 0 "register_operand")
5336 (unsigned_float:X87MODEF
5337 (match_operand:SI 1 "nonimmediate_operand")))
5338 (clobber (match_dup 2))
5339 (clobber (match_scratch:SI 3))])]
5341 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5343 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5345 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5347 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5352 enum ix86_stack_slot slot = (virtuals_instantiated
5355 operands[2] = assign_386_stack_local (DImode, slot);
5359 (define_expand "floatunsdisf2"
5360 [(use (match_operand:SF 0 "register_operand"))
5361 (use (match_operand:DI 1 "nonimmediate_operand"))]
5362 "TARGET_64BIT && TARGET_SSE_MATH"
5363 "x86_emit_floatuns (operands); DONE;")
5365 (define_expand "floatunsdidf2"
5366 [(use (match_operand:DF 0 "register_operand"))
5367 (use (match_operand:DI 1 "nonimmediate_operand"))]
5368 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5369 && TARGET_SSE2 && TARGET_SSE_MATH"
5372 x86_emit_floatuns (operands);
5374 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5380 (define_expand "add<mode>3"
5381 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5382 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5383 (match_operand:SDWIM 2 "<general_operand>")))]
5385 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5387 (define_insn_and_split "*add<dwi>3_doubleword"
5388 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5390 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5391 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5392 (clobber (reg:CC FLAGS_REG))]
5393 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5396 [(parallel [(set (reg:CC FLAGS_REG)
5397 (unspec:CC [(match_dup 1) (match_dup 2)]
5400 (plus:DWIH (match_dup 1) (match_dup 2)))])
5401 (parallel [(set (match_dup 3)
5405 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5407 (clobber (reg:CC FLAGS_REG))])]
5408 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5410 (define_insn "*add<mode>3_cc"
5411 [(set (reg:CC FLAGS_REG)
5413 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5414 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5416 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5417 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5418 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5419 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5420 [(set_attr "type" "alu")
5421 (set_attr "mode" "<MODE>")])
5423 (define_insn "addqi3_cc"
5424 [(set (reg:CC FLAGS_REG)
5426 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5427 (match_operand:QI 2 "general_operand" "qn,qm")]
5429 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5430 (plus:QI (match_dup 1) (match_dup 2)))]
5431 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5432 "add{b}\t{%2, %0|%0, %2}"
5433 [(set_attr "type" "alu")
5434 (set_attr "mode" "QI")])
5436 (define_insn_and_split "*lea_1"
5437 [(set (match_operand:SI 0 "register_operand" "=r")
5438 (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0))]
5440 "lea{l}\t{%E1, %0|%0, %E1}"
5441 "&& reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5444 ix86_split_lea_for_addr (operands, SImode);
5447 [(set_attr "type" "lea")
5448 (set_attr "mode" "SI")])
5450 (define_insn_and_split "*lea<mode>_2"
5451 [(set (match_operand:SWI48 0 "register_operand" "=r")
5452 (match_operand:SWI48 1 "lea_address_operand" "p"))]
5454 "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}"
5455 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5458 ix86_split_lea_for_addr (operands, <MODE>mode);
5461 [(set_attr "type" "lea")
5462 (set_attr "mode" "<MODE>")])
5464 (define_insn "*lea_3_zext"
5465 [(set (match_operand:DI 0 "register_operand" "=r")
5467 (subreg:SI (match_operand:DI 1 "lea_address_operand" "j") 0)))]
5469 "lea{l}\t{%E1, %k0|%k0, %E1}"
5470 [(set_attr "type" "lea")
5471 (set_attr "mode" "SI")])
5473 (define_insn "*lea_4_zext"
5474 [(set (match_operand:DI 0 "register_operand" "=r")
5476 (match_operand:SI 1 "lea_address_operand" "j")))]
5478 "lea{l}\t{%E1, %k0|%k0, %E1}"
5479 [(set_attr "type" "lea")
5480 (set_attr "mode" "SI")])
5482 (define_insn "*lea_5_zext"
5483 [(set (match_operand:DI 0 "register_operand" "=r")
5485 (subreg:DI (match_operand:SI 1 "lea_address_operand" "p") 0)
5486 (match_operand:DI 2 "const_32bit_mask" "n")))]
5488 "lea{l}\t{%E1, %k0|%k0, %E1}"
5489 [(set_attr "type" "lea")
5490 (set_attr "mode" "SI")])
5492 (define_insn "*lea_6_zext"
5493 [(set (match_operand:DI 0 "register_operand" "=r")
5495 (match_operand:DI 1 "lea_address_operand" "p")
5496 (match_operand:DI 2 "const_32bit_mask" "n")))]
5498 "lea{l}\t{%E1, %k0|%k0, %E1}"
5499 [(set_attr "type" "lea")
5500 (set_attr "mode" "SI")])
5502 (define_insn "*add<mode>_1"
5503 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5505 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5506 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5507 (clobber (reg:CC FLAGS_REG))]
5508 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5510 switch (get_attr_type (insn))
5516 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5517 if (operands[2] == const1_rtx)
5518 return "inc{<imodesuffix>}\t%0";
5521 gcc_assert (operands[2] == constm1_rtx);
5522 return "dec{<imodesuffix>}\t%0";
5526 /* For most processors, ADD is faster than LEA. This alternative
5527 was added to use ADD as much as possible. */
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 (cond [(eq_attr "alternative" "3")
5543 (const_string "lea")
5544 (match_operand:SWI48 2 "incdec_operand")
5545 (const_string "incdec")
5547 (const_string "alu")))
5548 (set (attr "length_immediate")
5550 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5552 (const_string "*")))
5553 (set_attr "mode" "<MODE>")])
5555 ;; It may seem that nonimmediate operand is proper one for operand 1.
5556 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5557 ;; we take care in ix86_binary_operator_ok to not allow two memory
5558 ;; operands so proper swapping will be done in reload. This allow
5559 ;; patterns constructed from addsi_1 to match.
5561 (define_insn "addsi_1_zext"
5562 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5564 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5565 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5566 (clobber (reg:CC FLAGS_REG))]
5567 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5569 switch (get_attr_type (insn))
5575 if (operands[2] == const1_rtx)
5576 return "inc{l}\t%k0";
5579 gcc_assert (operands[2] == constm1_rtx);
5580 return "dec{l}\t%k0";
5584 /* For most processors, ADD is faster than LEA. This alternative
5585 was added to use ADD as much as possible. */
5586 if (which_alternative == 1)
5589 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5592 if (x86_maybe_negate_const_int (&operands[2], SImode))
5593 return "sub{l}\t{%2, %k0|%k0, %2}";
5595 return "add{l}\t{%2, %k0|%k0, %2}";
5599 (cond [(eq_attr "alternative" "2")
5600 (const_string "lea")
5601 (match_operand:SI 2 "incdec_operand")
5602 (const_string "incdec")
5604 (const_string "alu")))
5605 (set (attr "length_immediate")
5607 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5609 (const_string "*")))
5610 (set_attr "mode" "SI")])
5612 (define_insn "*addhi_1"
5613 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5614 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5615 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5616 (clobber (reg:CC FLAGS_REG))]
5617 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5619 switch (get_attr_type (insn))
5625 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5626 if (operands[2] == const1_rtx)
5627 return "inc{w}\t%0";
5630 gcc_assert (operands[2] == constm1_rtx);
5631 return "dec{w}\t%0";
5635 /* For most processors, ADD is faster than LEA. This alternative
5636 was added to use ADD as much as possible. */
5637 if (which_alternative == 2)
5640 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5643 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5644 if (x86_maybe_negate_const_int (&operands[2], HImode))
5645 return "sub{w}\t{%2, %0|%0, %2}";
5647 return "add{w}\t{%2, %0|%0, %2}";
5651 (cond [(eq_attr "alternative" "3")
5652 (const_string "lea")
5653 (match_operand:HI 2 "incdec_operand")
5654 (const_string "incdec")
5656 (const_string "alu")))
5657 (set (attr "length_immediate")
5659 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5661 (const_string "*")))
5662 (set_attr "mode" "HI,HI,HI,SI")])
5664 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5665 (define_insn "*addqi_1"
5666 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5667 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5668 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5669 (clobber (reg:CC FLAGS_REG))]
5670 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5672 bool widen = (which_alternative == 3 || which_alternative == 4);
5674 switch (get_attr_type (insn))
5680 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5681 if (operands[2] == const1_rtx)
5682 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5685 gcc_assert (operands[2] == constm1_rtx);
5686 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5690 /* For most processors, ADD is faster than LEA. These alternatives
5691 were added to use ADD as much as possible. */
5692 if (which_alternative == 2 || which_alternative == 4)
5695 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5698 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5699 if (x86_maybe_negate_const_int (&operands[2], QImode))
5702 return "sub{l}\t{%2, %k0|%k0, %2}";
5704 return "sub{b}\t{%2, %0|%0, %2}";
5707 return "add{l}\t{%k2, %k0|%k0, %k2}";
5709 return "add{b}\t{%2, %0|%0, %2}";
5713 (cond [(eq_attr "alternative" "5")
5714 (const_string "lea")
5715 (match_operand:QI 2 "incdec_operand")
5716 (const_string "incdec")
5718 (const_string "alu")))
5719 (set (attr "length_immediate")
5721 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5723 (const_string "*")))
5724 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5726 (define_insn "*addqi_1_slp"
5727 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5728 (plus:QI (match_dup 0)
5729 (match_operand:QI 1 "general_operand" "qn,qm")))
5730 (clobber (reg:CC FLAGS_REG))]
5731 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5732 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5734 switch (get_attr_type (insn))
5737 if (operands[1] == const1_rtx)
5738 return "inc{b}\t%0";
5741 gcc_assert (operands[1] == constm1_rtx);
5742 return "dec{b}\t%0";
5746 if (x86_maybe_negate_const_int (&operands[1], QImode))
5747 return "sub{b}\t{%1, %0|%0, %1}";
5749 return "add{b}\t{%1, %0|%0, %1}";
5753 (if_then_else (match_operand:QI 1 "incdec_operand")
5754 (const_string "incdec")
5755 (const_string "alu1")))
5756 (set (attr "memory")
5757 (if_then_else (match_operand 1 "memory_operand")
5758 (const_string "load")
5759 (const_string "none")))
5760 (set_attr "mode" "QI")])
5762 ;; Split non destructive adds if we cannot use lea.
5764 [(set (match_operand:SWI48 0 "register_operand")
5765 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5766 (match_operand:SWI48 2 "nonmemory_operand")))
5767 (clobber (reg:CC FLAGS_REG))]
5768 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5769 [(set (match_dup 0) (match_dup 1))
5770 (parallel [(set (match_dup 0) (plus:<MODE> (match_dup 0) (match_dup 2)))
5771 (clobber (reg:CC FLAGS_REG))])])
5773 ;; Convert add to the lea pattern to avoid flags dependency.
5775 [(set (match_operand:SWI 0 "register_operand")
5776 (plus:SWI (match_operand:SWI 1 "register_operand")
5777 (match_operand:SWI 2 "<nonmemory_operand>")))
5778 (clobber (reg:CC FLAGS_REG))]
5779 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5782 enum machine_mode mode = <MODE>mode;
5785 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5788 operands[0] = gen_lowpart (mode, operands[0]);
5789 operands[1] = gen_lowpart (mode, operands[1]);
5790 operands[2] = gen_lowpart (mode, operands[2]);
5793 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5795 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5799 ;; Convert add to the lea pattern to avoid flags dependency.
5801 [(set (match_operand:DI 0 "register_operand")
5803 (plus:SI (match_operand:SI 1 "register_operand")
5804 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5805 (clobber (reg:CC FLAGS_REG))]
5806 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5808 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5810 (define_insn "*add<mode>_2"
5811 [(set (reg FLAGS_REG)
5814 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5815 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5817 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5818 (plus:SWI (match_dup 1) (match_dup 2)))]
5819 "ix86_match_ccmode (insn, CCGOCmode)
5820 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5822 switch (get_attr_type (insn))
5825 if (operands[2] == const1_rtx)
5826 return "inc{<imodesuffix>}\t%0";
5829 gcc_assert (operands[2] == constm1_rtx);
5830 return "dec{<imodesuffix>}\t%0";
5834 if (which_alternative == 2)
5837 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5840 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5841 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5842 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5844 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5848 (if_then_else (match_operand:SWI 2 "incdec_operand")
5849 (const_string "incdec")
5850 (const_string "alu")))
5851 (set (attr "length_immediate")
5853 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5855 (const_string "*")))
5856 (set_attr "mode" "<MODE>")])
5858 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5859 (define_insn "*addsi_2_zext"
5860 [(set (reg FLAGS_REG)
5862 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5863 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5865 (set (match_operand:DI 0 "register_operand" "=r,r")
5866 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5867 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5868 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5870 switch (get_attr_type (insn))
5873 if (operands[2] == const1_rtx)
5874 return "inc{l}\t%k0";
5877 gcc_assert (operands[2] == constm1_rtx);
5878 return "dec{l}\t%k0";
5882 if (which_alternative == 1)
5885 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5888 if (x86_maybe_negate_const_int (&operands[2], SImode))
5889 return "sub{l}\t{%2, %k0|%k0, %2}";
5891 return "add{l}\t{%2, %k0|%k0, %2}";
5895 (if_then_else (match_operand:SI 2 "incdec_operand")
5896 (const_string "incdec")
5897 (const_string "alu")))
5898 (set (attr "length_immediate")
5900 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5902 (const_string "*")))
5903 (set_attr "mode" "SI")])
5905 (define_insn "*add<mode>_3"
5906 [(set (reg FLAGS_REG)
5908 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5909 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5910 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5911 "ix86_match_ccmode (insn, CCZmode)
5912 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5914 switch (get_attr_type (insn))
5917 if (operands[2] == const1_rtx)
5918 return "inc{<imodesuffix>}\t%0";
5921 gcc_assert (operands[2] == constm1_rtx);
5922 return "dec{<imodesuffix>}\t%0";
5926 if (which_alternative == 1)
5929 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5932 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5933 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5934 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5936 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5940 (if_then_else (match_operand:SWI 2 "incdec_operand")
5941 (const_string "incdec")
5942 (const_string "alu")))
5943 (set (attr "length_immediate")
5945 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5947 (const_string "*")))
5948 (set_attr "mode" "<MODE>")])
5950 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5951 (define_insn "*addsi_3_zext"
5952 [(set (reg FLAGS_REG)
5954 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5955 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5956 (set (match_operand:DI 0 "register_operand" "=r,r")
5957 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5958 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5959 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5961 switch (get_attr_type (insn))
5964 if (operands[2] == const1_rtx)
5965 return "inc{l}\t%k0";
5968 gcc_assert (operands[2] == constm1_rtx);
5969 return "dec{l}\t%k0";
5973 if (which_alternative == 1)
5976 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5979 if (x86_maybe_negate_const_int (&operands[2], SImode))
5980 return "sub{l}\t{%2, %k0|%k0, %2}";
5982 return "add{l}\t{%2, %k0|%k0, %2}";
5986 (if_then_else (match_operand:SI 2 "incdec_operand")
5987 (const_string "incdec")
5988 (const_string "alu")))
5989 (set (attr "length_immediate")
5991 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5993 (const_string "*")))
5994 (set_attr "mode" "SI")])
5996 ; For comparisons against 1, -1 and 128, we may generate better code
5997 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5998 ; is matched then. We can't accept general immediate, because for
5999 ; case of overflows, the result is messed up.
6000 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6001 ; only for comparisons not depending on it.
6003 (define_insn "*adddi_4"
6004 [(set (reg FLAGS_REG)
6006 (match_operand:DI 1 "nonimmediate_operand" "0")
6007 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6008 (clobber (match_scratch:DI 0 "=rm"))]
6010 && ix86_match_ccmode (insn, CCGCmode)"
6012 switch (get_attr_type (insn))
6015 if (operands[2] == constm1_rtx)
6016 return "inc{q}\t%0";
6019 gcc_assert (operands[2] == const1_rtx);
6020 return "dec{q}\t%0";
6024 if (x86_maybe_negate_const_int (&operands[2], DImode))
6025 return "add{q}\t{%2, %0|%0, %2}";
6027 return "sub{q}\t{%2, %0|%0, %2}";
6031 (if_then_else (match_operand:DI 2 "incdec_operand")
6032 (const_string "incdec")
6033 (const_string "alu")))
6034 (set (attr "length_immediate")
6036 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6038 (const_string "*")))
6039 (set_attr "mode" "DI")])
6041 ; For comparisons against 1, -1 and 128, we may generate better code
6042 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6043 ; is matched then. We can't accept general immediate, because for
6044 ; case of overflows, the result is messed up.
6045 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6046 ; only for comparisons not depending on it.
6048 (define_insn "*add<mode>_4"
6049 [(set (reg FLAGS_REG)
6051 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6052 (match_operand:SWI124 2 "const_int_operand" "n")))
6053 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6054 "ix86_match_ccmode (insn, CCGCmode)"
6056 switch (get_attr_type (insn))
6059 if (operands[2] == constm1_rtx)
6060 return "inc{<imodesuffix>}\t%0";
6063 gcc_assert (operands[2] == const1_rtx);
6064 return "dec{<imodesuffix>}\t%0";
6068 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6069 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6071 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6075 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6076 (const_string "incdec")
6077 (const_string "alu")))
6078 (set (attr "length_immediate")
6080 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6082 (const_string "*")))
6083 (set_attr "mode" "<MODE>")])
6085 (define_insn "*add<mode>_5"
6086 [(set (reg FLAGS_REG)
6089 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6090 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6092 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6093 "ix86_match_ccmode (insn, CCGOCmode)
6094 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6096 switch (get_attr_type (insn))
6099 if (operands[2] == const1_rtx)
6100 return "inc{<imodesuffix>}\t%0";
6103 gcc_assert (operands[2] == constm1_rtx);
6104 return "dec{<imodesuffix>}\t%0";
6108 if (which_alternative == 1)
6111 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6114 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6115 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6116 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6118 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6122 (if_then_else (match_operand:SWI 2 "incdec_operand")
6123 (const_string "incdec")
6124 (const_string "alu")))
6125 (set (attr "length_immediate")
6127 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6129 (const_string "*")))
6130 (set_attr "mode" "<MODE>")])
6132 (define_insn "*addqi_ext_1_rex64"
6133 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6138 (match_operand 1 "ext_register_operand" "0")
6141 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6142 (clobber (reg:CC FLAGS_REG))]
6145 switch (get_attr_type (insn))
6148 if (operands[2] == const1_rtx)
6149 return "inc{b}\t%h0";
6152 gcc_assert (operands[2] == constm1_rtx);
6153 return "dec{b}\t%h0";
6157 return "add{b}\t{%2, %h0|%h0, %2}";
6161 (if_then_else (match_operand:QI 2 "incdec_operand")
6162 (const_string "incdec")
6163 (const_string "alu")))
6164 (set_attr "modrm" "1")
6165 (set_attr "mode" "QI")])
6167 (define_insn "addqi_ext_1"
6168 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6173 (match_operand 1 "ext_register_operand" "0")
6176 (match_operand:QI 2 "general_operand" "Qmn")))
6177 (clobber (reg:CC FLAGS_REG))]
6180 switch (get_attr_type (insn))
6183 if (operands[2] == const1_rtx)
6184 return "inc{b}\t%h0";
6187 gcc_assert (operands[2] == constm1_rtx);
6188 return "dec{b}\t%h0";
6192 return "add{b}\t{%2, %h0|%h0, %2}";
6196 (if_then_else (match_operand:QI 2 "incdec_operand")
6197 (const_string "incdec")
6198 (const_string "alu")))
6199 (set_attr "modrm" "1")
6200 (set_attr "mode" "QI")])
6202 (define_insn "*addqi_ext_2"
6203 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6208 (match_operand 1 "ext_register_operand" "%0")
6212 (match_operand 2 "ext_register_operand" "Q")
6215 (clobber (reg:CC FLAGS_REG))]
6217 "add{b}\t{%h2, %h0|%h0, %h2}"
6218 [(set_attr "type" "alu")
6219 (set_attr "mode" "QI")])
6221 ;; The lea patterns for modes less than 32 bits need to be matched by
6222 ;; several insns converted to real lea by splitters.
6224 (define_insn_and_split "*lea_general_1"
6225 [(set (match_operand 0 "register_operand" "=r")
6226 (plus (plus (match_operand 1 "index_register_operand" "l")
6227 (match_operand 2 "register_operand" "r"))
6228 (match_operand 3 "immediate_operand" "i")))]
6229 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6230 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6231 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6232 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6233 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6234 || GET_MODE (operands[3]) == VOIDmode)"
6236 "&& reload_completed"
6239 enum machine_mode mode = SImode;
6242 operands[0] = gen_lowpart (mode, operands[0]);
6243 operands[1] = gen_lowpart (mode, operands[1]);
6244 operands[2] = gen_lowpart (mode, operands[2]);
6245 operands[3] = gen_lowpart (mode, operands[3]);
6247 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6250 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6253 [(set_attr "type" "lea")
6254 (set_attr "mode" "SI")])
6256 (define_insn_and_split "*lea_general_2"
6257 [(set (match_operand 0 "register_operand" "=r")
6258 (plus (mult (match_operand 1 "index_register_operand" "l")
6259 (match_operand 2 "const248_operand" "n"))
6260 (match_operand 3 "nonmemory_operand" "ri")))]
6261 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6262 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6263 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6264 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6265 || GET_MODE (operands[3]) == VOIDmode)"
6267 "&& reload_completed"
6270 enum machine_mode mode = SImode;
6273 operands[0] = gen_lowpart (mode, operands[0]);
6274 operands[1] = gen_lowpart (mode, operands[1]);
6275 operands[3] = gen_lowpart (mode, operands[3]);
6277 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6280 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6283 [(set_attr "type" "lea")
6284 (set_attr "mode" "SI")])
6286 (define_insn_and_split "*lea_general_3"
6287 [(set (match_operand 0 "register_operand" "=r")
6288 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6289 (match_operand 2 "const248_operand" "n"))
6290 (match_operand 3 "register_operand" "r"))
6291 (match_operand 4 "immediate_operand" "i")))]
6292 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6293 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6294 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6295 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6297 "&& reload_completed"
6300 enum machine_mode mode = SImode;
6303 operands[0] = gen_lowpart (mode, operands[0]);
6304 operands[1] = gen_lowpart (mode, operands[1]);
6305 operands[3] = gen_lowpart (mode, operands[3]);
6306 operands[4] = gen_lowpart (mode, operands[4]);
6308 pat = gen_rtx_PLUS (mode,
6310 gen_rtx_MULT (mode, operands[1],
6315 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6318 [(set_attr "type" "lea")
6319 (set_attr "mode" "SI")])
6321 (define_insn_and_split "*lea_general_4"
6322 [(set (match_operand 0 "register_operand" "=r")
6324 (match_operand 1 "index_register_operand" "l")
6325 (match_operand 2 "const_int_operand" "n"))
6326 (match_operand 3 "const_int_operand" "n")))]
6327 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6328 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6329 || GET_MODE (operands[0]) == SImode
6330 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6331 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6332 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6333 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6334 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6336 "&& reload_completed"
6339 enum machine_mode mode = GET_MODE (operands[0]);
6342 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6345 operands[0] = gen_lowpart (mode, operands[0]);
6346 operands[1] = gen_lowpart (mode, operands[1]);
6349 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6351 pat = plus_constant (gen_rtx_MULT (mode, operands[1], operands[2]),
6352 INTVAL (operands[3]));
6354 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6357 [(set_attr "type" "lea")
6359 (if_then_else (match_operand:DI 0)
6361 (const_string "SI")))])
6363 ;; Subtract instructions
6365 (define_expand "sub<mode>3"
6366 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6367 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6368 (match_operand:SDWIM 2 "<general_operand>")))]
6370 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6372 (define_insn_and_split "*sub<dwi>3_doubleword"
6373 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6375 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6376 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6377 (clobber (reg:CC FLAGS_REG))]
6378 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6381 [(parallel [(set (reg:CC FLAGS_REG)
6382 (compare:CC (match_dup 1) (match_dup 2)))
6384 (minus:DWIH (match_dup 1) (match_dup 2)))])
6385 (parallel [(set (match_dup 3)
6389 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6391 (clobber (reg:CC FLAGS_REG))])]
6392 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6394 (define_insn "*sub<mode>_1"
6395 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6397 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6398 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6399 (clobber (reg:CC FLAGS_REG))]
6400 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6401 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6402 [(set_attr "type" "alu")
6403 (set_attr "mode" "<MODE>")])
6405 (define_insn "*subsi_1_zext"
6406 [(set (match_operand:DI 0 "register_operand" "=r")
6408 (minus:SI (match_operand:SI 1 "register_operand" "0")
6409 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6410 (clobber (reg:CC FLAGS_REG))]
6411 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6412 "sub{l}\t{%2, %k0|%k0, %2}"
6413 [(set_attr "type" "alu")
6414 (set_attr "mode" "SI")])
6416 (define_insn "*subqi_1_slp"
6417 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6418 (minus:QI (match_dup 0)
6419 (match_operand:QI 1 "general_operand" "qn,qm")))
6420 (clobber (reg:CC FLAGS_REG))]
6421 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6422 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6423 "sub{b}\t{%1, %0|%0, %1}"
6424 [(set_attr "type" "alu1")
6425 (set_attr "mode" "QI")])
6427 (define_insn "*sub<mode>_2"
6428 [(set (reg FLAGS_REG)
6431 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6432 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6434 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6435 (minus:SWI (match_dup 1) (match_dup 2)))]
6436 "ix86_match_ccmode (insn, CCGOCmode)
6437 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6438 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6439 [(set_attr "type" "alu")
6440 (set_attr "mode" "<MODE>")])
6442 (define_insn "*subsi_2_zext"
6443 [(set (reg FLAGS_REG)
6445 (minus:SI (match_operand:SI 1 "register_operand" "0")
6446 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6448 (set (match_operand:DI 0 "register_operand" "=r")
6450 (minus:SI (match_dup 1)
6452 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6453 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6454 "sub{l}\t{%2, %k0|%k0, %2}"
6455 [(set_attr "type" "alu")
6456 (set_attr "mode" "SI")])
6458 (define_insn "*sub<mode>_3"
6459 [(set (reg FLAGS_REG)
6460 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6461 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6462 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6463 (minus:SWI (match_dup 1) (match_dup 2)))]
6464 "ix86_match_ccmode (insn, CCmode)
6465 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6466 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6467 [(set_attr "type" "alu")
6468 (set_attr "mode" "<MODE>")])
6470 (define_insn "*subsi_3_zext"
6471 [(set (reg FLAGS_REG)
6472 (compare (match_operand:SI 1 "register_operand" "0")
6473 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6474 (set (match_operand:DI 0 "register_operand" "=r")
6476 (minus:SI (match_dup 1)
6478 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6479 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6480 "sub{l}\t{%2, %1|%1, %2}"
6481 [(set_attr "type" "alu")
6482 (set_attr "mode" "SI")])
6484 ;; Add with carry and subtract with borrow
6486 (define_expand "<plusminus_insn><mode>3_carry"
6488 [(set (match_operand:SWI 0 "nonimmediate_operand")
6490 (match_operand:SWI 1 "nonimmediate_operand")
6491 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6492 [(match_operand 3 "flags_reg_operand")
6494 (match_operand:SWI 2 "<general_operand>"))))
6495 (clobber (reg:CC FLAGS_REG))])]
6496 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6498 (define_insn "*<plusminus_insn><mode>3_carry"
6499 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6501 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6503 (match_operator 3 "ix86_carry_flag_operator"
6504 [(reg FLAGS_REG) (const_int 0)])
6505 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6506 (clobber (reg:CC FLAGS_REG))]
6507 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6508 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6509 [(set_attr "type" "alu")
6510 (set_attr "use_carry" "1")
6511 (set_attr "pent_pair" "pu")
6512 (set_attr "mode" "<MODE>")])
6514 (define_insn "*addsi3_carry_zext"
6515 [(set (match_operand:DI 0 "register_operand" "=r")
6517 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6518 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6519 [(reg FLAGS_REG) (const_int 0)])
6520 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6521 (clobber (reg:CC FLAGS_REG))]
6522 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6523 "adc{l}\t{%2, %k0|%k0, %2}"
6524 [(set_attr "type" "alu")
6525 (set_attr "use_carry" "1")
6526 (set_attr "pent_pair" "pu")
6527 (set_attr "mode" "SI")])
6529 (define_insn "*subsi3_carry_zext"
6530 [(set (match_operand:DI 0 "register_operand" "=r")
6532 (minus:SI (match_operand:SI 1 "register_operand" "0")
6533 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6534 [(reg FLAGS_REG) (const_int 0)])
6535 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6536 (clobber (reg:CC FLAGS_REG))]
6537 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6538 "sbb{l}\t{%2, %k0|%k0, %2}"
6539 [(set_attr "type" "alu")
6540 (set_attr "pent_pair" "pu")
6541 (set_attr "mode" "SI")])
6543 ;; Overflow setting add and subtract instructions
6545 (define_insn "*add<mode>3_cconly_overflow"
6546 [(set (reg:CCC FLAGS_REG)
6549 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6550 (match_operand:SWI 2 "<general_operand>" "<g>"))
6552 (clobber (match_scratch:SWI 0 "=<r>"))]
6553 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6554 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6555 [(set_attr "type" "alu")
6556 (set_attr "mode" "<MODE>")])
6558 (define_insn "*sub<mode>3_cconly_overflow"
6559 [(set (reg:CCC FLAGS_REG)
6562 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6563 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6566 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6567 [(set_attr "type" "icmp")
6568 (set_attr "mode" "<MODE>")])
6570 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6571 [(set (reg:CCC FLAGS_REG)
6574 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6575 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6577 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6578 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6579 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6580 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6581 [(set_attr "type" "alu")
6582 (set_attr "mode" "<MODE>")])
6584 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6585 [(set (reg:CCC FLAGS_REG)
6588 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6589 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6591 (set (match_operand:DI 0 "register_operand" "=r")
6592 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6593 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6594 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6595 [(set_attr "type" "alu")
6596 (set_attr "mode" "SI")])
6598 ;; The patterns that match these are at the end of this file.
6600 (define_expand "<plusminus_insn>xf3"
6601 [(set (match_operand:XF 0 "register_operand")
6603 (match_operand:XF 1 "register_operand")
6604 (match_operand:XF 2 "register_operand")))]
6607 (define_expand "<plusminus_insn><mode>3"
6608 [(set (match_operand:MODEF 0 "register_operand")
6610 (match_operand:MODEF 1 "register_operand")
6611 (match_operand:MODEF 2 "nonimmediate_operand")))]
6612 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6613 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6615 ;; Multiply instructions
6617 (define_expand "mul<mode>3"
6618 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6620 (match_operand:SWIM248 1 "register_operand")
6621 (match_operand:SWIM248 2 "<general_operand>")))
6622 (clobber (reg:CC FLAGS_REG))])])
6624 (define_expand "mulqi3"
6625 [(parallel [(set (match_operand:QI 0 "register_operand")
6627 (match_operand:QI 1 "register_operand")
6628 (match_operand:QI 2 "nonimmediate_operand")))
6629 (clobber (reg:CC FLAGS_REG))])]
6630 "TARGET_QIMODE_MATH")
6633 ;; IMUL reg32/64, reg32/64, imm8 Direct
6634 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6635 ;; IMUL reg32/64, reg32/64, imm32 Direct
6636 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6637 ;; IMUL reg32/64, reg32/64 Direct
6638 ;; IMUL reg32/64, mem32/64 Direct
6640 ;; On BDVER1, all above IMULs use DirectPath
6642 (define_insn "*mul<mode>3_1"
6643 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6645 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6646 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6647 (clobber (reg:CC FLAGS_REG))]
6648 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6650 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6651 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6652 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6653 [(set_attr "type" "imul")
6654 (set_attr "prefix_0f" "0,0,1")
6655 (set (attr "athlon_decode")
6656 (cond [(eq_attr "cpu" "athlon")
6657 (const_string "vector")
6658 (eq_attr "alternative" "1")
6659 (const_string "vector")
6660 (and (eq_attr "alternative" "2")
6661 (match_operand 1 "memory_operand"))
6662 (const_string "vector")]
6663 (const_string "direct")))
6664 (set (attr "amdfam10_decode")
6665 (cond [(and (eq_attr "alternative" "0,1")
6666 (match_operand 1 "memory_operand"))
6667 (const_string "vector")]
6668 (const_string "direct")))
6669 (set_attr "bdver1_decode" "direct")
6670 (set_attr "mode" "<MODE>")])
6672 (define_insn "*mulsi3_1_zext"
6673 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6675 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6676 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6677 (clobber (reg:CC FLAGS_REG))]
6679 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6681 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6682 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6683 imul{l}\t{%2, %k0|%k0, %2}"
6684 [(set_attr "type" "imul")
6685 (set_attr "prefix_0f" "0,0,1")
6686 (set (attr "athlon_decode")
6687 (cond [(eq_attr "cpu" "athlon")
6688 (const_string "vector")
6689 (eq_attr "alternative" "1")
6690 (const_string "vector")
6691 (and (eq_attr "alternative" "2")
6692 (match_operand 1 "memory_operand"))
6693 (const_string "vector")]
6694 (const_string "direct")))
6695 (set (attr "amdfam10_decode")
6696 (cond [(and (eq_attr "alternative" "0,1")
6697 (match_operand 1 "memory_operand"))
6698 (const_string "vector")]
6699 (const_string "direct")))
6700 (set_attr "bdver1_decode" "direct")
6701 (set_attr "mode" "SI")])
6704 ;; IMUL reg16, reg16, imm8 VectorPath
6705 ;; IMUL reg16, mem16, imm8 VectorPath
6706 ;; IMUL reg16, reg16, imm16 VectorPath
6707 ;; IMUL reg16, mem16, imm16 VectorPath
6708 ;; IMUL reg16, reg16 Direct
6709 ;; IMUL reg16, mem16 Direct
6711 ;; On BDVER1, all HI MULs use DoublePath
6713 (define_insn "*mulhi3_1"
6714 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6715 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6716 (match_operand:HI 2 "general_operand" "K,n,mr")))
6717 (clobber (reg:CC FLAGS_REG))]
6719 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6721 imul{w}\t{%2, %1, %0|%0, %1, %2}
6722 imul{w}\t{%2, %1, %0|%0, %1, %2}
6723 imul{w}\t{%2, %0|%0, %2}"
6724 [(set_attr "type" "imul")
6725 (set_attr "prefix_0f" "0,0,1")
6726 (set (attr "athlon_decode")
6727 (cond [(eq_attr "cpu" "athlon")
6728 (const_string "vector")
6729 (eq_attr "alternative" "1,2")
6730 (const_string "vector")]
6731 (const_string "direct")))
6732 (set (attr "amdfam10_decode")
6733 (cond [(eq_attr "alternative" "0,1")
6734 (const_string "vector")]
6735 (const_string "direct")))
6736 (set_attr "bdver1_decode" "double")
6737 (set_attr "mode" "HI")])
6739 ;;On AMDFAM10 and BDVER1
6743 (define_insn "*mulqi3_1"
6744 [(set (match_operand:QI 0 "register_operand" "=a")
6745 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6746 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6747 (clobber (reg:CC FLAGS_REG))]
6749 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6751 [(set_attr "type" "imul")
6752 (set_attr "length_immediate" "0")
6753 (set (attr "athlon_decode")
6754 (if_then_else (eq_attr "cpu" "athlon")
6755 (const_string "vector")
6756 (const_string "direct")))
6757 (set_attr "amdfam10_decode" "direct")
6758 (set_attr "bdver1_decode" "direct")
6759 (set_attr "mode" "QI")])
6761 (define_expand "<u>mul<mode><dwi>3"
6762 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6765 (match_operand:DWIH 1 "nonimmediate_operand"))
6767 (match_operand:DWIH 2 "register_operand"))))
6768 (clobber (reg:CC FLAGS_REG))])])
6770 (define_expand "<u>mulqihi3"
6771 [(parallel [(set (match_operand:HI 0 "register_operand")
6774 (match_operand:QI 1 "nonimmediate_operand"))
6776 (match_operand:QI 2 "register_operand"))))
6777 (clobber (reg:CC FLAGS_REG))])]
6778 "TARGET_QIMODE_MATH")
6780 (define_insn "*bmi2_umulditi3_1"
6781 [(set (match_operand:DI 0 "register_operand" "=r")
6783 (match_operand:DI 2 "nonimmediate_operand" "%d")
6784 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6785 (set (match_operand:DI 1 "register_operand" "=r")
6788 (mult:TI (zero_extend:TI (match_dup 2))
6789 (zero_extend:TI (match_dup 3)))
6791 "TARGET_64BIT && TARGET_BMI2
6792 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6793 "mulx\t{%3, %0, %1|%1, %0, %3}"
6794 [(set_attr "type" "imulx")
6795 (set_attr "prefix" "vex")
6796 (set_attr "mode" "DI")])
6798 (define_insn "*bmi2_umulsidi3_1"
6799 [(set (match_operand:SI 0 "register_operand" "=r")
6801 (match_operand:SI 2 "nonimmediate_operand" "%d")
6802 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6803 (set (match_operand:SI 1 "register_operand" "=r")
6806 (mult:DI (zero_extend:DI (match_dup 2))
6807 (zero_extend:DI (match_dup 3)))
6809 "!TARGET_64BIT && TARGET_BMI2
6810 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6811 "mulx\t{%3, %0, %1|%1, %0, %3}"
6812 [(set_attr "type" "imulx")
6813 (set_attr "prefix" "vex")
6814 (set_attr "mode" "SI")])
6816 (define_insn "*umul<mode><dwi>3_1"
6817 [(set (match_operand:<DWI> 0 "register_operand" "=A,r")
6820 (match_operand:DWIH 1 "nonimmediate_operand" "%0,d"))
6822 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6823 (clobber (reg:CC FLAGS_REG))]
6824 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6826 mul{<imodesuffix>}\t%2
6828 [(set_attr "isa" "*,bmi2")
6829 (set_attr "type" "imul,imulx")
6830 (set_attr "length_immediate" "0,*")
6831 (set (attr "athlon_decode")
6832 (cond [(eq_attr "alternative" "0")
6833 (if_then_else (eq_attr "cpu" "athlon")
6834 (const_string "vector")
6835 (const_string "double"))]
6836 (const_string "*")))
6837 (set_attr "amdfam10_decode" "double,*")
6838 (set_attr "bdver1_decode" "direct,*")
6839 (set_attr "prefix" "orig,vex")
6840 (set_attr "mode" "<MODE>")])
6842 ;; Convert mul to the mulx pattern to avoid flags dependency.
6844 [(set (match_operand:<DWI> 0 "register_operand")
6847 (match_operand:DWIH 1 "register_operand"))
6849 (match_operand:DWIH 2 "nonimmediate_operand"))))
6850 (clobber (reg:CC FLAGS_REG))]
6851 "TARGET_BMI2 && reload_completed
6852 && true_regnum (operands[1]) == DX_REG"
6853 [(parallel [(set (match_dup 3)
6854 (mult:DWIH (match_dup 1) (match_dup 2)))
6858 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6859 (zero_extend:<DWI> (match_dup 2)))
6862 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6864 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6867 (define_insn "*mul<mode><dwi>3_1"
6868 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6871 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6873 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6874 (clobber (reg:CC FLAGS_REG))]
6875 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6876 "imul{<imodesuffix>}\t%2"
6877 [(set_attr "type" "imul")
6878 (set_attr "length_immediate" "0")
6879 (set (attr "athlon_decode")
6880 (if_then_else (eq_attr "cpu" "athlon")
6881 (const_string "vector")
6882 (const_string "double")))
6883 (set_attr "amdfam10_decode" "double")
6884 (set_attr "bdver1_decode" "direct")
6885 (set_attr "mode" "<MODE>")])
6887 (define_insn "*<u>mulqihi3_1"
6888 [(set (match_operand:HI 0 "register_operand" "=a")
6891 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6893 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6894 (clobber (reg:CC FLAGS_REG))]
6896 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6897 "<sgnprefix>mul{b}\t%2"
6898 [(set_attr "type" "imul")
6899 (set_attr "length_immediate" "0")
6900 (set (attr "athlon_decode")
6901 (if_then_else (eq_attr "cpu" "athlon")
6902 (const_string "vector")
6903 (const_string "direct")))
6904 (set_attr "amdfam10_decode" "direct")
6905 (set_attr "bdver1_decode" "direct")
6906 (set_attr "mode" "QI")])
6908 (define_expand "<s>mul<mode>3_highpart"
6909 [(parallel [(set (match_operand:SWI48 0 "register_operand")
6914 (match_operand:SWI48 1 "nonimmediate_operand"))
6916 (match_operand:SWI48 2 "register_operand")))
6918 (clobber (match_scratch:SWI48 3))
6919 (clobber (reg:CC FLAGS_REG))])]
6921 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6923 (define_insn "*<s>muldi3_highpart_1"
6924 [(set (match_operand:DI 0 "register_operand" "=d")
6929 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6931 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6933 (clobber (match_scratch:DI 3 "=1"))
6934 (clobber (reg:CC FLAGS_REG))]
6936 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6937 "<sgnprefix>mul{q}\t%2"
6938 [(set_attr "type" "imul")
6939 (set_attr "length_immediate" "0")
6940 (set (attr "athlon_decode")
6941 (if_then_else (eq_attr "cpu" "athlon")
6942 (const_string "vector")
6943 (const_string "double")))
6944 (set_attr "amdfam10_decode" "double")
6945 (set_attr "bdver1_decode" "direct")
6946 (set_attr "mode" "DI")])
6948 (define_insn "*<s>mulsi3_highpart_1"
6949 [(set (match_operand:SI 0 "register_operand" "=d")
6954 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6956 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6958 (clobber (match_scratch:SI 3 "=1"))
6959 (clobber (reg:CC FLAGS_REG))]
6960 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6961 "<sgnprefix>mul{l}\t%2"
6962 [(set_attr "type" "imul")
6963 (set_attr "length_immediate" "0")
6964 (set (attr "athlon_decode")
6965 (if_then_else (eq_attr "cpu" "athlon")
6966 (const_string "vector")
6967 (const_string "double")))
6968 (set_attr "amdfam10_decode" "double")
6969 (set_attr "bdver1_decode" "direct")
6970 (set_attr "mode" "SI")])
6972 (define_insn "*<s>mulsi3_highpart_zext"
6973 [(set (match_operand:DI 0 "register_operand" "=d")
6974 (zero_extend:DI (truncate:SI
6976 (mult:DI (any_extend:DI
6977 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6979 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6981 (clobber (match_scratch:SI 3 "=1"))
6982 (clobber (reg:CC FLAGS_REG))]
6984 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6985 "<sgnprefix>mul{l}\t%2"
6986 [(set_attr "type" "imul")
6987 (set_attr "length_immediate" "0")
6988 (set (attr "athlon_decode")
6989 (if_then_else (eq_attr "cpu" "athlon")
6990 (const_string "vector")
6991 (const_string "double")))
6992 (set_attr "amdfam10_decode" "double")
6993 (set_attr "bdver1_decode" "direct")
6994 (set_attr "mode" "SI")])
6996 ;; The patterns that match these are at the end of this file.
6998 (define_expand "mulxf3"
6999 [(set (match_operand:XF 0 "register_operand")
7000 (mult:XF (match_operand:XF 1 "register_operand")
7001 (match_operand:XF 2 "register_operand")))]
7004 (define_expand "mul<mode>3"
7005 [(set (match_operand:MODEF 0 "register_operand")
7006 (mult:MODEF (match_operand:MODEF 1 "register_operand")
7007 (match_operand:MODEF 2 "nonimmediate_operand")))]
7008 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7009 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7011 ;; Divide instructions
7013 ;; The patterns that match these are at the end of this file.
7015 (define_expand "divxf3"
7016 [(set (match_operand:XF 0 "register_operand")
7017 (div:XF (match_operand:XF 1 "register_operand")
7018 (match_operand:XF 2 "register_operand")))]
7021 (define_expand "divdf3"
7022 [(set (match_operand:DF 0 "register_operand")
7023 (div:DF (match_operand:DF 1 "register_operand")
7024 (match_operand:DF 2 "nonimmediate_operand")))]
7025 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7026 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7028 (define_expand "divsf3"
7029 [(set (match_operand:SF 0 "register_operand")
7030 (div:SF (match_operand:SF 1 "register_operand")
7031 (match_operand:SF 2 "nonimmediate_operand")))]
7032 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7037 && optimize_insn_for_speed_p ()
7038 && flag_finite_math_only && !flag_trapping_math
7039 && flag_unsafe_math_optimizations)
7041 ix86_emit_swdivsf (operands[0], operands[1],
7042 operands[2], SFmode);
7047 ;; Divmod instructions.
7049 (define_expand "divmod<mode>4"
7050 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7052 (match_operand:SWIM248 1 "register_operand")
7053 (match_operand:SWIM248 2 "nonimmediate_operand")))
7054 (set (match_operand:SWIM248 3 "register_operand")
7055 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7056 (clobber (reg:CC FLAGS_REG))])])
7058 ;; Split with 8bit unsigned divide:
7059 ;; if (dividend an divisor are in [0-255])
7060 ;; use 8bit unsigned integer divide
7062 ;; use original integer divide
7064 [(set (match_operand:SWI48 0 "register_operand")
7065 (div:SWI48 (match_operand:SWI48 2 "register_operand")
7066 (match_operand:SWI48 3 "nonimmediate_operand")))
7067 (set (match_operand:SWI48 1 "register_operand")
7068 (mod:SWI48 (match_dup 2) (match_dup 3)))
7069 (clobber (reg:CC FLAGS_REG))]
7070 "TARGET_USE_8BIT_IDIV
7071 && TARGET_QIMODE_MATH
7072 && can_create_pseudo_p ()
7073 && !optimize_insn_for_size_p ()"
7075 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7077 (define_insn_and_split "divmod<mode>4_1"
7078 [(set (match_operand:SWI48 0 "register_operand" "=a")
7079 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7080 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7081 (set (match_operand:SWI48 1 "register_operand" "=&d")
7082 (mod:SWI48 (match_dup 2) (match_dup 3)))
7083 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7084 (clobber (reg:CC FLAGS_REG))]
7088 [(parallel [(set (match_dup 1)
7089 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7090 (clobber (reg:CC FLAGS_REG))])
7091 (parallel [(set (match_dup 0)
7092 (div:SWI48 (match_dup 2) (match_dup 3)))
7094 (mod:SWI48 (match_dup 2) (match_dup 3)))
7096 (clobber (reg:CC FLAGS_REG))])]
7098 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7100 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7101 operands[4] = operands[2];
7104 /* Avoid use of cltd in favor of a mov+shift. */
7105 emit_move_insn (operands[1], operands[2]);
7106 operands[4] = operands[1];
7109 [(set_attr "type" "multi")
7110 (set_attr "mode" "<MODE>")])
7112 (define_insn_and_split "*divmod<mode>4"
7113 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7114 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7115 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7116 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7117 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7118 (clobber (reg:CC FLAGS_REG))]
7122 [(parallel [(set (match_dup 1)
7123 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7124 (clobber (reg:CC FLAGS_REG))])
7125 (parallel [(set (match_dup 0)
7126 (div:SWIM248 (match_dup 2) (match_dup 3)))
7128 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7130 (clobber (reg:CC FLAGS_REG))])]
7132 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7134 if (<MODE>mode != HImode
7135 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7136 operands[4] = operands[2];
7139 /* Avoid use of cltd in favor of a mov+shift. */
7140 emit_move_insn (operands[1], operands[2]);
7141 operands[4] = operands[1];
7144 [(set_attr "type" "multi")
7145 (set_attr "mode" "<MODE>")])
7147 (define_insn "*divmod<mode>4_noext"
7148 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7149 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7150 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7151 (set (match_operand:SWIM248 1 "register_operand" "=d")
7152 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7153 (use (match_operand:SWIM248 4 "register_operand" "1"))
7154 (clobber (reg:CC FLAGS_REG))]
7156 "idiv{<imodesuffix>}\t%3"
7157 [(set_attr "type" "idiv")
7158 (set_attr "mode" "<MODE>")])
7160 (define_expand "divmodqi4"
7161 [(parallel [(set (match_operand:QI 0 "register_operand")
7163 (match_operand:QI 1 "register_operand")
7164 (match_operand:QI 2 "nonimmediate_operand")))
7165 (set (match_operand:QI 3 "register_operand")
7166 (mod:QI (match_dup 1) (match_dup 2)))
7167 (clobber (reg:CC FLAGS_REG))])]
7168 "TARGET_QIMODE_MATH"
7173 tmp0 = gen_reg_rtx (HImode);
7174 tmp1 = gen_reg_rtx (HImode);
7176 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7178 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7179 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7181 /* Extract remainder from AH. */
7182 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7183 insn = emit_move_insn (operands[3], tmp1);
7185 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7186 set_unique_reg_note (insn, REG_EQUAL, mod);
7188 /* Extract quotient from AL. */
7189 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7191 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7192 set_unique_reg_note (insn, REG_EQUAL, div);
7197 ;; Divide AX by r/m8, with result stored in
7200 ;; Change div/mod to HImode and extend the second argument to HImode
7201 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7202 ;; combine may fail.
7203 (define_insn "divmodhiqi3"
7204 [(set (match_operand:HI 0 "register_operand" "=a")
7209 (mod:HI (match_operand:HI 1 "register_operand" "0")
7211 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7215 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7216 (clobber (reg:CC FLAGS_REG))]
7217 "TARGET_QIMODE_MATH"
7219 [(set_attr "type" "idiv")
7220 (set_attr "mode" "QI")])
7222 (define_expand "udivmod<mode>4"
7223 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7225 (match_operand:SWIM248 1 "register_operand")
7226 (match_operand:SWIM248 2 "nonimmediate_operand")))
7227 (set (match_operand:SWIM248 3 "register_operand")
7228 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7229 (clobber (reg:CC FLAGS_REG))])])
7231 ;; Split with 8bit unsigned divide:
7232 ;; if (dividend an divisor are in [0-255])
7233 ;; use 8bit unsigned integer divide
7235 ;; use original integer divide
7237 [(set (match_operand:SWI48 0 "register_operand")
7238 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7239 (match_operand:SWI48 3 "nonimmediate_operand")))
7240 (set (match_operand:SWI48 1 "register_operand")
7241 (umod:SWI48 (match_dup 2) (match_dup 3)))
7242 (clobber (reg:CC FLAGS_REG))]
7243 "TARGET_USE_8BIT_IDIV
7244 && TARGET_QIMODE_MATH
7245 && can_create_pseudo_p ()
7246 && !optimize_insn_for_size_p ()"
7248 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7250 (define_insn_and_split "udivmod<mode>4_1"
7251 [(set (match_operand:SWI48 0 "register_operand" "=a")
7252 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7253 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7254 (set (match_operand:SWI48 1 "register_operand" "=&d")
7255 (umod:SWI48 (match_dup 2) (match_dup 3)))
7256 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7257 (clobber (reg:CC FLAGS_REG))]
7261 [(set (match_dup 1) (const_int 0))
7262 (parallel [(set (match_dup 0)
7263 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7265 (umod:SWI48 (match_dup 2) (match_dup 3)))
7267 (clobber (reg:CC FLAGS_REG))])]
7269 [(set_attr "type" "multi")
7270 (set_attr "mode" "<MODE>")])
7272 (define_insn_and_split "*udivmod<mode>4"
7273 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7274 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7275 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7276 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7277 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7278 (clobber (reg:CC FLAGS_REG))]
7282 [(set (match_dup 1) (const_int 0))
7283 (parallel [(set (match_dup 0)
7284 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7286 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7288 (clobber (reg:CC FLAGS_REG))])]
7290 [(set_attr "type" "multi")
7291 (set_attr "mode" "<MODE>")])
7293 (define_insn "*udivmod<mode>4_noext"
7294 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7295 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7296 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7297 (set (match_operand:SWIM248 1 "register_operand" "=d")
7298 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7299 (use (match_operand:SWIM248 4 "register_operand" "1"))
7300 (clobber (reg:CC FLAGS_REG))]
7302 "div{<imodesuffix>}\t%3"
7303 [(set_attr "type" "idiv")
7304 (set_attr "mode" "<MODE>")])
7306 (define_expand "udivmodqi4"
7307 [(parallel [(set (match_operand:QI 0 "register_operand")
7309 (match_operand:QI 1 "register_operand")
7310 (match_operand:QI 2 "nonimmediate_operand")))
7311 (set (match_operand:QI 3 "register_operand")
7312 (umod:QI (match_dup 1) (match_dup 2)))
7313 (clobber (reg:CC FLAGS_REG))])]
7314 "TARGET_QIMODE_MATH"
7319 tmp0 = gen_reg_rtx (HImode);
7320 tmp1 = gen_reg_rtx (HImode);
7322 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7324 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7325 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7327 /* Extract remainder from AH. */
7328 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7329 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7330 insn = emit_move_insn (operands[3], tmp1);
7332 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7333 set_unique_reg_note (insn, REG_EQUAL, mod);
7335 /* Extract quotient from AL. */
7336 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7338 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7339 set_unique_reg_note (insn, REG_EQUAL, div);
7344 (define_insn "udivmodhiqi3"
7345 [(set (match_operand:HI 0 "register_operand" "=a")
7350 (mod:HI (match_operand:HI 1 "register_operand" "0")
7352 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7356 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7357 (clobber (reg:CC FLAGS_REG))]
7358 "TARGET_QIMODE_MATH"
7360 [(set_attr "type" "idiv")
7361 (set_attr "mode" "QI")])
7363 ;; We cannot use div/idiv for double division, because it causes
7364 ;; "division by zero" on the overflow and that's not what we expect
7365 ;; from truncate. Because true (non truncating) double division is
7366 ;; never generated, we can't create this insn anyway.
7369 ; [(set (match_operand:SI 0 "register_operand" "=a")
7371 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7373 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7374 ; (set (match_operand:SI 3 "register_operand" "=d")
7376 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7377 ; (clobber (reg:CC FLAGS_REG))]
7379 ; "div{l}\t{%2, %0|%0, %2}"
7380 ; [(set_attr "type" "idiv")])
7382 ;;- Logical AND instructions
7384 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7385 ;; Note that this excludes ah.
7387 (define_expand "testsi_ccno_1"
7388 [(set (reg:CCNO FLAGS_REG)
7390 (and:SI (match_operand:SI 0 "nonimmediate_operand")
7391 (match_operand:SI 1 "x86_64_nonmemory_operand"))
7394 (define_expand "testqi_ccz_1"
7395 [(set (reg:CCZ FLAGS_REG)
7396 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7397 (match_operand:QI 1 "nonmemory_operand"))
7400 (define_expand "testdi_ccno_1"
7401 [(set (reg:CCNO FLAGS_REG)
7403 (and:DI (match_operand:DI 0 "nonimmediate_operand")
7404 (match_operand:DI 1 "x86_64_szext_general_operand"))
7406 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7408 (define_insn "*testdi_1"
7409 [(set (reg FLAGS_REG)
7412 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7413 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7415 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7416 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7418 test{l}\t{%k1, %k0|%k0, %k1}
7419 test{l}\t{%k1, %k0|%k0, %k1}
7420 test{q}\t{%1, %0|%0, %1}
7421 test{q}\t{%1, %0|%0, %1}
7422 test{q}\t{%1, %0|%0, %1}"
7423 [(set_attr "type" "test")
7424 (set_attr "modrm" "0,1,0,1,1")
7425 (set_attr "mode" "SI,SI,DI,DI,DI")])
7427 (define_insn "*testqi_1_maybe_si"
7428 [(set (reg FLAGS_REG)
7431 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7432 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7434 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7435 && ix86_match_ccmode (insn,
7436 CONST_INT_P (operands[1])
7437 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7439 if (which_alternative == 3)
7441 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7442 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7443 return "test{l}\t{%1, %k0|%k0, %1}";
7445 return "test{b}\t{%1, %0|%0, %1}";
7447 [(set_attr "type" "test")
7448 (set_attr "modrm" "0,1,1,1")
7449 (set_attr "mode" "QI,QI,QI,SI")
7450 (set_attr "pent_pair" "uv,np,uv,np")])
7452 (define_insn "*test<mode>_1"
7453 [(set (reg FLAGS_REG)
7456 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7457 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7459 "ix86_match_ccmode (insn, CCNOmode)
7460 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7461 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7462 [(set_attr "type" "test")
7463 (set_attr "modrm" "0,1,1")
7464 (set_attr "mode" "<MODE>")
7465 (set_attr "pent_pair" "uv,np,uv")])
7467 (define_expand "testqi_ext_ccno_0"
7468 [(set (reg:CCNO FLAGS_REG)
7472 (match_operand 0 "ext_register_operand")
7475 (match_operand 1 "const_int_operand"))
7478 (define_insn "*testqi_ext_0"
7479 [(set (reg FLAGS_REG)
7483 (match_operand 0 "ext_register_operand" "Q")
7486 (match_operand 1 "const_int_operand" "n"))
7488 "ix86_match_ccmode (insn, CCNOmode)"
7489 "test{b}\t{%1, %h0|%h0, %1}"
7490 [(set_attr "type" "test")
7491 (set_attr "mode" "QI")
7492 (set_attr "length_immediate" "1")
7493 (set_attr "modrm" "1")
7494 (set_attr "pent_pair" "np")])
7496 (define_insn "*testqi_ext_1_rex64"
7497 [(set (reg FLAGS_REG)
7501 (match_operand 0 "ext_register_operand" "Q")
7505 (match_operand:QI 1 "register_operand" "Q")))
7507 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7508 "test{b}\t{%1, %h0|%h0, %1}"
7509 [(set_attr "type" "test")
7510 (set_attr "mode" "QI")])
7512 (define_insn "*testqi_ext_1"
7513 [(set (reg FLAGS_REG)
7517 (match_operand 0 "ext_register_operand" "Q")
7521 (match_operand:QI 1 "general_operand" "Qm")))
7523 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7524 "test{b}\t{%1, %h0|%h0, %1}"
7525 [(set_attr "type" "test")
7526 (set_attr "mode" "QI")])
7528 (define_insn "*testqi_ext_2"
7529 [(set (reg FLAGS_REG)
7533 (match_operand 0 "ext_register_operand" "Q")
7537 (match_operand 1 "ext_register_operand" "Q")
7541 "ix86_match_ccmode (insn, CCNOmode)"
7542 "test{b}\t{%h1, %h0|%h0, %h1}"
7543 [(set_attr "type" "test")
7544 (set_attr "mode" "QI")])
7546 (define_insn "*testqi_ext_3_rex64"
7547 [(set (reg FLAGS_REG)
7548 (compare (zero_extract:DI
7549 (match_operand 0 "nonimmediate_operand" "rm")
7550 (match_operand:DI 1 "const_int_operand")
7551 (match_operand:DI 2 "const_int_operand"))
7554 && ix86_match_ccmode (insn, CCNOmode)
7555 && INTVAL (operands[1]) > 0
7556 && INTVAL (operands[2]) >= 0
7557 /* Ensure that resulting mask is zero or sign extended operand. */
7558 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7559 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7560 && INTVAL (operands[1]) > 32))
7561 && (GET_MODE (operands[0]) == SImode
7562 || GET_MODE (operands[0]) == DImode
7563 || GET_MODE (operands[0]) == HImode
7564 || GET_MODE (operands[0]) == QImode)"
7567 ;; Combine likes to form bit extractions for some tests. Humor it.
7568 (define_insn "*testqi_ext_3"
7569 [(set (reg FLAGS_REG)
7570 (compare (zero_extract:SI
7571 (match_operand 0 "nonimmediate_operand" "rm")
7572 (match_operand:SI 1 "const_int_operand")
7573 (match_operand:SI 2 "const_int_operand"))
7575 "ix86_match_ccmode (insn, CCNOmode)
7576 && INTVAL (operands[1]) > 0
7577 && INTVAL (operands[2]) >= 0
7578 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7579 && (GET_MODE (operands[0]) == SImode
7580 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7581 || GET_MODE (operands[0]) == HImode
7582 || GET_MODE (operands[0]) == QImode)"
7586 [(set (match_operand 0 "flags_reg_operand")
7587 (match_operator 1 "compare_operator"
7589 (match_operand 2 "nonimmediate_operand")
7590 (match_operand 3 "const_int_operand")
7591 (match_operand 4 "const_int_operand"))
7593 "ix86_match_ccmode (insn, CCNOmode)"
7594 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7596 rtx val = operands[2];
7597 HOST_WIDE_INT len = INTVAL (operands[3]);
7598 HOST_WIDE_INT pos = INTVAL (operands[4]);
7600 enum machine_mode mode, submode;
7602 mode = GET_MODE (val);
7605 /* ??? Combine likes to put non-volatile mem extractions in QImode
7606 no matter the size of the test. So find a mode that works. */
7607 if (! MEM_VOLATILE_P (val))
7609 mode = smallest_mode_for_size (pos + len, MODE_INT);
7610 val = adjust_address (val, mode, 0);
7613 else if (GET_CODE (val) == SUBREG
7614 && (submode = GET_MODE (SUBREG_REG (val)),
7615 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7616 && pos + len <= GET_MODE_BITSIZE (submode)
7617 && GET_MODE_CLASS (submode) == MODE_INT)
7619 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7621 val = SUBREG_REG (val);
7623 else if (mode == HImode && pos + len <= 8)
7625 /* Small HImode tests can be converted to QImode. */
7627 val = gen_lowpart (QImode, val);
7630 if (len == HOST_BITS_PER_WIDE_INT)
7633 mask = ((HOST_WIDE_INT)1 << len) - 1;
7636 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7639 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7640 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7641 ;; this is relatively important trick.
7642 ;; Do the conversion only post-reload to avoid limiting of the register class
7645 [(set (match_operand 0 "flags_reg_operand")
7646 (match_operator 1 "compare_operator"
7647 [(and (match_operand 2 "register_operand")
7648 (match_operand 3 "const_int_operand"))
7651 && QI_REG_P (operands[2])
7652 && GET_MODE (operands[2]) != QImode
7653 && ((ix86_match_ccmode (insn, CCZmode)
7654 && !(INTVAL (operands[3]) & ~(255 << 8)))
7655 || (ix86_match_ccmode (insn, CCNOmode)
7656 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7659 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7663 operands[2] = gen_lowpart (SImode, operands[2]);
7664 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7668 [(set (match_operand 0 "flags_reg_operand")
7669 (match_operator 1 "compare_operator"
7670 [(and (match_operand 2 "nonimmediate_operand")
7671 (match_operand 3 "const_int_operand"))
7674 && GET_MODE (operands[2]) != QImode
7675 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7676 && ((ix86_match_ccmode (insn, CCZmode)
7677 && !(INTVAL (operands[3]) & ~255))
7678 || (ix86_match_ccmode (insn, CCNOmode)
7679 && !(INTVAL (operands[3]) & ~127)))"
7681 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7684 operands[2] = gen_lowpart (QImode, operands[2]);
7685 operands[3] = gen_lowpart (QImode, operands[3]);
7688 ;; %%% This used to optimize known byte-wide and operations to memory,
7689 ;; and sometimes to QImode registers. If this is considered useful,
7690 ;; it should be done with splitters.
7692 (define_expand "and<mode>3"
7693 [(set (match_operand:SWIM 0 "nonimmediate_operand")
7694 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7695 (match_operand:SWIM 2 "<general_szext_operand>")))]
7698 enum machine_mode mode = GET_MODE (operands[1]);
7699 rtx (*insn) (rtx, rtx);
7701 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7703 HOST_WIDE_INT ival = INTVAL (operands[2]);
7705 if (ival == (HOST_WIDE_INT) 0xffffffff)
7707 else if (ival == 0xffff)
7709 else if (ival == 0xff)
7713 if (mode == GET_MODE (operands[1]))
7715 ix86_expand_binary_operator (AND, <MODE>mode, operands);
7719 operands[1] = gen_lowpart (mode, operands[1]);
7721 if (GET_MODE (operands[0]) == DImode)
7722 insn = (mode == SImode)
7723 ? gen_zero_extendsidi2
7725 ? gen_zero_extendhidi2
7726 : gen_zero_extendqidi2;
7727 else if (GET_MODE (operands[0]) == SImode)
7728 insn = (mode == HImode)
7729 ? gen_zero_extendhisi2
7730 : gen_zero_extendqisi2;
7731 else if (GET_MODE (operands[0]) == HImode)
7732 insn = gen_zero_extendqihi2;
7736 emit_insn (insn (operands[0], operands[1]));
7740 (define_insn "*anddi_1"
7741 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7743 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7744 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7745 (clobber (reg:CC FLAGS_REG))]
7746 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7748 switch (get_attr_type (insn))
7754 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7755 if (get_attr_mode (insn) == MODE_SI)
7756 return "and{l}\t{%k2, %k0|%k0, %k2}";
7758 return "and{q}\t{%2, %0|%0, %2}";
7761 [(set_attr "type" "alu,alu,alu,imovx")
7762 (set_attr "length_immediate" "*,*,*,0")
7763 (set (attr "prefix_rex")
7765 (and (eq_attr "type" "imovx")
7766 (and (match_test "INTVAL (operands[2]) == 0xff")
7767 (match_operand 1 "ext_QIreg_operand")))
7769 (const_string "*")))
7770 (set_attr "mode" "SI,DI,DI,SI")])
7772 (define_insn "*andsi_1"
7773 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya")
7774 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7775 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7776 (clobber (reg:CC FLAGS_REG))]
7777 "ix86_binary_operator_ok (AND, SImode, operands)"
7779 switch (get_attr_type (insn))
7785 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7786 return "and{l}\t{%2, %0|%0, %2}";
7789 [(set_attr "type" "alu,alu,imovx")
7790 (set (attr "prefix_rex")
7792 (and (eq_attr "type" "imovx")
7793 (and (match_test "INTVAL (operands[2]) == 0xff")
7794 (match_operand 1 "ext_QIreg_operand")))
7796 (const_string "*")))
7797 (set_attr "length_immediate" "*,*,0")
7798 (set_attr "mode" "SI")])
7800 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7801 (define_insn "*andsi_1_zext"
7802 [(set (match_operand:DI 0 "register_operand" "=r")
7804 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7805 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7806 (clobber (reg:CC FLAGS_REG))]
7807 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7808 "and{l}\t{%2, %k0|%k0, %2}"
7809 [(set_attr "type" "alu")
7810 (set_attr "mode" "SI")])
7812 (define_insn "*andhi_1"
7813 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya")
7814 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7815 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7816 (clobber (reg:CC FLAGS_REG))]
7817 "ix86_binary_operator_ok (AND, HImode, operands)"
7819 switch (get_attr_type (insn))
7825 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7826 return "and{w}\t{%2, %0|%0, %2}";
7829 [(set_attr "type" "alu,alu,imovx")
7830 (set_attr "length_immediate" "*,*,0")
7831 (set (attr "prefix_rex")
7833 (and (eq_attr "type" "imovx")
7834 (match_operand 1 "ext_QIreg_operand"))
7836 (const_string "*")))
7837 (set_attr "mode" "HI,HI,SI")])
7839 ;; %%% Potential partial reg stall on alternative 2. What to do?
7840 (define_insn "*andqi_1"
7841 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7842 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7843 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7844 (clobber (reg:CC FLAGS_REG))]
7845 "ix86_binary_operator_ok (AND, QImode, operands)"
7847 and{b}\t{%2, %0|%0, %2}
7848 and{b}\t{%2, %0|%0, %2}
7849 and{l}\t{%k2, %k0|%k0, %k2}"
7850 [(set_attr "type" "alu")
7851 (set_attr "mode" "QI,QI,SI")])
7853 (define_insn "*andqi_1_slp"
7854 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7855 (and:QI (match_dup 0)
7856 (match_operand:QI 1 "general_operand" "qn,qmn")))
7857 (clobber (reg:CC FLAGS_REG))]
7858 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7859 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7860 "and{b}\t{%1, %0|%0, %1}"
7861 [(set_attr "type" "alu1")
7862 (set_attr "mode" "QI")])
7865 [(set (match_operand:SWI248 0 "register_operand")
7866 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
7867 (match_operand:SWI248 2 "const_int_operand")))
7868 (clobber (reg:CC FLAGS_REG))]
7870 && true_regnum (operands[0]) != true_regnum (operands[1])"
7873 HOST_WIDE_INT ival = INTVAL (operands[2]);
7874 enum machine_mode mode;
7875 rtx (*insn) (rtx, rtx);
7877 if (ival == (HOST_WIDE_INT) 0xffffffff)
7879 else if (ival == 0xffff)
7883 gcc_assert (ival == 0xff);
7887 operands[1] = gen_lowpart (mode, operands[1]);
7889 if (GET_MODE (operands[0]) == DImode)
7890 insn = (mode == SImode)
7891 ? gen_zero_extendsidi2
7893 ? gen_zero_extendhidi2
7894 : gen_zero_extendqidi2;
7897 /* Zero extend to SImode to avoid partial register stalls. */
7898 operands[0] = gen_lowpart (SImode, operands[0]);
7900 insn = (mode == HImode)
7901 ? gen_zero_extendhisi2
7902 : gen_zero_extendqisi2;
7904 emit_insn (insn (operands[0], operands[1]));
7909 [(set (match_operand 0 "register_operand")
7911 (const_int -65536)))
7912 (clobber (reg:CC FLAGS_REG))]
7913 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7914 || optimize_function_for_size_p (cfun)"
7915 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7916 "operands[1] = gen_lowpart (HImode, operands[0]);")
7919 [(set (match_operand 0 "ext_register_operand")
7922 (clobber (reg:CC FLAGS_REG))]
7923 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7924 && reload_completed"
7925 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7926 "operands[1] = gen_lowpart (QImode, operands[0]);")
7929 [(set (match_operand 0 "ext_register_operand")
7931 (const_int -65281)))
7932 (clobber (reg:CC FLAGS_REG))]
7933 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7934 && reload_completed"
7935 [(parallel [(set (zero_extract:SI (match_dup 0)
7939 (zero_extract:SI (match_dup 0)
7942 (zero_extract:SI (match_dup 0)
7945 (clobber (reg:CC FLAGS_REG))])]
7946 "operands[0] = gen_lowpart (SImode, operands[0]);")
7948 (define_insn "*anddi_2"
7949 [(set (reg FLAGS_REG)
7952 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7953 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7955 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7956 (and:DI (match_dup 1) (match_dup 2)))]
7957 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7958 && ix86_binary_operator_ok (AND, DImode, operands)"
7960 and{l}\t{%k2, %k0|%k0, %k2}
7961 and{q}\t{%2, %0|%0, %2}
7962 and{q}\t{%2, %0|%0, %2}"
7963 [(set_attr "type" "alu")
7964 (set_attr "mode" "SI,DI,DI")])
7966 (define_insn "*andqi_2_maybe_si"
7967 [(set (reg FLAGS_REG)
7969 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7970 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7972 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7973 (and:QI (match_dup 1) (match_dup 2)))]
7974 "ix86_binary_operator_ok (AND, QImode, operands)
7975 && ix86_match_ccmode (insn,
7976 CONST_INT_P (operands[2])
7977 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7979 if (which_alternative == 2)
7981 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7982 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7983 return "and{l}\t{%2, %k0|%k0, %2}";
7985 return "and{b}\t{%2, %0|%0, %2}";
7987 [(set_attr "type" "alu")
7988 (set_attr "mode" "QI,QI,SI")])
7990 (define_insn "*and<mode>_2"
7991 [(set (reg FLAGS_REG)
7992 (compare (and:SWI124
7993 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7994 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7996 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7997 (and:SWI124 (match_dup 1) (match_dup 2)))]
7998 "ix86_match_ccmode (insn, CCNOmode)
7999 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8000 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8001 [(set_attr "type" "alu")
8002 (set_attr "mode" "<MODE>")])
8004 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8005 (define_insn "*andsi_2_zext"
8006 [(set (reg FLAGS_REG)
8008 (match_operand:SI 1 "nonimmediate_operand" "%0")
8009 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8011 (set (match_operand:DI 0 "register_operand" "=r")
8012 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8013 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8014 && ix86_binary_operator_ok (AND, SImode, operands)"
8015 "and{l}\t{%2, %k0|%k0, %2}"
8016 [(set_attr "type" "alu")
8017 (set_attr "mode" "SI")])
8019 (define_insn "*andqi_2_slp"
8020 [(set (reg FLAGS_REG)
8022 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8023 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8025 (set (strict_low_part (match_dup 0))
8026 (and:QI (match_dup 0) (match_dup 1)))]
8027 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8028 && ix86_match_ccmode (insn, CCNOmode)
8029 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8030 "and{b}\t{%1, %0|%0, %1}"
8031 [(set_attr "type" "alu1")
8032 (set_attr "mode" "QI")])
8034 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8035 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8036 ;; for a QImode operand, which of course failed.
8037 (define_insn "andqi_ext_0"
8038 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8043 (match_operand 1 "ext_register_operand" "0")
8046 (match_operand 2 "const_int_operand" "n")))
8047 (clobber (reg:CC FLAGS_REG))]
8049 "and{b}\t{%2, %h0|%h0, %2}"
8050 [(set_attr "type" "alu")
8051 (set_attr "length_immediate" "1")
8052 (set_attr "modrm" "1")
8053 (set_attr "mode" "QI")])
8055 ;; Generated by peephole translating test to and. This shows up
8056 ;; often in fp comparisons.
8057 (define_insn "*andqi_ext_0_cc"
8058 [(set (reg FLAGS_REG)
8062 (match_operand 1 "ext_register_operand" "0")
8065 (match_operand 2 "const_int_operand" "n"))
8067 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8076 "ix86_match_ccmode (insn, CCNOmode)"
8077 "and{b}\t{%2, %h0|%h0, %2}"
8078 [(set_attr "type" "alu")
8079 (set_attr "length_immediate" "1")
8080 (set_attr "modrm" "1")
8081 (set_attr "mode" "QI")])
8083 (define_insn "*andqi_ext_1_rex64"
8084 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8089 (match_operand 1 "ext_register_operand" "0")
8093 (match_operand 2 "ext_register_operand" "Q"))))
8094 (clobber (reg:CC FLAGS_REG))]
8096 "and{b}\t{%2, %h0|%h0, %2}"
8097 [(set_attr "type" "alu")
8098 (set_attr "length_immediate" "0")
8099 (set_attr "mode" "QI")])
8101 (define_insn "*andqi_ext_1"
8102 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8107 (match_operand 1 "ext_register_operand" "0")
8111 (match_operand:QI 2 "general_operand" "Qm"))))
8112 (clobber (reg:CC FLAGS_REG))]
8114 "and{b}\t{%2, %h0|%h0, %2}"
8115 [(set_attr "type" "alu")
8116 (set_attr "length_immediate" "0")
8117 (set_attr "mode" "QI")])
8119 (define_insn "*andqi_ext_2"
8120 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8125 (match_operand 1 "ext_register_operand" "%0")
8129 (match_operand 2 "ext_register_operand" "Q")
8132 (clobber (reg:CC FLAGS_REG))]
8134 "and{b}\t{%h2, %h0|%h0, %h2}"
8135 [(set_attr "type" "alu")
8136 (set_attr "length_immediate" "0")
8137 (set_attr "mode" "QI")])
8139 ;; Convert wide AND instructions with immediate operand to shorter QImode
8140 ;; equivalents when possible.
8141 ;; Don't do the splitting with memory operands, since it introduces risk
8142 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8143 ;; for size, but that can (should?) be handled by generic code instead.
8145 [(set (match_operand 0 "register_operand")
8146 (and (match_operand 1 "register_operand")
8147 (match_operand 2 "const_int_operand")))
8148 (clobber (reg:CC FLAGS_REG))]
8150 && QI_REG_P (operands[0])
8151 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8152 && !(~INTVAL (operands[2]) & ~(255 << 8))
8153 && GET_MODE (operands[0]) != QImode"
8154 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8155 (and:SI (zero_extract:SI (match_dup 1)
8156 (const_int 8) (const_int 8))
8158 (clobber (reg:CC FLAGS_REG))])]
8160 operands[0] = gen_lowpart (SImode, operands[0]);
8161 operands[1] = gen_lowpart (SImode, operands[1]);
8162 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8165 ;; Since AND can be encoded with sign extended immediate, this is only
8166 ;; profitable when 7th bit is not set.
8168 [(set (match_operand 0 "register_operand")
8169 (and (match_operand 1 "general_operand")
8170 (match_operand 2 "const_int_operand")))
8171 (clobber (reg:CC FLAGS_REG))]
8173 && ANY_QI_REG_P (operands[0])
8174 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8175 && !(~INTVAL (operands[2]) & ~255)
8176 && !(INTVAL (operands[2]) & 128)
8177 && GET_MODE (operands[0]) != QImode"
8178 [(parallel [(set (strict_low_part (match_dup 0))
8179 (and:QI (match_dup 1)
8181 (clobber (reg:CC FLAGS_REG))])]
8183 operands[0] = gen_lowpart (QImode, operands[0]);
8184 operands[1] = gen_lowpart (QImode, operands[1]);
8185 operands[2] = gen_lowpart (QImode, operands[2]);
8188 ;; Logical inclusive and exclusive OR instructions
8190 ;; %%% This used to optimize known byte-wide and operations to memory.
8191 ;; If this is considered useful, it should be done with splitters.
8193 (define_expand "<code><mode>3"
8194 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8195 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
8196 (match_operand:SWIM 2 "<general_operand>")))]
8198 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8200 (define_insn "*<code><mode>_1"
8201 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8203 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8204 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8205 (clobber (reg:CC FLAGS_REG))]
8206 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8207 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8208 [(set_attr "type" "alu")
8209 (set_attr "mode" "<MODE>")])
8211 ;; %%% Potential partial reg stall on alternative 2. What to do?
8212 (define_insn "*<code>qi_1"
8213 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8214 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8215 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8216 (clobber (reg:CC FLAGS_REG))]
8217 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8219 <logic>{b}\t{%2, %0|%0, %2}
8220 <logic>{b}\t{%2, %0|%0, %2}
8221 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8222 [(set_attr "type" "alu")
8223 (set_attr "mode" "QI,QI,SI")])
8225 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8226 (define_insn "*<code>si_1_zext"
8227 [(set (match_operand:DI 0 "register_operand" "=r")
8229 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8230 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8231 (clobber (reg:CC FLAGS_REG))]
8232 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8233 "<logic>{l}\t{%2, %k0|%k0, %2}"
8234 [(set_attr "type" "alu")
8235 (set_attr "mode" "SI")])
8237 (define_insn "*<code>si_1_zext_imm"
8238 [(set (match_operand:DI 0 "register_operand" "=r")
8240 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8241 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8242 (clobber (reg:CC FLAGS_REG))]
8243 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8244 "<logic>{l}\t{%2, %k0|%k0, %2}"
8245 [(set_attr "type" "alu")
8246 (set_attr "mode" "SI")])
8248 (define_insn "*<code>qi_1_slp"
8249 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8250 (any_or:QI (match_dup 0)
8251 (match_operand:QI 1 "general_operand" "qmn,qn")))
8252 (clobber (reg:CC FLAGS_REG))]
8253 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8254 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8255 "<logic>{b}\t{%1, %0|%0, %1}"
8256 [(set_attr "type" "alu1")
8257 (set_attr "mode" "QI")])
8259 (define_insn "*<code><mode>_2"
8260 [(set (reg FLAGS_REG)
8261 (compare (any_or:SWI
8262 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8263 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8265 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8266 (any_or:SWI (match_dup 1) (match_dup 2)))]
8267 "ix86_match_ccmode (insn, CCNOmode)
8268 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8269 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8270 [(set_attr "type" "alu")
8271 (set_attr "mode" "<MODE>")])
8273 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8274 ;; ??? Special case for immediate operand is missing - it is tricky.
8275 (define_insn "*<code>si_2_zext"
8276 [(set (reg FLAGS_REG)
8277 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8278 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8280 (set (match_operand:DI 0 "register_operand" "=r")
8281 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8282 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8283 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8284 "<logic>{l}\t{%2, %k0|%k0, %2}"
8285 [(set_attr "type" "alu")
8286 (set_attr "mode" "SI")])
8288 (define_insn "*<code>si_2_zext_imm"
8289 [(set (reg FLAGS_REG)
8291 (match_operand:SI 1 "nonimmediate_operand" "%0")
8292 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8294 (set (match_operand:DI 0 "register_operand" "=r")
8295 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8296 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8297 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8298 "<logic>{l}\t{%2, %k0|%k0, %2}"
8299 [(set_attr "type" "alu")
8300 (set_attr "mode" "SI")])
8302 (define_insn "*<code>qi_2_slp"
8303 [(set (reg FLAGS_REG)
8304 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8305 (match_operand:QI 1 "general_operand" "qmn,qn"))
8307 (set (strict_low_part (match_dup 0))
8308 (any_or:QI (match_dup 0) (match_dup 1)))]
8309 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8310 && ix86_match_ccmode (insn, CCNOmode)
8311 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8312 "<logic>{b}\t{%1, %0|%0, %1}"
8313 [(set_attr "type" "alu1")
8314 (set_attr "mode" "QI")])
8316 (define_insn "*<code><mode>_3"
8317 [(set (reg FLAGS_REG)
8318 (compare (any_or:SWI
8319 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8320 (match_operand:SWI 2 "<general_operand>" "<g>"))
8322 (clobber (match_scratch:SWI 0 "=<r>"))]
8323 "ix86_match_ccmode (insn, CCNOmode)
8324 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8325 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8326 [(set_attr "type" "alu")
8327 (set_attr "mode" "<MODE>")])
8329 (define_insn "*<code>qi_ext_0"
8330 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8335 (match_operand 1 "ext_register_operand" "0")
8338 (match_operand 2 "const_int_operand" "n")))
8339 (clobber (reg:CC FLAGS_REG))]
8340 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8341 "<logic>{b}\t{%2, %h0|%h0, %2}"
8342 [(set_attr "type" "alu")
8343 (set_attr "length_immediate" "1")
8344 (set_attr "modrm" "1")
8345 (set_attr "mode" "QI")])
8347 (define_insn "*<code>qi_ext_1_rex64"
8348 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8353 (match_operand 1 "ext_register_operand" "0")
8357 (match_operand 2 "ext_register_operand" "Q"))))
8358 (clobber (reg:CC FLAGS_REG))]
8360 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8361 "<logic>{b}\t{%2, %h0|%h0, %2}"
8362 [(set_attr "type" "alu")
8363 (set_attr "length_immediate" "0")
8364 (set_attr "mode" "QI")])
8366 (define_insn "*<code>qi_ext_1"
8367 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8372 (match_operand 1 "ext_register_operand" "0")
8376 (match_operand:QI 2 "general_operand" "Qm"))))
8377 (clobber (reg:CC FLAGS_REG))]
8379 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8380 "<logic>{b}\t{%2, %h0|%h0, %2}"
8381 [(set_attr "type" "alu")
8382 (set_attr "length_immediate" "0")
8383 (set_attr "mode" "QI")])
8385 (define_insn "*<code>qi_ext_2"
8386 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8390 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8393 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8396 (clobber (reg:CC FLAGS_REG))]
8397 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8398 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8399 [(set_attr "type" "alu")
8400 (set_attr "length_immediate" "0")
8401 (set_attr "mode" "QI")])
8404 [(set (match_operand 0 "register_operand")
8405 (any_or (match_operand 1 "register_operand")
8406 (match_operand 2 "const_int_operand")))
8407 (clobber (reg:CC FLAGS_REG))]
8409 && QI_REG_P (operands[0])
8410 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8411 && !(INTVAL (operands[2]) & ~(255 << 8))
8412 && GET_MODE (operands[0]) != QImode"
8413 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8414 (any_or:SI (zero_extract:SI (match_dup 1)
8415 (const_int 8) (const_int 8))
8417 (clobber (reg:CC FLAGS_REG))])]
8419 operands[0] = gen_lowpart (SImode, operands[0]);
8420 operands[1] = gen_lowpart (SImode, operands[1]);
8421 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8424 ;; Since OR can be encoded with sign extended immediate, this is only
8425 ;; profitable when 7th bit is set.
8427 [(set (match_operand 0 "register_operand")
8428 (any_or (match_operand 1 "general_operand")
8429 (match_operand 2 "const_int_operand")))
8430 (clobber (reg:CC FLAGS_REG))]
8432 && ANY_QI_REG_P (operands[0])
8433 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8434 && !(INTVAL (operands[2]) & ~255)
8435 && (INTVAL (operands[2]) & 128)
8436 && GET_MODE (operands[0]) != QImode"
8437 [(parallel [(set (strict_low_part (match_dup 0))
8438 (any_or:QI (match_dup 1)
8440 (clobber (reg:CC FLAGS_REG))])]
8442 operands[0] = gen_lowpart (QImode, operands[0]);
8443 operands[1] = gen_lowpart (QImode, operands[1]);
8444 operands[2] = gen_lowpart (QImode, operands[2]);
8447 (define_expand "xorqi_cc_ext_1"
8449 (set (reg:CCNO FLAGS_REG)
8453 (match_operand 1 "ext_register_operand")
8456 (match_operand:QI 2 "general_operand"))
8458 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8468 (define_insn "*xorqi_cc_ext_1_rex64"
8469 [(set (reg FLAGS_REG)
8473 (match_operand 1 "ext_register_operand" "0")
8476 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8478 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8487 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8488 "xor{b}\t{%2, %h0|%h0, %2}"
8489 [(set_attr "type" "alu")
8490 (set_attr "modrm" "1")
8491 (set_attr "mode" "QI")])
8493 (define_insn "*xorqi_cc_ext_1"
8494 [(set (reg FLAGS_REG)
8498 (match_operand 1 "ext_register_operand" "0")
8501 (match_operand:QI 2 "general_operand" "qmn"))
8503 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8512 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8513 "xor{b}\t{%2, %h0|%h0, %2}"
8514 [(set_attr "type" "alu")
8515 (set_attr "modrm" "1")
8516 (set_attr "mode" "QI")])
8518 ;; Negation instructions
8520 (define_expand "neg<mode>2"
8521 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8522 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8524 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8526 (define_insn_and_split "*neg<dwi>2_doubleword"
8527 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8528 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8529 (clobber (reg:CC FLAGS_REG))]
8530 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8534 [(set (reg:CCZ FLAGS_REG)
8535 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8536 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8539 (plus:DWIH (match_dup 3)
8540 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8542 (clobber (reg:CC FLAGS_REG))])
8545 (neg:DWIH (match_dup 2)))
8546 (clobber (reg:CC FLAGS_REG))])]
8547 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8549 (define_insn "*neg<mode>2_1"
8550 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8551 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8552 (clobber (reg:CC FLAGS_REG))]
8553 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8554 "neg{<imodesuffix>}\t%0"
8555 [(set_attr "type" "negnot")
8556 (set_attr "mode" "<MODE>")])
8558 ;; Combine is quite creative about this pattern.
8559 (define_insn "*negsi2_1_zext"
8560 [(set (match_operand:DI 0 "register_operand" "=r")
8562 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8565 (clobber (reg:CC FLAGS_REG))]
8566 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8568 [(set_attr "type" "negnot")
8569 (set_attr "mode" "SI")])
8571 ;; The problem with neg is that it does not perform (compare x 0),
8572 ;; it really performs (compare 0 x), which leaves us with the zero
8573 ;; flag being the only useful item.
8575 (define_insn "*neg<mode>2_cmpz"
8576 [(set (reg:CCZ FLAGS_REG)
8578 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8580 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8581 (neg:SWI (match_dup 1)))]
8582 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8583 "neg{<imodesuffix>}\t%0"
8584 [(set_attr "type" "negnot")
8585 (set_attr "mode" "<MODE>")])
8587 (define_insn "*negsi2_cmpz_zext"
8588 [(set (reg:CCZ FLAGS_REG)
8592 (match_operand:DI 1 "register_operand" "0")
8596 (set (match_operand:DI 0 "register_operand" "=r")
8597 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8600 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8602 [(set_attr "type" "negnot")
8603 (set_attr "mode" "SI")])
8605 ;; Changing of sign for FP values is doable using integer unit too.
8607 (define_expand "<code><mode>2"
8608 [(set (match_operand:X87MODEF 0 "register_operand")
8609 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8610 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8611 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8613 (define_insn "*absneg<mode>2_mixed"
8614 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8615 (match_operator:MODEF 3 "absneg_operator"
8616 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8617 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8618 (clobber (reg:CC FLAGS_REG))]
8619 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8622 (define_insn "*absneg<mode>2_sse"
8623 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8624 (match_operator:MODEF 3 "absneg_operator"
8625 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8626 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8627 (clobber (reg:CC FLAGS_REG))]
8628 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8631 (define_insn "*absneg<mode>2_i387"
8632 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8633 (match_operator:X87MODEF 3 "absneg_operator"
8634 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8635 (use (match_operand 2))
8636 (clobber (reg:CC FLAGS_REG))]
8637 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8640 (define_expand "<code>tf2"
8641 [(set (match_operand:TF 0 "register_operand")
8642 (absneg:TF (match_operand:TF 1 "register_operand")))]
8644 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8646 (define_insn "*absnegtf2_sse"
8647 [(set (match_operand:TF 0 "register_operand" "=x,x")
8648 (match_operator:TF 3 "absneg_operator"
8649 [(match_operand:TF 1 "register_operand" "0,x")]))
8650 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8651 (clobber (reg:CC FLAGS_REG))]
8655 ;; Splitters for fp abs and neg.
8658 [(set (match_operand 0 "fp_register_operand")
8659 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8660 (use (match_operand 2))
8661 (clobber (reg:CC FLAGS_REG))]
8663 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8666 [(set (match_operand 0 "register_operand")
8667 (match_operator 3 "absneg_operator"
8668 [(match_operand 1 "register_operand")]))
8669 (use (match_operand 2 "nonimmediate_operand"))
8670 (clobber (reg:CC FLAGS_REG))]
8671 "reload_completed && SSE_REG_P (operands[0])"
8672 [(set (match_dup 0) (match_dup 3))]
8674 enum machine_mode mode = GET_MODE (operands[0]);
8675 enum machine_mode vmode = GET_MODE (operands[2]);
8678 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8679 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8680 if (operands_match_p (operands[0], operands[2]))
8683 operands[1] = operands[2];
8686 if (GET_CODE (operands[3]) == ABS)
8687 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8689 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8694 [(set (match_operand:SF 0 "register_operand")
8695 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8696 (use (match_operand:V4SF 2))
8697 (clobber (reg:CC FLAGS_REG))]
8699 [(parallel [(set (match_dup 0) (match_dup 1))
8700 (clobber (reg:CC FLAGS_REG))])]
8703 operands[0] = gen_lowpart (SImode, operands[0]);
8704 if (GET_CODE (operands[1]) == ABS)
8706 tmp = gen_int_mode (0x7fffffff, SImode);
8707 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8711 tmp = gen_int_mode (0x80000000, SImode);
8712 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8718 [(set (match_operand:DF 0 "register_operand")
8719 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8720 (use (match_operand 2))
8721 (clobber (reg:CC FLAGS_REG))]
8723 [(parallel [(set (match_dup 0) (match_dup 1))
8724 (clobber (reg:CC FLAGS_REG))])]
8729 tmp = gen_lowpart (DImode, operands[0]);
8730 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8733 if (GET_CODE (operands[1]) == ABS)
8736 tmp = gen_rtx_NOT (DImode, tmp);
8740 operands[0] = gen_highpart (SImode, operands[0]);
8741 if (GET_CODE (operands[1]) == ABS)
8743 tmp = gen_int_mode (0x7fffffff, SImode);
8744 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8748 tmp = gen_int_mode (0x80000000, SImode);
8749 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8756 [(set (match_operand:XF 0 "register_operand")
8757 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8758 (use (match_operand 2))
8759 (clobber (reg:CC FLAGS_REG))]
8761 [(parallel [(set (match_dup 0) (match_dup 1))
8762 (clobber (reg:CC FLAGS_REG))])]
8765 operands[0] = gen_rtx_REG (SImode,
8766 true_regnum (operands[0])
8767 + (TARGET_64BIT ? 1 : 2));
8768 if (GET_CODE (operands[1]) == ABS)
8770 tmp = GEN_INT (0x7fff);
8771 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8775 tmp = GEN_INT (0x8000);
8776 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8781 ;; Conditionalize these after reload. If they match before reload, we
8782 ;; lose the clobber and ability to use integer instructions.
8784 (define_insn "*<code><mode>2_1"
8785 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8786 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8788 && (reload_completed
8789 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8790 "f<absneg_mnemonic>"
8791 [(set_attr "type" "fsgn")
8792 (set_attr "mode" "<MODE>")])
8794 (define_insn "*<code>extendsfdf2"
8795 [(set (match_operand:DF 0 "register_operand" "=f")
8796 (absneg:DF (float_extend:DF
8797 (match_operand:SF 1 "register_operand" "0"))))]
8798 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8799 "f<absneg_mnemonic>"
8800 [(set_attr "type" "fsgn")
8801 (set_attr "mode" "DF")])
8803 (define_insn "*<code>extendsfxf2"
8804 [(set (match_operand:XF 0 "register_operand" "=f")
8805 (absneg:XF (float_extend:XF
8806 (match_operand:SF 1 "register_operand" "0"))))]
8808 "f<absneg_mnemonic>"
8809 [(set_attr "type" "fsgn")
8810 (set_attr "mode" "XF")])
8812 (define_insn "*<code>extenddfxf2"
8813 [(set (match_operand:XF 0 "register_operand" "=f")
8814 (absneg:XF (float_extend:XF
8815 (match_operand:DF 1 "register_operand" "0"))))]
8817 "f<absneg_mnemonic>"
8818 [(set_attr "type" "fsgn")
8819 (set_attr "mode" "XF")])
8821 ;; Copysign instructions
8823 (define_mode_iterator CSGNMODE [SF DF TF])
8824 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8826 (define_expand "copysign<mode>3"
8827 [(match_operand:CSGNMODE 0 "register_operand")
8828 (match_operand:CSGNMODE 1 "nonmemory_operand")
8829 (match_operand:CSGNMODE 2 "register_operand")]
8830 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8831 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8832 "ix86_expand_copysign (operands); DONE;")
8834 (define_insn_and_split "copysign<mode>3_const"
8835 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8837 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8838 (match_operand:CSGNMODE 2 "register_operand" "0")
8839 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8841 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8842 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8844 "&& reload_completed"
8846 "ix86_split_copysign_const (operands); DONE;")
8848 (define_insn "copysign<mode>3_var"
8849 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8851 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8852 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8853 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8854 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8856 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8857 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8858 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8862 [(set (match_operand:CSGNMODE 0 "register_operand")
8864 [(match_operand:CSGNMODE 2 "register_operand")
8865 (match_operand:CSGNMODE 3 "register_operand")
8866 (match_operand:<CSGNVMODE> 4)
8867 (match_operand:<CSGNVMODE> 5)]
8869 (clobber (match_scratch:<CSGNVMODE> 1))]
8870 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8871 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8872 && reload_completed"
8874 "ix86_split_copysign_var (operands); DONE;")
8876 ;; One complement instructions
8878 (define_expand "one_cmpl<mode>2"
8879 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8880 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
8882 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8884 (define_insn "*one_cmpl<mode>2_1"
8885 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8886 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8887 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8888 "not{<imodesuffix>}\t%0"
8889 [(set_attr "type" "negnot")
8890 (set_attr "mode" "<MODE>")])
8892 ;; %%% Potential partial reg stall on alternative 1. What to do?
8893 (define_insn "*one_cmplqi2_1"
8894 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8895 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8896 "ix86_unary_operator_ok (NOT, QImode, operands)"
8900 [(set_attr "type" "negnot")
8901 (set_attr "mode" "QI,SI")])
8903 ;; ??? Currently never generated - xor is used instead.
8904 (define_insn "*one_cmplsi2_1_zext"
8905 [(set (match_operand:DI 0 "register_operand" "=r")
8907 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8908 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8910 [(set_attr "type" "negnot")
8911 (set_attr "mode" "SI")])
8913 (define_insn "*one_cmpl<mode>2_2"
8914 [(set (reg FLAGS_REG)
8915 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8917 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8918 (not:SWI (match_dup 1)))]
8919 "ix86_match_ccmode (insn, CCNOmode)
8920 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8922 [(set_attr "type" "alu1")
8923 (set_attr "mode" "<MODE>")])
8926 [(set (match_operand 0 "flags_reg_operand")
8927 (match_operator 2 "compare_operator"
8928 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
8930 (set (match_operand:SWI 1 "nonimmediate_operand")
8931 (not:SWI (match_dup 3)))]
8932 "ix86_match_ccmode (insn, CCNOmode)"
8933 [(parallel [(set (match_dup 0)
8934 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8937 (xor:SWI (match_dup 3) (const_int -1)))])])
8939 ;; ??? Currently never generated - xor is used instead.
8940 (define_insn "*one_cmplsi2_2_zext"
8941 [(set (reg FLAGS_REG)
8942 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8944 (set (match_operand:DI 0 "register_operand" "=r")
8945 (zero_extend:DI (not:SI (match_dup 1))))]
8946 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8947 && ix86_unary_operator_ok (NOT, SImode, operands)"
8949 [(set_attr "type" "alu1")
8950 (set_attr "mode" "SI")])
8953 [(set (match_operand 0 "flags_reg_operand")
8954 (match_operator 2 "compare_operator"
8955 [(not:SI (match_operand:SI 3 "register_operand"))
8957 (set (match_operand:DI 1 "register_operand")
8958 (zero_extend:DI (not:SI (match_dup 3))))]
8959 "ix86_match_ccmode (insn, CCNOmode)"
8960 [(parallel [(set (match_dup 0)
8961 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8964 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8966 ;; Shift instructions
8968 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8969 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8970 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8971 ;; from the assembler input.
8973 ;; This instruction shifts the target reg/mem as usual, but instead of
8974 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8975 ;; is a left shift double, bits are taken from the high order bits of
8976 ;; reg, else if the insn is a shift right double, bits are taken from the
8977 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8978 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8980 ;; Since sh[lr]d does not change the `reg' operand, that is done
8981 ;; separately, making all shifts emit pairs of shift double and normal
8982 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8983 ;; support a 63 bit shift, each shift where the count is in a reg expands
8984 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8986 ;; If the shift count is a constant, we need never emit more than one
8987 ;; shift pair, instead using moves and sign extension for counts greater
8990 (define_expand "ashl<mode>3"
8991 [(set (match_operand:SDWIM 0 "<shift_operand>")
8992 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
8993 (match_operand:QI 2 "nonmemory_operand")))]
8995 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8997 (define_insn "*ashl<mode>3_doubleword"
8998 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8999 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9000 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9001 (clobber (reg:CC FLAGS_REG))]
9004 [(set_attr "type" "multi")])
9007 [(set (match_operand:DWI 0 "register_operand")
9008 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9009 (match_operand:QI 2 "nonmemory_operand")))
9010 (clobber (reg:CC FLAGS_REG))]
9011 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9013 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9015 ;; By default we don't ask for a scratch register, because when DWImode
9016 ;; values are manipulated, registers are already at a premium. But if
9017 ;; we have one handy, we won't turn it away.
9020 [(match_scratch:DWIH 3 "r")
9021 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9023 (match_operand:<DWI> 1 "nonmemory_operand")
9024 (match_operand:QI 2 "nonmemory_operand")))
9025 (clobber (reg:CC FLAGS_REG))])
9029 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9031 (define_insn "x86_64_shld"
9032 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9033 (ior:DI (ashift:DI (match_dup 0)
9034 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9035 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9036 (minus:QI (const_int 64) (match_dup 2)))))
9037 (clobber (reg:CC FLAGS_REG))]
9039 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9040 [(set_attr "type" "ishift")
9041 (set_attr "prefix_0f" "1")
9042 (set_attr "mode" "DI")
9043 (set_attr "athlon_decode" "vector")
9044 (set_attr "amdfam10_decode" "vector")
9045 (set_attr "bdver1_decode" "vector")])
9047 (define_insn "x86_shld"
9048 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9049 (ior:SI (ashift:SI (match_dup 0)
9050 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9051 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9052 (minus:QI (const_int 32) (match_dup 2)))))
9053 (clobber (reg:CC FLAGS_REG))]
9055 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9056 [(set_attr "type" "ishift")
9057 (set_attr "prefix_0f" "1")
9058 (set_attr "mode" "SI")
9059 (set_attr "pent_pair" "np")
9060 (set_attr "athlon_decode" "vector")
9061 (set_attr "amdfam10_decode" "vector")
9062 (set_attr "bdver1_decode" "vector")])
9064 (define_expand "x86_shift<mode>_adj_1"
9065 [(set (reg:CCZ FLAGS_REG)
9066 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9069 (set (match_operand:SWI48 0 "register_operand")
9070 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9071 (match_operand:SWI48 1 "register_operand")
9074 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9075 (match_operand:SWI48 3 "register_operand")
9078 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9080 (define_expand "x86_shift<mode>_adj_2"
9081 [(use (match_operand:SWI48 0 "register_operand"))
9082 (use (match_operand:SWI48 1 "register_operand"))
9083 (use (match_operand:QI 2 "register_operand"))]
9086 rtx label = gen_label_rtx ();
9089 emit_insn (gen_testqi_ccz_1 (operands[2],
9090 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9092 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9093 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9094 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9095 gen_rtx_LABEL_REF (VOIDmode, label),
9097 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9098 JUMP_LABEL (tmp) = label;
9100 emit_move_insn (operands[0], operands[1]);
9101 ix86_expand_clear (operands[1]);
9104 LABEL_NUSES (label) = 1;
9109 ;; Avoid useless masking of count operand.
9110 (define_insn_and_split "*ashl<mode>3_mask"
9111 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9113 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9116 (match_operand:SI 2 "nonimmediate_operand" "c")
9117 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9118 (clobber (reg:CC FLAGS_REG))]
9119 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9120 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9121 == GET_MODE_BITSIZE (<MODE>mode)-1"
9124 [(parallel [(set (match_dup 0)
9125 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9126 (clobber (reg:CC FLAGS_REG))])]
9128 if (can_create_pseudo_p ())
9129 operands [2] = force_reg (SImode, operands[2]);
9131 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9133 [(set_attr "type" "ishift")
9134 (set_attr "mode" "<MODE>")])
9136 (define_insn "*bmi2_ashl<mode>3_1"
9137 [(set (match_operand:SWI48 0 "register_operand" "=r")
9138 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9139 (match_operand:SWI48 2 "register_operand" "r")))]
9141 "shlx\t{%2, %1, %0|%0, %1, %2}"
9142 [(set_attr "type" "ishiftx")
9143 (set_attr "mode" "<MODE>")])
9145 (define_insn "*ashl<mode>3_1"
9146 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9147 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9148 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9149 (clobber (reg:CC FLAGS_REG))]
9150 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9152 switch (get_attr_type (insn))
9159 gcc_assert (operands[2] == const1_rtx);
9160 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9161 return "add{<imodesuffix>}\t%0, %0";
9164 if (operands[2] == const1_rtx
9165 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9166 return "sal{<imodesuffix>}\t%0";
9168 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9171 [(set_attr "isa" "*,*,bmi2")
9173 (cond [(eq_attr "alternative" "1")
9174 (const_string "lea")
9175 (eq_attr "alternative" "2")
9176 (const_string "ishiftx")
9177 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9178 (match_operand 0 "register_operand"))
9179 (match_operand 2 "const1_operand"))
9180 (const_string "alu")
9182 (const_string "ishift")))
9183 (set (attr "length_immediate")
9185 (ior (eq_attr "type" "alu")
9186 (and (eq_attr "type" "ishift")
9187 (and (match_operand 2 "const1_operand")
9188 (ior (match_test "TARGET_SHIFT1")
9189 (match_test "optimize_function_for_size_p (cfun)")))))
9191 (const_string "*")))
9192 (set_attr "mode" "<MODE>")])
9194 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9196 [(set (match_operand:SWI48 0 "register_operand")
9197 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9198 (match_operand:QI 2 "register_operand")))
9199 (clobber (reg:CC FLAGS_REG))]
9200 "TARGET_BMI2 && reload_completed"
9202 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9203 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9205 (define_insn "*bmi2_ashlsi3_1_zext"
9206 [(set (match_operand:DI 0 "register_operand" "=r")
9208 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9209 (match_operand:SI 2 "register_operand" "r"))))]
9210 "TARGET_64BIT && TARGET_BMI2"
9211 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9212 [(set_attr "type" "ishiftx")
9213 (set_attr "mode" "SI")])
9215 (define_insn "*ashlsi3_1_zext"
9216 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9218 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9219 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9220 (clobber (reg:CC FLAGS_REG))]
9221 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9223 switch (get_attr_type (insn))
9230 gcc_assert (operands[2] == const1_rtx);
9231 return "add{l}\t%k0, %k0";
9234 if (operands[2] == const1_rtx
9235 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9236 return "sal{l}\t%k0";
9238 return "sal{l}\t{%2, %k0|%k0, %2}";
9241 [(set_attr "isa" "*,*,bmi2")
9243 (cond [(eq_attr "alternative" "1")
9244 (const_string "lea")
9245 (eq_attr "alternative" "2")
9246 (const_string "ishiftx")
9247 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9248 (match_operand 2 "const1_operand"))
9249 (const_string "alu")
9251 (const_string "ishift")))
9252 (set (attr "length_immediate")
9254 (ior (eq_attr "type" "alu")
9255 (and (eq_attr "type" "ishift")
9256 (and (match_operand 2 "const1_operand")
9257 (ior (match_test "TARGET_SHIFT1")
9258 (match_test "optimize_function_for_size_p (cfun)")))))
9260 (const_string "*")))
9261 (set_attr "mode" "SI")])
9263 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9265 [(set (match_operand:DI 0 "register_operand")
9267 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9268 (match_operand:QI 2 "register_operand"))))
9269 (clobber (reg:CC FLAGS_REG))]
9270 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9272 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9273 "operands[2] = gen_lowpart (SImode, operands[2]);")
9275 (define_insn "*ashlhi3_1"
9276 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9277 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9278 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9279 (clobber (reg:CC FLAGS_REG))]
9280 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9282 switch (get_attr_type (insn))
9288 gcc_assert (operands[2] == const1_rtx);
9289 return "add{w}\t%0, %0";
9292 if (operands[2] == const1_rtx
9293 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9294 return "sal{w}\t%0";
9296 return "sal{w}\t{%2, %0|%0, %2}";
9300 (cond [(eq_attr "alternative" "1")
9301 (const_string "lea")
9302 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9303 (match_operand 0 "register_operand"))
9304 (match_operand 2 "const1_operand"))
9305 (const_string "alu")
9307 (const_string "ishift")))
9308 (set (attr "length_immediate")
9310 (ior (eq_attr "type" "alu")
9311 (and (eq_attr "type" "ishift")
9312 (and (match_operand 2 "const1_operand")
9313 (ior (match_test "TARGET_SHIFT1")
9314 (match_test "optimize_function_for_size_p (cfun)")))))
9316 (const_string "*")))
9317 (set_attr "mode" "HI,SI")])
9319 ;; %%% Potential partial reg stall on alternative 1. What to do?
9320 (define_insn "*ashlqi3_1"
9321 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9322 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9323 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9324 (clobber (reg:CC FLAGS_REG))]
9325 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9327 switch (get_attr_type (insn))
9333 gcc_assert (operands[2] == const1_rtx);
9334 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9335 return "add{l}\t%k0, %k0";
9337 return "add{b}\t%0, %0";
9340 if (operands[2] == const1_rtx
9341 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9343 if (get_attr_mode (insn) == MODE_SI)
9344 return "sal{l}\t%k0";
9346 return "sal{b}\t%0";
9350 if (get_attr_mode (insn) == MODE_SI)
9351 return "sal{l}\t{%2, %k0|%k0, %2}";
9353 return "sal{b}\t{%2, %0|%0, %2}";
9358 (cond [(eq_attr "alternative" "2")
9359 (const_string "lea")
9360 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9361 (match_operand 0 "register_operand"))
9362 (match_operand 2 "const1_operand"))
9363 (const_string "alu")
9365 (const_string "ishift")))
9366 (set (attr "length_immediate")
9368 (ior (eq_attr "type" "alu")
9369 (and (eq_attr "type" "ishift")
9370 (and (match_operand 2 "const1_operand")
9371 (ior (match_test "TARGET_SHIFT1")
9372 (match_test "optimize_function_for_size_p (cfun)")))))
9374 (const_string "*")))
9375 (set_attr "mode" "QI,SI,SI")])
9377 (define_insn "*ashlqi3_1_slp"
9378 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9379 (ashift:QI (match_dup 0)
9380 (match_operand:QI 1 "nonmemory_operand" "cI")))
9381 (clobber (reg:CC FLAGS_REG))]
9382 "(optimize_function_for_size_p (cfun)
9383 || !TARGET_PARTIAL_FLAG_REG_STALL
9384 || (operands[1] == const1_rtx
9386 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9388 switch (get_attr_type (insn))
9391 gcc_assert (operands[1] == const1_rtx);
9392 return "add{b}\t%0, %0";
9395 if (operands[1] == const1_rtx
9396 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9397 return "sal{b}\t%0";
9399 return "sal{b}\t{%1, %0|%0, %1}";
9403 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9404 (match_operand 0 "register_operand"))
9405 (match_operand 1 "const1_operand"))
9406 (const_string "alu")
9408 (const_string "ishift1")))
9409 (set (attr "length_immediate")
9411 (ior (eq_attr "type" "alu")
9412 (and (eq_attr "type" "ishift1")
9413 (and (match_operand 1 "const1_operand")
9414 (ior (match_test "TARGET_SHIFT1")
9415 (match_test "optimize_function_for_size_p (cfun)")))))
9417 (const_string "*")))
9418 (set_attr "mode" "QI")])
9420 ;; Convert ashift to the lea pattern to avoid flags dependency.
9422 [(set (match_operand 0 "register_operand")
9423 (ashift (match_operand 1 "index_register_operand")
9424 (match_operand:QI 2 "const_int_operand")))
9425 (clobber (reg:CC FLAGS_REG))]
9426 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9428 && true_regnum (operands[0]) != true_regnum (operands[1])"
9431 enum machine_mode mode = GET_MODE (operands[0]);
9434 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9437 operands[0] = gen_lowpart (mode, operands[0]);
9438 operands[1] = gen_lowpart (mode, operands[1]);
9441 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9443 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9445 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9449 ;; Convert ashift to the lea pattern to avoid flags dependency.
9451 [(set (match_operand:DI 0 "register_operand")
9453 (ashift:SI (match_operand:SI 1 "index_register_operand")
9454 (match_operand:QI 2 "const_int_operand"))))
9455 (clobber (reg:CC FLAGS_REG))]
9456 "TARGET_64BIT && reload_completed
9457 && true_regnum (operands[0]) != true_regnum (operands[1])"
9459 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9461 operands[1] = gen_lowpart (DImode, operands[1]);
9462 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9465 ;; This pattern can't accept a variable shift count, since shifts by
9466 ;; zero don't affect the flags. We assume that shifts by constant
9467 ;; zero are optimized away.
9468 (define_insn "*ashl<mode>3_cmp"
9469 [(set (reg FLAGS_REG)
9471 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9472 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9474 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9475 (ashift:SWI (match_dup 1) (match_dup 2)))]
9476 "(optimize_function_for_size_p (cfun)
9477 || !TARGET_PARTIAL_FLAG_REG_STALL
9478 || (operands[2] == const1_rtx
9480 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9481 && ix86_match_ccmode (insn, CCGOCmode)
9482 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9484 switch (get_attr_type (insn))
9487 gcc_assert (operands[2] == const1_rtx);
9488 return "add{<imodesuffix>}\t%0, %0";
9491 if (operands[2] == const1_rtx
9492 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9493 return "sal{<imodesuffix>}\t%0";
9495 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9499 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9500 (match_operand 0 "register_operand"))
9501 (match_operand 2 "const1_operand"))
9502 (const_string "alu")
9504 (const_string "ishift")))
9505 (set (attr "length_immediate")
9507 (ior (eq_attr "type" "alu")
9508 (and (eq_attr "type" "ishift")
9509 (and (match_operand 2 "const1_operand")
9510 (ior (match_test "TARGET_SHIFT1")
9511 (match_test "optimize_function_for_size_p (cfun)")))))
9513 (const_string "*")))
9514 (set_attr "mode" "<MODE>")])
9516 (define_insn "*ashlsi3_cmp_zext"
9517 [(set (reg FLAGS_REG)
9519 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9520 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9522 (set (match_operand:DI 0 "register_operand" "=r")
9523 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9525 && (optimize_function_for_size_p (cfun)
9526 || !TARGET_PARTIAL_FLAG_REG_STALL
9527 || (operands[2] == const1_rtx
9529 || TARGET_DOUBLE_WITH_ADD)))
9530 && ix86_match_ccmode (insn, CCGOCmode)
9531 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9533 switch (get_attr_type (insn))
9536 gcc_assert (operands[2] == const1_rtx);
9537 return "add{l}\t%k0, %k0";
9540 if (operands[2] == const1_rtx
9541 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9542 return "sal{l}\t%k0";
9544 return "sal{l}\t{%2, %k0|%k0, %2}";
9548 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9549 (match_operand 2 "const1_operand"))
9550 (const_string "alu")
9552 (const_string "ishift")))
9553 (set (attr "length_immediate")
9555 (ior (eq_attr "type" "alu")
9556 (and (eq_attr "type" "ishift")
9557 (and (match_operand 2 "const1_operand")
9558 (ior (match_test "TARGET_SHIFT1")
9559 (match_test "optimize_function_for_size_p (cfun)")))))
9561 (const_string "*")))
9562 (set_attr "mode" "SI")])
9564 (define_insn "*ashl<mode>3_cconly"
9565 [(set (reg FLAGS_REG)
9567 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9568 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9570 (clobber (match_scratch:SWI 0 "=<r>"))]
9571 "(optimize_function_for_size_p (cfun)
9572 || !TARGET_PARTIAL_FLAG_REG_STALL
9573 || (operands[2] == const1_rtx
9575 || TARGET_DOUBLE_WITH_ADD)))
9576 && ix86_match_ccmode (insn, CCGOCmode)"
9578 switch (get_attr_type (insn))
9581 gcc_assert (operands[2] == const1_rtx);
9582 return "add{<imodesuffix>}\t%0, %0";
9585 if (operands[2] == const1_rtx
9586 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9587 return "sal{<imodesuffix>}\t%0";
9589 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9593 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9594 (match_operand 0 "register_operand"))
9595 (match_operand 2 "const1_operand"))
9596 (const_string "alu")
9598 (const_string "ishift")))
9599 (set (attr "length_immediate")
9601 (ior (eq_attr "type" "alu")
9602 (and (eq_attr "type" "ishift")
9603 (and (match_operand 2 "const1_operand")
9604 (ior (match_test "TARGET_SHIFT1")
9605 (match_test "optimize_function_for_size_p (cfun)")))))
9607 (const_string "*")))
9608 (set_attr "mode" "<MODE>")])
9610 ;; See comment above `ashl<mode>3' about how this works.
9612 (define_expand "<shift_insn><mode>3"
9613 [(set (match_operand:SDWIM 0 "<shift_operand>")
9614 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9615 (match_operand:QI 2 "nonmemory_operand")))]
9617 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9619 ;; Avoid useless masking of count operand.
9620 (define_insn_and_split "*<shift_insn><mode>3_mask"
9621 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9623 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9626 (match_operand:SI 2 "nonimmediate_operand" "c")
9627 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9628 (clobber (reg:CC FLAGS_REG))]
9629 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9630 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9631 == GET_MODE_BITSIZE (<MODE>mode)-1"
9634 [(parallel [(set (match_dup 0)
9635 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9636 (clobber (reg:CC FLAGS_REG))])]
9638 if (can_create_pseudo_p ())
9639 operands [2] = force_reg (SImode, operands[2]);
9641 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9643 [(set_attr "type" "ishift")
9644 (set_attr "mode" "<MODE>")])
9646 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9647 [(set (match_operand:DWI 0 "register_operand" "=r")
9648 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9649 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9650 (clobber (reg:CC FLAGS_REG))]
9653 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9655 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9656 [(set_attr "type" "multi")])
9658 ;; By default we don't ask for a scratch register, because when DWImode
9659 ;; values are manipulated, registers are already at a premium. But if
9660 ;; we have one handy, we won't turn it away.
9663 [(match_scratch:DWIH 3 "r")
9664 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9666 (match_operand:<DWI> 1 "register_operand")
9667 (match_operand:QI 2 "nonmemory_operand")))
9668 (clobber (reg:CC FLAGS_REG))])
9672 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9674 (define_insn "x86_64_shrd"
9675 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9676 (ior:DI (ashiftrt:DI (match_dup 0)
9677 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9678 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9679 (minus:QI (const_int 64) (match_dup 2)))))
9680 (clobber (reg:CC FLAGS_REG))]
9682 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9683 [(set_attr "type" "ishift")
9684 (set_attr "prefix_0f" "1")
9685 (set_attr "mode" "DI")
9686 (set_attr "athlon_decode" "vector")
9687 (set_attr "amdfam10_decode" "vector")
9688 (set_attr "bdver1_decode" "vector")])
9690 (define_insn "x86_shrd"
9691 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9692 (ior:SI (ashiftrt:SI (match_dup 0)
9693 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9694 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9695 (minus:QI (const_int 32) (match_dup 2)))))
9696 (clobber (reg:CC FLAGS_REG))]
9698 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9699 [(set_attr "type" "ishift")
9700 (set_attr "prefix_0f" "1")
9701 (set_attr "mode" "SI")
9702 (set_attr "pent_pair" "np")
9703 (set_attr "athlon_decode" "vector")
9704 (set_attr "amdfam10_decode" "vector")
9705 (set_attr "bdver1_decode" "vector")])
9707 (define_insn "ashrdi3_cvt"
9708 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9709 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9710 (match_operand:QI 2 "const_int_operand")))
9711 (clobber (reg:CC FLAGS_REG))]
9712 "TARGET_64BIT && INTVAL (operands[2]) == 63
9713 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9714 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9717 sar{q}\t{%2, %0|%0, %2}"
9718 [(set_attr "type" "imovx,ishift")
9719 (set_attr "prefix_0f" "0,*")
9720 (set_attr "length_immediate" "0,*")
9721 (set_attr "modrm" "0,1")
9722 (set_attr "mode" "DI")])
9724 (define_insn "ashrsi3_cvt"
9725 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9726 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9727 (match_operand:QI 2 "const_int_operand")))
9728 (clobber (reg:CC FLAGS_REG))]
9729 "INTVAL (operands[2]) == 31
9730 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9731 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9734 sar{l}\t{%2, %0|%0, %2}"
9735 [(set_attr "type" "imovx,ishift")
9736 (set_attr "prefix_0f" "0,*")
9737 (set_attr "length_immediate" "0,*")
9738 (set_attr "modrm" "0,1")
9739 (set_attr "mode" "SI")])
9741 (define_insn "*ashrsi3_cvt_zext"
9742 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9744 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9745 (match_operand:QI 2 "const_int_operand"))))
9746 (clobber (reg:CC FLAGS_REG))]
9747 "TARGET_64BIT && INTVAL (operands[2]) == 31
9748 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9749 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9752 sar{l}\t{%2, %k0|%k0, %2}"
9753 [(set_attr "type" "imovx,ishift")
9754 (set_attr "prefix_0f" "0,*")
9755 (set_attr "length_immediate" "0,*")
9756 (set_attr "modrm" "0,1")
9757 (set_attr "mode" "SI")])
9759 (define_expand "x86_shift<mode>_adj_3"
9760 [(use (match_operand:SWI48 0 "register_operand"))
9761 (use (match_operand:SWI48 1 "register_operand"))
9762 (use (match_operand:QI 2 "register_operand"))]
9765 rtx label = gen_label_rtx ();
9768 emit_insn (gen_testqi_ccz_1 (operands[2],
9769 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9771 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9772 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9773 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9774 gen_rtx_LABEL_REF (VOIDmode, label),
9776 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9777 JUMP_LABEL (tmp) = label;
9779 emit_move_insn (operands[0], operands[1]);
9780 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9781 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9783 LABEL_NUSES (label) = 1;
9788 (define_insn "*bmi2_<shift_insn><mode>3_1"
9789 [(set (match_operand:SWI48 0 "register_operand" "=r")
9790 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9791 (match_operand:SWI48 2 "register_operand" "r")))]
9793 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9794 [(set_attr "type" "ishiftx")
9795 (set_attr "mode" "<MODE>")])
9797 (define_insn "*<shift_insn><mode>3_1"
9798 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9800 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9801 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9802 (clobber (reg:CC FLAGS_REG))]
9803 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9805 switch (get_attr_type (insn))
9811 if (operands[2] == const1_rtx
9812 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9813 return "<shift>{<imodesuffix>}\t%0";
9815 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9818 [(set_attr "isa" "*,bmi2")
9819 (set_attr "type" "ishift,ishiftx")
9820 (set (attr "length_immediate")
9822 (and (match_operand 2 "const1_operand")
9823 (ior (match_test "TARGET_SHIFT1")
9824 (match_test "optimize_function_for_size_p (cfun)")))
9826 (const_string "*")))
9827 (set_attr "mode" "<MODE>")])
9829 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9831 [(set (match_operand:SWI48 0 "register_operand")
9832 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9833 (match_operand:QI 2 "register_operand")))
9834 (clobber (reg:CC FLAGS_REG))]
9835 "TARGET_BMI2 && reload_completed"
9837 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9838 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9840 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9841 [(set (match_operand:DI 0 "register_operand" "=r")
9843 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9844 (match_operand:SI 2 "register_operand" "r"))))]
9845 "TARGET_64BIT && TARGET_BMI2"
9846 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9847 [(set_attr "type" "ishiftx")
9848 (set_attr "mode" "SI")])
9850 (define_insn "*<shift_insn>si3_1_zext"
9851 [(set (match_operand:DI 0 "register_operand" "=r,r")
9853 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9854 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9855 (clobber (reg:CC FLAGS_REG))]
9856 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9858 switch (get_attr_type (insn))
9864 if (operands[2] == const1_rtx
9865 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9866 return "<shift>{l}\t%k0";
9868 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9871 [(set_attr "isa" "*,bmi2")
9872 (set_attr "type" "ishift,ishiftx")
9873 (set (attr "length_immediate")
9875 (and (match_operand 2 "const1_operand")
9876 (ior (match_test "TARGET_SHIFT1")
9877 (match_test "optimize_function_for_size_p (cfun)")))
9879 (const_string "*")))
9880 (set_attr "mode" "SI")])
9882 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9884 [(set (match_operand:DI 0 "register_operand")
9886 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
9887 (match_operand:QI 2 "register_operand"))))
9888 (clobber (reg:CC FLAGS_REG))]
9889 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9891 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9892 "operands[2] = gen_lowpart (SImode, operands[2]);")
9894 (define_insn "*<shift_insn><mode>3_1"
9895 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9897 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9898 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9899 (clobber (reg:CC FLAGS_REG))]
9900 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9902 if (operands[2] == const1_rtx
9903 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9904 return "<shift>{<imodesuffix>}\t%0";
9906 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9908 [(set_attr "type" "ishift")
9909 (set (attr "length_immediate")
9911 (and (match_operand 2 "const1_operand")
9912 (ior (match_test "TARGET_SHIFT1")
9913 (match_test "optimize_function_for_size_p (cfun)")))
9915 (const_string "*")))
9916 (set_attr "mode" "<MODE>")])
9918 (define_insn "*<shift_insn>qi3_1_slp"
9919 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9920 (any_shiftrt:QI (match_dup 0)
9921 (match_operand:QI 1 "nonmemory_operand" "cI")))
9922 (clobber (reg:CC FLAGS_REG))]
9923 "(optimize_function_for_size_p (cfun)
9924 || !TARGET_PARTIAL_REG_STALL
9925 || (operands[1] == const1_rtx
9928 if (operands[1] == const1_rtx
9929 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9930 return "<shift>{b}\t%0";
9932 return "<shift>{b}\t{%1, %0|%0, %1}";
9934 [(set_attr "type" "ishift1")
9935 (set (attr "length_immediate")
9937 (and (match_operand 1 "const1_operand")
9938 (ior (match_test "TARGET_SHIFT1")
9939 (match_test "optimize_function_for_size_p (cfun)")))
9941 (const_string "*")))
9942 (set_attr "mode" "QI")])
9944 ;; This pattern can't accept a variable shift count, since shifts by
9945 ;; zero don't affect the flags. We assume that shifts by constant
9946 ;; zero are optimized away.
9947 (define_insn "*<shift_insn><mode>3_cmp"
9948 [(set (reg FLAGS_REG)
9951 (match_operand:SWI 1 "nonimmediate_operand" "0")
9952 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9954 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9955 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9956 "(optimize_function_for_size_p (cfun)
9957 || !TARGET_PARTIAL_FLAG_REG_STALL
9958 || (operands[2] == const1_rtx
9960 && ix86_match_ccmode (insn, CCGOCmode)
9961 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9963 if (operands[2] == const1_rtx
9964 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9965 return "<shift>{<imodesuffix>}\t%0";
9967 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9969 [(set_attr "type" "ishift")
9970 (set (attr "length_immediate")
9972 (and (match_operand 2 "const1_operand")
9973 (ior (match_test "TARGET_SHIFT1")
9974 (match_test "optimize_function_for_size_p (cfun)")))
9976 (const_string "*")))
9977 (set_attr "mode" "<MODE>")])
9979 (define_insn "*<shift_insn>si3_cmp_zext"
9980 [(set (reg FLAGS_REG)
9982 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9983 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9985 (set (match_operand:DI 0 "register_operand" "=r")
9986 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9988 && (optimize_function_for_size_p (cfun)
9989 || !TARGET_PARTIAL_FLAG_REG_STALL
9990 || (operands[2] == const1_rtx
9992 && ix86_match_ccmode (insn, CCGOCmode)
9993 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9995 if (operands[2] == const1_rtx
9996 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9997 return "<shift>{l}\t%k0";
9999 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10001 [(set_attr "type" "ishift")
10002 (set (attr "length_immediate")
10004 (and (match_operand 2 "const1_operand")
10005 (ior (match_test "TARGET_SHIFT1")
10006 (match_test "optimize_function_for_size_p (cfun)")))
10008 (const_string "*")))
10009 (set_attr "mode" "SI")])
10011 (define_insn "*<shift_insn><mode>3_cconly"
10012 [(set (reg FLAGS_REG)
10015 (match_operand:SWI 1 "register_operand" "0")
10016 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10018 (clobber (match_scratch:SWI 0 "=<r>"))]
10019 "(optimize_function_for_size_p (cfun)
10020 || !TARGET_PARTIAL_FLAG_REG_STALL
10021 || (operands[2] == const1_rtx
10023 && ix86_match_ccmode (insn, CCGOCmode)"
10025 if (operands[2] == const1_rtx
10026 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10027 return "<shift>{<imodesuffix>}\t%0";
10029 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10031 [(set_attr "type" "ishift")
10032 (set (attr "length_immediate")
10034 (and (match_operand 2 "const1_operand")
10035 (ior (match_test "TARGET_SHIFT1")
10036 (match_test "optimize_function_for_size_p (cfun)")))
10038 (const_string "*")))
10039 (set_attr "mode" "<MODE>")])
10041 ;; Rotate instructions
10043 (define_expand "<rotate_insn>ti3"
10044 [(set (match_operand:TI 0 "register_operand")
10045 (any_rotate:TI (match_operand:TI 1 "register_operand")
10046 (match_operand:QI 2 "nonmemory_operand")))]
10049 if (const_1_to_63_operand (operands[2], VOIDmode))
10050 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10051 (operands[0], operands[1], operands[2]));
10058 (define_expand "<rotate_insn>di3"
10059 [(set (match_operand:DI 0 "shiftdi_operand")
10060 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10061 (match_operand:QI 2 "nonmemory_operand")))]
10065 ix86_expand_binary_operator (<CODE>, DImode, operands);
10066 else if (const_1_to_31_operand (operands[2], VOIDmode))
10067 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10068 (operands[0], operands[1], operands[2]));
10075 (define_expand "<rotate_insn><mode>3"
10076 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10077 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10078 (match_operand:QI 2 "nonmemory_operand")))]
10080 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10082 ;; Avoid useless masking of count operand.
10083 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10084 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10086 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10089 (match_operand:SI 2 "nonimmediate_operand" "c")
10090 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10091 (clobber (reg:CC FLAGS_REG))]
10092 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10093 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10094 == GET_MODE_BITSIZE (<MODE>mode)-1"
10097 [(parallel [(set (match_dup 0)
10098 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10099 (clobber (reg:CC FLAGS_REG))])]
10101 if (can_create_pseudo_p ())
10102 operands [2] = force_reg (SImode, operands[2]);
10104 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10106 [(set_attr "type" "rotate")
10107 (set_attr "mode" "<MODE>")])
10109 ;; Implement rotation using two double-precision
10110 ;; shift instructions and a scratch register.
10112 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10113 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10114 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10115 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10116 (clobber (reg:CC FLAGS_REG))
10117 (clobber (match_scratch:DWIH 3 "=&r"))]
10121 [(set (match_dup 3) (match_dup 4))
10123 [(set (match_dup 4)
10124 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10125 (lshiftrt:DWIH (match_dup 5)
10126 (minus:QI (match_dup 6) (match_dup 2)))))
10127 (clobber (reg:CC FLAGS_REG))])
10129 [(set (match_dup 5)
10130 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10131 (lshiftrt:DWIH (match_dup 3)
10132 (minus:QI (match_dup 6) (match_dup 2)))))
10133 (clobber (reg:CC FLAGS_REG))])]
10135 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10137 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10140 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10141 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10142 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10143 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10144 (clobber (reg:CC FLAGS_REG))
10145 (clobber (match_scratch:DWIH 3 "=&r"))]
10149 [(set (match_dup 3) (match_dup 4))
10151 [(set (match_dup 4)
10152 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10153 (ashift:DWIH (match_dup 5)
10154 (minus:QI (match_dup 6) (match_dup 2)))))
10155 (clobber (reg:CC FLAGS_REG))])
10157 [(set (match_dup 5)
10158 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10159 (ashift:DWIH (match_dup 3)
10160 (minus:QI (match_dup 6) (match_dup 2)))))
10161 (clobber (reg:CC FLAGS_REG))])]
10163 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10165 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10168 (define_insn "*bmi2_rorx<mode>3_1"
10169 [(set (match_operand:SWI48 0 "register_operand" "=r")
10170 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10171 (match_operand:QI 2 "immediate_operand" "<S>")))]
10173 "rorx\t{%2, %1, %0|%0, %1, %2}"
10174 [(set_attr "type" "rotatex")
10175 (set_attr "mode" "<MODE>")])
10177 (define_insn "*<rotate_insn><mode>3_1"
10178 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10180 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10181 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10182 (clobber (reg:CC FLAGS_REG))]
10183 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10185 switch (get_attr_type (insn))
10191 if (operands[2] == const1_rtx
10192 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10193 return "<rotate>{<imodesuffix>}\t%0";
10195 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10198 [(set_attr "isa" "*,bmi2")
10199 (set_attr "type" "rotate,rotatex")
10200 (set (attr "length_immediate")
10202 (and (eq_attr "type" "rotate")
10203 (and (match_operand 2 "const1_operand")
10204 (ior (match_test "TARGET_SHIFT1")
10205 (match_test "optimize_function_for_size_p (cfun)"))))
10207 (const_string "*")))
10208 (set_attr "mode" "<MODE>")])
10210 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10212 [(set (match_operand:SWI48 0 "register_operand")
10213 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10214 (match_operand:QI 2 "immediate_operand")))
10215 (clobber (reg:CC FLAGS_REG))]
10216 "TARGET_BMI2 && reload_completed"
10217 [(set (match_dup 0)
10218 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10221 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10225 [(set (match_operand:SWI48 0 "register_operand")
10226 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10227 (match_operand:QI 2 "immediate_operand")))
10228 (clobber (reg:CC FLAGS_REG))]
10229 "TARGET_BMI2 && reload_completed"
10230 [(set (match_dup 0)
10231 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10233 (define_insn "*bmi2_rorxsi3_1_zext"
10234 [(set (match_operand:DI 0 "register_operand" "=r")
10236 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10237 (match_operand:QI 2 "immediate_operand" "I"))))]
10238 "TARGET_64BIT && TARGET_BMI2"
10239 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10240 [(set_attr "type" "rotatex")
10241 (set_attr "mode" "SI")])
10243 (define_insn "*<rotate_insn>si3_1_zext"
10244 [(set (match_operand:DI 0 "register_operand" "=r,r")
10246 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10247 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10248 (clobber (reg:CC FLAGS_REG))]
10249 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10251 switch (get_attr_type (insn))
10257 if (operands[2] == const1_rtx
10258 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10259 return "<rotate>{l}\t%k0";
10261 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10264 [(set_attr "isa" "*,bmi2")
10265 (set_attr "type" "rotate,rotatex")
10266 (set (attr "length_immediate")
10268 (and (eq_attr "type" "rotate")
10269 (and (match_operand 2 "const1_operand")
10270 (ior (match_test "TARGET_SHIFT1")
10271 (match_test "optimize_function_for_size_p (cfun)"))))
10273 (const_string "*")))
10274 (set_attr "mode" "SI")])
10276 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10278 [(set (match_operand:DI 0 "register_operand")
10280 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10281 (match_operand:QI 2 "immediate_operand"))))
10282 (clobber (reg:CC FLAGS_REG))]
10283 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10284 [(set (match_dup 0)
10285 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10288 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10292 [(set (match_operand:DI 0 "register_operand")
10294 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10295 (match_operand:QI 2 "immediate_operand"))))
10296 (clobber (reg:CC FLAGS_REG))]
10297 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10298 [(set (match_dup 0)
10299 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10301 (define_insn "*<rotate_insn><mode>3_1"
10302 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10303 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10304 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10305 (clobber (reg:CC FLAGS_REG))]
10306 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10308 if (operands[2] == const1_rtx
10309 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10310 return "<rotate>{<imodesuffix>}\t%0";
10312 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10314 [(set_attr "type" "rotate")
10315 (set (attr "length_immediate")
10317 (and (match_operand 2 "const1_operand")
10318 (ior (match_test "TARGET_SHIFT1")
10319 (match_test "optimize_function_for_size_p (cfun)")))
10321 (const_string "*")))
10322 (set_attr "mode" "<MODE>")])
10324 (define_insn "*<rotate_insn>qi3_1_slp"
10325 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10326 (any_rotate:QI (match_dup 0)
10327 (match_operand:QI 1 "nonmemory_operand" "cI")))
10328 (clobber (reg:CC FLAGS_REG))]
10329 "(optimize_function_for_size_p (cfun)
10330 || !TARGET_PARTIAL_REG_STALL
10331 || (operands[1] == const1_rtx
10332 && TARGET_SHIFT1))"
10334 if (operands[1] == const1_rtx
10335 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10336 return "<rotate>{b}\t%0";
10338 return "<rotate>{b}\t{%1, %0|%0, %1}";
10340 [(set_attr "type" "rotate1")
10341 (set (attr "length_immediate")
10343 (and (match_operand 1 "const1_operand")
10344 (ior (match_test "TARGET_SHIFT1")
10345 (match_test "optimize_function_for_size_p (cfun)")))
10347 (const_string "*")))
10348 (set_attr "mode" "QI")])
10351 [(set (match_operand:HI 0 "register_operand")
10352 (any_rotate:HI (match_dup 0) (const_int 8)))
10353 (clobber (reg:CC FLAGS_REG))]
10355 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10356 [(parallel [(set (strict_low_part (match_dup 0))
10357 (bswap:HI (match_dup 0)))
10358 (clobber (reg:CC FLAGS_REG))])])
10360 ;; Bit set / bit test instructions
10362 (define_expand "extv"
10363 [(set (match_operand:SI 0 "register_operand")
10364 (sign_extract:SI (match_operand:SI 1 "register_operand")
10365 (match_operand:SI 2 "const8_operand")
10366 (match_operand:SI 3 "const8_operand")))]
10369 /* Handle extractions from %ah et al. */
10370 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10373 /* From mips.md: extract_bit_field doesn't verify that our source
10374 matches the predicate, so check it again here. */
10375 if (! ext_register_operand (operands[1], VOIDmode))
10379 (define_expand "extzv"
10380 [(set (match_operand:SI 0 "register_operand")
10381 (zero_extract:SI (match_operand 1 "ext_register_operand")
10382 (match_operand:SI 2 "const8_operand")
10383 (match_operand:SI 3 "const8_operand")))]
10386 /* Handle extractions from %ah et al. */
10387 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10390 /* From mips.md: extract_bit_field doesn't verify that our source
10391 matches the predicate, so check it again here. */
10392 if (! ext_register_operand (operands[1], VOIDmode))
10396 (define_expand "insv"
10397 [(set (zero_extract (match_operand 0 "register_operand")
10398 (match_operand 1 "const_int_operand")
10399 (match_operand 2 "const_int_operand"))
10400 (match_operand 3 "register_operand"))]
10403 rtx (*gen_mov_insv_1) (rtx, rtx);
10405 if (ix86_expand_pinsr (operands))
10408 /* Handle insertions to %ah et al. */
10409 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10412 /* From mips.md: insert_bit_field doesn't verify that our source
10413 matches the predicate, so check it again here. */
10414 if (! ext_register_operand (operands[0], VOIDmode))
10417 gen_mov_insv_1 = (TARGET_64BIT
10418 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10420 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10424 ;; %%% bts, btr, btc, bt.
10425 ;; In general these instructions are *slow* when applied to memory,
10426 ;; since they enforce atomic operation. When applied to registers,
10427 ;; it depends on the cpu implementation. They're never faster than
10428 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10429 ;; no point. But in 64-bit, we can't hold the relevant immediates
10430 ;; within the instruction itself, so operating on bits in the high
10431 ;; 32-bits of a register becomes easier.
10433 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10434 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10435 ;; negdf respectively, so they can never be disabled entirely.
10437 (define_insn "*btsq"
10438 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10440 (match_operand:DI 1 "const_0_to_63_operand"))
10442 (clobber (reg:CC FLAGS_REG))]
10443 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10444 "bts{q}\t{%1, %0|%0, %1}"
10445 [(set_attr "type" "alu1")
10446 (set_attr "prefix_0f" "1")
10447 (set_attr "mode" "DI")])
10449 (define_insn "*btrq"
10450 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10452 (match_operand:DI 1 "const_0_to_63_operand"))
10454 (clobber (reg:CC FLAGS_REG))]
10455 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10456 "btr{q}\t{%1, %0|%0, %1}"
10457 [(set_attr "type" "alu1")
10458 (set_attr "prefix_0f" "1")
10459 (set_attr "mode" "DI")])
10461 (define_insn "*btcq"
10462 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10464 (match_operand:DI 1 "const_0_to_63_operand"))
10465 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10466 (clobber (reg:CC FLAGS_REG))]
10467 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10468 "btc{q}\t{%1, %0|%0, %1}"
10469 [(set_attr "type" "alu1")
10470 (set_attr "prefix_0f" "1")
10471 (set_attr "mode" "DI")])
10473 ;; Allow Nocona to avoid these instructions if a register is available.
10476 [(match_scratch:DI 2 "r")
10477 (parallel [(set (zero_extract:DI
10478 (match_operand:DI 0 "register_operand")
10480 (match_operand:DI 1 "const_0_to_63_operand"))
10482 (clobber (reg:CC FLAGS_REG))])]
10483 "TARGET_64BIT && !TARGET_USE_BT"
10486 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10489 if (HOST_BITS_PER_WIDE_INT >= 64)
10490 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10491 else if (i < HOST_BITS_PER_WIDE_INT)
10492 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10494 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10496 op1 = immed_double_const (lo, hi, DImode);
10499 emit_move_insn (operands[2], op1);
10503 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10508 [(match_scratch:DI 2 "r")
10509 (parallel [(set (zero_extract:DI
10510 (match_operand:DI 0 "register_operand")
10512 (match_operand:DI 1 "const_0_to_63_operand"))
10514 (clobber (reg:CC FLAGS_REG))])]
10515 "TARGET_64BIT && !TARGET_USE_BT"
10518 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10521 if (HOST_BITS_PER_WIDE_INT >= 64)
10522 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10523 else if (i < HOST_BITS_PER_WIDE_INT)
10524 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10526 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10528 op1 = immed_double_const (~lo, ~hi, DImode);
10531 emit_move_insn (operands[2], op1);
10535 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10540 [(match_scratch:DI 2 "r")
10541 (parallel [(set (zero_extract:DI
10542 (match_operand:DI 0 "register_operand")
10544 (match_operand:DI 1 "const_0_to_63_operand"))
10545 (not:DI (zero_extract:DI
10546 (match_dup 0) (const_int 1) (match_dup 1))))
10547 (clobber (reg:CC FLAGS_REG))])]
10548 "TARGET_64BIT && !TARGET_USE_BT"
10551 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10554 if (HOST_BITS_PER_WIDE_INT >= 64)
10555 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10556 else if (i < HOST_BITS_PER_WIDE_INT)
10557 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10559 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10561 op1 = immed_double_const (lo, hi, DImode);
10564 emit_move_insn (operands[2], op1);
10568 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10572 (define_insn "*bt<mode>"
10573 [(set (reg:CCC FLAGS_REG)
10575 (zero_extract:SWI48
10576 (match_operand:SWI48 0 "register_operand" "r")
10578 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10580 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10581 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10582 [(set_attr "type" "alu1")
10583 (set_attr "prefix_0f" "1")
10584 (set_attr "mode" "<MODE>")])
10586 ;; Store-flag instructions.
10588 ;; For all sCOND expanders, also expand the compare or test insn that
10589 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10591 (define_insn_and_split "*setcc_di_1"
10592 [(set (match_operand:DI 0 "register_operand" "=q")
10593 (match_operator:DI 1 "ix86_comparison_operator"
10594 [(reg FLAGS_REG) (const_int 0)]))]
10595 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10597 "&& reload_completed"
10598 [(set (match_dup 2) (match_dup 1))
10599 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10601 PUT_MODE (operands[1], QImode);
10602 operands[2] = gen_lowpart (QImode, operands[0]);
10605 (define_insn_and_split "*setcc_si_1_and"
10606 [(set (match_operand:SI 0 "register_operand" "=q")
10607 (match_operator:SI 1 "ix86_comparison_operator"
10608 [(reg FLAGS_REG) (const_int 0)]))
10609 (clobber (reg:CC FLAGS_REG))]
10610 "!TARGET_PARTIAL_REG_STALL
10611 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10613 "&& reload_completed"
10614 [(set (match_dup 2) (match_dup 1))
10615 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10616 (clobber (reg:CC FLAGS_REG))])]
10618 PUT_MODE (operands[1], QImode);
10619 operands[2] = gen_lowpart (QImode, operands[0]);
10622 (define_insn_and_split "*setcc_si_1_movzbl"
10623 [(set (match_operand:SI 0 "register_operand" "=q")
10624 (match_operator:SI 1 "ix86_comparison_operator"
10625 [(reg FLAGS_REG) (const_int 0)]))]
10626 "!TARGET_PARTIAL_REG_STALL
10627 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10629 "&& reload_completed"
10630 [(set (match_dup 2) (match_dup 1))
10631 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10633 PUT_MODE (operands[1], QImode);
10634 operands[2] = gen_lowpart (QImode, operands[0]);
10637 (define_insn "*setcc_qi"
10638 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10639 (match_operator:QI 1 "ix86_comparison_operator"
10640 [(reg FLAGS_REG) (const_int 0)]))]
10643 [(set_attr "type" "setcc")
10644 (set_attr "mode" "QI")])
10646 (define_insn "*setcc_qi_slp"
10647 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10648 (match_operator:QI 1 "ix86_comparison_operator"
10649 [(reg FLAGS_REG) (const_int 0)]))]
10652 [(set_attr "type" "setcc")
10653 (set_attr "mode" "QI")])
10655 ;; In general it is not safe to assume too much about CCmode registers,
10656 ;; so simplify-rtx stops when it sees a second one. Under certain
10657 ;; conditions this is safe on x86, so help combine not create
10664 [(set (match_operand:QI 0 "nonimmediate_operand")
10665 (ne:QI (match_operator 1 "ix86_comparison_operator"
10666 [(reg FLAGS_REG) (const_int 0)])
10669 [(set (match_dup 0) (match_dup 1))]
10670 "PUT_MODE (operands[1], QImode);")
10673 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10674 (ne:QI (match_operator 1 "ix86_comparison_operator"
10675 [(reg FLAGS_REG) (const_int 0)])
10678 [(set (match_dup 0) (match_dup 1))]
10679 "PUT_MODE (operands[1], QImode);")
10682 [(set (match_operand:QI 0 "nonimmediate_operand")
10683 (eq:QI (match_operator 1 "ix86_comparison_operator"
10684 [(reg FLAGS_REG) (const_int 0)])
10687 [(set (match_dup 0) (match_dup 1))]
10689 rtx new_op1 = copy_rtx (operands[1]);
10690 operands[1] = new_op1;
10691 PUT_MODE (new_op1, QImode);
10692 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10693 GET_MODE (XEXP (new_op1, 0))));
10695 /* Make sure that (a) the CCmode we have for the flags is strong
10696 enough for the reversed compare or (b) we have a valid FP compare. */
10697 if (! ix86_comparison_operator (new_op1, VOIDmode))
10702 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10703 (eq:QI (match_operator 1 "ix86_comparison_operator"
10704 [(reg FLAGS_REG) (const_int 0)])
10707 [(set (match_dup 0) (match_dup 1))]
10709 rtx new_op1 = copy_rtx (operands[1]);
10710 operands[1] = new_op1;
10711 PUT_MODE (new_op1, QImode);
10712 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10713 GET_MODE (XEXP (new_op1, 0))));
10715 /* Make sure that (a) the CCmode we have for the flags is strong
10716 enough for the reversed compare or (b) we have a valid FP compare. */
10717 if (! ix86_comparison_operator (new_op1, VOIDmode))
10721 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10722 ;; subsequent logical operations are used to imitate conditional moves.
10723 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10726 (define_insn "setcc_<mode>_sse"
10727 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10728 (match_operator:MODEF 3 "sse_comparison_operator"
10729 [(match_operand:MODEF 1 "register_operand" "0,x")
10730 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10731 "SSE_FLOAT_MODE_P (<MODE>mode)"
10733 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10734 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10735 [(set_attr "isa" "noavx,avx")
10736 (set_attr "type" "ssecmp")
10737 (set_attr "length_immediate" "1")
10738 (set_attr "prefix" "orig,vex")
10739 (set_attr "mode" "<MODE>")])
10741 ;; Basic conditional jump instructions.
10742 ;; We ignore the overflow flag for signed branch instructions.
10744 (define_insn "*jcc_1"
10746 (if_then_else (match_operator 1 "ix86_comparison_operator"
10747 [(reg FLAGS_REG) (const_int 0)])
10748 (label_ref (match_operand 0))
10752 [(set_attr "type" "ibr")
10753 (set_attr "modrm" "0")
10754 (set (attr "length")
10755 (if_then_else (and (ge (minus (match_dup 0) (pc))
10757 (lt (minus (match_dup 0) (pc))
10762 (define_insn "*jcc_2"
10764 (if_then_else (match_operator 1 "ix86_comparison_operator"
10765 [(reg FLAGS_REG) (const_int 0)])
10767 (label_ref (match_operand 0))))]
10770 [(set_attr "type" "ibr")
10771 (set_attr "modrm" "0")
10772 (set (attr "length")
10773 (if_then_else (and (ge (minus (match_dup 0) (pc))
10775 (lt (minus (match_dup 0) (pc))
10780 ;; In general it is not safe to assume too much about CCmode registers,
10781 ;; so simplify-rtx stops when it sees a second one. Under certain
10782 ;; conditions this is safe on x86, so help combine not create
10790 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10791 [(reg FLAGS_REG) (const_int 0)])
10793 (label_ref (match_operand 1))
10797 (if_then_else (match_dup 0)
10798 (label_ref (match_dup 1))
10800 "PUT_MODE (operands[0], VOIDmode);")
10804 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10805 [(reg FLAGS_REG) (const_int 0)])
10807 (label_ref (match_operand 1))
10811 (if_then_else (match_dup 0)
10812 (label_ref (match_dup 1))
10815 rtx new_op0 = copy_rtx (operands[0]);
10816 operands[0] = new_op0;
10817 PUT_MODE (new_op0, VOIDmode);
10818 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10819 GET_MODE (XEXP (new_op0, 0))));
10821 /* Make sure that (a) the CCmode we have for the flags is strong
10822 enough for the reversed compare or (b) we have a valid FP compare. */
10823 if (! ix86_comparison_operator (new_op0, VOIDmode))
10827 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10828 ;; pass generates from shift insn with QImode operand. Actually, the mode
10829 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10830 ;; appropriate modulo of the bit offset value.
10832 (define_insn_and_split "*jcc_bt<mode>"
10834 (if_then_else (match_operator 0 "bt_comparison_operator"
10835 [(zero_extract:SWI48
10836 (match_operand:SWI48 1 "register_operand" "r")
10839 (match_operand:QI 2 "register_operand" "r")))
10841 (label_ref (match_operand 3))
10843 (clobber (reg:CC FLAGS_REG))]
10844 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10847 [(set (reg:CCC FLAGS_REG)
10849 (zero_extract:SWI48
10855 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10856 (label_ref (match_dup 3))
10859 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10861 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10864 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10865 ;; also for DImode, this is what combine produces.
10866 (define_insn_and_split "*jcc_bt<mode>_mask"
10868 (if_then_else (match_operator 0 "bt_comparison_operator"
10869 [(zero_extract:SWI48
10870 (match_operand:SWI48 1 "register_operand" "r")
10873 (match_operand:SI 2 "register_operand" "r")
10874 (match_operand:SI 3 "const_int_operand" "n")))])
10875 (label_ref (match_operand 4))
10877 (clobber (reg:CC FLAGS_REG))]
10878 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10879 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10880 == GET_MODE_BITSIZE (<MODE>mode)-1"
10883 [(set (reg:CCC FLAGS_REG)
10885 (zero_extract:SWI48
10891 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10892 (label_ref (match_dup 4))
10895 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10897 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10900 (define_insn_and_split "*jcc_btsi_1"
10902 (if_then_else (match_operator 0 "bt_comparison_operator"
10905 (match_operand:SI 1 "register_operand" "r")
10906 (match_operand:QI 2 "register_operand" "r"))
10909 (label_ref (match_operand 3))
10911 (clobber (reg:CC FLAGS_REG))]
10912 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10915 [(set (reg:CCC FLAGS_REG)
10923 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10924 (label_ref (match_dup 3))
10927 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10929 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10932 ;; avoid useless masking of bit offset operand
10933 (define_insn_and_split "*jcc_btsi_mask_1"
10936 (match_operator 0 "bt_comparison_operator"
10939 (match_operand:SI 1 "register_operand" "r")
10942 (match_operand:SI 2 "register_operand" "r")
10943 (match_operand:SI 3 "const_int_operand" "n")) 0))
10946 (label_ref (match_operand 4))
10948 (clobber (reg:CC FLAGS_REG))]
10949 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10950 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10953 [(set (reg:CCC FLAGS_REG)
10961 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10962 (label_ref (match_dup 4))
10964 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10966 ;; Define combination compare-and-branch fp compare instructions to help
10969 (define_insn "*fp_jcc_1_387"
10971 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10972 [(match_operand 1 "register_operand" "f")
10973 (match_operand 2 "nonimmediate_operand" "fm")])
10974 (label_ref (match_operand 3))
10976 (clobber (reg:CCFP FPSR_REG))
10977 (clobber (reg:CCFP FLAGS_REG))
10978 (clobber (match_scratch:HI 4 "=a"))]
10980 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10981 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10982 && SELECT_CC_MODE (GET_CODE (operands[0]),
10983 operands[1], operands[2]) == CCFPmode
10987 (define_insn "*fp_jcc_1r_387"
10989 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10990 [(match_operand 1 "register_operand" "f")
10991 (match_operand 2 "nonimmediate_operand" "fm")])
10993 (label_ref (match_operand 3))))
10994 (clobber (reg:CCFP FPSR_REG))
10995 (clobber (reg:CCFP FLAGS_REG))
10996 (clobber (match_scratch:HI 4 "=a"))]
10998 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10999 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11000 && SELECT_CC_MODE (GET_CODE (operands[0]),
11001 operands[1], operands[2]) == CCFPmode
11005 (define_insn "*fp_jcc_2_387"
11007 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11008 [(match_operand 1 "register_operand" "f")
11009 (match_operand 2 "register_operand" "f")])
11010 (label_ref (match_operand 3))
11012 (clobber (reg:CCFP FPSR_REG))
11013 (clobber (reg:CCFP FLAGS_REG))
11014 (clobber (match_scratch:HI 4 "=a"))]
11015 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11016 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11020 (define_insn "*fp_jcc_2r_387"
11022 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11023 [(match_operand 1 "register_operand" "f")
11024 (match_operand 2 "register_operand" "f")])
11026 (label_ref (match_operand 3))))
11027 (clobber (reg:CCFP FPSR_REG))
11028 (clobber (reg:CCFP FLAGS_REG))
11029 (clobber (match_scratch:HI 4 "=a"))]
11030 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11031 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11035 (define_insn "*fp_jcc_3_387"
11037 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11038 [(match_operand 1 "register_operand" "f")
11039 (match_operand 2 "const0_operand")])
11040 (label_ref (match_operand 3))
11042 (clobber (reg:CCFP FPSR_REG))
11043 (clobber (reg:CCFP FLAGS_REG))
11044 (clobber (match_scratch:HI 4 "=a"))]
11045 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11046 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11047 && SELECT_CC_MODE (GET_CODE (operands[0]),
11048 operands[1], operands[2]) == CCFPmode
11054 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11055 [(match_operand 1 "register_operand")
11056 (match_operand 2 "nonimmediate_operand")])
11058 (match_operand 4)))
11059 (clobber (reg:CCFP FPSR_REG))
11060 (clobber (reg:CCFP FLAGS_REG))]
11064 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11065 operands[3], operands[4], NULL_RTX, NULL_RTX);
11071 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11072 [(match_operand 1 "register_operand")
11073 (match_operand 2 "general_operand")])
11075 (match_operand 4)))
11076 (clobber (reg:CCFP FPSR_REG))
11077 (clobber (reg:CCFP FLAGS_REG))
11078 (clobber (match_scratch:HI 5 "=a"))]
11082 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11083 operands[3], operands[4], operands[5], NULL_RTX);
11087 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11088 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11089 ;; with a precedence over other operators and is always put in the first
11090 ;; place. Swap condition and operands to match ficom instruction.
11092 (define_insn "*fp_jcc_4_<mode>_387"
11095 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11096 [(match_operator 1 "float_operator"
11097 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11098 (match_operand 3 "register_operand" "f,f")])
11099 (label_ref (match_operand 4))
11101 (clobber (reg:CCFP FPSR_REG))
11102 (clobber (reg:CCFP FLAGS_REG))
11103 (clobber (match_scratch:HI 5 "=a,a"))]
11104 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11105 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11106 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11107 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11114 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11115 [(match_operator 1 "float_operator"
11116 [(match_operand:SWI24 2 "memory_operand")])
11117 (match_operand 3 "register_operand")])
11119 (match_operand 5)))
11120 (clobber (reg:CCFP FPSR_REG))
11121 (clobber (reg:CCFP FLAGS_REG))
11122 (clobber (match_scratch:HI 6 "=a"))]
11126 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11128 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11129 operands[3], operands[7],
11130 operands[4], operands[5], operands[6], NULL_RTX);
11134 ;; %%% Kill this when reload knows how to do it.
11138 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11139 [(match_operator 1 "float_operator"
11140 [(match_operand:SWI24 2 "register_operand")])
11141 (match_operand 3 "register_operand")])
11143 (match_operand 5)))
11144 (clobber (reg:CCFP FPSR_REG))
11145 (clobber (reg:CCFP FLAGS_REG))
11146 (clobber (match_scratch:HI 6 "=a"))]
11150 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11151 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11153 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11154 operands[3], operands[7],
11155 operands[4], operands[5], operands[6], operands[2]);
11159 ;; Unconditional and other jump instructions
11161 (define_insn "jump"
11163 (label_ref (match_operand 0)))]
11166 [(set_attr "type" "ibr")
11167 (set (attr "length")
11168 (if_then_else (and (ge (minus (match_dup 0) (pc))
11170 (lt (minus (match_dup 0) (pc))
11174 (set_attr "modrm" "0")])
11176 (define_expand "indirect_jump"
11177 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11181 operands[0] = convert_memory_address (word_mode, operands[0]);
11184 (define_insn "*indirect_jump"
11185 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))]
11188 [(set_attr "type" "ibr")
11189 (set_attr "length_immediate" "0")])
11191 (define_expand "tablejump"
11192 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11193 (use (label_ref (match_operand 1)))])]
11196 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11197 relative. Convert the relative address to an absolute address. */
11201 enum rtx_code code;
11203 /* We can't use @GOTOFF for text labels on VxWorks;
11204 see gotoff_operand. */
11205 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11209 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11211 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11215 op1 = pic_offset_table_rtx;
11220 op0 = pic_offset_table_rtx;
11224 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11229 operands[0] = convert_memory_address (word_mode, operands[0]);
11232 (define_insn "*tablejump_1"
11233 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))
11234 (use (label_ref (match_operand 1)))]
11237 [(set_attr "type" "ibr")
11238 (set_attr "length_immediate" "0")])
11240 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11243 [(set (reg FLAGS_REG) (match_operand 0))
11244 (set (match_operand:QI 1 "register_operand")
11245 (match_operator:QI 2 "ix86_comparison_operator"
11246 [(reg FLAGS_REG) (const_int 0)]))
11247 (set (match_operand 3 "q_regs_operand")
11248 (zero_extend (match_dup 1)))]
11249 "(peep2_reg_dead_p (3, operands[1])
11250 || operands_match_p (operands[1], operands[3]))
11251 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11252 [(set (match_dup 4) (match_dup 0))
11253 (set (strict_low_part (match_dup 5))
11256 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11257 operands[5] = gen_lowpart (QImode, operands[3]);
11258 ix86_expand_clear (operands[3]);
11262 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11263 (match_operand 4)])
11264 (set (match_operand:QI 1 "register_operand")
11265 (match_operator:QI 2 "ix86_comparison_operator"
11266 [(reg FLAGS_REG) (const_int 0)]))
11267 (set (match_operand 3 "q_regs_operand")
11268 (zero_extend (match_dup 1)))]
11269 "(peep2_reg_dead_p (3, operands[1])
11270 || operands_match_p (operands[1], operands[3]))
11271 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11272 [(parallel [(set (match_dup 5) (match_dup 0))
11274 (set (strict_low_part (match_dup 6))
11277 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11278 operands[6] = gen_lowpart (QImode, operands[3]);
11279 ix86_expand_clear (operands[3]);
11282 ;; Similar, but match zero extend with andsi3.
11285 [(set (reg FLAGS_REG) (match_operand 0))
11286 (set (match_operand:QI 1 "register_operand")
11287 (match_operator:QI 2 "ix86_comparison_operator"
11288 [(reg FLAGS_REG) (const_int 0)]))
11289 (parallel [(set (match_operand:SI 3 "q_regs_operand")
11290 (and:SI (match_dup 3) (const_int 255)))
11291 (clobber (reg:CC FLAGS_REG))])]
11292 "REGNO (operands[1]) == REGNO (operands[3])
11293 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11294 [(set (match_dup 4) (match_dup 0))
11295 (set (strict_low_part (match_dup 5))
11298 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11299 operands[5] = gen_lowpart (QImode, operands[3]);
11300 ix86_expand_clear (operands[3]);
11304 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11305 (match_operand 4)])
11306 (set (match_operand:QI 1 "register_operand")
11307 (match_operator:QI 2 "ix86_comparison_operator"
11308 [(reg FLAGS_REG) (const_int 0)]))
11309 (parallel [(set (match_operand 3 "q_regs_operand")
11310 (zero_extend (match_dup 1)))
11311 (clobber (reg:CC FLAGS_REG))])]
11312 "(peep2_reg_dead_p (3, operands[1])
11313 || operands_match_p (operands[1], operands[3]))
11314 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11315 [(parallel [(set (match_dup 5) (match_dup 0))
11317 (set (strict_low_part (match_dup 6))
11320 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11321 operands[6] = gen_lowpart (QImode, operands[3]);
11322 ix86_expand_clear (operands[3]);
11325 ;; Call instructions.
11327 ;; The predicates normally associated with named expanders are not properly
11328 ;; checked for calls. This is a bug in the generic code, but it isn't that
11329 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11331 ;; P6 processors will jump to the address after the decrement when %esp
11332 ;; is used as a call operand, so they will execute return address as a code.
11333 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11335 ;; Register constraint for call instruction.
11336 (define_mode_attr c [(SI "l") (DI "r")])
11338 ;; Call subroutine returning no value.
11340 (define_expand "call"
11341 [(call (match_operand:QI 0)
11343 (use (match_operand 2))]
11346 ix86_expand_call (NULL, operands[0], operands[1],
11347 operands[2], NULL, false);
11351 (define_expand "sibcall"
11352 [(call (match_operand:QI 0)
11354 (use (match_operand 2))]
11357 ix86_expand_call (NULL, operands[0], operands[1],
11358 operands[2], NULL, true);
11362 (define_insn_and_split "*call_vzeroupper"
11363 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11365 (unspec [(match_operand 2 "const_int_operand")]
11366 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11367 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11369 "&& reload_completed"
11371 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11372 [(set_attr "type" "call")])
11374 (define_insn "*call"
11375 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11376 (match_operand 1))]
11377 "!SIBLING_CALL_P (insn)"
11378 "* return ix86_output_call_insn (insn, operands[0]);"
11379 [(set_attr "type" "call")])
11381 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11382 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11384 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11385 (clobber (reg:TI XMM6_REG))
11386 (clobber (reg:TI XMM7_REG))
11387 (clobber (reg:TI XMM8_REG))
11388 (clobber (reg:TI XMM9_REG))
11389 (clobber (reg:TI XMM10_REG))
11390 (clobber (reg:TI XMM11_REG))
11391 (clobber (reg:TI XMM12_REG))
11392 (clobber (reg:TI XMM13_REG))
11393 (clobber (reg:TI XMM14_REG))
11394 (clobber (reg:TI XMM15_REG))
11395 (clobber (reg:DI SI_REG))
11396 (clobber (reg:DI DI_REG))
11397 (unspec [(match_operand 2 "const_int_operand")]
11398 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11399 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11401 "&& reload_completed"
11403 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11404 [(set_attr "type" "call")])
11406 (define_insn "*call_rex64_ms_sysv"
11407 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11409 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11410 (clobber (reg:TI XMM6_REG))
11411 (clobber (reg:TI XMM7_REG))
11412 (clobber (reg:TI XMM8_REG))
11413 (clobber (reg:TI XMM9_REG))
11414 (clobber (reg:TI XMM10_REG))
11415 (clobber (reg:TI XMM11_REG))
11416 (clobber (reg:TI XMM12_REG))
11417 (clobber (reg:TI XMM13_REG))
11418 (clobber (reg:TI XMM14_REG))
11419 (clobber (reg:TI XMM15_REG))
11420 (clobber (reg:DI SI_REG))
11421 (clobber (reg:DI DI_REG))]
11422 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11423 "* return ix86_output_call_insn (insn, operands[0]);"
11424 [(set_attr "type" "call")])
11426 (define_insn_and_split "*sibcall_vzeroupper"
11427 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11429 (unspec [(match_operand 2 "const_int_operand")]
11430 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11431 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11433 "&& reload_completed"
11435 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11436 [(set_attr "type" "call")])
11438 (define_insn "*sibcall"
11439 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11440 (match_operand 1))]
11441 "SIBLING_CALL_P (insn)"
11442 "* return ix86_output_call_insn (insn, operands[0]);"
11443 [(set_attr "type" "call")])
11445 (define_expand "call_pop"
11446 [(parallel [(call (match_operand:QI 0)
11447 (match_operand:SI 1))
11448 (set (reg:SI SP_REG)
11449 (plus:SI (reg:SI SP_REG)
11450 (match_operand:SI 3)))])]
11453 ix86_expand_call (NULL, operands[0], operands[1],
11454 operands[2], operands[3], false);
11458 (define_insn_and_split "*call_pop_vzeroupper"
11459 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11461 (set (reg:SI SP_REG)
11462 (plus:SI (reg:SI SP_REG)
11463 (match_operand:SI 2 "immediate_operand" "i")))
11464 (unspec [(match_operand 3 "const_int_operand")]
11465 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11466 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11468 "&& reload_completed"
11470 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11471 [(set_attr "type" "call")])
11473 (define_insn "*call_pop"
11474 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11476 (set (reg:SI SP_REG)
11477 (plus:SI (reg:SI SP_REG)
11478 (match_operand:SI 2 "immediate_operand" "i")))]
11479 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11480 "* return ix86_output_call_insn (insn, operands[0]);"
11481 [(set_attr "type" "call")])
11483 (define_insn_and_split "*sibcall_pop_vzeroupper"
11484 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11486 (set (reg:SI SP_REG)
11487 (plus:SI (reg:SI SP_REG)
11488 (match_operand:SI 2 "immediate_operand" "i")))
11489 (unspec [(match_operand 3 "const_int_operand")]
11490 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11491 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11493 "&& reload_completed"
11495 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11496 [(set_attr "type" "call")])
11498 (define_insn "*sibcall_pop"
11499 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11501 (set (reg:SI SP_REG)
11502 (plus:SI (reg:SI SP_REG)
11503 (match_operand:SI 2 "immediate_operand" "i")))]
11504 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11505 "* return ix86_output_call_insn (insn, operands[0]);"
11506 [(set_attr "type" "call")])
11508 ;; Call subroutine, returning value in operand 0
11510 (define_expand "call_value"
11511 [(set (match_operand 0)
11512 (call (match_operand:QI 1)
11513 (match_operand 2)))
11514 (use (match_operand 3))]
11517 ix86_expand_call (operands[0], operands[1], operands[2],
11518 operands[3], NULL, false);
11522 (define_expand "sibcall_value"
11523 [(set (match_operand 0)
11524 (call (match_operand:QI 1)
11525 (match_operand 2)))
11526 (use (match_operand 3))]
11529 ix86_expand_call (operands[0], operands[1], operands[2],
11530 operands[3], NULL, true);
11534 (define_insn_and_split "*call_value_vzeroupper"
11535 [(set (match_operand 0)
11536 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11537 (match_operand 2)))
11538 (unspec [(match_operand 3 "const_int_operand")]
11539 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11540 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11542 "&& reload_completed"
11544 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11545 [(set_attr "type" "callv")])
11547 (define_insn "*call_value"
11548 [(set (match_operand 0)
11549 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11550 (match_operand 2)))]
11551 "!SIBLING_CALL_P (insn)"
11552 "* return ix86_output_call_insn (insn, operands[1]);"
11553 [(set_attr "type" "callv")])
11555 (define_insn_and_split "*sibcall_value_vzeroupper"
11556 [(set (match_operand 0)
11557 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11558 (match_operand 2)))
11559 (unspec [(match_operand 3 "const_int_operand")]
11560 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11561 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11563 "&& reload_completed"
11565 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11566 [(set_attr "type" "callv")])
11568 (define_insn "*sibcall_value"
11569 [(set (match_operand 0)
11570 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11571 (match_operand 2)))]
11572 "SIBLING_CALL_P (insn)"
11573 "* return ix86_output_call_insn (insn, operands[1]);"
11574 [(set_attr "type" "callv")])
11576 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11577 [(set (match_operand 0)
11578 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11579 (match_operand 2)))
11580 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11581 (clobber (reg:TI XMM6_REG))
11582 (clobber (reg:TI XMM7_REG))
11583 (clobber (reg:TI XMM8_REG))
11584 (clobber (reg:TI XMM9_REG))
11585 (clobber (reg:TI XMM10_REG))
11586 (clobber (reg:TI XMM11_REG))
11587 (clobber (reg:TI XMM12_REG))
11588 (clobber (reg:TI XMM13_REG))
11589 (clobber (reg:TI XMM14_REG))
11590 (clobber (reg:TI XMM15_REG))
11591 (clobber (reg:DI SI_REG))
11592 (clobber (reg:DI DI_REG))
11593 (unspec [(match_operand 3 "const_int_operand")]
11594 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11595 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11597 "&& reload_completed"
11599 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11600 [(set_attr "type" "callv")])
11602 (define_insn "*call_value_rex64_ms_sysv"
11603 [(set (match_operand 0)
11604 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11605 (match_operand 2)))
11606 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11607 (clobber (reg:TI XMM6_REG))
11608 (clobber (reg:TI XMM7_REG))
11609 (clobber (reg:TI XMM8_REG))
11610 (clobber (reg:TI XMM9_REG))
11611 (clobber (reg:TI XMM10_REG))
11612 (clobber (reg:TI XMM11_REG))
11613 (clobber (reg:TI XMM12_REG))
11614 (clobber (reg:TI XMM13_REG))
11615 (clobber (reg:TI XMM14_REG))
11616 (clobber (reg:TI XMM15_REG))
11617 (clobber (reg:DI SI_REG))
11618 (clobber (reg:DI DI_REG))]
11619 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11620 "* return ix86_output_call_insn (insn, operands[1]);"
11621 [(set_attr "type" "callv")])
11623 (define_expand "call_value_pop"
11624 [(parallel [(set (match_operand 0)
11625 (call (match_operand:QI 1)
11626 (match_operand:SI 2)))
11627 (set (reg:SI SP_REG)
11628 (plus:SI (reg:SI SP_REG)
11629 (match_operand:SI 4)))])]
11632 ix86_expand_call (operands[0], operands[1], operands[2],
11633 operands[3], operands[4], false);
11637 (define_insn_and_split "*call_value_pop_vzeroupper"
11638 [(set (match_operand 0)
11639 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11640 (match_operand 2)))
11641 (set (reg:SI SP_REG)
11642 (plus:SI (reg:SI SP_REG)
11643 (match_operand:SI 3 "immediate_operand" "i")))
11644 (unspec [(match_operand 4 "const_int_operand")]
11645 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11646 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11648 "&& reload_completed"
11650 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11651 [(set_attr "type" "callv")])
11653 (define_insn "*call_value_pop"
11654 [(set (match_operand 0)
11655 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11656 (match_operand 2)))
11657 (set (reg:SI SP_REG)
11658 (plus:SI (reg:SI SP_REG)
11659 (match_operand:SI 3 "immediate_operand" "i")))]
11660 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11661 "* return ix86_output_call_insn (insn, operands[1]);"
11662 [(set_attr "type" "callv")])
11664 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11665 [(set (match_operand 0)
11666 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11667 (match_operand 2)))
11668 (set (reg:SI SP_REG)
11669 (plus:SI (reg:SI SP_REG)
11670 (match_operand:SI 3 "immediate_operand" "i")))
11671 (unspec [(match_operand 4 "const_int_operand")]
11672 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11673 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11675 "&& reload_completed"
11677 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11678 [(set_attr "type" "callv")])
11680 (define_insn "*sibcall_value_pop"
11681 [(set (match_operand 0)
11682 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11683 (match_operand 2)))
11684 (set (reg:SI SP_REG)
11685 (plus:SI (reg:SI SP_REG)
11686 (match_operand:SI 3 "immediate_operand" "i")))]
11687 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11688 "* return ix86_output_call_insn (insn, operands[1]);"
11689 [(set_attr "type" "callv")])
11691 ;; Call subroutine returning any type.
11693 (define_expand "untyped_call"
11694 [(parallel [(call (match_operand 0)
11697 (match_operand 2)])]
11702 /* In order to give reg-stack an easier job in validating two
11703 coprocessor registers as containing a possible return value,
11704 simply pretend the untyped call returns a complex long double
11707 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11708 and should have the default ABI. */
11710 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11711 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11712 operands[0], const0_rtx,
11713 GEN_INT ((TARGET_64BIT
11714 ? (ix86_abi == SYSV_ABI
11715 ? X86_64_SSE_REGPARM_MAX
11716 : X86_64_MS_SSE_REGPARM_MAX)
11717 : X86_32_SSE_REGPARM_MAX)
11721 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11723 rtx set = XVECEXP (operands[2], 0, i);
11724 emit_move_insn (SET_DEST (set), SET_SRC (set));
11727 /* The optimizer does not know that the call sets the function value
11728 registers we stored in the result block. We avoid problems by
11729 claiming that all hard registers are used and clobbered at this
11731 emit_insn (gen_blockage ());
11736 ;; Prologue and epilogue instructions
11738 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11739 ;; all of memory. This blocks insns from being moved across this point.
11741 (define_insn "blockage"
11742 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11745 [(set_attr "length" "0")])
11747 ;; Do not schedule instructions accessing memory across this point.
11749 (define_expand "memory_blockage"
11750 [(set (match_dup 0)
11751 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11754 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11755 MEM_VOLATILE_P (operands[0]) = 1;
11758 (define_insn "*memory_blockage"
11759 [(set (match_operand:BLK 0)
11760 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11763 [(set_attr "length" "0")])
11765 ;; As USE insns aren't meaningful after reload, this is used instead
11766 ;; to prevent deleting instructions setting registers for PIC code
11767 (define_insn "prologue_use"
11768 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
11771 [(set_attr "length" "0")])
11773 ;; Insn emitted into the body of a function to return from a function.
11774 ;; This is only done if the function's epilogue is known to be simple.
11775 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11777 (define_expand "return"
11779 "ix86_can_use_return_insn_p ()"
11781 ix86_maybe_emit_epilogue_vzeroupper ();
11782 if (crtl->args.pops_args)
11784 rtx popc = GEN_INT (crtl->args.pops_args);
11785 emit_jump_insn (gen_simple_return_pop_internal (popc));
11790 ;; We need to disable this for TARGET_SEH, as otherwise
11791 ;; shrink-wrapped prologue gets enabled too. This might exceed
11792 ;; the maximum size of prologue in unwind information.
11794 (define_expand "simple_return"
11798 ix86_maybe_emit_epilogue_vzeroupper ();
11799 if (crtl->args.pops_args)
11801 rtx popc = GEN_INT (crtl->args.pops_args);
11802 emit_jump_insn (gen_simple_return_pop_internal (popc));
11807 (define_insn "simple_return_internal"
11811 [(set_attr "length" "1")
11812 (set_attr "atom_unit" "jeu")
11813 (set_attr "length_immediate" "0")
11814 (set_attr "modrm" "0")])
11816 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11817 ;; instruction Athlon and K8 have.
11819 (define_insn "simple_return_internal_long"
11821 (unspec [(const_int 0)] UNSPEC_REP)]
11824 [(set_attr "length" "2")
11825 (set_attr "atom_unit" "jeu")
11826 (set_attr "length_immediate" "0")
11827 (set_attr "prefix_rep" "1")
11828 (set_attr "modrm" "0")])
11830 (define_insn "simple_return_pop_internal"
11832 (use (match_operand:SI 0 "const_int_operand"))]
11835 [(set_attr "length" "3")
11836 (set_attr "atom_unit" "jeu")
11837 (set_attr "length_immediate" "2")
11838 (set_attr "modrm" "0")])
11840 (define_insn "simple_return_indirect_internal"
11842 (use (match_operand:SI 0 "register_operand" "r"))]
11845 [(set_attr "type" "ibr")
11846 (set_attr "length_immediate" "0")])
11852 [(set_attr "length" "1")
11853 (set_attr "length_immediate" "0")
11854 (set_attr "modrm" "0")])
11856 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11857 (define_insn "nops"
11858 [(unspec_volatile [(match_operand 0 "const_int_operand")]
11862 int num = INTVAL (operands[0]);
11864 gcc_assert (num >= 1 && num <= 8);
11867 fputs ("\tnop\n", asm_out_file);
11871 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11872 (set_attr "length_immediate" "0")
11873 (set_attr "modrm" "0")])
11875 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11876 ;; branch prediction penalty for the third jump in a 16-byte
11880 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
11883 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11884 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11886 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11887 The align insn is used to avoid 3 jump instructions in the row to improve
11888 branch prediction and the benefits hardly outweigh the cost of extra 8
11889 nops on the average inserted by full alignment pseudo operation. */
11893 [(set_attr "length" "16")])
11895 (define_expand "prologue"
11898 "ix86_expand_prologue (); DONE;")
11900 (define_insn "set_got"
11901 [(set (match_operand:SI 0 "register_operand" "=r")
11902 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11903 (clobber (reg:CC FLAGS_REG))]
11905 "* return output_set_got (operands[0], NULL_RTX);"
11906 [(set_attr "type" "multi")
11907 (set_attr "length" "12")])
11909 (define_insn "set_got_labelled"
11910 [(set (match_operand:SI 0 "register_operand" "=r")
11911 (unspec:SI [(label_ref (match_operand 1))]
11913 (clobber (reg:CC FLAGS_REG))]
11915 "* return output_set_got (operands[0], operands[1]);"
11916 [(set_attr "type" "multi")
11917 (set_attr "length" "12")])
11919 (define_insn "set_got_rex64"
11920 [(set (match_operand:DI 0 "register_operand" "=r")
11921 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11923 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11924 [(set_attr "type" "lea")
11925 (set_attr "length_address" "4")
11926 (set_attr "mode" "DI")])
11928 (define_insn "set_rip_rex64"
11929 [(set (match_operand:DI 0 "register_operand" "=r")
11930 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
11932 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11933 [(set_attr "type" "lea")
11934 (set_attr "length_address" "4")
11935 (set_attr "mode" "DI")])
11937 (define_insn "set_got_offset_rex64"
11938 [(set (match_operand:DI 0 "register_operand" "=r")
11940 [(label_ref (match_operand 1))]
11941 UNSPEC_SET_GOT_OFFSET))]
11943 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11944 [(set_attr "type" "imov")
11945 (set_attr "length_immediate" "0")
11946 (set_attr "length_address" "8")
11947 (set_attr "mode" "DI")])
11949 (define_expand "epilogue"
11952 "ix86_expand_epilogue (1); DONE;")
11954 (define_expand "sibcall_epilogue"
11957 "ix86_expand_epilogue (0); DONE;")
11959 (define_expand "eh_return"
11960 [(use (match_operand 0 "register_operand"))]
11963 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11965 /* Tricky bit: we write the address of the handler to which we will
11966 be returning into someone else's stack frame, one word below the
11967 stack address we wish to restore. */
11968 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11969 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11970 tmp = gen_rtx_MEM (Pmode, tmp);
11971 emit_move_insn (tmp, ra);
11973 emit_jump_insn (gen_eh_return_internal ());
11978 (define_insn_and_split "eh_return_internal"
11982 "epilogue_completed"
11984 "ix86_expand_epilogue (2); DONE;")
11986 (define_insn "leave"
11987 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11988 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11989 (clobber (mem:BLK (scratch)))]
11992 [(set_attr "type" "leave")])
11994 (define_insn "leave_rex64"
11995 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11996 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11997 (clobber (mem:BLK (scratch)))]
12000 [(set_attr "type" "leave")])
12002 ;; Handle -fsplit-stack.
12004 (define_expand "split_stack_prologue"
12008 ix86_expand_split_stack_prologue ();
12012 ;; In order to support the call/return predictor, we use a return
12013 ;; instruction which the middle-end doesn't see.
12014 (define_insn "split_stack_return"
12015 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12016 UNSPECV_SPLIT_STACK_RETURN)]
12019 if (operands[0] == const0_rtx)
12024 [(set_attr "atom_unit" "jeu")
12025 (set_attr "modrm" "0")
12026 (set (attr "length")
12027 (if_then_else (match_operand:SI 0 "const0_operand")
12030 (set (attr "length_immediate")
12031 (if_then_else (match_operand:SI 0 "const0_operand")
12035 ;; If there are operand 0 bytes available on the stack, jump to
12038 (define_expand "split_stack_space_check"
12039 [(set (pc) (if_then_else
12040 (ltu (minus (reg SP_REG)
12041 (match_operand 0 "register_operand"))
12042 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12043 (label_ref (match_operand 1))
12047 rtx reg, size, limit;
12049 reg = gen_reg_rtx (Pmode);
12050 size = force_reg (Pmode, operands[0]);
12051 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12052 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12053 UNSPEC_STACK_CHECK);
12054 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12055 ix86_expand_branch (GEU, reg, limit, operands[1]);
12060 ;; Bit manipulation instructions.
12062 (define_expand "ffs<mode>2"
12063 [(set (match_dup 2) (const_int -1))
12064 (parallel [(set (reg:CCZ FLAGS_REG)
12066 (match_operand:SWI48 1 "nonimmediate_operand")
12068 (set (match_operand:SWI48 0 "register_operand")
12069 (ctz:SWI48 (match_dup 1)))])
12070 (set (match_dup 0) (if_then_else:SWI48
12071 (eq (reg:CCZ FLAGS_REG) (const_int 0))
12074 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12075 (clobber (reg:CC FLAGS_REG))])]
12078 if (<MODE>mode == SImode && !TARGET_CMOVE)
12080 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12083 operands[2] = gen_reg_rtx (<MODE>mode);
12086 (define_insn_and_split "ffssi2_no_cmove"
12087 [(set (match_operand:SI 0 "register_operand" "=r")
12088 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12089 (clobber (match_scratch:SI 2 "=&q"))
12090 (clobber (reg:CC FLAGS_REG))]
12093 "&& reload_completed"
12094 [(parallel [(set (reg:CCZ FLAGS_REG)
12095 (compare:CCZ (match_dup 1) (const_int 0)))
12096 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12097 (set (strict_low_part (match_dup 3))
12098 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
12099 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12100 (clobber (reg:CC FLAGS_REG))])
12101 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12102 (clobber (reg:CC FLAGS_REG))])
12103 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12104 (clobber (reg:CC FLAGS_REG))])]
12106 operands[3] = gen_lowpart (QImode, operands[2]);
12107 ix86_expand_clear (operands[2]);
12110 (define_insn "*ffs<mode>_1"
12111 [(set (reg:CCZ FLAGS_REG)
12112 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12114 (set (match_operand:SWI48 0 "register_operand" "=r")
12115 (ctz:SWI48 (match_dup 1)))]
12117 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12118 [(set_attr "type" "alu1")
12119 (set_attr "prefix_0f" "1")
12120 (set_attr "mode" "<MODE>")])
12122 (define_insn "ctz<mode>2"
12123 [(set (match_operand:SWI248 0 "register_operand" "=r")
12124 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12125 (clobber (reg:CC FLAGS_REG))]
12129 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12131 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12133 [(set_attr "type" "alu1")
12134 (set_attr "prefix_0f" "1")
12135 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
12136 (set_attr "mode" "<MODE>")])
12138 (define_expand "clz<mode>2"
12140 [(set (match_operand:SWI248 0 "register_operand")
12143 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12144 (clobber (reg:CC FLAGS_REG))])
12146 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12147 (clobber (reg:CC FLAGS_REG))])]
12152 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12155 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12158 (define_insn "clz<mode>2_lzcnt"
12159 [(set (match_operand:SWI248 0 "register_operand" "=r")
12160 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12161 (clobber (reg:CC FLAGS_REG))]
12163 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12164 [(set_attr "prefix_rep" "1")
12165 (set_attr "type" "bitmanip")
12166 (set_attr "mode" "<MODE>")])
12168 ;; BMI instructions.
12169 (define_insn "*bmi_andn_<mode>"
12170 [(set (match_operand:SWI48 0 "register_operand" "=r")
12173 (match_operand:SWI48 1 "register_operand" "r"))
12174 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12175 (clobber (reg:CC FLAGS_REG))]
12177 "andn\t{%2, %1, %0|%0, %1, %2}"
12178 [(set_attr "type" "bitmanip")
12179 (set_attr "mode" "<MODE>")])
12181 (define_insn "bmi_bextr_<mode>"
12182 [(set (match_operand:SWI48 0 "register_operand" "=r")
12183 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12184 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12186 (clobber (reg:CC FLAGS_REG))]
12188 "bextr\t{%2, %1, %0|%0, %1, %2}"
12189 [(set_attr "type" "bitmanip")
12190 (set_attr "mode" "<MODE>")])
12192 (define_insn "*bmi_blsi_<mode>"
12193 [(set (match_operand:SWI48 0 "register_operand" "=r")
12196 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12198 (clobber (reg:CC FLAGS_REG))]
12200 "blsi\t{%1, %0|%0, %1}"
12201 [(set_attr "type" "bitmanip")
12202 (set_attr "mode" "<MODE>")])
12204 (define_insn "*bmi_blsmsk_<mode>"
12205 [(set (match_operand:SWI48 0 "register_operand" "=r")
12208 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12211 (clobber (reg:CC FLAGS_REG))]
12213 "blsmsk\t{%1, %0|%0, %1}"
12214 [(set_attr "type" "bitmanip")
12215 (set_attr "mode" "<MODE>")])
12217 (define_insn "*bmi_blsr_<mode>"
12218 [(set (match_operand:SWI48 0 "register_operand" "=r")
12221 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12224 (clobber (reg:CC FLAGS_REG))]
12226 "blsr\t{%1, %0|%0, %1}"
12227 [(set_attr "type" "bitmanip")
12228 (set_attr "mode" "<MODE>")])
12230 ;; BMI2 instructions.
12231 (define_insn "bmi2_bzhi_<mode>3"
12232 [(set (match_operand:SWI48 0 "register_operand" "=r")
12233 (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
12234 (lshiftrt:SWI48 (const_int -1)
12235 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
12236 (clobber (reg:CC FLAGS_REG))]
12238 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12239 [(set_attr "type" "bitmanip")
12240 (set_attr "prefix" "vex")
12241 (set_attr "mode" "<MODE>")])
12243 (define_insn "bmi2_pdep_<mode>3"
12244 [(set (match_operand:SWI48 0 "register_operand" "=r")
12245 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12246 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12249 "pdep\t{%2, %1, %0|%0, %1, %2}"
12250 [(set_attr "type" "bitmanip")
12251 (set_attr "prefix" "vex")
12252 (set_attr "mode" "<MODE>")])
12254 (define_insn "bmi2_pext_<mode>3"
12255 [(set (match_operand:SWI48 0 "register_operand" "=r")
12256 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12257 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12260 "pext\t{%2, %1, %0|%0, %1, %2}"
12261 [(set_attr "type" "bitmanip")
12262 (set_attr "prefix" "vex")
12263 (set_attr "mode" "<MODE>")])
12265 ;; TBM instructions.
12266 (define_insn "tbm_bextri_<mode>"
12267 [(set (match_operand:SWI48 0 "register_operand" "=r")
12268 (zero_extract:SWI48
12269 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12270 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12271 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12272 (clobber (reg:CC FLAGS_REG))]
12275 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12276 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12278 [(set_attr "type" "bitmanip")
12279 (set_attr "mode" "<MODE>")])
12281 (define_insn "*tbm_blcfill_<mode>"
12282 [(set (match_operand:SWI48 0 "register_operand" "=r")
12285 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12288 (clobber (reg:CC FLAGS_REG))]
12290 "blcfill\t{%1, %0|%0, %1}"
12291 [(set_attr "type" "bitmanip")
12292 (set_attr "mode" "<MODE>")])
12294 (define_insn "*tbm_blci_<mode>"
12295 [(set (match_operand:SWI48 0 "register_operand" "=r")
12299 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12302 (clobber (reg:CC FLAGS_REG))]
12304 "blci\t{%1, %0|%0, %1}"
12305 [(set_attr "type" "bitmanip")
12306 (set_attr "mode" "<MODE>")])
12308 (define_insn "*tbm_blcic_<mode>"
12309 [(set (match_operand:SWI48 0 "register_operand" "=r")
12312 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12316 (clobber (reg:CC FLAGS_REG))]
12318 "blcic\t{%1, %0|%0, %1}"
12319 [(set_attr "type" "bitmanip")
12320 (set_attr "mode" "<MODE>")])
12322 (define_insn "*tbm_blcmsk_<mode>"
12323 [(set (match_operand:SWI48 0 "register_operand" "=r")
12326 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12329 (clobber (reg:CC FLAGS_REG))]
12331 "blcmsk\t{%1, %0|%0, %1}"
12332 [(set_attr "type" "bitmanip")
12333 (set_attr "mode" "<MODE>")])
12335 (define_insn "*tbm_blcs_<mode>"
12336 [(set (match_operand:SWI48 0 "register_operand" "=r")
12339 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12342 (clobber (reg:CC FLAGS_REG))]
12344 "blcs\t{%1, %0|%0, %1}"
12345 [(set_attr "type" "bitmanip")
12346 (set_attr "mode" "<MODE>")])
12348 (define_insn "*tbm_blsfill_<mode>"
12349 [(set (match_operand:SWI48 0 "register_operand" "=r")
12352 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12355 (clobber (reg:CC FLAGS_REG))]
12357 "blsfill\t{%1, %0|%0, %1}"
12358 [(set_attr "type" "bitmanip")
12359 (set_attr "mode" "<MODE>")])
12361 (define_insn "*tbm_blsic_<mode>"
12362 [(set (match_operand:SWI48 0 "register_operand" "=r")
12365 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12369 (clobber (reg:CC FLAGS_REG))]
12371 "blsic\t{%1, %0|%0, %1}"
12372 [(set_attr "type" "bitmanip")
12373 (set_attr "mode" "<MODE>")])
12375 (define_insn "*tbm_t1mskc_<mode>"
12376 [(set (match_operand:SWI48 0 "register_operand" "=r")
12379 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12383 (clobber (reg:CC FLAGS_REG))]
12385 "t1mskc\t{%1, %0|%0, %1}"
12386 [(set_attr "type" "bitmanip")
12387 (set_attr "mode" "<MODE>")])
12389 (define_insn "*tbm_tzmsk_<mode>"
12390 [(set (match_operand:SWI48 0 "register_operand" "=r")
12393 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12397 (clobber (reg:CC FLAGS_REG))]
12399 "tzmsk\t{%1, %0|%0, %1}"
12400 [(set_attr "type" "bitmanip")
12401 (set_attr "mode" "<MODE>")])
12403 (define_insn "bsr_rex64"
12404 [(set (match_operand:DI 0 "register_operand" "=r")
12405 (minus:DI (const_int 63)
12406 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12407 (clobber (reg:CC FLAGS_REG))]
12409 "bsr{q}\t{%1, %0|%0, %1}"
12410 [(set_attr "type" "alu1")
12411 (set_attr "prefix_0f" "1")
12412 (set_attr "mode" "DI")])
12415 [(set (match_operand:SI 0 "register_operand" "=r")
12416 (minus:SI (const_int 31)
12417 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12418 (clobber (reg:CC FLAGS_REG))]
12420 "bsr{l}\t{%1, %0|%0, %1}"
12421 [(set_attr "type" "alu1")
12422 (set_attr "prefix_0f" "1")
12423 (set_attr "mode" "SI")])
12425 (define_insn "*bsrhi"
12426 [(set (match_operand:HI 0 "register_operand" "=r")
12427 (minus:HI (const_int 15)
12428 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12429 (clobber (reg:CC FLAGS_REG))]
12431 "bsr{w}\t{%1, %0|%0, %1}"
12432 [(set_attr "type" "alu1")
12433 (set_attr "prefix_0f" "1")
12434 (set_attr "mode" "HI")])
12436 (define_insn "popcount<mode>2"
12437 [(set (match_operand:SWI248 0 "register_operand" "=r")
12439 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12440 (clobber (reg:CC FLAGS_REG))]
12444 return "popcnt\t{%1, %0|%0, %1}";
12446 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12449 [(set_attr "prefix_rep" "1")
12450 (set_attr "type" "bitmanip")
12451 (set_attr "mode" "<MODE>")])
12453 (define_insn "*popcount<mode>2_cmp"
12454 [(set (reg FLAGS_REG)
12457 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12459 (set (match_operand:SWI248 0 "register_operand" "=r")
12460 (popcount:SWI248 (match_dup 1)))]
12461 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12464 return "popcnt\t{%1, %0|%0, %1}";
12466 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12469 [(set_attr "prefix_rep" "1")
12470 (set_attr "type" "bitmanip")
12471 (set_attr "mode" "<MODE>")])
12473 (define_insn "*popcountsi2_cmp_zext"
12474 [(set (reg FLAGS_REG)
12476 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12478 (set (match_operand:DI 0 "register_operand" "=r")
12479 (zero_extend:DI(popcount:SI (match_dup 1))))]
12480 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12483 return "popcnt\t{%1, %0|%0, %1}";
12485 return "popcnt{l}\t{%1, %0|%0, %1}";
12488 [(set_attr "prefix_rep" "1")
12489 (set_attr "type" "bitmanip")
12490 (set_attr "mode" "SI")])
12492 (define_expand "bswap<mode>2"
12493 [(set (match_operand:SWI48 0 "register_operand")
12494 (bswap:SWI48 (match_operand:SWI48 1 "register_operand")))]
12497 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12499 rtx x = operands[0];
12501 emit_move_insn (x, operands[1]);
12502 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12503 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12504 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12509 (define_insn "*bswap<mode>2_movbe"
12510 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12511 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12513 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12516 movbe\t{%1, %0|%0, %1}
12517 movbe\t{%1, %0|%0, %1}"
12518 [(set_attr "type" "bitmanip,imov,imov")
12519 (set_attr "modrm" "0,1,1")
12520 (set_attr "prefix_0f" "*,1,1")
12521 (set_attr "prefix_extra" "*,1,1")
12522 (set_attr "mode" "<MODE>")])
12524 (define_insn "*bswap<mode>2_1"
12525 [(set (match_operand:SWI48 0 "register_operand" "=r")
12526 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12529 [(set_attr "type" "bitmanip")
12530 (set_attr "modrm" "0")
12531 (set_attr "mode" "<MODE>")])
12533 (define_insn "*bswaphi_lowpart_1"
12534 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12535 (bswap:HI (match_dup 0)))
12536 (clobber (reg:CC FLAGS_REG))]
12537 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12539 xchg{b}\t{%h0, %b0|%b0, %h0}
12540 rol{w}\t{$8, %0|%0, 8}"
12541 [(set_attr "length" "2,4")
12542 (set_attr "mode" "QI,HI")])
12544 (define_insn "bswaphi_lowpart"
12545 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12546 (bswap:HI (match_dup 0)))
12547 (clobber (reg:CC FLAGS_REG))]
12549 "rol{w}\t{$8, %0|%0, 8}"
12550 [(set_attr "length" "4")
12551 (set_attr "mode" "HI")])
12553 (define_expand "paritydi2"
12554 [(set (match_operand:DI 0 "register_operand")
12555 (parity:DI (match_operand:DI 1 "register_operand")))]
12558 rtx scratch = gen_reg_rtx (QImode);
12561 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12562 NULL_RTX, operands[1]));
12564 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12565 gen_rtx_REG (CCmode, FLAGS_REG),
12567 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12570 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12573 rtx tmp = gen_reg_rtx (SImode);
12575 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12576 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12581 (define_expand "paritysi2"
12582 [(set (match_operand:SI 0 "register_operand")
12583 (parity:SI (match_operand:SI 1 "register_operand")))]
12586 rtx scratch = gen_reg_rtx (QImode);
12589 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12591 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12592 gen_rtx_REG (CCmode, FLAGS_REG),
12594 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12596 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12600 (define_insn_and_split "paritydi2_cmp"
12601 [(set (reg:CC FLAGS_REG)
12602 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12604 (clobber (match_scratch:DI 0 "=r"))
12605 (clobber (match_scratch:SI 1 "=&r"))
12606 (clobber (match_scratch:HI 2 "=Q"))]
12609 "&& reload_completed"
12611 [(set (match_dup 1)
12612 (xor:SI (match_dup 1) (match_dup 4)))
12613 (clobber (reg:CC FLAGS_REG))])
12615 [(set (reg:CC FLAGS_REG)
12616 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12617 (clobber (match_dup 1))
12618 (clobber (match_dup 2))])]
12620 operands[4] = gen_lowpart (SImode, operands[3]);
12624 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12625 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12628 operands[1] = gen_highpart (SImode, operands[3]);
12631 (define_insn_and_split "paritysi2_cmp"
12632 [(set (reg:CC FLAGS_REG)
12633 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12635 (clobber (match_scratch:SI 0 "=r"))
12636 (clobber (match_scratch:HI 1 "=&Q"))]
12639 "&& reload_completed"
12641 [(set (match_dup 1)
12642 (xor:HI (match_dup 1) (match_dup 3)))
12643 (clobber (reg:CC FLAGS_REG))])
12645 [(set (reg:CC FLAGS_REG)
12646 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12647 (clobber (match_dup 1))])]
12649 operands[3] = gen_lowpart (HImode, operands[2]);
12651 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12652 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12655 (define_insn "*parityhi2_cmp"
12656 [(set (reg:CC FLAGS_REG)
12657 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12659 (clobber (match_scratch:HI 0 "=Q"))]
12661 "xor{b}\t{%h0, %b0|%b0, %h0}"
12662 [(set_attr "length" "2")
12663 (set_attr "mode" "HI")])
12666 ;; Thread-local storage patterns for ELF.
12668 ;; Note that these code sequences must appear exactly as shown
12669 ;; in order to allow linker relaxation.
12671 (define_insn "*tls_global_dynamic_32_gnu"
12672 [(set (match_operand:SI 0 "register_operand" "=a")
12674 [(match_operand:SI 1 "register_operand" "b")
12675 (match_operand 2 "tls_symbolic_operand")
12676 (match_operand 3 "constant_call_address_operand" "z")]
12678 (clobber (match_scratch:SI 4 "=d"))
12679 (clobber (match_scratch:SI 5 "=c"))
12680 (clobber (reg:CC FLAGS_REG))]
12681 "!TARGET_64BIT && TARGET_GNU_TLS"
12684 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12685 if (TARGET_SUN_TLS)
12686 #ifdef HAVE_AS_IX86_TLSGDPLT
12687 return "call\t%a2@tlsgdplt";
12689 return "call\t%p3@plt";
12691 return "call\t%P3";
12693 [(set_attr "type" "multi")
12694 (set_attr "length" "12")])
12696 (define_expand "tls_global_dynamic_32"
12698 [(set (match_operand:SI 0 "register_operand")
12699 (unspec:SI [(match_operand:SI 2 "register_operand")
12700 (match_operand 1 "tls_symbolic_operand")
12701 (match_operand 3 "constant_call_address_operand")]
12703 (clobber (match_scratch:SI 4))
12704 (clobber (match_scratch:SI 5))
12705 (clobber (reg:CC FLAGS_REG))])])
12707 (define_insn "*tls_global_dynamic_64_<mode>"
12708 [(set (match_operand:P 0 "register_operand" "=a")
12710 (mem:QI (match_operand 2 "constant_call_address_operand" "z"))
12711 (match_operand 3)))
12712 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12717 fputs (ASM_BYTE "0x66\n", asm_out_file);
12719 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12720 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12721 fputs ("\trex64\n", asm_out_file);
12722 if (TARGET_SUN_TLS)
12723 return "call\t%p2@plt";
12724 return "call\t%P2";
12726 [(set_attr "type" "multi")
12727 (set (attr "length")
12728 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12730 (define_expand "tls_global_dynamic_64_<mode>"
12732 [(set (match_operand:P 0 "register_operand")
12734 (mem:QI (match_operand 2 "constant_call_address_operand"))
12736 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12740 (define_insn "*tls_local_dynamic_base_32_gnu"
12741 [(set (match_operand:SI 0 "register_operand" "=a")
12743 [(match_operand:SI 1 "register_operand" "b")
12744 (match_operand 2 "constant_call_address_operand" "z")]
12745 UNSPEC_TLS_LD_BASE))
12746 (clobber (match_scratch:SI 3 "=d"))
12747 (clobber (match_scratch:SI 4 "=c"))
12748 (clobber (reg:CC FLAGS_REG))]
12749 "!TARGET_64BIT && TARGET_GNU_TLS"
12752 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12753 if (TARGET_SUN_TLS)
12754 #ifdef HAVE_AS_IX86_TLSLDMPLT
12755 return "call\t%&@tlsldmplt";
12757 return "call\t%p2@plt";
12759 return "call\t%P2";
12761 [(set_attr "type" "multi")
12762 (set_attr "length" "11")])
12764 (define_expand "tls_local_dynamic_base_32"
12766 [(set (match_operand:SI 0 "register_operand")
12768 [(match_operand:SI 1 "register_operand")
12769 (match_operand 2 "constant_call_address_operand")]
12770 UNSPEC_TLS_LD_BASE))
12771 (clobber (match_scratch:SI 3))
12772 (clobber (match_scratch:SI 4))
12773 (clobber (reg:CC FLAGS_REG))])])
12775 (define_insn "*tls_local_dynamic_base_64_<mode>"
12776 [(set (match_operand:P 0 "register_operand" "=a")
12778 (mem:QI (match_operand 1 "constant_call_address_operand" "z"))
12779 (match_operand 2)))
12780 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12784 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12785 if (TARGET_SUN_TLS)
12786 return "call\t%p1@plt";
12787 return "call\t%P1";
12789 [(set_attr "type" "multi")
12790 (set_attr "length" "12")])
12792 (define_expand "tls_local_dynamic_base_64_<mode>"
12794 [(set (match_operand:P 0 "register_operand")
12796 (mem:QI (match_operand 1 "constant_call_address_operand"))
12798 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12801 ;; Local dynamic of a single variable is a lose. Show combine how
12802 ;; to convert that back to global dynamic.
12804 (define_insn_and_split "*tls_local_dynamic_32_once"
12805 [(set (match_operand:SI 0 "register_operand" "=a")
12807 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12808 (match_operand 2 "constant_call_address_operand" "z")]
12809 UNSPEC_TLS_LD_BASE)
12810 (const:SI (unspec:SI
12811 [(match_operand 3 "tls_symbolic_operand")]
12813 (clobber (match_scratch:SI 4 "=d"))
12814 (clobber (match_scratch:SI 5 "=c"))
12815 (clobber (reg:CC FLAGS_REG))]
12820 [(set (match_dup 0)
12821 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12823 (clobber (match_dup 4))
12824 (clobber (match_dup 5))
12825 (clobber (reg:CC FLAGS_REG))])])
12827 ;; Segment register for the thread base ptr load
12828 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12830 ;; Load and add the thread base pointer from %<tp_seg>:0.
12831 (define_insn "*load_tp_x32"
12832 [(set (match_operand:SI 0 "register_operand" "=r")
12833 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12835 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12836 [(set_attr "type" "imov")
12837 (set_attr "modrm" "0")
12838 (set_attr "length" "7")
12839 (set_attr "memory" "load")
12840 (set_attr "imm_disp" "false")])
12842 (define_insn "*load_tp_x32_zext"
12843 [(set (match_operand:DI 0 "register_operand" "=r")
12844 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12846 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12847 [(set_attr "type" "imov")
12848 (set_attr "modrm" "0")
12849 (set_attr "length" "7")
12850 (set_attr "memory" "load")
12851 (set_attr "imm_disp" "false")])
12853 (define_insn "*load_tp_<mode>"
12854 [(set (match_operand:P 0 "register_operand" "=r")
12855 (unspec:P [(const_int 0)] UNSPEC_TP))]
12857 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12858 [(set_attr "type" "imov")
12859 (set_attr "modrm" "0")
12860 (set_attr "length" "7")
12861 (set_attr "memory" "load")
12862 (set_attr "imm_disp" "false")])
12864 (define_insn "*add_tp_x32"
12865 [(set (match_operand:SI 0 "register_operand" "=r")
12866 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12867 (match_operand:SI 1 "register_operand" "0")))
12868 (clobber (reg:CC FLAGS_REG))]
12870 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12871 [(set_attr "type" "alu")
12872 (set_attr "modrm" "0")
12873 (set_attr "length" "7")
12874 (set_attr "memory" "load")
12875 (set_attr "imm_disp" "false")])
12877 (define_insn "*add_tp_x32_zext"
12878 [(set (match_operand:DI 0 "register_operand" "=r")
12880 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12881 (match_operand:SI 1 "register_operand" "0"))))
12882 (clobber (reg:CC FLAGS_REG))]
12884 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12885 [(set_attr "type" "alu")
12886 (set_attr "modrm" "0")
12887 (set_attr "length" "7")
12888 (set_attr "memory" "load")
12889 (set_attr "imm_disp" "false")])
12891 (define_insn "*add_tp_<mode>"
12892 [(set (match_operand:P 0 "register_operand" "=r")
12893 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12894 (match_operand:P 1 "register_operand" "0")))
12895 (clobber (reg:CC FLAGS_REG))]
12897 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12898 [(set_attr "type" "alu")
12899 (set_attr "modrm" "0")
12900 (set_attr "length" "7")
12901 (set_attr "memory" "load")
12902 (set_attr "imm_disp" "false")])
12904 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12905 ;; %rax as destination of the initial executable code sequence.
12906 (define_insn "tls_initial_exec_64_sun"
12907 [(set (match_operand:DI 0 "register_operand" "=a")
12909 [(match_operand 1 "tls_symbolic_operand")]
12910 UNSPEC_TLS_IE_SUN))
12911 (clobber (reg:CC FLAGS_REG))]
12912 "TARGET_64BIT && TARGET_SUN_TLS"
12915 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12916 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12918 [(set_attr "type" "multi")])
12920 ;; GNU2 TLS patterns can be split.
12922 (define_expand "tls_dynamic_gnu2_32"
12923 [(set (match_dup 3)
12924 (plus:SI (match_operand:SI 2 "register_operand")
12926 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
12929 [(set (match_operand:SI 0 "register_operand")
12930 (unspec:SI [(match_dup 1) (match_dup 3)
12931 (match_dup 2) (reg:SI SP_REG)]
12933 (clobber (reg:CC FLAGS_REG))])]
12934 "!TARGET_64BIT && TARGET_GNU2_TLS"
12936 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12937 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12940 (define_insn "*tls_dynamic_gnu2_lea_32"
12941 [(set (match_operand:SI 0 "register_operand" "=r")
12942 (plus:SI (match_operand:SI 1 "register_operand" "b")
12944 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
12945 UNSPEC_TLSDESC))))]
12946 "!TARGET_64BIT && TARGET_GNU2_TLS"
12947 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
12948 [(set_attr "type" "lea")
12949 (set_attr "mode" "SI")
12950 (set_attr "length" "6")
12951 (set_attr "length_address" "4")])
12953 (define_insn "*tls_dynamic_gnu2_call_32"
12954 [(set (match_operand:SI 0 "register_operand" "=a")
12955 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
12956 (match_operand:SI 2 "register_operand" "0")
12957 ;; we have to make sure %ebx still points to the GOT
12958 (match_operand:SI 3 "register_operand" "b")
12961 (clobber (reg:CC FLAGS_REG))]
12962 "!TARGET_64BIT && TARGET_GNU2_TLS"
12963 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12964 [(set_attr "type" "call")
12965 (set_attr "length" "2")
12966 (set_attr "length_address" "0")])
12968 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12969 [(set (match_operand:SI 0 "register_operand" "=&a")
12971 (unspec:SI [(match_operand 3 "tls_modbase_operand")
12972 (match_operand:SI 4)
12973 (match_operand:SI 2 "register_operand" "b")
12976 (const:SI (unspec:SI
12977 [(match_operand 1 "tls_symbolic_operand")]
12979 (clobber (reg:CC FLAGS_REG))]
12980 "!TARGET_64BIT && TARGET_GNU2_TLS"
12983 [(set (match_dup 0) (match_dup 5))]
12985 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12986 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12989 (define_expand "tls_dynamic_gnu2_64"
12990 [(set (match_dup 2)
12991 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
12994 [(set (match_operand:DI 0 "register_operand")
12995 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12997 (clobber (reg:CC FLAGS_REG))])]
12998 "TARGET_64BIT && TARGET_GNU2_TLS"
13000 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13001 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13004 (define_insn "*tls_dynamic_gnu2_lea_64"
13005 [(set (match_operand:DI 0 "register_operand" "=r")
13006 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13008 "TARGET_64BIT && TARGET_GNU2_TLS"
13009 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13010 [(set_attr "type" "lea")
13011 (set_attr "mode" "DI")
13012 (set_attr "length" "7")
13013 (set_attr "length_address" "4")])
13015 (define_insn "*tls_dynamic_gnu2_call_64"
13016 [(set (match_operand:DI 0 "register_operand" "=a")
13017 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13018 (match_operand:DI 2 "register_operand" "0")
13021 (clobber (reg:CC FLAGS_REG))]
13022 "TARGET_64BIT && TARGET_GNU2_TLS"
13023 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13024 [(set_attr "type" "call")
13025 (set_attr "length" "2")
13026 (set_attr "length_address" "0")])
13028 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13029 [(set (match_operand:DI 0 "register_operand" "=&a")
13031 (unspec:DI [(match_operand 2 "tls_modbase_operand")
13032 (match_operand:DI 3)
13035 (const:DI (unspec:DI
13036 [(match_operand 1 "tls_symbolic_operand")]
13038 (clobber (reg:CC FLAGS_REG))]
13039 "TARGET_64BIT && TARGET_GNU2_TLS"
13042 [(set (match_dup 0) (match_dup 4))]
13044 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13045 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13048 ;; These patterns match the binary 387 instructions for addM3, subM3,
13049 ;; mulM3 and divM3. There are three patterns for each of DFmode and
13050 ;; SFmode. The first is the normal insn, the second the same insn but
13051 ;; with one operand a conversion, and the third the same insn but with
13052 ;; the other operand a conversion. The conversion may be SFmode or
13053 ;; SImode if the target mode DFmode, but only SImode if the target mode
13056 ;; Gcc is slightly more smart about handling normal two address instructions
13057 ;; so use special patterns for add and mull.
13059 (define_insn "*fop_<mode>_comm_mixed"
13060 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
13061 (match_operator:MODEF 3 "binary_fp_operator"
13062 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
13063 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
13064 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13065 && COMMUTATIVE_ARITH_P (operands[3])
13066 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13067 "* return output_387_binary_op (insn, operands);"
13068 [(set (attr "type")
13069 (if_then_else (eq_attr "alternative" "1,2")
13070 (if_then_else (match_operand:MODEF 3 "mult_operator")
13071 (const_string "ssemul")
13072 (const_string "sseadd"))
13073 (if_then_else (match_operand:MODEF 3 "mult_operator")
13074 (const_string "fmul")
13075 (const_string "fop"))))
13076 (set_attr "isa" "*,noavx,avx")
13077 (set_attr "prefix" "orig,orig,vex")
13078 (set_attr "mode" "<MODE>")])
13080 (define_insn "*fop_<mode>_comm_sse"
13081 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13082 (match_operator:MODEF 3 "binary_fp_operator"
13083 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
13084 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13085 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13086 && COMMUTATIVE_ARITH_P (operands[3])
13087 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13088 "* return output_387_binary_op (insn, operands);"
13089 [(set (attr "type")
13090 (if_then_else (match_operand:MODEF 3 "mult_operator")
13091 (const_string "ssemul")
13092 (const_string "sseadd")))
13093 (set_attr "isa" "noavx,avx")
13094 (set_attr "prefix" "orig,vex")
13095 (set_attr "mode" "<MODE>")])
13097 (define_insn "*fop_<mode>_comm_i387"
13098 [(set (match_operand:MODEF 0 "register_operand" "=f")
13099 (match_operator:MODEF 3 "binary_fp_operator"
13100 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13101 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13102 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13103 && COMMUTATIVE_ARITH_P (operands[3])
13104 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13105 "* return output_387_binary_op (insn, operands);"
13106 [(set (attr "type")
13107 (if_then_else (match_operand:MODEF 3 "mult_operator")
13108 (const_string "fmul")
13109 (const_string "fop")))
13110 (set_attr "mode" "<MODE>")])
13112 (define_insn "*fop_<mode>_1_mixed"
13113 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13114 (match_operator:MODEF 3 "binary_fp_operator"
13115 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13116 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13117 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13118 && !COMMUTATIVE_ARITH_P (operands[3])
13119 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13120 "* return output_387_binary_op (insn, operands);"
13121 [(set (attr "type")
13122 (cond [(and (eq_attr "alternative" "2,3")
13123 (match_operand:MODEF 3 "mult_operator"))
13124 (const_string "ssemul")
13125 (and (eq_attr "alternative" "2,3")
13126 (match_operand:MODEF 3 "div_operator"))
13127 (const_string "ssediv")
13128 (eq_attr "alternative" "2,3")
13129 (const_string "sseadd")
13130 (match_operand:MODEF 3 "mult_operator")
13131 (const_string "fmul")
13132 (match_operand:MODEF 3 "div_operator")
13133 (const_string "fdiv")
13135 (const_string "fop")))
13136 (set_attr "isa" "*,*,noavx,avx")
13137 (set_attr "prefix" "orig,orig,orig,vex")
13138 (set_attr "mode" "<MODE>")])
13140 (define_insn "*rcpsf2_sse"
13141 [(set (match_operand:SF 0 "register_operand" "=x")
13142 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13145 "%vrcpss\t{%1, %d0|%d0, %1}"
13146 [(set_attr "type" "sse")
13147 (set_attr "atom_sse_attr" "rcp")
13148 (set_attr "prefix" "maybe_vex")
13149 (set_attr "mode" "SF")])
13151 (define_insn "*fop_<mode>_1_sse"
13152 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13153 (match_operator:MODEF 3 "binary_fp_operator"
13154 [(match_operand:MODEF 1 "register_operand" "0,x")
13155 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13156 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13157 && !COMMUTATIVE_ARITH_P (operands[3])"
13158 "* return output_387_binary_op (insn, operands);"
13159 [(set (attr "type")
13160 (cond [(match_operand:MODEF 3 "mult_operator")
13161 (const_string "ssemul")
13162 (match_operand:MODEF 3 "div_operator")
13163 (const_string "ssediv")
13165 (const_string "sseadd")))
13166 (set_attr "isa" "noavx,avx")
13167 (set_attr "prefix" "orig,vex")
13168 (set_attr "mode" "<MODE>")])
13170 ;; This pattern is not fully shadowed by the pattern above.
13171 (define_insn "*fop_<mode>_1_i387"
13172 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13173 (match_operator:MODEF 3 "binary_fp_operator"
13174 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13175 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13176 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13177 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13178 && !COMMUTATIVE_ARITH_P (operands[3])
13179 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13180 "* return output_387_binary_op (insn, operands);"
13181 [(set (attr "type")
13182 (cond [(match_operand:MODEF 3 "mult_operator")
13183 (const_string "fmul")
13184 (match_operand:MODEF 3 "div_operator")
13185 (const_string "fdiv")
13187 (const_string "fop")))
13188 (set_attr "mode" "<MODE>")])
13190 ;; ??? Add SSE splitters for these!
13191 (define_insn "*fop_<MODEF:mode>_2_i387"
13192 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13193 (match_operator:MODEF 3 "binary_fp_operator"
13195 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13196 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13197 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13198 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13199 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13200 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13201 [(set (attr "type")
13202 (cond [(match_operand:MODEF 3 "mult_operator")
13203 (const_string "fmul")
13204 (match_operand:MODEF 3 "div_operator")
13205 (const_string "fdiv")
13207 (const_string "fop")))
13208 (set_attr "fp_int_src" "true")
13209 (set_attr "mode" "<SWI24:MODE>")])
13211 (define_insn "*fop_<MODEF:mode>_3_i387"
13212 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13213 (match_operator:MODEF 3 "binary_fp_operator"
13214 [(match_operand:MODEF 1 "register_operand" "0,0")
13216 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13217 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13218 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13219 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13220 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13221 [(set (attr "type")
13222 (cond [(match_operand:MODEF 3 "mult_operator")
13223 (const_string "fmul")
13224 (match_operand:MODEF 3 "div_operator")
13225 (const_string "fdiv")
13227 (const_string "fop")))
13228 (set_attr "fp_int_src" "true")
13229 (set_attr "mode" "<MODE>")])
13231 (define_insn "*fop_df_4_i387"
13232 [(set (match_operand:DF 0 "register_operand" "=f,f")
13233 (match_operator:DF 3 "binary_fp_operator"
13235 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13236 (match_operand:DF 2 "register_operand" "0,f")]))]
13237 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13238 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13239 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13240 "* return output_387_binary_op (insn, operands);"
13241 [(set (attr "type")
13242 (cond [(match_operand:DF 3 "mult_operator")
13243 (const_string "fmul")
13244 (match_operand:DF 3 "div_operator")
13245 (const_string "fdiv")
13247 (const_string "fop")))
13248 (set_attr "mode" "SF")])
13250 (define_insn "*fop_df_5_i387"
13251 [(set (match_operand:DF 0 "register_operand" "=f,f")
13252 (match_operator:DF 3 "binary_fp_operator"
13253 [(match_operand:DF 1 "register_operand" "0,f")
13255 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13256 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13257 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13258 "* return output_387_binary_op (insn, operands);"
13259 [(set (attr "type")
13260 (cond [(match_operand:DF 3 "mult_operator")
13261 (const_string "fmul")
13262 (match_operand:DF 3 "div_operator")
13263 (const_string "fdiv")
13265 (const_string "fop")))
13266 (set_attr "mode" "SF")])
13268 (define_insn "*fop_df_6_i387"
13269 [(set (match_operand:DF 0 "register_operand" "=f,f")
13270 (match_operator:DF 3 "binary_fp_operator"
13272 (match_operand:SF 1 "register_operand" "0,f"))
13274 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13275 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13276 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13277 "* return output_387_binary_op (insn, operands);"
13278 [(set (attr "type")
13279 (cond [(match_operand:DF 3 "mult_operator")
13280 (const_string "fmul")
13281 (match_operand:DF 3 "div_operator")
13282 (const_string "fdiv")
13284 (const_string "fop")))
13285 (set_attr "mode" "SF")])
13287 (define_insn "*fop_xf_comm_i387"
13288 [(set (match_operand:XF 0 "register_operand" "=f")
13289 (match_operator:XF 3 "binary_fp_operator"
13290 [(match_operand:XF 1 "register_operand" "%0")
13291 (match_operand:XF 2 "register_operand" "f")]))]
13293 && COMMUTATIVE_ARITH_P (operands[3])"
13294 "* return output_387_binary_op (insn, operands);"
13295 [(set (attr "type")
13296 (if_then_else (match_operand:XF 3 "mult_operator")
13297 (const_string "fmul")
13298 (const_string "fop")))
13299 (set_attr "mode" "XF")])
13301 (define_insn "*fop_xf_1_i387"
13302 [(set (match_operand:XF 0 "register_operand" "=f,f")
13303 (match_operator:XF 3 "binary_fp_operator"
13304 [(match_operand:XF 1 "register_operand" "0,f")
13305 (match_operand:XF 2 "register_operand" "f,0")]))]
13307 && !COMMUTATIVE_ARITH_P (operands[3])"
13308 "* return output_387_binary_op (insn, operands);"
13309 [(set (attr "type")
13310 (cond [(match_operand:XF 3 "mult_operator")
13311 (const_string "fmul")
13312 (match_operand:XF 3 "div_operator")
13313 (const_string "fdiv")
13315 (const_string "fop")))
13316 (set_attr "mode" "XF")])
13318 (define_insn "*fop_xf_2_i387"
13319 [(set (match_operand:XF 0 "register_operand" "=f,f")
13320 (match_operator:XF 3 "binary_fp_operator"
13322 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13323 (match_operand:XF 2 "register_operand" "0,0")]))]
13324 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13325 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13326 [(set (attr "type")
13327 (cond [(match_operand:XF 3 "mult_operator")
13328 (const_string "fmul")
13329 (match_operand:XF 3 "div_operator")
13330 (const_string "fdiv")
13332 (const_string "fop")))
13333 (set_attr "fp_int_src" "true")
13334 (set_attr "mode" "<MODE>")])
13336 (define_insn "*fop_xf_3_i387"
13337 [(set (match_operand:XF 0 "register_operand" "=f,f")
13338 (match_operator:XF 3 "binary_fp_operator"
13339 [(match_operand:XF 1 "register_operand" "0,0")
13341 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13342 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13343 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13344 [(set (attr "type")
13345 (cond [(match_operand:XF 3 "mult_operator")
13346 (const_string "fmul")
13347 (match_operand:XF 3 "div_operator")
13348 (const_string "fdiv")
13350 (const_string "fop")))
13351 (set_attr "fp_int_src" "true")
13352 (set_attr "mode" "<MODE>")])
13354 (define_insn "*fop_xf_4_i387"
13355 [(set (match_operand:XF 0 "register_operand" "=f,f")
13356 (match_operator:XF 3 "binary_fp_operator"
13358 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13359 (match_operand:XF 2 "register_operand" "0,f")]))]
13361 "* return output_387_binary_op (insn, operands);"
13362 [(set (attr "type")
13363 (cond [(match_operand:XF 3 "mult_operator")
13364 (const_string "fmul")
13365 (match_operand:XF 3 "div_operator")
13366 (const_string "fdiv")
13368 (const_string "fop")))
13369 (set_attr "mode" "<MODE>")])
13371 (define_insn "*fop_xf_5_i387"
13372 [(set (match_operand:XF 0 "register_operand" "=f,f")
13373 (match_operator:XF 3 "binary_fp_operator"
13374 [(match_operand:XF 1 "register_operand" "0,f")
13376 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13378 "* return output_387_binary_op (insn, operands);"
13379 [(set (attr "type")
13380 (cond [(match_operand:XF 3 "mult_operator")
13381 (const_string "fmul")
13382 (match_operand:XF 3 "div_operator")
13383 (const_string "fdiv")
13385 (const_string "fop")))
13386 (set_attr "mode" "<MODE>")])
13388 (define_insn "*fop_xf_6_i387"
13389 [(set (match_operand:XF 0 "register_operand" "=f,f")
13390 (match_operator:XF 3 "binary_fp_operator"
13392 (match_operand:MODEF 1 "register_operand" "0,f"))
13394 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13396 "* return output_387_binary_op (insn, operands);"
13397 [(set (attr "type")
13398 (cond [(match_operand:XF 3 "mult_operator")
13399 (const_string "fmul")
13400 (match_operand:XF 3 "div_operator")
13401 (const_string "fdiv")
13403 (const_string "fop")))
13404 (set_attr "mode" "<MODE>")])
13407 [(set (match_operand 0 "register_operand")
13408 (match_operator 3 "binary_fp_operator"
13409 [(float (match_operand:SWI24 1 "register_operand"))
13410 (match_operand 2 "register_operand")]))]
13412 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13413 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13416 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13417 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13418 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13419 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13420 GET_MODE (operands[3]),
13423 ix86_free_from_memory (GET_MODE (operands[1]));
13428 [(set (match_operand 0 "register_operand")
13429 (match_operator 3 "binary_fp_operator"
13430 [(match_operand 1 "register_operand")
13431 (float (match_operand:SWI24 2 "register_operand"))]))]
13433 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13434 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13437 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13438 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13439 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13440 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13441 GET_MODE (operands[3]),
13444 ix86_free_from_memory (GET_MODE (operands[2]));
13448 ;; FPU special functions.
13450 ;; This pattern implements a no-op XFmode truncation for
13451 ;; all fancy i386 XFmode math functions.
13453 (define_insn "truncxf<mode>2_i387_noop_unspec"
13454 [(set (match_operand:MODEF 0 "register_operand" "=f")
13455 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13456 UNSPEC_TRUNC_NOOP))]
13457 "TARGET_USE_FANCY_MATH_387"
13458 "* return output_387_reg_move (insn, operands);"
13459 [(set_attr "type" "fmov")
13460 (set_attr "mode" "<MODE>")])
13462 (define_insn "sqrtxf2"
13463 [(set (match_operand:XF 0 "register_operand" "=f")
13464 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13465 "TARGET_USE_FANCY_MATH_387"
13467 [(set_attr "type" "fpspc")
13468 (set_attr "mode" "XF")
13469 (set_attr "athlon_decode" "direct")
13470 (set_attr "amdfam10_decode" "direct")
13471 (set_attr "bdver1_decode" "direct")])
13473 (define_insn "sqrt_extend<mode>xf2_i387"
13474 [(set (match_operand:XF 0 "register_operand" "=f")
13477 (match_operand:MODEF 1 "register_operand" "0"))))]
13478 "TARGET_USE_FANCY_MATH_387"
13480 [(set_attr "type" "fpspc")
13481 (set_attr "mode" "XF")
13482 (set_attr "athlon_decode" "direct")
13483 (set_attr "amdfam10_decode" "direct")
13484 (set_attr "bdver1_decode" "direct")])
13486 (define_insn "*rsqrtsf2_sse"
13487 [(set (match_operand:SF 0 "register_operand" "=x")
13488 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13491 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13492 [(set_attr "type" "sse")
13493 (set_attr "atom_sse_attr" "rcp")
13494 (set_attr "prefix" "maybe_vex")
13495 (set_attr "mode" "SF")])
13497 (define_expand "rsqrtsf2"
13498 [(set (match_operand:SF 0 "register_operand")
13499 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
13503 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13507 (define_insn "*sqrt<mode>2_sse"
13508 [(set (match_operand:MODEF 0 "register_operand" "=x")
13510 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13511 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13512 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13513 [(set_attr "type" "sse")
13514 (set_attr "atom_sse_attr" "sqrt")
13515 (set_attr "prefix" "maybe_vex")
13516 (set_attr "mode" "<MODE>")
13517 (set_attr "athlon_decode" "*")
13518 (set_attr "amdfam10_decode" "*")
13519 (set_attr "bdver1_decode" "*")])
13521 (define_expand "sqrt<mode>2"
13522 [(set (match_operand:MODEF 0 "register_operand")
13524 (match_operand:MODEF 1 "nonimmediate_operand")))]
13525 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13526 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13528 if (<MODE>mode == SFmode
13530 && TARGET_RECIP_SQRT
13531 && !optimize_function_for_size_p (cfun)
13532 && flag_finite_math_only && !flag_trapping_math
13533 && flag_unsafe_math_optimizations)
13535 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13539 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13541 rtx op0 = gen_reg_rtx (XFmode);
13542 rtx op1 = force_reg (<MODE>mode, operands[1]);
13544 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13545 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13550 (define_insn "fpremxf4_i387"
13551 [(set (match_operand:XF 0 "register_operand" "=f")
13552 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13553 (match_operand:XF 3 "register_operand" "1")]
13555 (set (match_operand:XF 1 "register_operand" "=u")
13556 (unspec:XF [(match_dup 2) (match_dup 3)]
13558 (set (reg:CCFP FPSR_REG)
13559 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13561 "TARGET_USE_FANCY_MATH_387"
13563 [(set_attr "type" "fpspc")
13564 (set_attr "mode" "XF")])
13566 (define_expand "fmodxf3"
13567 [(use (match_operand:XF 0 "register_operand"))
13568 (use (match_operand:XF 1 "general_operand"))
13569 (use (match_operand:XF 2 "general_operand"))]
13570 "TARGET_USE_FANCY_MATH_387"
13572 rtx label = gen_label_rtx ();
13574 rtx op1 = gen_reg_rtx (XFmode);
13575 rtx op2 = gen_reg_rtx (XFmode);
13577 emit_move_insn (op2, operands[2]);
13578 emit_move_insn (op1, operands[1]);
13580 emit_label (label);
13581 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13582 ix86_emit_fp_unordered_jump (label);
13583 LABEL_NUSES (label) = 1;
13585 emit_move_insn (operands[0], op1);
13589 (define_expand "fmod<mode>3"
13590 [(use (match_operand:MODEF 0 "register_operand"))
13591 (use (match_operand:MODEF 1 "general_operand"))
13592 (use (match_operand:MODEF 2 "general_operand"))]
13593 "TARGET_USE_FANCY_MATH_387"
13595 rtx (*gen_truncxf) (rtx, rtx);
13597 rtx label = gen_label_rtx ();
13599 rtx op1 = gen_reg_rtx (XFmode);
13600 rtx op2 = gen_reg_rtx (XFmode);
13602 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13603 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13605 emit_label (label);
13606 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13607 ix86_emit_fp_unordered_jump (label);
13608 LABEL_NUSES (label) = 1;
13610 /* Truncate the result properly for strict SSE math. */
13611 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13612 && !TARGET_MIX_SSE_I387)
13613 gen_truncxf = gen_truncxf<mode>2;
13615 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13617 emit_insn (gen_truncxf (operands[0], op1));
13621 (define_insn "fprem1xf4_i387"
13622 [(set (match_operand:XF 0 "register_operand" "=f")
13623 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13624 (match_operand:XF 3 "register_operand" "1")]
13626 (set (match_operand:XF 1 "register_operand" "=u")
13627 (unspec:XF [(match_dup 2) (match_dup 3)]
13629 (set (reg:CCFP FPSR_REG)
13630 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13632 "TARGET_USE_FANCY_MATH_387"
13634 [(set_attr "type" "fpspc")
13635 (set_attr "mode" "XF")])
13637 (define_expand "remainderxf3"
13638 [(use (match_operand:XF 0 "register_operand"))
13639 (use (match_operand:XF 1 "general_operand"))
13640 (use (match_operand:XF 2 "general_operand"))]
13641 "TARGET_USE_FANCY_MATH_387"
13643 rtx label = gen_label_rtx ();
13645 rtx op1 = gen_reg_rtx (XFmode);
13646 rtx op2 = gen_reg_rtx (XFmode);
13648 emit_move_insn (op2, operands[2]);
13649 emit_move_insn (op1, operands[1]);
13651 emit_label (label);
13652 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13653 ix86_emit_fp_unordered_jump (label);
13654 LABEL_NUSES (label) = 1;
13656 emit_move_insn (operands[0], op1);
13660 (define_expand "remainder<mode>3"
13661 [(use (match_operand:MODEF 0 "register_operand"))
13662 (use (match_operand:MODEF 1 "general_operand"))
13663 (use (match_operand:MODEF 2 "general_operand"))]
13664 "TARGET_USE_FANCY_MATH_387"
13666 rtx (*gen_truncxf) (rtx, rtx);
13668 rtx label = gen_label_rtx ();
13670 rtx op1 = gen_reg_rtx (XFmode);
13671 rtx op2 = gen_reg_rtx (XFmode);
13673 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13674 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13676 emit_label (label);
13678 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13679 ix86_emit_fp_unordered_jump (label);
13680 LABEL_NUSES (label) = 1;
13682 /* Truncate the result properly for strict SSE math. */
13683 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13684 && !TARGET_MIX_SSE_I387)
13685 gen_truncxf = gen_truncxf<mode>2;
13687 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13689 emit_insn (gen_truncxf (operands[0], op1));
13693 (define_insn "*sinxf2_i387"
13694 [(set (match_operand:XF 0 "register_operand" "=f")
13695 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13696 "TARGET_USE_FANCY_MATH_387
13697 && flag_unsafe_math_optimizations"
13699 [(set_attr "type" "fpspc")
13700 (set_attr "mode" "XF")])
13702 (define_insn "*sin_extend<mode>xf2_i387"
13703 [(set (match_operand:XF 0 "register_operand" "=f")
13704 (unspec:XF [(float_extend:XF
13705 (match_operand:MODEF 1 "register_operand" "0"))]
13707 "TARGET_USE_FANCY_MATH_387
13708 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13709 || TARGET_MIX_SSE_I387)
13710 && flag_unsafe_math_optimizations"
13712 [(set_attr "type" "fpspc")
13713 (set_attr "mode" "XF")])
13715 (define_insn "*cosxf2_i387"
13716 [(set (match_operand:XF 0 "register_operand" "=f")
13717 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13718 "TARGET_USE_FANCY_MATH_387
13719 && flag_unsafe_math_optimizations"
13721 [(set_attr "type" "fpspc")
13722 (set_attr "mode" "XF")])
13724 (define_insn "*cos_extend<mode>xf2_i387"
13725 [(set (match_operand:XF 0 "register_operand" "=f")
13726 (unspec:XF [(float_extend:XF
13727 (match_operand:MODEF 1 "register_operand" "0"))]
13729 "TARGET_USE_FANCY_MATH_387
13730 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13731 || TARGET_MIX_SSE_I387)
13732 && flag_unsafe_math_optimizations"
13734 [(set_attr "type" "fpspc")
13735 (set_attr "mode" "XF")])
13737 ;; When sincos pattern is defined, sin and cos builtin functions will be
13738 ;; expanded to sincos pattern with one of its outputs left unused.
13739 ;; CSE pass will figure out if two sincos patterns can be combined,
13740 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13741 ;; depending on the unused output.
13743 (define_insn "sincosxf3"
13744 [(set (match_operand:XF 0 "register_operand" "=f")
13745 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13746 UNSPEC_SINCOS_COS))
13747 (set (match_operand:XF 1 "register_operand" "=u")
13748 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13749 "TARGET_USE_FANCY_MATH_387
13750 && flag_unsafe_math_optimizations"
13752 [(set_attr "type" "fpspc")
13753 (set_attr "mode" "XF")])
13756 [(set (match_operand:XF 0 "register_operand")
13757 (unspec:XF [(match_operand:XF 2 "register_operand")]
13758 UNSPEC_SINCOS_COS))
13759 (set (match_operand:XF 1 "register_operand")
13760 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13761 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13762 && can_create_pseudo_p ()"
13763 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13766 [(set (match_operand:XF 0 "register_operand")
13767 (unspec:XF [(match_operand:XF 2 "register_operand")]
13768 UNSPEC_SINCOS_COS))
13769 (set (match_operand:XF 1 "register_operand")
13770 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13771 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13772 && can_create_pseudo_p ()"
13773 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13775 (define_insn "sincos_extend<mode>xf3_i387"
13776 [(set (match_operand:XF 0 "register_operand" "=f")
13777 (unspec:XF [(float_extend:XF
13778 (match_operand:MODEF 2 "register_operand" "0"))]
13779 UNSPEC_SINCOS_COS))
13780 (set (match_operand:XF 1 "register_operand" "=u")
13781 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13782 "TARGET_USE_FANCY_MATH_387
13783 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13784 || TARGET_MIX_SSE_I387)
13785 && flag_unsafe_math_optimizations"
13787 [(set_attr "type" "fpspc")
13788 (set_attr "mode" "XF")])
13791 [(set (match_operand:XF 0 "register_operand")
13792 (unspec:XF [(float_extend:XF
13793 (match_operand:MODEF 2 "register_operand"))]
13794 UNSPEC_SINCOS_COS))
13795 (set (match_operand:XF 1 "register_operand")
13796 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13797 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13798 && can_create_pseudo_p ()"
13799 [(set (match_dup 1)
13800 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13803 [(set (match_operand:XF 0 "register_operand")
13804 (unspec:XF [(float_extend:XF
13805 (match_operand:MODEF 2 "register_operand"))]
13806 UNSPEC_SINCOS_COS))
13807 (set (match_operand:XF 1 "register_operand")
13808 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13809 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13810 && can_create_pseudo_p ()"
13811 [(set (match_dup 0)
13812 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13814 (define_expand "sincos<mode>3"
13815 [(use (match_operand:MODEF 0 "register_operand"))
13816 (use (match_operand:MODEF 1 "register_operand"))
13817 (use (match_operand:MODEF 2 "register_operand"))]
13818 "TARGET_USE_FANCY_MATH_387
13819 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13820 || TARGET_MIX_SSE_I387)
13821 && flag_unsafe_math_optimizations"
13823 rtx op0 = gen_reg_rtx (XFmode);
13824 rtx op1 = gen_reg_rtx (XFmode);
13826 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13827 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13828 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13832 (define_insn "fptanxf4_i387"
13833 [(set (match_operand:XF 0 "register_operand" "=f")
13834 (match_operand:XF 3 "const_double_operand" "F"))
13835 (set (match_operand:XF 1 "register_operand" "=u")
13836 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13838 "TARGET_USE_FANCY_MATH_387
13839 && flag_unsafe_math_optimizations
13840 && standard_80387_constant_p (operands[3]) == 2"
13842 [(set_attr "type" "fpspc")
13843 (set_attr "mode" "XF")])
13845 (define_insn "fptan_extend<mode>xf4_i387"
13846 [(set (match_operand:MODEF 0 "register_operand" "=f")
13847 (match_operand:MODEF 3 "const_double_operand" "F"))
13848 (set (match_operand:XF 1 "register_operand" "=u")
13849 (unspec:XF [(float_extend:XF
13850 (match_operand:MODEF 2 "register_operand" "0"))]
13852 "TARGET_USE_FANCY_MATH_387
13853 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13854 || TARGET_MIX_SSE_I387)
13855 && flag_unsafe_math_optimizations
13856 && standard_80387_constant_p (operands[3]) == 2"
13858 [(set_attr "type" "fpspc")
13859 (set_attr "mode" "XF")])
13861 (define_expand "tanxf2"
13862 [(use (match_operand:XF 0 "register_operand"))
13863 (use (match_operand:XF 1 "register_operand"))]
13864 "TARGET_USE_FANCY_MATH_387
13865 && flag_unsafe_math_optimizations"
13867 rtx one = gen_reg_rtx (XFmode);
13868 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13870 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13874 (define_expand "tan<mode>2"
13875 [(use (match_operand:MODEF 0 "register_operand"))
13876 (use (match_operand:MODEF 1 "register_operand"))]
13877 "TARGET_USE_FANCY_MATH_387
13878 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13879 || TARGET_MIX_SSE_I387)
13880 && flag_unsafe_math_optimizations"
13882 rtx op0 = gen_reg_rtx (XFmode);
13884 rtx one = gen_reg_rtx (<MODE>mode);
13885 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13887 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13888 operands[1], op2));
13889 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13893 (define_insn "*fpatanxf3_i387"
13894 [(set (match_operand:XF 0 "register_operand" "=f")
13895 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13896 (match_operand:XF 2 "register_operand" "u")]
13898 (clobber (match_scratch:XF 3 "=2"))]
13899 "TARGET_USE_FANCY_MATH_387
13900 && flag_unsafe_math_optimizations"
13902 [(set_attr "type" "fpspc")
13903 (set_attr "mode" "XF")])
13905 (define_insn "fpatan_extend<mode>xf3_i387"
13906 [(set (match_operand:XF 0 "register_operand" "=f")
13907 (unspec:XF [(float_extend:XF
13908 (match_operand:MODEF 1 "register_operand" "0"))
13910 (match_operand:MODEF 2 "register_operand" "u"))]
13912 (clobber (match_scratch:XF 3 "=2"))]
13913 "TARGET_USE_FANCY_MATH_387
13914 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13915 || TARGET_MIX_SSE_I387)
13916 && flag_unsafe_math_optimizations"
13918 [(set_attr "type" "fpspc")
13919 (set_attr "mode" "XF")])
13921 (define_expand "atan2xf3"
13922 [(parallel [(set (match_operand:XF 0 "register_operand")
13923 (unspec:XF [(match_operand:XF 2 "register_operand")
13924 (match_operand:XF 1 "register_operand")]
13926 (clobber (match_scratch:XF 3))])]
13927 "TARGET_USE_FANCY_MATH_387
13928 && flag_unsafe_math_optimizations")
13930 (define_expand "atan2<mode>3"
13931 [(use (match_operand:MODEF 0 "register_operand"))
13932 (use (match_operand:MODEF 1 "register_operand"))
13933 (use (match_operand:MODEF 2 "register_operand"))]
13934 "TARGET_USE_FANCY_MATH_387
13935 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13936 || TARGET_MIX_SSE_I387)
13937 && flag_unsafe_math_optimizations"
13939 rtx op0 = gen_reg_rtx (XFmode);
13941 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13942 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13946 (define_expand "atanxf2"
13947 [(parallel [(set (match_operand:XF 0 "register_operand")
13948 (unspec:XF [(match_dup 2)
13949 (match_operand:XF 1 "register_operand")]
13951 (clobber (match_scratch:XF 3))])]
13952 "TARGET_USE_FANCY_MATH_387
13953 && flag_unsafe_math_optimizations"
13955 operands[2] = gen_reg_rtx (XFmode);
13956 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13959 (define_expand "atan<mode>2"
13960 [(use (match_operand:MODEF 0 "register_operand"))
13961 (use (match_operand:MODEF 1 "register_operand"))]
13962 "TARGET_USE_FANCY_MATH_387
13963 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13964 || TARGET_MIX_SSE_I387)
13965 && flag_unsafe_math_optimizations"
13967 rtx op0 = gen_reg_rtx (XFmode);
13969 rtx op2 = gen_reg_rtx (<MODE>mode);
13970 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13972 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13973 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13977 (define_expand "asinxf2"
13978 [(set (match_dup 2)
13979 (mult:XF (match_operand:XF 1 "register_operand")
13981 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13982 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13983 (parallel [(set (match_operand:XF 0 "register_operand")
13984 (unspec:XF [(match_dup 5) (match_dup 1)]
13986 (clobber (match_scratch:XF 6))])]
13987 "TARGET_USE_FANCY_MATH_387
13988 && flag_unsafe_math_optimizations"
13992 if (optimize_insn_for_size_p ())
13995 for (i = 2; i < 6; i++)
13996 operands[i] = gen_reg_rtx (XFmode);
13998 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14001 (define_expand "asin<mode>2"
14002 [(use (match_operand:MODEF 0 "register_operand"))
14003 (use (match_operand:MODEF 1 "general_operand"))]
14004 "TARGET_USE_FANCY_MATH_387
14005 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14006 || TARGET_MIX_SSE_I387)
14007 && flag_unsafe_math_optimizations"
14009 rtx op0 = gen_reg_rtx (XFmode);
14010 rtx op1 = gen_reg_rtx (XFmode);
14012 if (optimize_insn_for_size_p ())
14015 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14016 emit_insn (gen_asinxf2 (op0, op1));
14017 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14021 (define_expand "acosxf2"
14022 [(set (match_dup 2)
14023 (mult:XF (match_operand:XF 1 "register_operand")
14025 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14026 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14027 (parallel [(set (match_operand:XF 0 "register_operand")
14028 (unspec:XF [(match_dup 1) (match_dup 5)]
14030 (clobber (match_scratch:XF 6))])]
14031 "TARGET_USE_FANCY_MATH_387
14032 && flag_unsafe_math_optimizations"
14036 if (optimize_insn_for_size_p ())
14039 for (i = 2; i < 6; i++)
14040 operands[i] = gen_reg_rtx (XFmode);
14042 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14045 (define_expand "acos<mode>2"
14046 [(use (match_operand:MODEF 0 "register_operand"))
14047 (use (match_operand:MODEF 1 "general_operand"))]
14048 "TARGET_USE_FANCY_MATH_387
14049 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14050 || TARGET_MIX_SSE_I387)
14051 && flag_unsafe_math_optimizations"
14053 rtx op0 = gen_reg_rtx (XFmode);
14054 rtx op1 = gen_reg_rtx (XFmode);
14056 if (optimize_insn_for_size_p ())
14059 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14060 emit_insn (gen_acosxf2 (op0, op1));
14061 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14065 (define_insn "fyl2xxf3_i387"
14066 [(set (match_operand:XF 0 "register_operand" "=f")
14067 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14068 (match_operand:XF 2 "register_operand" "u")]
14070 (clobber (match_scratch:XF 3 "=2"))]
14071 "TARGET_USE_FANCY_MATH_387
14072 && flag_unsafe_math_optimizations"
14074 [(set_attr "type" "fpspc")
14075 (set_attr "mode" "XF")])
14077 (define_insn "fyl2x_extend<mode>xf3_i387"
14078 [(set (match_operand:XF 0 "register_operand" "=f")
14079 (unspec:XF [(float_extend:XF
14080 (match_operand:MODEF 1 "register_operand" "0"))
14081 (match_operand:XF 2 "register_operand" "u")]
14083 (clobber (match_scratch:XF 3 "=2"))]
14084 "TARGET_USE_FANCY_MATH_387
14085 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14086 || TARGET_MIX_SSE_I387)
14087 && flag_unsafe_math_optimizations"
14089 [(set_attr "type" "fpspc")
14090 (set_attr "mode" "XF")])
14092 (define_expand "logxf2"
14093 [(parallel [(set (match_operand:XF 0 "register_operand")
14094 (unspec:XF [(match_operand:XF 1 "register_operand")
14095 (match_dup 2)] UNSPEC_FYL2X))
14096 (clobber (match_scratch:XF 3))])]
14097 "TARGET_USE_FANCY_MATH_387
14098 && flag_unsafe_math_optimizations"
14100 operands[2] = gen_reg_rtx (XFmode);
14101 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14104 (define_expand "log<mode>2"
14105 [(use (match_operand:MODEF 0 "register_operand"))
14106 (use (match_operand:MODEF 1 "register_operand"))]
14107 "TARGET_USE_FANCY_MATH_387
14108 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14109 || TARGET_MIX_SSE_I387)
14110 && flag_unsafe_math_optimizations"
14112 rtx op0 = gen_reg_rtx (XFmode);
14114 rtx op2 = gen_reg_rtx (XFmode);
14115 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14117 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14118 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14122 (define_expand "log10xf2"
14123 [(parallel [(set (match_operand:XF 0 "register_operand")
14124 (unspec:XF [(match_operand:XF 1 "register_operand")
14125 (match_dup 2)] UNSPEC_FYL2X))
14126 (clobber (match_scratch:XF 3))])]
14127 "TARGET_USE_FANCY_MATH_387
14128 && flag_unsafe_math_optimizations"
14130 operands[2] = gen_reg_rtx (XFmode);
14131 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14134 (define_expand "log10<mode>2"
14135 [(use (match_operand:MODEF 0 "register_operand"))
14136 (use (match_operand:MODEF 1 "register_operand"))]
14137 "TARGET_USE_FANCY_MATH_387
14138 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14139 || TARGET_MIX_SSE_I387)
14140 && flag_unsafe_math_optimizations"
14142 rtx op0 = gen_reg_rtx (XFmode);
14144 rtx op2 = gen_reg_rtx (XFmode);
14145 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14147 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14148 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14152 (define_expand "log2xf2"
14153 [(parallel [(set (match_operand:XF 0 "register_operand")
14154 (unspec:XF [(match_operand:XF 1 "register_operand")
14155 (match_dup 2)] UNSPEC_FYL2X))
14156 (clobber (match_scratch:XF 3))])]
14157 "TARGET_USE_FANCY_MATH_387
14158 && flag_unsafe_math_optimizations"
14160 operands[2] = gen_reg_rtx (XFmode);
14161 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14164 (define_expand "log2<mode>2"
14165 [(use (match_operand:MODEF 0 "register_operand"))
14166 (use (match_operand:MODEF 1 "register_operand"))]
14167 "TARGET_USE_FANCY_MATH_387
14168 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14169 || TARGET_MIX_SSE_I387)
14170 && flag_unsafe_math_optimizations"
14172 rtx op0 = gen_reg_rtx (XFmode);
14174 rtx op2 = gen_reg_rtx (XFmode);
14175 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14177 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14178 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14182 (define_insn "fyl2xp1xf3_i387"
14183 [(set (match_operand:XF 0 "register_operand" "=f")
14184 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14185 (match_operand:XF 2 "register_operand" "u")]
14187 (clobber (match_scratch:XF 3 "=2"))]
14188 "TARGET_USE_FANCY_MATH_387
14189 && flag_unsafe_math_optimizations"
14191 [(set_attr "type" "fpspc")
14192 (set_attr "mode" "XF")])
14194 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14195 [(set (match_operand:XF 0 "register_operand" "=f")
14196 (unspec:XF [(float_extend:XF
14197 (match_operand:MODEF 1 "register_operand" "0"))
14198 (match_operand:XF 2 "register_operand" "u")]
14200 (clobber (match_scratch:XF 3 "=2"))]
14201 "TARGET_USE_FANCY_MATH_387
14202 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14203 || TARGET_MIX_SSE_I387)
14204 && flag_unsafe_math_optimizations"
14206 [(set_attr "type" "fpspc")
14207 (set_attr "mode" "XF")])
14209 (define_expand "log1pxf2"
14210 [(use (match_operand:XF 0 "register_operand"))
14211 (use (match_operand:XF 1 "register_operand"))]
14212 "TARGET_USE_FANCY_MATH_387
14213 && flag_unsafe_math_optimizations"
14215 if (optimize_insn_for_size_p ())
14218 ix86_emit_i387_log1p (operands[0], operands[1]);
14222 (define_expand "log1p<mode>2"
14223 [(use (match_operand:MODEF 0 "register_operand"))
14224 (use (match_operand:MODEF 1 "register_operand"))]
14225 "TARGET_USE_FANCY_MATH_387
14226 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14227 || TARGET_MIX_SSE_I387)
14228 && flag_unsafe_math_optimizations"
14232 if (optimize_insn_for_size_p ())
14235 op0 = gen_reg_rtx (XFmode);
14237 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14239 ix86_emit_i387_log1p (op0, operands[1]);
14240 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14244 (define_insn "fxtractxf3_i387"
14245 [(set (match_operand:XF 0 "register_operand" "=f")
14246 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14247 UNSPEC_XTRACT_FRACT))
14248 (set (match_operand:XF 1 "register_operand" "=u")
14249 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14250 "TARGET_USE_FANCY_MATH_387
14251 && flag_unsafe_math_optimizations"
14253 [(set_attr "type" "fpspc")
14254 (set_attr "mode" "XF")])
14256 (define_insn "fxtract_extend<mode>xf3_i387"
14257 [(set (match_operand:XF 0 "register_operand" "=f")
14258 (unspec:XF [(float_extend:XF
14259 (match_operand:MODEF 2 "register_operand" "0"))]
14260 UNSPEC_XTRACT_FRACT))
14261 (set (match_operand:XF 1 "register_operand" "=u")
14262 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14263 "TARGET_USE_FANCY_MATH_387
14264 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14265 || TARGET_MIX_SSE_I387)
14266 && flag_unsafe_math_optimizations"
14268 [(set_attr "type" "fpspc")
14269 (set_attr "mode" "XF")])
14271 (define_expand "logbxf2"
14272 [(parallel [(set (match_dup 2)
14273 (unspec:XF [(match_operand:XF 1 "register_operand")]
14274 UNSPEC_XTRACT_FRACT))
14275 (set (match_operand:XF 0 "register_operand")
14276 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14277 "TARGET_USE_FANCY_MATH_387
14278 && flag_unsafe_math_optimizations"
14279 "operands[2] = gen_reg_rtx (XFmode);")
14281 (define_expand "logb<mode>2"
14282 [(use (match_operand:MODEF 0 "register_operand"))
14283 (use (match_operand:MODEF 1 "register_operand"))]
14284 "TARGET_USE_FANCY_MATH_387
14285 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14286 || TARGET_MIX_SSE_I387)
14287 && flag_unsafe_math_optimizations"
14289 rtx op0 = gen_reg_rtx (XFmode);
14290 rtx op1 = gen_reg_rtx (XFmode);
14292 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14293 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14297 (define_expand "ilogbxf2"
14298 [(use (match_operand:SI 0 "register_operand"))
14299 (use (match_operand:XF 1 "register_operand"))]
14300 "TARGET_USE_FANCY_MATH_387
14301 && flag_unsafe_math_optimizations"
14305 if (optimize_insn_for_size_p ())
14308 op0 = gen_reg_rtx (XFmode);
14309 op1 = gen_reg_rtx (XFmode);
14311 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14312 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14316 (define_expand "ilogb<mode>2"
14317 [(use (match_operand:SI 0 "register_operand"))
14318 (use (match_operand:MODEF 1 "register_operand"))]
14319 "TARGET_USE_FANCY_MATH_387
14320 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14321 || TARGET_MIX_SSE_I387)
14322 && flag_unsafe_math_optimizations"
14326 if (optimize_insn_for_size_p ())
14329 op0 = gen_reg_rtx (XFmode);
14330 op1 = gen_reg_rtx (XFmode);
14332 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14333 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14337 (define_insn "*f2xm1xf2_i387"
14338 [(set (match_operand:XF 0 "register_operand" "=f")
14339 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14341 "TARGET_USE_FANCY_MATH_387
14342 && flag_unsafe_math_optimizations"
14344 [(set_attr "type" "fpspc")
14345 (set_attr "mode" "XF")])
14347 (define_insn "*fscalexf4_i387"
14348 [(set (match_operand:XF 0 "register_operand" "=f")
14349 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14350 (match_operand:XF 3 "register_operand" "1")]
14351 UNSPEC_FSCALE_FRACT))
14352 (set (match_operand:XF 1 "register_operand" "=u")
14353 (unspec:XF [(match_dup 2) (match_dup 3)]
14354 UNSPEC_FSCALE_EXP))]
14355 "TARGET_USE_FANCY_MATH_387
14356 && flag_unsafe_math_optimizations"
14358 [(set_attr "type" "fpspc")
14359 (set_attr "mode" "XF")])
14361 (define_expand "expNcorexf3"
14362 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14363 (match_operand:XF 2 "register_operand")))
14364 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14365 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14366 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14367 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14368 (parallel [(set (match_operand:XF 0 "register_operand")
14369 (unspec:XF [(match_dup 8) (match_dup 4)]
14370 UNSPEC_FSCALE_FRACT))
14372 (unspec:XF [(match_dup 8) (match_dup 4)]
14373 UNSPEC_FSCALE_EXP))])]
14374 "TARGET_USE_FANCY_MATH_387
14375 && flag_unsafe_math_optimizations"
14379 if (optimize_insn_for_size_p ())
14382 for (i = 3; i < 10; i++)
14383 operands[i] = gen_reg_rtx (XFmode);
14385 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14388 (define_expand "expxf2"
14389 [(use (match_operand:XF 0 "register_operand"))
14390 (use (match_operand:XF 1 "register_operand"))]
14391 "TARGET_USE_FANCY_MATH_387
14392 && flag_unsafe_math_optimizations"
14396 if (optimize_insn_for_size_p ())
14399 op2 = gen_reg_rtx (XFmode);
14400 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14402 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14406 (define_expand "exp<mode>2"
14407 [(use (match_operand:MODEF 0 "register_operand"))
14408 (use (match_operand:MODEF 1 "general_operand"))]
14409 "TARGET_USE_FANCY_MATH_387
14410 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14411 || TARGET_MIX_SSE_I387)
14412 && flag_unsafe_math_optimizations"
14416 if (optimize_insn_for_size_p ())
14419 op0 = gen_reg_rtx (XFmode);
14420 op1 = gen_reg_rtx (XFmode);
14422 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14423 emit_insn (gen_expxf2 (op0, op1));
14424 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14428 (define_expand "exp10xf2"
14429 [(use (match_operand:XF 0 "register_operand"))
14430 (use (match_operand:XF 1 "register_operand"))]
14431 "TARGET_USE_FANCY_MATH_387
14432 && flag_unsafe_math_optimizations"
14436 if (optimize_insn_for_size_p ())
14439 op2 = gen_reg_rtx (XFmode);
14440 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14442 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14446 (define_expand "exp10<mode>2"
14447 [(use (match_operand:MODEF 0 "register_operand"))
14448 (use (match_operand:MODEF 1 "general_operand"))]
14449 "TARGET_USE_FANCY_MATH_387
14450 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14451 || TARGET_MIX_SSE_I387)
14452 && flag_unsafe_math_optimizations"
14456 if (optimize_insn_for_size_p ())
14459 op0 = gen_reg_rtx (XFmode);
14460 op1 = gen_reg_rtx (XFmode);
14462 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14463 emit_insn (gen_exp10xf2 (op0, op1));
14464 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14468 (define_expand "exp2xf2"
14469 [(use (match_operand:XF 0 "register_operand"))
14470 (use (match_operand:XF 1 "register_operand"))]
14471 "TARGET_USE_FANCY_MATH_387
14472 && flag_unsafe_math_optimizations"
14476 if (optimize_insn_for_size_p ())
14479 op2 = gen_reg_rtx (XFmode);
14480 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14482 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14486 (define_expand "exp2<mode>2"
14487 [(use (match_operand:MODEF 0 "register_operand"))
14488 (use (match_operand:MODEF 1 "general_operand"))]
14489 "TARGET_USE_FANCY_MATH_387
14490 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14491 || TARGET_MIX_SSE_I387)
14492 && flag_unsafe_math_optimizations"
14496 if (optimize_insn_for_size_p ())
14499 op0 = gen_reg_rtx (XFmode);
14500 op1 = gen_reg_rtx (XFmode);
14502 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14503 emit_insn (gen_exp2xf2 (op0, op1));
14504 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14508 (define_expand "expm1xf2"
14509 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14511 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14512 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14513 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14514 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14515 (parallel [(set (match_dup 7)
14516 (unspec:XF [(match_dup 6) (match_dup 4)]
14517 UNSPEC_FSCALE_FRACT))
14519 (unspec:XF [(match_dup 6) (match_dup 4)]
14520 UNSPEC_FSCALE_EXP))])
14521 (parallel [(set (match_dup 10)
14522 (unspec:XF [(match_dup 9) (match_dup 8)]
14523 UNSPEC_FSCALE_FRACT))
14524 (set (match_dup 11)
14525 (unspec:XF [(match_dup 9) (match_dup 8)]
14526 UNSPEC_FSCALE_EXP))])
14527 (set (match_dup 12) (minus:XF (match_dup 10)
14528 (float_extend:XF (match_dup 13))))
14529 (set (match_operand:XF 0 "register_operand")
14530 (plus:XF (match_dup 12) (match_dup 7)))]
14531 "TARGET_USE_FANCY_MATH_387
14532 && flag_unsafe_math_optimizations"
14536 if (optimize_insn_for_size_p ())
14539 for (i = 2; i < 13; i++)
14540 operands[i] = gen_reg_rtx (XFmode);
14543 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14545 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14548 (define_expand "expm1<mode>2"
14549 [(use (match_operand:MODEF 0 "register_operand"))
14550 (use (match_operand:MODEF 1 "general_operand"))]
14551 "TARGET_USE_FANCY_MATH_387
14552 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14553 || TARGET_MIX_SSE_I387)
14554 && flag_unsafe_math_optimizations"
14558 if (optimize_insn_for_size_p ())
14561 op0 = gen_reg_rtx (XFmode);
14562 op1 = gen_reg_rtx (XFmode);
14564 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14565 emit_insn (gen_expm1xf2 (op0, op1));
14566 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14570 (define_expand "ldexpxf3"
14571 [(set (match_dup 3)
14572 (float:XF (match_operand:SI 2 "register_operand")))
14573 (parallel [(set (match_operand:XF 0 " register_operand")
14574 (unspec:XF [(match_operand:XF 1 "register_operand")
14576 UNSPEC_FSCALE_FRACT))
14578 (unspec:XF [(match_dup 1) (match_dup 3)]
14579 UNSPEC_FSCALE_EXP))])]
14580 "TARGET_USE_FANCY_MATH_387
14581 && flag_unsafe_math_optimizations"
14583 if (optimize_insn_for_size_p ())
14586 operands[3] = gen_reg_rtx (XFmode);
14587 operands[4] = gen_reg_rtx (XFmode);
14590 (define_expand "ldexp<mode>3"
14591 [(use (match_operand:MODEF 0 "register_operand"))
14592 (use (match_operand:MODEF 1 "general_operand"))
14593 (use (match_operand:SI 2 "register_operand"))]
14594 "TARGET_USE_FANCY_MATH_387
14595 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14596 || TARGET_MIX_SSE_I387)
14597 && flag_unsafe_math_optimizations"
14601 if (optimize_insn_for_size_p ())
14604 op0 = gen_reg_rtx (XFmode);
14605 op1 = gen_reg_rtx (XFmode);
14607 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14608 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14609 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14613 (define_expand "scalbxf3"
14614 [(parallel [(set (match_operand:XF 0 " register_operand")
14615 (unspec:XF [(match_operand:XF 1 "register_operand")
14616 (match_operand:XF 2 "register_operand")]
14617 UNSPEC_FSCALE_FRACT))
14619 (unspec:XF [(match_dup 1) (match_dup 2)]
14620 UNSPEC_FSCALE_EXP))])]
14621 "TARGET_USE_FANCY_MATH_387
14622 && flag_unsafe_math_optimizations"
14624 if (optimize_insn_for_size_p ())
14627 operands[3] = gen_reg_rtx (XFmode);
14630 (define_expand "scalb<mode>3"
14631 [(use (match_operand:MODEF 0 "register_operand"))
14632 (use (match_operand:MODEF 1 "general_operand"))
14633 (use (match_operand:MODEF 2 "general_operand"))]
14634 "TARGET_USE_FANCY_MATH_387
14635 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14636 || TARGET_MIX_SSE_I387)
14637 && flag_unsafe_math_optimizations"
14641 if (optimize_insn_for_size_p ())
14644 op0 = gen_reg_rtx (XFmode);
14645 op1 = gen_reg_rtx (XFmode);
14646 op2 = gen_reg_rtx (XFmode);
14648 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14649 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14650 emit_insn (gen_scalbxf3 (op0, op1, op2));
14651 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14655 (define_expand "significandxf2"
14656 [(parallel [(set (match_operand:XF 0 "register_operand")
14657 (unspec:XF [(match_operand:XF 1 "register_operand")]
14658 UNSPEC_XTRACT_FRACT))
14660 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14661 "TARGET_USE_FANCY_MATH_387
14662 && flag_unsafe_math_optimizations"
14663 "operands[2] = gen_reg_rtx (XFmode);")
14665 (define_expand "significand<mode>2"
14666 [(use (match_operand:MODEF 0 "register_operand"))
14667 (use (match_operand:MODEF 1 "register_operand"))]
14668 "TARGET_USE_FANCY_MATH_387
14669 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14670 || TARGET_MIX_SSE_I387)
14671 && flag_unsafe_math_optimizations"
14673 rtx op0 = gen_reg_rtx (XFmode);
14674 rtx op1 = gen_reg_rtx (XFmode);
14676 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14677 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14682 (define_insn "sse4_1_round<mode>2"
14683 [(set (match_operand:MODEF 0 "register_operand" "=x")
14684 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14685 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14688 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14689 [(set_attr "type" "ssecvt")
14690 (set_attr "prefix_extra" "1")
14691 (set_attr "prefix" "maybe_vex")
14692 (set_attr "mode" "<MODE>")])
14694 (define_insn "rintxf2"
14695 [(set (match_operand:XF 0 "register_operand" "=f")
14696 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14698 "TARGET_USE_FANCY_MATH_387
14699 && flag_unsafe_math_optimizations"
14701 [(set_attr "type" "fpspc")
14702 (set_attr "mode" "XF")])
14704 (define_expand "rint<mode>2"
14705 [(use (match_operand:MODEF 0 "register_operand"))
14706 (use (match_operand:MODEF 1 "register_operand"))]
14707 "(TARGET_USE_FANCY_MATH_387
14708 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14709 || TARGET_MIX_SSE_I387)
14710 && flag_unsafe_math_optimizations)
14711 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14712 && !flag_trapping_math)"
14714 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14715 && !flag_trapping_math)
14718 emit_insn (gen_sse4_1_round<mode>2
14719 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14720 else if (optimize_insn_for_size_p ())
14723 ix86_expand_rint (operands[0], operands[1]);
14727 rtx op0 = gen_reg_rtx (XFmode);
14728 rtx op1 = gen_reg_rtx (XFmode);
14730 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14731 emit_insn (gen_rintxf2 (op0, op1));
14733 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14738 (define_expand "round<mode>2"
14739 [(match_operand:X87MODEF 0 "register_operand")
14740 (match_operand:X87MODEF 1 "nonimmediate_operand")]
14741 "(TARGET_USE_FANCY_MATH_387
14742 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14743 || TARGET_MIX_SSE_I387)
14744 && flag_unsafe_math_optimizations)
14745 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14746 && !flag_trapping_math && !flag_rounding_math)"
14748 if (optimize_insn_for_size_p ())
14751 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14752 && !flag_trapping_math && !flag_rounding_math)
14756 operands[1] = force_reg (<MODE>mode, operands[1]);
14757 ix86_expand_round_sse4 (operands[0], operands[1]);
14759 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14760 ix86_expand_round (operands[0], operands[1]);
14762 ix86_expand_rounddf_32 (operands[0], operands[1]);
14766 operands[1] = force_reg (<MODE>mode, operands[1]);
14767 ix86_emit_i387_round (operands[0], operands[1]);
14772 (define_insn_and_split "*fistdi2_1"
14773 [(set (match_operand:DI 0 "nonimmediate_operand")
14774 (unspec:DI [(match_operand:XF 1 "register_operand")]
14776 "TARGET_USE_FANCY_MATH_387
14777 && can_create_pseudo_p ()"
14782 if (memory_operand (operands[0], VOIDmode))
14783 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14786 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14787 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14792 [(set_attr "type" "fpspc")
14793 (set_attr "mode" "DI")])
14795 (define_insn "fistdi2"
14796 [(set (match_operand:DI 0 "memory_operand" "=m")
14797 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14799 (clobber (match_scratch:XF 2 "=&1f"))]
14800 "TARGET_USE_FANCY_MATH_387"
14801 "* return output_fix_trunc (insn, operands, false);"
14802 [(set_attr "type" "fpspc")
14803 (set_attr "mode" "DI")])
14805 (define_insn "fistdi2_with_temp"
14806 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14807 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14809 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14810 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14811 "TARGET_USE_FANCY_MATH_387"
14813 [(set_attr "type" "fpspc")
14814 (set_attr "mode" "DI")])
14817 [(set (match_operand:DI 0 "register_operand")
14818 (unspec:DI [(match_operand:XF 1 "register_operand")]
14820 (clobber (match_operand:DI 2 "memory_operand"))
14821 (clobber (match_scratch 3))]
14823 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14824 (clobber (match_dup 3))])
14825 (set (match_dup 0) (match_dup 2))])
14828 [(set (match_operand:DI 0 "memory_operand")
14829 (unspec:DI [(match_operand:XF 1 "register_operand")]
14831 (clobber (match_operand:DI 2 "memory_operand"))
14832 (clobber (match_scratch 3))]
14834 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14835 (clobber (match_dup 3))])])
14837 (define_insn_and_split "*fist<mode>2_1"
14838 [(set (match_operand:SWI24 0 "register_operand")
14839 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14841 "TARGET_USE_FANCY_MATH_387
14842 && can_create_pseudo_p ()"
14847 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14848 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14852 [(set_attr "type" "fpspc")
14853 (set_attr "mode" "<MODE>")])
14855 (define_insn "fist<mode>2"
14856 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14857 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14859 "TARGET_USE_FANCY_MATH_387"
14860 "* return output_fix_trunc (insn, operands, false);"
14861 [(set_attr "type" "fpspc")
14862 (set_attr "mode" "<MODE>")])
14864 (define_insn "fist<mode>2_with_temp"
14865 [(set (match_operand:SWI24 0 "register_operand" "=r")
14866 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14868 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14869 "TARGET_USE_FANCY_MATH_387"
14871 [(set_attr "type" "fpspc")
14872 (set_attr "mode" "<MODE>")])
14875 [(set (match_operand:SWI24 0 "register_operand")
14876 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14878 (clobber (match_operand:SWI24 2 "memory_operand"))]
14880 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14881 (set (match_dup 0) (match_dup 2))])
14884 [(set (match_operand:SWI24 0 "memory_operand")
14885 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14887 (clobber (match_operand:SWI24 2 "memory_operand"))]
14889 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14891 (define_expand "lrintxf<mode>2"
14892 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
14893 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
14895 "TARGET_USE_FANCY_MATH_387")
14897 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14898 [(set (match_operand:SWI48x 0 "nonimmediate_operand")
14899 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand")]
14900 UNSPEC_FIX_NOTRUNC))]
14901 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14902 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14904 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14905 [(match_operand:SWI248x 0 "nonimmediate_operand")
14906 (match_operand:X87MODEF 1 "register_operand")]
14907 "(TARGET_USE_FANCY_MATH_387
14908 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14909 || TARGET_MIX_SSE_I387)
14910 && flag_unsafe_math_optimizations)
14911 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14912 && <SWI248x:MODE>mode != HImode
14913 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14914 && !flag_trapping_math && !flag_rounding_math)"
14916 if (optimize_insn_for_size_p ())
14919 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14920 && <SWI248x:MODE>mode != HImode
14921 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14922 && !flag_trapping_math && !flag_rounding_math)
14923 ix86_expand_lround (operands[0], operands[1]);
14925 ix86_emit_i387_round (operands[0], operands[1]);
14929 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14930 (define_insn_and_split "frndintxf2_floor"
14931 [(set (match_operand:XF 0 "register_operand")
14932 (unspec:XF [(match_operand:XF 1 "register_operand")]
14933 UNSPEC_FRNDINT_FLOOR))
14934 (clobber (reg:CC FLAGS_REG))]
14935 "TARGET_USE_FANCY_MATH_387
14936 && flag_unsafe_math_optimizations
14937 && can_create_pseudo_p ()"
14942 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14944 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14945 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14947 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14948 operands[2], operands[3]));
14951 [(set_attr "type" "frndint")
14952 (set_attr "i387_cw" "floor")
14953 (set_attr "mode" "XF")])
14955 (define_insn "frndintxf2_floor_i387"
14956 [(set (match_operand:XF 0 "register_operand" "=f")
14957 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14958 UNSPEC_FRNDINT_FLOOR))
14959 (use (match_operand:HI 2 "memory_operand" "m"))
14960 (use (match_operand:HI 3 "memory_operand" "m"))]
14961 "TARGET_USE_FANCY_MATH_387
14962 && flag_unsafe_math_optimizations"
14963 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14964 [(set_attr "type" "frndint")
14965 (set_attr "i387_cw" "floor")
14966 (set_attr "mode" "XF")])
14968 (define_expand "floorxf2"
14969 [(use (match_operand:XF 0 "register_operand"))
14970 (use (match_operand:XF 1 "register_operand"))]
14971 "TARGET_USE_FANCY_MATH_387
14972 && flag_unsafe_math_optimizations"
14974 if (optimize_insn_for_size_p ())
14976 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14980 (define_expand "floor<mode>2"
14981 [(use (match_operand:MODEF 0 "register_operand"))
14982 (use (match_operand:MODEF 1 "register_operand"))]
14983 "(TARGET_USE_FANCY_MATH_387
14984 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14985 || TARGET_MIX_SSE_I387)
14986 && flag_unsafe_math_optimizations)
14987 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14988 && !flag_trapping_math)"
14990 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14991 && !flag_trapping_math)
14994 emit_insn (gen_sse4_1_round<mode>2
14995 (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14996 else if (optimize_insn_for_size_p ())
14998 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14999 ix86_expand_floorceil (operands[0], operands[1], true);
15001 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15007 if (optimize_insn_for_size_p ())
15010 op0 = gen_reg_rtx (XFmode);
15011 op1 = gen_reg_rtx (XFmode);
15012 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15013 emit_insn (gen_frndintxf2_floor (op0, op1));
15015 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15020 (define_insn_and_split "*fist<mode>2_floor_1"
15021 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15022 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15023 UNSPEC_FIST_FLOOR))
15024 (clobber (reg:CC FLAGS_REG))]
15025 "TARGET_USE_FANCY_MATH_387
15026 && flag_unsafe_math_optimizations
15027 && can_create_pseudo_p ()"
15032 ix86_optimize_mode_switching[I387_FLOOR] = 1;
15034 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15035 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
15036 if (memory_operand (operands[0], VOIDmode))
15037 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
15038 operands[2], operands[3]));
15041 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15042 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
15043 operands[2], operands[3],
15048 [(set_attr "type" "fistp")
15049 (set_attr "i387_cw" "floor")
15050 (set_attr "mode" "<MODE>")])
15052 (define_insn "fistdi2_floor"
15053 [(set (match_operand:DI 0 "memory_operand" "=m")
15054 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15055 UNSPEC_FIST_FLOOR))
15056 (use (match_operand:HI 2 "memory_operand" "m"))
15057 (use (match_operand:HI 3 "memory_operand" "m"))
15058 (clobber (match_scratch:XF 4 "=&1f"))]
15059 "TARGET_USE_FANCY_MATH_387
15060 && flag_unsafe_math_optimizations"
15061 "* return output_fix_trunc (insn, operands, false);"
15062 [(set_attr "type" "fistp")
15063 (set_attr "i387_cw" "floor")
15064 (set_attr "mode" "DI")])
15066 (define_insn "fistdi2_floor_with_temp"
15067 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15068 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15069 UNSPEC_FIST_FLOOR))
15070 (use (match_operand:HI 2 "memory_operand" "m,m"))
15071 (use (match_operand:HI 3 "memory_operand" "m,m"))
15072 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15073 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15074 "TARGET_USE_FANCY_MATH_387
15075 && flag_unsafe_math_optimizations"
15077 [(set_attr "type" "fistp")
15078 (set_attr "i387_cw" "floor")
15079 (set_attr "mode" "DI")])
15082 [(set (match_operand:DI 0 "register_operand")
15083 (unspec:DI [(match_operand:XF 1 "register_operand")]
15084 UNSPEC_FIST_FLOOR))
15085 (use (match_operand:HI 2 "memory_operand"))
15086 (use (match_operand:HI 3 "memory_operand"))
15087 (clobber (match_operand:DI 4 "memory_operand"))
15088 (clobber (match_scratch 5))]
15090 [(parallel [(set (match_dup 4)
15091 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15092 (use (match_dup 2))
15093 (use (match_dup 3))
15094 (clobber (match_dup 5))])
15095 (set (match_dup 0) (match_dup 4))])
15098 [(set (match_operand:DI 0 "memory_operand")
15099 (unspec:DI [(match_operand:XF 1 "register_operand")]
15100 UNSPEC_FIST_FLOOR))
15101 (use (match_operand:HI 2 "memory_operand"))
15102 (use (match_operand:HI 3 "memory_operand"))
15103 (clobber (match_operand:DI 4 "memory_operand"))
15104 (clobber (match_scratch 5))]
15106 [(parallel [(set (match_dup 0)
15107 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15108 (use (match_dup 2))
15109 (use (match_dup 3))
15110 (clobber (match_dup 5))])])
15112 (define_insn "fist<mode>2_floor"
15113 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15114 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15115 UNSPEC_FIST_FLOOR))
15116 (use (match_operand:HI 2 "memory_operand" "m"))
15117 (use (match_operand:HI 3 "memory_operand" "m"))]
15118 "TARGET_USE_FANCY_MATH_387
15119 && flag_unsafe_math_optimizations"
15120 "* return output_fix_trunc (insn, operands, false);"
15121 [(set_attr "type" "fistp")
15122 (set_attr "i387_cw" "floor")
15123 (set_attr "mode" "<MODE>")])
15125 (define_insn "fist<mode>2_floor_with_temp"
15126 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15127 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15128 UNSPEC_FIST_FLOOR))
15129 (use (match_operand:HI 2 "memory_operand" "m,m"))
15130 (use (match_operand:HI 3 "memory_operand" "m,m"))
15131 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15132 "TARGET_USE_FANCY_MATH_387
15133 && flag_unsafe_math_optimizations"
15135 [(set_attr "type" "fistp")
15136 (set_attr "i387_cw" "floor")
15137 (set_attr "mode" "<MODE>")])
15140 [(set (match_operand:SWI24 0 "register_operand")
15141 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15142 UNSPEC_FIST_FLOOR))
15143 (use (match_operand:HI 2 "memory_operand"))
15144 (use (match_operand:HI 3 "memory_operand"))
15145 (clobber (match_operand:SWI24 4 "memory_operand"))]
15147 [(parallel [(set (match_dup 4)
15148 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15149 (use (match_dup 2))
15150 (use (match_dup 3))])
15151 (set (match_dup 0) (match_dup 4))])
15154 [(set (match_operand:SWI24 0 "memory_operand")
15155 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15156 UNSPEC_FIST_FLOOR))
15157 (use (match_operand:HI 2 "memory_operand"))
15158 (use (match_operand:HI 3 "memory_operand"))
15159 (clobber (match_operand:SWI24 4 "memory_operand"))]
15161 [(parallel [(set (match_dup 0)
15162 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15163 (use (match_dup 2))
15164 (use (match_dup 3))])])
15166 (define_expand "lfloorxf<mode>2"
15167 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15168 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15169 UNSPEC_FIST_FLOOR))
15170 (clobber (reg:CC FLAGS_REG))])]
15171 "TARGET_USE_FANCY_MATH_387
15172 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15173 && flag_unsafe_math_optimizations")
15175 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15176 [(match_operand:SWI48 0 "nonimmediate_operand")
15177 (match_operand:MODEF 1 "register_operand")]
15178 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15179 && !flag_trapping_math"
15181 if (TARGET_64BIT && optimize_insn_for_size_p ())
15183 ix86_expand_lfloorceil (operands[0], operands[1], true);
15187 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15188 (define_insn_and_split "frndintxf2_ceil"
15189 [(set (match_operand:XF 0 "register_operand")
15190 (unspec:XF [(match_operand:XF 1 "register_operand")]
15191 UNSPEC_FRNDINT_CEIL))
15192 (clobber (reg:CC FLAGS_REG))]
15193 "TARGET_USE_FANCY_MATH_387
15194 && flag_unsafe_math_optimizations
15195 && can_create_pseudo_p ()"
15200 ix86_optimize_mode_switching[I387_CEIL] = 1;
15202 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15203 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15205 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15206 operands[2], operands[3]));
15209 [(set_attr "type" "frndint")
15210 (set_attr "i387_cw" "ceil")
15211 (set_attr "mode" "XF")])
15213 (define_insn "frndintxf2_ceil_i387"
15214 [(set (match_operand:XF 0 "register_operand" "=f")
15215 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15216 UNSPEC_FRNDINT_CEIL))
15217 (use (match_operand:HI 2 "memory_operand" "m"))
15218 (use (match_operand:HI 3 "memory_operand" "m"))]
15219 "TARGET_USE_FANCY_MATH_387
15220 && flag_unsafe_math_optimizations"
15221 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15222 [(set_attr "type" "frndint")
15223 (set_attr "i387_cw" "ceil")
15224 (set_attr "mode" "XF")])
15226 (define_expand "ceilxf2"
15227 [(use (match_operand:XF 0 "register_operand"))
15228 (use (match_operand:XF 1 "register_operand"))]
15229 "TARGET_USE_FANCY_MATH_387
15230 && flag_unsafe_math_optimizations"
15232 if (optimize_insn_for_size_p ())
15234 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15238 (define_expand "ceil<mode>2"
15239 [(use (match_operand:MODEF 0 "register_operand"))
15240 (use (match_operand:MODEF 1 "register_operand"))]
15241 "(TARGET_USE_FANCY_MATH_387
15242 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15243 || TARGET_MIX_SSE_I387)
15244 && flag_unsafe_math_optimizations)
15245 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15246 && !flag_trapping_math)"
15248 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15249 && !flag_trapping_math)
15252 emit_insn (gen_sse4_1_round<mode>2
15253 (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
15254 else if (optimize_insn_for_size_p ())
15256 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15257 ix86_expand_floorceil (operands[0], operands[1], false);
15259 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15265 if (optimize_insn_for_size_p ())
15268 op0 = gen_reg_rtx (XFmode);
15269 op1 = gen_reg_rtx (XFmode);
15270 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15271 emit_insn (gen_frndintxf2_ceil (op0, op1));
15273 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15278 (define_insn_and_split "*fist<mode>2_ceil_1"
15279 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15280 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15282 (clobber (reg:CC FLAGS_REG))]
15283 "TARGET_USE_FANCY_MATH_387
15284 && flag_unsafe_math_optimizations
15285 && can_create_pseudo_p ()"
15290 ix86_optimize_mode_switching[I387_CEIL] = 1;
15292 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15293 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15294 if (memory_operand (operands[0], VOIDmode))
15295 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15296 operands[2], operands[3]));
15299 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15300 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15301 operands[2], operands[3],
15306 [(set_attr "type" "fistp")
15307 (set_attr "i387_cw" "ceil")
15308 (set_attr "mode" "<MODE>")])
15310 (define_insn "fistdi2_ceil"
15311 [(set (match_operand:DI 0 "memory_operand" "=m")
15312 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15314 (use (match_operand:HI 2 "memory_operand" "m"))
15315 (use (match_operand:HI 3 "memory_operand" "m"))
15316 (clobber (match_scratch:XF 4 "=&1f"))]
15317 "TARGET_USE_FANCY_MATH_387
15318 && flag_unsafe_math_optimizations"
15319 "* return output_fix_trunc (insn, operands, false);"
15320 [(set_attr "type" "fistp")
15321 (set_attr "i387_cw" "ceil")
15322 (set_attr "mode" "DI")])
15324 (define_insn "fistdi2_ceil_with_temp"
15325 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15326 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15328 (use (match_operand:HI 2 "memory_operand" "m,m"))
15329 (use (match_operand:HI 3 "memory_operand" "m,m"))
15330 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15331 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15332 "TARGET_USE_FANCY_MATH_387
15333 && flag_unsafe_math_optimizations"
15335 [(set_attr "type" "fistp")
15336 (set_attr "i387_cw" "ceil")
15337 (set_attr "mode" "DI")])
15340 [(set (match_operand:DI 0 "register_operand")
15341 (unspec:DI [(match_operand:XF 1 "register_operand")]
15343 (use (match_operand:HI 2 "memory_operand"))
15344 (use (match_operand:HI 3 "memory_operand"))
15345 (clobber (match_operand:DI 4 "memory_operand"))
15346 (clobber (match_scratch 5))]
15348 [(parallel [(set (match_dup 4)
15349 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15350 (use (match_dup 2))
15351 (use (match_dup 3))
15352 (clobber (match_dup 5))])
15353 (set (match_dup 0) (match_dup 4))])
15356 [(set (match_operand:DI 0 "memory_operand")
15357 (unspec:DI [(match_operand:XF 1 "register_operand")]
15359 (use (match_operand:HI 2 "memory_operand"))
15360 (use (match_operand:HI 3 "memory_operand"))
15361 (clobber (match_operand:DI 4 "memory_operand"))
15362 (clobber (match_scratch 5))]
15364 [(parallel [(set (match_dup 0)
15365 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15366 (use (match_dup 2))
15367 (use (match_dup 3))
15368 (clobber (match_dup 5))])])
15370 (define_insn "fist<mode>2_ceil"
15371 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15372 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15374 (use (match_operand:HI 2 "memory_operand" "m"))
15375 (use (match_operand:HI 3 "memory_operand" "m"))]
15376 "TARGET_USE_FANCY_MATH_387
15377 && flag_unsafe_math_optimizations"
15378 "* return output_fix_trunc (insn, operands, false);"
15379 [(set_attr "type" "fistp")
15380 (set_attr "i387_cw" "ceil")
15381 (set_attr "mode" "<MODE>")])
15383 (define_insn "fist<mode>2_ceil_with_temp"
15384 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15385 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15387 (use (match_operand:HI 2 "memory_operand" "m,m"))
15388 (use (match_operand:HI 3 "memory_operand" "m,m"))
15389 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15390 "TARGET_USE_FANCY_MATH_387
15391 && flag_unsafe_math_optimizations"
15393 [(set_attr "type" "fistp")
15394 (set_attr "i387_cw" "ceil")
15395 (set_attr "mode" "<MODE>")])
15398 [(set (match_operand:SWI24 0 "register_operand")
15399 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15401 (use (match_operand:HI 2 "memory_operand"))
15402 (use (match_operand:HI 3 "memory_operand"))
15403 (clobber (match_operand:SWI24 4 "memory_operand"))]
15405 [(parallel [(set (match_dup 4)
15406 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15407 (use (match_dup 2))
15408 (use (match_dup 3))])
15409 (set (match_dup 0) (match_dup 4))])
15412 [(set (match_operand:SWI24 0 "memory_operand")
15413 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15415 (use (match_operand:HI 2 "memory_operand"))
15416 (use (match_operand:HI 3 "memory_operand"))
15417 (clobber (match_operand:SWI24 4 "memory_operand"))]
15419 [(parallel [(set (match_dup 0)
15420 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15421 (use (match_dup 2))
15422 (use (match_dup 3))])])
15424 (define_expand "lceilxf<mode>2"
15425 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15426 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15428 (clobber (reg:CC FLAGS_REG))])]
15429 "TARGET_USE_FANCY_MATH_387
15430 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15431 && flag_unsafe_math_optimizations")
15433 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15434 [(match_operand:SWI48 0 "nonimmediate_operand")
15435 (match_operand:MODEF 1 "register_operand")]
15436 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15437 && !flag_trapping_math"
15439 ix86_expand_lfloorceil (operands[0], operands[1], false);
15443 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15444 (define_insn_and_split "frndintxf2_trunc"
15445 [(set (match_operand:XF 0 "register_operand")
15446 (unspec:XF [(match_operand:XF 1 "register_operand")]
15447 UNSPEC_FRNDINT_TRUNC))
15448 (clobber (reg:CC FLAGS_REG))]
15449 "TARGET_USE_FANCY_MATH_387
15450 && flag_unsafe_math_optimizations
15451 && can_create_pseudo_p ()"
15456 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15458 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15459 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15461 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15462 operands[2], operands[3]));
15465 [(set_attr "type" "frndint")
15466 (set_attr "i387_cw" "trunc")
15467 (set_attr "mode" "XF")])
15469 (define_insn "frndintxf2_trunc_i387"
15470 [(set (match_operand:XF 0 "register_operand" "=f")
15471 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15472 UNSPEC_FRNDINT_TRUNC))
15473 (use (match_operand:HI 2 "memory_operand" "m"))
15474 (use (match_operand:HI 3 "memory_operand" "m"))]
15475 "TARGET_USE_FANCY_MATH_387
15476 && flag_unsafe_math_optimizations"
15477 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15478 [(set_attr "type" "frndint")
15479 (set_attr "i387_cw" "trunc")
15480 (set_attr "mode" "XF")])
15482 (define_expand "btruncxf2"
15483 [(use (match_operand:XF 0 "register_operand"))
15484 (use (match_operand:XF 1 "register_operand"))]
15485 "TARGET_USE_FANCY_MATH_387
15486 && flag_unsafe_math_optimizations"
15488 if (optimize_insn_for_size_p ())
15490 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15494 (define_expand "btrunc<mode>2"
15495 [(use (match_operand:MODEF 0 "register_operand"))
15496 (use (match_operand:MODEF 1 "register_operand"))]
15497 "(TARGET_USE_FANCY_MATH_387
15498 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15499 || TARGET_MIX_SSE_I387)
15500 && flag_unsafe_math_optimizations)
15501 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15502 && !flag_trapping_math)"
15504 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15505 && !flag_trapping_math)
15508 emit_insn (gen_sse4_1_round<mode>2
15509 (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15510 else if (optimize_insn_for_size_p ())
15512 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15513 ix86_expand_trunc (operands[0], operands[1]);
15515 ix86_expand_truncdf_32 (operands[0], operands[1]);
15521 if (optimize_insn_for_size_p ())
15524 op0 = gen_reg_rtx (XFmode);
15525 op1 = gen_reg_rtx (XFmode);
15526 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15527 emit_insn (gen_frndintxf2_trunc (op0, op1));
15529 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15534 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15535 (define_insn_and_split "frndintxf2_mask_pm"
15536 [(set (match_operand:XF 0 "register_operand")
15537 (unspec:XF [(match_operand:XF 1 "register_operand")]
15538 UNSPEC_FRNDINT_MASK_PM))
15539 (clobber (reg:CC FLAGS_REG))]
15540 "TARGET_USE_FANCY_MATH_387
15541 && flag_unsafe_math_optimizations
15542 && can_create_pseudo_p ()"
15547 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15549 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15550 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15552 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15553 operands[2], operands[3]));
15556 [(set_attr "type" "frndint")
15557 (set_attr "i387_cw" "mask_pm")
15558 (set_attr "mode" "XF")])
15560 (define_insn "frndintxf2_mask_pm_i387"
15561 [(set (match_operand:XF 0 "register_operand" "=f")
15562 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15563 UNSPEC_FRNDINT_MASK_PM))
15564 (use (match_operand:HI 2 "memory_operand" "m"))
15565 (use (match_operand:HI 3 "memory_operand" "m"))]
15566 "TARGET_USE_FANCY_MATH_387
15567 && flag_unsafe_math_optimizations"
15568 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15569 [(set_attr "type" "frndint")
15570 (set_attr "i387_cw" "mask_pm")
15571 (set_attr "mode" "XF")])
15573 (define_expand "nearbyintxf2"
15574 [(use (match_operand:XF 0 "register_operand"))
15575 (use (match_operand:XF 1 "register_operand"))]
15576 "TARGET_USE_FANCY_MATH_387
15577 && flag_unsafe_math_optimizations"
15579 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15583 (define_expand "nearbyint<mode>2"
15584 [(use (match_operand:MODEF 0 "register_operand"))
15585 (use (match_operand:MODEF 1 "register_operand"))]
15586 "TARGET_USE_FANCY_MATH_387
15587 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15588 || TARGET_MIX_SSE_I387)
15589 && flag_unsafe_math_optimizations"
15591 rtx op0 = gen_reg_rtx (XFmode);
15592 rtx op1 = gen_reg_rtx (XFmode);
15594 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15595 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15597 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15601 (define_insn "fxam<mode>2_i387"
15602 [(set (match_operand:HI 0 "register_operand" "=a")
15604 [(match_operand:X87MODEF 1 "register_operand" "f")]
15606 "TARGET_USE_FANCY_MATH_387"
15607 "fxam\n\tfnstsw\t%0"
15608 [(set_attr "type" "multi")
15609 (set_attr "length" "4")
15610 (set_attr "unit" "i387")
15611 (set_attr "mode" "<MODE>")])
15613 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15614 [(set (match_operand:HI 0 "register_operand")
15616 [(match_operand:MODEF 1 "memory_operand")]
15618 "TARGET_USE_FANCY_MATH_387
15619 && can_create_pseudo_p ()"
15622 [(set (match_dup 2)(match_dup 1))
15624 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15626 operands[2] = gen_reg_rtx (<MODE>mode);
15628 MEM_VOLATILE_P (operands[1]) = 1;
15630 [(set_attr "type" "multi")
15631 (set_attr "unit" "i387")
15632 (set_attr "mode" "<MODE>")])
15634 (define_expand "isinfxf2"
15635 [(use (match_operand:SI 0 "register_operand"))
15636 (use (match_operand:XF 1 "register_operand"))]
15637 "TARGET_USE_FANCY_MATH_387
15638 && TARGET_C99_FUNCTIONS"
15640 rtx mask = GEN_INT (0x45);
15641 rtx val = GEN_INT (0x05);
15645 rtx scratch = gen_reg_rtx (HImode);
15646 rtx res = gen_reg_rtx (QImode);
15648 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15650 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15651 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15652 cond = gen_rtx_fmt_ee (EQ, QImode,
15653 gen_rtx_REG (CCmode, FLAGS_REG),
15655 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15656 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15660 (define_expand "isinf<mode>2"
15661 [(use (match_operand:SI 0 "register_operand"))
15662 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15663 "TARGET_USE_FANCY_MATH_387
15664 && TARGET_C99_FUNCTIONS
15665 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15667 rtx mask = GEN_INT (0x45);
15668 rtx val = GEN_INT (0x05);
15672 rtx scratch = gen_reg_rtx (HImode);
15673 rtx res = gen_reg_rtx (QImode);
15675 /* Remove excess precision by forcing value through memory. */
15676 if (memory_operand (operands[1], VOIDmode))
15677 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15680 enum ix86_stack_slot slot = (virtuals_instantiated
15683 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15685 emit_move_insn (temp, operands[1]);
15686 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15689 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15690 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15691 cond = gen_rtx_fmt_ee (EQ, QImode,
15692 gen_rtx_REG (CCmode, FLAGS_REG),
15694 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15695 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15699 (define_expand "signbitxf2"
15700 [(use (match_operand:SI 0 "register_operand"))
15701 (use (match_operand:XF 1 "register_operand"))]
15702 "TARGET_USE_FANCY_MATH_387"
15704 rtx scratch = gen_reg_rtx (HImode);
15706 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15707 emit_insn (gen_andsi3 (operands[0],
15708 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15712 (define_insn "movmsk_df"
15713 [(set (match_operand:SI 0 "register_operand" "=r")
15715 [(match_operand:DF 1 "register_operand" "x")]
15717 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15718 "%vmovmskpd\t{%1, %0|%0, %1}"
15719 [(set_attr "type" "ssemov")
15720 (set_attr "prefix" "maybe_vex")
15721 (set_attr "mode" "DF")])
15723 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15724 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15725 (define_expand "signbitdf2"
15726 [(use (match_operand:SI 0 "register_operand"))
15727 (use (match_operand:DF 1 "register_operand"))]
15728 "TARGET_USE_FANCY_MATH_387
15729 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15731 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15733 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15734 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15738 rtx scratch = gen_reg_rtx (HImode);
15740 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15741 emit_insn (gen_andsi3 (operands[0],
15742 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15747 (define_expand "signbitsf2"
15748 [(use (match_operand:SI 0 "register_operand"))
15749 (use (match_operand:SF 1 "register_operand"))]
15750 "TARGET_USE_FANCY_MATH_387
15751 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15753 rtx scratch = gen_reg_rtx (HImode);
15755 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15756 emit_insn (gen_andsi3 (operands[0],
15757 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15761 ;; Block operation instructions
15764 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15767 [(set_attr "length" "1")
15768 (set_attr "length_immediate" "0")
15769 (set_attr "modrm" "0")])
15771 (define_expand "movmem<mode>"
15772 [(use (match_operand:BLK 0 "memory_operand"))
15773 (use (match_operand:BLK 1 "memory_operand"))
15774 (use (match_operand:SWI48 2 "nonmemory_operand"))
15775 (use (match_operand:SWI48 3 "const_int_operand"))
15776 (use (match_operand:SI 4 "const_int_operand"))
15777 (use (match_operand:SI 5 "const_int_operand"))]
15780 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15781 operands[4], operands[5]))
15787 ;; Most CPUs don't like single string operations
15788 ;; Handle this case here to simplify previous expander.
15790 (define_expand "strmov"
15791 [(set (match_dup 4) (match_operand 3 "memory_operand"))
15792 (set (match_operand 1 "memory_operand") (match_dup 4))
15793 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
15794 (clobber (reg:CC FLAGS_REG))])
15795 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
15796 (clobber (reg:CC FLAGS_REG))])]
15799 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15801 /* If .md ever supports :P for Pmode, these can be directly
15802 in the pattern above. */
15803 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15804 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15806 /* Can't use this if the user has appropriated esi or edi. */
15807 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15808 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15810 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15811 operands[2], operands[3],
15812 operands[5], operands[6]));
15816 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15819 (define_expand "strmov_singleop"
15820 [(parallel [(set (match_operand 1 "memory_operand")
15821 (match_operand 3 "memory_operand"))
15822 (set (match_operand 0 "register_operand")
15824 (set (match_operand 2 "register_operand")
15825 (match_operand 5))])]
15827 "ix86_current_function_needs_cld = 1;")
15829 (define_insn "*strmovdi_rex_1"
15830 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15831 (mem:DI (match_operand:P 3 "register_operand" "1")))
15832 (set (match_operand:P 0 "register_operand" "=D")
15833 (plus:P (match_dup 2)
15835 (set (match_operand:P 1 "register_operand" "=S")
15836 (plus:P (match_dup 3)
15839 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15841 [(set_attr "type" "str")
15842 (set_attr "memory" "both")
15843 (set_attr "mode" "DI")])
15845 (define_insn "*strmovsi_1"
15846 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15847 (mem:SI (match_operand:P 3 "register_operand" "1")))
15848 (set (match_operand:P 0 "register_operand" "=D")
15849 (plus:P (match_dup 2)
15851 (set (match_operand:P 1 "register_operand" "=S")
15852 (plus:P (match_dup 3)
15854 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15856 [(set_attr "type" "str")
15857 (set_attr "memory" "both")
15858 (set_attr "mode" "SI")])
15860 (define_insn "*strmovhi_1"
15861 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15862 (mem:HI (match_operand:P 3 "register_operand" "1")))
15863 (set (match_operand:P 0 "register_operand" "=D")
15864 (plus:P (match_dup 2)
15866 (set (match_operand:P 1 "register_operand" "=S")
15867 (plus:P (match_dup 3)
15869 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15871 [(set_attr "type" "str")
15872 (set_attr "memory" "both")
15873 (set_attr "mode" "HI")])
15875 (define_insn "*strmovqi_1"
15876 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15877 (mem:QI (match_operand:P 3 "register_operand" "1")))
15878 (set (match_operand:P 0 "register_operand" "=D")
15879 (plus:P (match_dup 2)
15881 (set (match_operand:P 1 "register_operand" "=S")
15882 (plus:P (match_dup 3)
15884 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15886 [(set_attr "type" "str")
15887 (set_attr "memory" "both")
15888 (set (attr "prefix_rex")
15890 (match_test "<P:MODE>mode == DImode")
15892 (const_string "*")))
15893 (set_attr "mode" "QI")])
15895 (define_expand "rep_mov"
15896 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
15897 (set (match_operand 0 "register_operand")
15899 (set (match_operand 2 "register_operand")
15901 (set (match_operand 1 "memory_operand")
15902 (match_operand 3 "memory_operand"))
15903 (use (match_dup 4))])]
15905 "ix86_current_function_needs_cld = 1;")
15907 (define_insn "*rep_movdi_rex64"
15908 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15909 (set (match_operand:P 0 "register_operand" "=D")
15910 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15912 (match_operand:P 3 "register_operand" "0")))
15913 (set (match_operand:P 1 "register_operand" "=S")
15914 (plus:P (ashift:P (match_dup 5) (const_int 3))
15915 (match_operand:P 4 "register_operand" "1")))
15916 (set (mem:BLK (match_dup 3))
15917 (mem:BLK (match_dup 4)))
15918 (use (match_dup 5))]
15920 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15922 [(set_attr "type" "str")
15923 (set_attr "prefix_rep" "1")
15924 (set_attr "memory" "both")
15925 (set_attr "mode" "DI")])
15927 (define_insn "*rep_movsi"
15928 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15929 (set (match_operand:P 0 "register_operand" "=D")
15930 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15932 (match_operand:P 3 "register_operand" "0")))
15933 (set (match_operand:P 1 "register_operand" "=S")
15934 (plus:P (ashift:P (match_dup 5) (const_int 2))
15935 (match_operand:P 4 "register_operand" "1")))
15936 (set (mem:BLK (match_dup 3))
15937 (mem:BLK (match_dup 4)))
15938 (use (match_dup 5))]
15939 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15940 "%^rep{%;} movs{l|d}"
15941 [(set_attr "type" "str")
15942 (set_attr "prefix_rep" "1")
15943 (set_attr "memory" "both")
15944 (set_attr "mode" "SI")])
15946 (define_insn "*rep_movqi"
15947 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15948 (set (match_operand:P 0 "register_operand" "=D")
15949 (plus:P (match_operand:P 3 "register_operand" "0")
15950 (match_operand:P 5 "register_operand" "2")))
15951 (set (match_operand:P 1 "register_operand" "=S")
15952 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15953 (set (mem:BLK (match_dup 3))
15954 (mem:BLK (match_dup 4)))
15955 (use (match_dup 5))]
15956 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15958 [(set_attr "type" "str")
15959 (set_attr "prefix_rep" "1")
15960 (set_attr "memory" "both")
15961 (set_attr "mode" "QI")])
15963 (define_expand "setmem<mode>"
15964 [(use (match_operand:BLK 0 "memory_operand"))
15965 (use (match_operand:SWI48 1 "nonmemory_operand"))
15966 (use (match_operand:QI 2 "nonmemory_operand"))
15967 (use (match_operand 3 "const_int_operand"))
15968 (use (match_operand:SI 4 "const_int_operand"))
15969 (use (match_operand:SI 5 "const_int_operand"))]
15972 if (ix86_expand_setmem (operands[0], operands[1],
15973 operands[2], operands[3],
15974 operands[4], operands[5]))
15980 ;; Most CPUs don't like single string operations
15981 ;; Handle this case here to simplify previous expander.
15983 (define_expand "strset"
15984 [(set (match_operand 1 "memory_operand")
15985 (match_operand 2 "register_operand"))
15986 (parallel [(set (match_operand 0 "register_operand")
15988 (clobber (reg:CC FLAGS_REG))])]
15991 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15992 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15994 /* If .md ever supports :P for Pmode, this can be directly
15995 in the pattern above. */
15996 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15997 GEN_INT (GET_MODE_SIZE (GET_MODE
15999 /* Can't use this if the user has appropriated eax or edi. */
16000 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
16001 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
16003 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
16009 (define_expand "strset_singleop"
16010 [(parallel [(set (match_operand 1 "memory_operand")
16011 (match_operand 2 "register_operand"))
16012 (set (match_operand 0 "register_operand")
16013 (match_operand 3))])]
16015 "ix86_current_function_needs_cld = 1;")
16017 (define_insn "*strsetdi_rex_1"
16018 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
16019 (match_operand:DI 2 "register_operand" "a"))
16020 (set (match_operand:P 0 "register_operand" "=D")
16021 (plus:P (match_dup 1)
16024 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16026 [(set_attr "type" "str")
16027 (set_attr "memory" "store")
16028 (set_attr "mode" "DI")])
16030 (define_insn "*strsetsi_1"
16031 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
16032 (match_operand:SI 2 "register_operand" "a"))
16033 (set (match_operand:P 0 "register_operand" "=D")
16034 (plus:P (match_dup 1)
16036 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16038 [(set_attr "type" "str")
16039 (set_attr "memory" "store")
16040 (set_attr "mode" "SI")])
16042 (define_insn "*strsethi_1"
16043 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
16044 (match_operand:HI 2 "register_operand" "a"))
16045 (set (match_operand:P 0 "register_operand" "=D")
16046 (plus:P (match_dup 1)
16048 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16050 [(set_attr "type" "str")
16051 (set_attr "memory" "store")
16052 (set_attr "mode" "HI")])
16054 (define_insn "*strsetqi_1"
16055 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
16056 (match_operand:QI 2 "register_operand" "a"))
16057 (set (match_operand:P 0 "register_operand" "=D")
16058 (plus:P (match_dup 1)
16060 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
16062 [(set_attr "type" "str")
16063 (set_attr "memory" "store")
16064 (set (attr "prefix_rex")
16066 (match_test "<P:MODE>mode == DImode")
16068 (const_string "*")))
16069 (set_attr "mode" "QI")])
16071 (define_expand "rep_stos"
16072 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
16073 (set (match_operand 0 "register_operand")
16075 (set (match_operand 2 "memory_operand") (const_int 0))
16076 (use (match_operand 3 "register_operand"))
16077 (use (match_dup 1))])]
16079 "ix86_current_function_needs_cld = 1;")
16081 (define_insn "*rep_stosdi_rex64"
16082 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16083 (set (match_operand:P 0 "register_operand" "=D")
16084 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16086 (match_operand:P 3 "register_operand" "0")))
16087 (set (mem:BLK (match_dup 3))
16089 (use (match_operand:DI 2 "register_operand" "a"))
16090 (use (match_dup 4))]
16092 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16094 [(set_attr "type" "str")
16095 (set_attr "prefix_rep" "1")
16096 (set_attr "memory" "store")
16097 (set_attr "mode" "DI")])
16099 (define_insn "*rep_stossi"
16100 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16101 (set (match_operand:P 0 "register_operand" "=D")
16102 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16104 (match_operand:P 3 "register_operand" "0")))
16105 (set (mem:BLK (match_dup 3))
16107 (use (match_operand:SI 2 "register_operand" "a"))
16108 (use (match_dup 4))]
16109 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16110 "%^rep{%;} stos{l|d}"
16111 [(set_attr "type" "str")
16112 (set_attr "prefix_rep" "1")
16113 (set_attr "memory" "store")
16114 (set_attr "mode" "SI")])
16116 (define_insn "*rep_stosqi"
16117 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16118 (set (match_operand:P 0 "register_operand" "=D")
16119 (plus:P (match_operand:P 3 "register_operand" "0")
16120 (match_operand:P 4 "register_operand" "1")))
16121 (set (mem:BLK (match_dup 3))
16123 (use (match_operand:QI 2 "register_operand" "a"))
16124 (use (match_dup 4))]
16125 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16127 [(set_attr "type" "str")
16128 (set_attr "prefix_rep" "1")
16129 (set_attr "memory" "store")
16130 (set (attr "prefix_rex")
16132 (match_test "<P:MODE>mode == DImode")
16134 (const_string "*")))
16135 (set_attr "mode" "QI")])
16137 (define_expand "cmpstrnsi"
16138 [(set (match_operand:SI 0 "register_operand")
16139 (compare:SI (match_operand:BLK 1 "general_operand")
16140 (match_operand:BLK 2 "general_operand")))
16141 (use (match_operand 3 "general_operand"))
16142 (use (match_operand 4 "immediate_operand"))]
16145 rtx addr1, addr2, out, outlow, count, countreg, align;
16147 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16150 /* Can't use this if the user has appropriated ecx, esi or edi. */
16151 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16156 out = gen_reg_rtx (SImode);
16158 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16159 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16160 if (addr1 != XEXP (operands[1], 0))
16161 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16162 if (addr2 != XEXP (operands[2], 0))
16163 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16165 count = operands[3];
16166 countreg = ix86_zero_extend_to_Pmode (count);
16168 /* %%% Iff we are testing strict equality, we can use known alignment
16169 to good advantage. This may be possible with combine, particularly
16170 once cc0 is dead. */
16171 align = operands[4];
16173 if (CONST_INT_P (count))
16175 if (INTVAL (count) == 0)
16177 emit_move_insn (operands[0], const0_rtx);
16180 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16181 operands[1], operands[2]));
16185 rtx (*gen_cmp) (rtx, rtx);
16187 gen_cmp = (TARGET_64BIT
16188 ? gen_cmpdi_1 : gen_cmpsi_1);
16190 emit_insn (gen_cmp (countreg, countreg));
16191 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16192 operands[1], operands[2]));
16195 outlow = gen_lowpart (QImode, out);
16196 emit_insn (gen_cmpintqi (outlow));
16197 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16199 if (operands[0] != out)
16200 emit_move_insn (operands[0], out);
16205 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16207 (define_expand "cmpintqi"
16208 [(set (match_dup 1)
16209 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16211 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16212 (parallel [(set (match_operand:QI 0 "register_operand")
16213 (minus:QI (match_dup 1)
16215 (clobber (reg:CC FLAGS_REG))])]
16218 operands[1] = gen_reg_rtx (QImode);
16219 operands[2] = gen_reg_rtx (QImode);
16222 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16223 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16225 (define_expand "cmpstrnqi_nz_1"
16226 [(parallel [(set (reg:CC FLAGS_REG)
16227 (compare:CC (match_operand 4 "memory_operand")
16228 (match_operand 5 "memory_operand")))
16229 (use (match_operand 2 "register_operand"))
16230 (use (match_operand:SI 3 "immediate_operand"))
16231 (clobber (match_operand 0 "register_operand"))
16232 (clobber (match_operand 1 "register_operand"))
16233 (clobber (match_dup 2))])]
16235 "ix86_current_function_needs_cld = 1;")
16237 (define_insn "*cmpstrnqi_nz_1"
16238 [(set (reg:CC FLAGS_REG)
16239 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16240 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16241 (use (match_operand:P 6 "register_operand" "2"))
16242 (use (match_operand:SI 3 "immediate_operand" "i"))
16243 (clobber (match_operand:P 0 "register_operand" "=S"))
16244 (clobber (match_operand:P 1 "register_operand" "=D"))
16245 (clobber (match_operand:P 2 "register_operand" "=c"))]
16246 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16248 [(set_attr "type" "str")
16249 (set_attr "mode" "QI")
16250 (set (attr "prefix_rex")
16252 (match_test "<P:MODE>mode == DImode")
16254 (const_string "*")))
16255 (set_attr "prefix_rep" "1")])
16257 ;; The same, but the count is not known to not be zero.
16259 (define_expand "cmpstrnqi_1"
16260 [(parallel [(set (reg:CC FLAGS_REG)
16261 (if_then_else:CC (ne (match_operand 2 "register_operand")
16263 (compare:CC (match_operand 4 "memory_operand")
16264 (match_operand 5 "memory_operand"))
16266 (use (match_operand:SI 3 "immediate_operand"))
16267 (use (reg:CC FLAGS_REG))
16268 (clobber (match_operand 0 "register_operand"))
16269 (clobber (match_operand 1 "register_operand"))
16270 (clobber (match_dup 2))])]
16272 "ix86_current_function_needs_cld = 1;")
16274 (define_insn "*cmpstrnqi_1"
16275 [(set (reg:CC FLAGS_REG)
16276 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16278 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16279 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16281 (use (match_operand:SI 3 "immediate_operand" "i"))
16282 (use (reg:CC FLAGS_REG))
16283 (clobber (match_operand:P 0 "register_operand" "=S"))
16284 (clobber (match_operand:P 1 "register_operand" "=D"))
16285 (clobber (match_operand:P 2 "register_operand" "=c"))]
16286 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16288 [(set_attr "type" "str")
16289 (set_attr "mode" "QI")
16290 (set (attr "prefix_rex")
16292 (match_test "<P:MODE>mode == DImode")
16294 (const_string "*")))
16295 (set_attr "prefix_rep" "1")])
16297 (define_expand "strlen<mode>"
16298 [(set (match_operand:P 0 "register_operand")
16299 (unspec:P [(match_operand:BLK 1 "general_operand")
16300 (match_operand:QI 2 "immediate_operand")
16301 (match_operand 3 "immediate_operand")]
16305 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16311 (define_expand "strlenqi_1"
16312 [(parallel [(set (match_operand 0 "register_operand")
16314 (clobber (match_operand 1 "register_operand"))
16315 (clobber (reg:CC FLAGS_REG))])]
16317 "ix86_current_function_needs_cld = 1;")
16319 (define_insn "*strlenqi_1"
16320 [(set (match_operand:P 0 "register_operand" "=&c")
16321 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16322 (match_operand:QI 2 "register_operand" "a")
16323 (match_operand:P 3 "immediate_operand" "i")
16324 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16325 (clobber (match_operand:P 1 "register_operand" "=D"))
16326 (clobber (reg:CC FLAGS_REG))]
16327 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16328 "%^repnz{%;} scasb"
16329 [(set_attr "type" "str")
16330 (set_attr "mode" "QI")
16331 (set (attr "prefix_rex")
16333 (match_test "<P:MODE>mode == DImode")
16335 (const_string "*")))
16336 (set_attr "prefix_rep" "1")])
16338 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16339 ;; handled in combine, but it is not currently up to the task.
16340 ;; When used for their truth value, the cmpstrn* expanders generate
16349 ;; The intermediate three instructions are unnecessary.
16351 ;; This one handles cmpstrn*_nz_1...
16354 (set (reg:CC FLAGS_REG)
16355 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16356 (mem:BLK (match_operand 5 "register_operand"))))
16357 (use (match_operand 6 "register_operand"))
16358 (use (match_operand:SI 3 "immediate_operand"))
16359 (clobber (match_operand 0 "register_operand"))
16360 (clobber (match_operand 1 "register_operand"))
16361 (clobber (match_operand 2 "register_operand"))])
16362 (set (match_operand:QI 7 "register_operand")
16363 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16364 (set (match_operand:QI 8 "register_operand")
16365 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16366 (set (reg FLAGS_REG)
16367 (compare (match_dup 7) (match_dup 8)))
16369 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16371 (set (reg:CC FLAGS_REG)
16372 (compare:CC (mem:BLK (match_dup 4))
16373 (mem:BLK (match_dup 5))))
16374 (use (match_dup 6))
16375 (use (match_dup 3))
16376 (clobber (match_dup 0))
16377 (clobber (match_dup 1))
16378 (clobber (match_dup 2))])])
16380 ;; ...and this one handles cmpstrn*_1.
16383 (set (reg:CC FLAGS_REG)
16384 (if_then_else:CC (ne (match_operand 6 "register_operand")
16386 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16387 (mem:BLK (match_operand 5 "register_operand")))
16389 (use (match_operand:SI 3 "immediate_operand"))
16390 (use (reg:CC FLAGS_REG))
16391 (clobber (match_operand 0 "register_operand"))
16392 (clobber (match_operand 1 "register_operand"))
16393 (clobber (match_operand 2 "register_operand"))])
16394 (set (match_operand:QI 7 "register_operand")
16395 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16396 (set (match_operand:QI 8 "register_operand")
16397 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16398 (set (reg FLAGS_REG)
16399 (compare (match_dup 7) (match_dup 8)))
16401 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16403 (set (reg:CC FLAGS_REG)
16404 (if_then_else:CC (ne (match_dup 6)
16406 (compare:CC (mem:BLK (match_dup 4))
16407 (mem:BLK (match_dup 5)))
16409 (use (match_dup 3))
16410 (use (reg:CC FLAGS_REG))
16411 (clobber (match_dup 0))
16412 (clobber (match_dup 1))
16413 (clobber (match_dup 2))])])
16415 ;; Conditional move instructions.
16417 (define_expand "mov<mode>cc"
16418 [(set (match_operand:SWIM 0 "register_operand")
16419 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator")
16420 (match_operand:SWIM 2 "<general_operand>")
16421 (match_operand:SWIM 3 "<general_operand>")))]
16423 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16425 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16426 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16427 ;; So just document what we're doing explicitly.
16429 (define_expand "x86_mov<mode>cc_0_m1"
16431 [(set (match_operand:SWI48 0 "register_operand")
16432 (if_then_else:SWI48
16433 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16434 [(match_operand 1 "flags_reg_operand")
16438 (clobber (reg:CC FLAGS_REG))])])
16440 (define_insn "*x86_mov<mode>cc_0_m1"
16441 [(set (match_operand:SWI48 0 "register_operand" "=r")
16442 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16443 [(reg FLAGS_REG) (const_int 0)])
16446 (clobber (reg:CC FLAGS_REG))]
16448 "sbb{<imodesuffix>}\t%0, %0"
16449 ; Since we don't have the proper number of operands for an alu insn,
16450 ; fill in all the blanks.
16451 [(set_attr "type" "alu")
16452 (set_attr "use_carry" "1")
16453 (set_attr "pent_pair" "pu")
16454 (set_attr "memory" "none")
16455 (set_attr "imm_disp" "false")
16456 (set_attr "mode" "<MODE>")
16457 (set_attr "length_immediate" "0")])
16459 (define_insn "*x86_mov<mode>cc_0_m1_se"
16460 [(set (match_operand:SWI48 0 "register_operand" "=r")
16461 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16462 [(reg FLAGS_REG) (const_int 0)])
16465 (clobber (reg:CC FLAGS_REG))]
16467 "sbb{<imodesuffix>}\t%0, %0"
16468 [(set_attr "type" "alu")
16469 (set_attr "use_carry" "1")
16470 (set_attr "pent_pair" "pu")
16471 (set_attr "memory" "none")
16472 (set_attr "imm_disp" "false")
16473 (set_attr "mode" "<MODE>")
16474 (set_attr "length_immediate" "0")])
16476 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16477 [(set (match_operand:SWI48 0 "register_operand" "=r")
16478 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16479 [(reg FLAGS_REG) (const_int 0)])))
16480 (clobber (reg:CC FLAGS_REG))]
16482 "sbb{<imodesuffix>}\t%0, %0"
16483 [(set_attr "type" "alu")
16484 (set_attr "use_carry" "1")
16485 (set_attr "pent_pair" "pu")
16486 (set_attr "memory" "none")
16487 (set_attr "imm_disp" "false")
16488 (set_attr "mode" "<MODE>")
16489 (set_attr "length_immediate" "0")])
16491 (define_insn "*mov<mode>cc_noc"
16492 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16493 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16494 [(reg FLAGS_REG) (const_int 0)])
16495 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16496 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16497 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16499 cmov%O2%C1\t{%2, %0|%0, %2}
16500 cmov%O2%c1\t{%3, %0|%0, %3}"
16501 [(set_attr "type" "icmov")
16502 (set_attr "mode" "<MODE>")])
16504 (define_insn_and_split "*movqicc_noc"
16505 [(set (match_operand:QI 0 "register_operand" "=r,r")
16506 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16507 [(match_operand 4 "flags_reg_operand")
16509 (match_operand:QI 2 "register_operand" "r,0")
16510 (match_operand:QI 3 "register_operand" "0,r")))]
16511 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16513 "&& reload_completed"
16514 [(set (match_dup 0)
16515 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16518 "operands[0] = gen_lowpart (SImode, operands[0]);
16519 operands[2] = gen_lowpart (SImode, operands[2]);
16520 operands[3] = gen_lowpart (SImode, operands[3]);"
16521 [(set_attr "type" "icmov")
16522 (set_attr "mode" "SI")])
16524 (define_expand "mov<mode>cc"
16525 [(set (match_operand:X87MODEF 0 "register_operand")
16526 (if_then_else:X87MODEF
16527 (match_operand 1 "ix86_fp_comparison_operator")
16528 (match_operand:X87MODEF 2 "register_operand")
16529 (match_operand:X87MODEF 3 "register_operand")))]
16530 "(TARGET_80387 && TARGET_CMOVE)
16531 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16532 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16534 (define_insn "*movxfcc_1"
16535 [(set (match_operand:XF 0 "register_operand" "=f,f")
16536 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16537 [(reg FLAGS_REG) (const_int 0)])
16538 (match_operand:XF 2 "register_operand" "f,0")
16539 (match_operand:XF 3 "register_operand" "0,f")))]
16540 "TARGET_80387 && TARGET_CMOVE"
16542 fcmov%F1\t{%2, %0|%0, %2}
16543 fcmov%f1\t{%3, %0|%0, %3}"
16544 [(set_attr "type" "fcmov")
16545 (set_attr "mode" "XF")])
16547 (define_insn "*movdfcc_1_rex64"
16548 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16549 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16550 [(reg FLAGS_REG) (const_int 0)])
16551 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16552 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16553 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16554 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16556 fcmov%F1\t{%2, %0|%0, %2}
16557 fcmov%f1\t{%3, %0|%0, %3}
16558 cmov%O2%C1\t{%2, %0|%0, %2}
16559 cmov%O2%c1\t{%3, %0|%0, %3}"
16560 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16561 (set_attr "mode" "DF,DF,DI,DI")])
16563 (define_insn "*movdfcc_1"
16564 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16565 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16566 [(reg FLAGS_REG) (const_int 0)])
16567 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16568 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16569 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16570 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16572 fcmov%F1\t{%2, %0|%0, %2}
16573 fcmov%f1\t{%3, %0|%0, %3}
16576 [(set_attr "type" "fcmov,fcmov,multi,multi")
16577 (set_attr "mode" "DF,DF,DI,DI")])
16580 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16581 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16582 [(match_operand 4 "flags_reg_operand")
16584 (match_operand:DF 2 "nonimmediate_operand")
16585 (match_operand:DF 3 "nonimmediate_operand")))]
16586 "!TARGET_64BIT && reload_completed"
16587 [(set (match_dup 2)
16588 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16592 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16596 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16597 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16600 (define_insn "*movsfcc_1_387"
16601 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16602 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16603 [(reg FLAGS_REG) (const_int 0)])
16604 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16605 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16606 "TARGET_80387 && TARGET_CMOVE
16607 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16609 fcmov%F1\t{%2, %0|%0, %2}
16610 fcmov%f1\t{%3, %0|%0, %3}
16611 cmov%O2%C1\t{%2, %0|%0, %2}
16612 cmov%O2%c1\t{%3, %0|%0, %3}"
16613 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16614 (set_attr "mode" "SF,SF,SI,SI")])
16616 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16617 ;; the scalar versions to have only XMM registers as operands.
16619 ;; XOP conditional move
16620 (define_insn "*xop_pcmov_<mode>"
16621 [(set (match_operand:MODEF 0 "register_operand" "=x")
16622 (if_then_else:MODEF
16623 (match_operand:MODEF 1 "register_operand" "x")
16624 (match_operand:MODEF 2 "register_operand" "x")
16625 (match_operand:MODEF 3 "register_operand" "x")))]
16627 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16628 [(set_attr "type" "sse4arg")])
16630 ;; These versions of the min/max patterns are intentionally ignorant of
16631 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16632 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16633 ;; are undefined in this condition, we're certain this is correct.
16635 (define_insn "<code><mode>3"
16636 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16638 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16639 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16640 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16642 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16643 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16644 [(set_attr "isa" "noavx,avx")
16645 (set_attr "prefix" "orig,vex")
16646 (set_attr "type" "sseadd")
16647 (set_attr "mode" "<MODE>")])
16649 ;; These versions of the min/max patterns implement exactly the operations
16650 ;; min = (op1 < op2 ? op1 : op2)
16651 ;; max = (!(op1 < op2) ? op1 : op2)
16652 ;; Their operands are not commutative, and thus they may be used in the
16653 ;; presence of -0.0 and NaN.
16655 (define_insn "*ieee_smin<mode>3"
16656 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16658 [(match_operand:MODEF 1 "register_operand" "0,x")
16659 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16661 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16663 min<ssemodesuffix>\t{%2, %0|%0, %2}
16664 vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16665 [(set_attr "isa" "noavx,avx")
16666 (set_attr "prefix" "orig,vex")
16667 (set_attr "type" "sseadd")
16668 (set_attr "mode" "<MODE>")])
16670 (define_insn "*ieee_smax<mode>3"
16671 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16673 [(match_operand:MODEF 1 "register_operand" "0,x")
16674 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16676 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16678 max<ssemodesuffix>\t{%2, %0|%0, %2}
16679 vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16680 [(set_attr "isa" "noavx,avx")
16681 (set_attr "prefix" "orig,vex")
16682 (set_attr "type" "sseadd")
16683 (set_attr "mode" "<MODE>")])
16685 ;; Make two stack loads independent:
16687 ;; fld %st(0) -> fld bb
16688 ;; fmul bb fmul %st(1), %st
16690 ;; Actually we only match the last two instructions for simplicity.
16692 [(set (match_operand 0 "fp_register_operand")
16693 (match_operand 1 "fp_register_operand"))
16695 (match_operator 2 "binary_fp_operator"
16697 (match_operand 3 "memory_operand")]))]
16698 "REGNO (operands[0]) != REGNO (operands[1])"
16699 [(set (match_dup 0) (match_dup 3))
16700 (set (match_dup 0) (match_dup 4))]
16702 ;; The % modifier is not operational anymore in peephole2's, so we have to
16703 ;; swap the operands manually in the case of addition and multiplication.
16707 if (COMMUTATIVE_ARITH_P (operands[2]))
16708 op0 = operands[0], op1 = operands[1];
16710 op0 = operands[1], op1 = operands[0];
16712 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16713 GET_MODE (operands[2]),
16717 ;; Conditional addition patterns
16718 (define_expand "add<mode>cc"
16719 [(match_operand:SWI 0 "register_operand")
16720 (match_operand 1 "ordered_comparison_operator")
16721 (match_operand:SWI 2 "register_operand")
16722 (match_operand:SWI 3 "const_int_operand")]
16724 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16726 ;; Misc patterns (?)
16728 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16729 ;; Otherwise there will be nothing to keep
16731 ;; [(set (reg ebp) (reg esp))]
16732 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16733 ;; (clobber (eflags)]
16734 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16736 ;; in proper program order.
16738 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16739 [(set (match_operand:P 0 "register_operand" "=r,r")
16740 (plus:P (match_operand:P 1 "register_operand" "0,r")
16741 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16742 (clobber (reg:CC FLAGS_REG))
16743 (clobber (mem:BLK (scratch)))]
16746 switch (get_attr_type (insn))
16749 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16752 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16753 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16754 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16756 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16759 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16760 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16763 [(set (attr "type")
16764 (cond [(and (eq_attr "alternative" "0")
16765 (not (match_test "TARGET_OPT_AGU")))
16766 (const_string "alu")
16767 (match_operand:<MODE> 2 "const0_operand")
16768 (const_string "imov")
16770 (const_string "lea")))
16771 (set (attr "length_immediate")
16772 (cond [(eq_attr "type" "imov")
16774 (and (eq_attr "type" "alu")
16775 (match_operand 2 "const128_operand"))
16778 (const_string "*")))
16779 (set_attr "mode" "<MODE>")])
16781 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16782 [(set (match_operand:P 0 "register_operand" "=r")
16783 (minus:P (match_operand:P 1 "register_operand" "0")
16784 (match_operand:P 2 "register_operand" "r")))
16785 (clobber (reg:CC FLAGS_REG))
16786 (clobber (mem:BLK (scratch)))]
16788 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16789 [(set_attr "type" "alu")
16790 (set_attr "mode" "<MODE>")])
16792 (define_insn "allocate_stack_worker_probe_<mode>"
16793 [(set (match_operand:P 0 "register_operand" "=a")
16794 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16795 UNSPECV_STACK_PROBE))
16796 (clobber (reg:CC FLAGS_REG))]
16797 "ix86_target_stack_probe ()"
16798 "call\t___chkstk_ms"
16799 [(set_attr "type" "multi")
16800 (set_attr "length" "5")])
16802 (define_expand "allocate_stack"
16803 [(match_operand 0 "register_operand")
16804 (match_operand 1 "general_operand")]
16805 "ix86_target_stack_probe ()"
16809 #ifndef CHECK_STACK_LIMIT
16810 #define CHECK_STACK_LIMIT 0
16813 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16814 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16818 rtx (*insn) (rtx, rtx);
16820 x = copy_to_mode_reg (Pmode, operands[1]);
16822 insn = (TARGET_64BIT
16823 ? gen_allocate_stack_worker_probe_di
16824 : gen_allocate_stack_worker_probe_si);
16826 emit_insn (insn (x, x));
16829 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16830 stack_pointer_rtx, 0, OPTAB_DIRECT);
16832 if (x != stack_pointer_rtx)
16833 emit_move_insn (stack_pointer_rtx, x);
16835 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16839 ;; Use IOR for stack probes, this is shorter.
16840 (define_expand "probe_stack"
16841 [(match_operand 0 "memory_operand")]
16844 rtx (*gen_ior3) (rtx, rtx, rtx);
16846 gen_ior3 = (GET_MODE (operands[0]) == DImode
16847 ? gen_iordi3 : gen_iorsi3);
16849 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16853 (define_insn "adjust_stack_and_probe<mode>"
16854 [(set (match_operand:P 0 "register_operand" "=r")
16855 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16856 UNSPECV_PROBE_STACK_RANGE))
16857 (set (reg:P SP_REG)
16858 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16859 (clobber (reg:CC FLAGS_REG))
16860 (clobber (mem:BLK (scratch)))]
16862 "* return output_adjust_stack_and_probe (operands[0]);"
16863 [(set_attr "type" "multi")])
16865 (define_insn "probe_stack_range<mode>"
16866 [(set (match_operand:P 0 "register_operand" "=r")
16867 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16868 (match_operand:P 2 "const_int_operand" "n")]
16869 UNSPECV_PROBE_STACK_RANGE))
16870 (clobber (reg:CC FLAGS_REG))]
16872 "* return output_probe_stack_range (operands[0], operands[2]);"
16873 [(set_attr "type" "multi")])
16875 (define_expand "builtin_setjmp_receiver"
16876 [(label_ref (match_operand 0))]
16877 "!TARGET_64BIT && flag_pic"
16883 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16884 rtx label_rtx = gen_label_rtx ();
16885 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16886 xops[0] = xops[1] = picreg;
16887 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16888 ix86_expand_binary_operator (MINUS, SImode, xops);
16892 emit_insn (gen_set_got (pic_offset_table_rtx));
16896 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16899 [(set (match_operand 0 "register_operand")
16900 (match_operator 3 "promotable_binary_operator"
16901 [(match_operand 1 "register_operand")
16902 (match_operand 2 "aligned_operand")]))
16903 (clobber (reg:CC FLAGS_REG))]
16904 "! TARGET_PARTIAL_REG_STALL && reload_completed
16905 && ((GET_MODE (operands[0]) == HImode
16906 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16907 /* ??? next two lines just !satisfies_constraint_K (...) */
16908 || !CONST_INT_P (operands[2])
16909 || satisfies_constraint_K (operands[2])))
16910 || (GET_MODE (operands[0]) == QImode
16911 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16912 [(parallel [(set (match_dup 0)
16913 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16914 (clobber (reg:CC FLAGS_REG))])]
16916 operands[0] = gen_lowpart (SImode, operands[0]);
16917 operands[1] = gen_lowpart (SImode, operands[1]);
16918 if (GET_CODE (operands[3]) != ASHIFT)
16919 operands[2] = gen_lowpart (SImode, operands[2]);
16920 PUT_MODE (operands[3], SImode);
16923 ; Promote the QImode tests, as i386 has encoding of the AND
16924 ; instruction with 32-bit sign-extended immediate and thus the
16925 ; instruction size is unchanged, except in the %eax case for
16926 ; which it is increased by one byte, hence the ! optimize_size.
16928 [(set (match_operand 0 "flags_reg_operand")
16929 (match_operator 2 "compare_operator"
16930 [(and (match_operand 3 "aligned_operand")
16931 (match_operand 4 "const_int_operand"))
16933 (set (match_operand 1 "register_operand")
16934 (and (match_dup 3) (match_dup 4)))]
16935 "! TARGET_PARTIAL_REG_STALL && reload_completed
16936 && optimize_insn_for_speed_p ()
16937 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16938 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16939 /* Ensure that the operand will remain sign-extended immediate. */
16940 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16941 [(parallel [(set (match_dup 0)
16942 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16945 (and:SI (match_dup 3) (match_dup 4)))])]
16948 = gen_int_mode (INTVAL (operands[4])
16949 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16950 operands[1] = gen_lowpart (SImode, operands[1]);
16951 operands[3] = gen_lowpart (SImode, operands[3]);
16954 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16955 ; the TEST instruction with 32-bit sign-extended immediate and thus
16956 ; the instruction size would at least double, which is not what we
16957 ; want even with ! optimize_size.
16959 [(set (match_operand 0 "flags_reg_operand")
16960 (match_operator 1 "compare_operator"
16961 [(and (match_operand:HI 2 "aligned_operand")
16962 (match_operand:HI 3 "const_int_operand"))
16964 "! TARGET_PARTIAL_REG_STALL && reload_completed
16965 && ! TARGET_FAST_PREFIX
16966 && optimize_insn_for_speed_p ()
16967 /* Ensure that the operand will remain sign-extended immediate. */
16968 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16969 [(set (match_dup 0)
16970 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16974 = gen_int_mode (INTVAL (operands[3])
16975 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16976 operands[2] = gen_lowpart (SImode, operands[2]);
16980 [(set (match_operand 0 "register_operand")
16981 (neg (match_operand 1 "register_operand")))
16982 (clobber (reg:CC FLAGS_REG))]
16983 "! TARGET_PARTIAL_REG_STALL && reload_completed
16984 && (GET_MODE (operands[0]) == HImode
16985 || (GET_MODE (operands[0]) == QImode
16986 && (TARGET_PROMOTE_QImode
16987 || optimize_insn_for_size_p ())))"
16988 [(parallel [(set (match_dup 0)
16989 (neg:SI (match_dup 1)))
16990 (clobber (reg:CC FLAGS_REG))])]
16992 operands[0] = gen_lowpart (SImode, operands[0]);
16993 operands[1] = gen_lowpart (SImode, operands[1]);
16997 [(set (match_operand 0 "register_operand")
16998 (not (match_operand 1 "register_operand")))]
16999 "! TARGET_PARTIAL_REG_STALL && reload_completed
17000 && (GET_MODE (operands[0]) == HImode
17001 || (GET_MODE (operands[0]) == QImode
17002 && (TARGET_PROMOTE_QImode
17003 || optimize_insn_for_size_p ())))"
17004 [(set (match_dup 0)
17005 (not:SI (match_dup 1)))]
17007 operands[0] = gen_lowpart (SImode, operands[0]);
17008 operands[1] = gen_lowpart (SImode, operands[1]);
17012 [(set (match_operand 0 "register_operand")
17013 (if_then_else (match_operator 1 "ordered_comparison_operator"
17014 [(reg FLAGS_REG) (const_int 0)])
17015 (match_operand 2 "register_operand")
17016 (match_operand 3 "register_operand")))]
17017 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
17018 && (GET_MODE (operands[0]) == HImode
17019 || (GET_MODE (operands[0]) == QImode
17020 && (TARGET_PROMOTE_QImode
17021 || optimize_insn_for_size_p ())))"
17022 [(set (match_dup 0)
17023 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
17025 operands[0] = gen_lowpart (SImode, operands[0]);
17026 operands[2] = gen_lowpart (SImode, operands[2]);
17027 operands[3] = gen_lowpart (SImode, operands[3]);
17030 ;; RTL Peephole optimizations, run before sched2. These primarily look to
17031 ;; transform a complex memory operation into two memory to register operations.
17033 ;; Don't push memory operands
17035 [(set (match_operand:SWI 0 "push_operand")
17036 (match_operand:SWI 1 "memory_operand"))
17037 (match_scratch:SWI 2 "<r>")]
17038 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17039 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17040 [(set (match_dup 2) (match_dup 1))
17041 (set (match_dup 0) (match_dup 2))])
17043 ;; We need to handle SFmode only, because DFmode and XFmode are split to
17046 [(set (match_operand:SF 0 "push_operand")
17047 (match_operand:SF 1 "memory_operand"))
17048 (match_scratch:SF 2 "r")]
17049 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
17050 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
17051 [(set (match_dup 2) (match_dup 1))
17052 (set (match_dup 0) (match_dup 2))])
17054 ;; Don't move an immediate directly to memory when the instruction
17055 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
17057 [(match_scratch:SWI124 1 "<r>")
17058 (set (match_operand:SWI124 0 "memory_operand")
17060 "optimize_insn_for_speed_p ()
17061 && ((<MODE>mode == HImode
17062 && TARGET_LCP_STALL)
17063 || (!TARGET_USE_MOV0
17064 && TARGET_SPLIT_LONG_MOVES
17065 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
17066 && peep2_regno_dead_p (0, FLAGS_REG)"
17067 [(parallel [(set (match_dup 2) (const_int 0))
17068 (clobber (reg:CC FLAGS_REG))])
17069 (set (match_dup 0) (match_dup 1))]
17070 "operands[2] = gen_lowpart (SImode, operands[1]);")
17073 [(match_scratch:SWI124 2 "<r>")
17074 (set (match_operand:SWI124 0 "memory_operand")
17075 (match_operand:SWI124 1 "immediate_operand"))]
17076 "optimize_insn_for_speed_p ()
17077 && ((<MODE>mode == HImode
17078 && TARGET_LCP_STALL)
17079 || (TARGET_SPLIT_LONG_MOVES
17080 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
17081 [(set (match_dup 2) (match_dup 1))
17082 (set (match_dup 0) (match_dup 2))])
17084 ;; Don't compare memory with zero, load and use a test instead.
17086 [(set (match_operand 0 "flags_reg_operand")
17087 (match_operator 1 "compare_operator"
17088 [(match_operand:SI 2 "memory_operand")
17090 (match_scratch:SI 3 "r")]
17091 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17092 [(set (match_dup 3) (match_dup 2))
17093 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17095 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17096 ;; Don't split NOTs with a displacement operand, because resulting XOR
17097 ;; will not be pairable anyway.
17099 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17100 ;; represented using a modRM byte. The XOR replacement is long decoded,
17101 ;; so this split helps here as well.
17103 ;; Note: Can't do this as a regular split because we can't get proper
17104 ;; lifetime information then.
17107 [(set (match_operand:SWI124 0 "nonimmediate_operand")
17108 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
17109 "optimize_insn_for_speed_p ()
17110 && ((TARGET_NOT_UNPAIRABLE
17111 && (!MEM_P (operands[0])
17112 || !memory_displacement_operand (operands[0], <MODE>mode)))
17113 || (TARGET_NOT_VECTORMODE
17114 && long_memory_operand (operands[0], <MODE>mode)))
17115 && peep2_regno_dead_p (0, FLAGS_REG)"
17116 [(parallel [(set (match_dup 0)
17117 (xor:SWI124 (match_dup 1) (const_int -1)))
17118 (clobber (reg:CC FLAGS_REG))])])
17120 ;; Non pairable "test imm, reg" instructions can be translated to
17121 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17122 ;; byte opcode instead of two, have a short form for byte operands),
17123 ;; so do it for other CPUs as well. Given that the value was dead,
17124 ;; this should not create any new dependencies. Pass on the sub-word
17125 ;; versions if we're concerned about partial register stalls.
17128 [(set (match_operand 0 "flags_reg_operand")
17129 (match_operator 1 "compare_operator"
17130 [(and:SI (match_operand:SI 2 "register_operand")
17131 (match_operand:SI 3 "immediate_operand"))
17133 "ix86_match_ccmode (insn, CCNOmode)
17134 && (true_regnum (operands[2]) != AX_REG
17135 || satisfies_constraint_K (operands[3]))
17136 && peep2_reg_dead_p (1, operands[2])"
17138 [(set (match_dup 0)
17139 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17142 (and:SI (match_dup 2) (match_dup 3)))])])
17144 ;; We don't need to handle HImode case, because it will be promoted to SImode
17145 ;; on ! TARGET_PARTIAL_REG_STALL
17148 [(set (match_operand 0 "flags_reg_operand")
17149 (match_operator 1 "compare_operator"
17150 [(and:QI (match_operand:QI 2 "register_operand")
17151 (match_operand:QI 3 "immediate_operand"))
17153 "! TARGET_PARTIAL_REG_STALL
17154 && ix86_match_ccmode (insn, CCNOmode)
17155 && true_regnum (operands[2]) != AX_REG
17156 && peep2_reg_dead_p (1, operands[2])"
17158 [(set (match_dup 0)
17159 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17162 (and:QI (match_dup 2) (match_dup 3)))])])
17165 [(set (match_operand 0 "flags_reg_operand")
17166 (match_operator 1 "compare_operator"
17169 (match_operand 2 "ext_register_operand")
17172 (match_operand 3 "const_int_operand"))
17174 "! TARGET_PARTIAL_REG_STALL
17175 && ix86_match_ccmode (insn, CCNOmode)
17176 && true_regnum (operands[2]) != AX_REG
17177 && peep2_reg_dead_p (1, operands[2])"
17178 [(parallel [(set (match_dup 0)
17187 (set (zero_extract:SI (match_dup 2)
17195 (match_dup 3)))])])
17197 ;; Don't do logical operations with memory inputs.
17199 [(match_scratch:SI 2 "r")
17200 (parallel [(set (match_operand:SI 0 "register_operand")
17201 (match_operator:SI 3 "arith_or_logical_operator"
17203 (match_operand:SI 1 "memory_operand")]))
17204 (clobber (reg:CC FLAGS_REG))])]
17205 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17206 [(set (match_dup 2) (match_dup 1))
17207 (parallel [(set (match_dup 0)
17208 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17209 (clobber (reg:CC FLAGS_REG))])])
17212 [(match_scratch:SI 2 "r")
17213 (parallel [(set (match_operand:SI 0 "register_operand")
17214 (match_operator:SI 3 "arith_or_logical_operator"
17215 [(match_operand:SI 1 "memory_operand")
17217 (clobber (reg:CC FLAGS_REG))])]
17218 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17219 [(set (match_dup 2) (match_dup 1))
17220 (parallel [(set (match_dup 0)
17221 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17222 (clobber (reg:CC FLAGS_REG))])])
17224 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17225 ;; refers to the destination of the load!
17228 [(set (match_operand:SI 0 "register_operand")
17229 (match_operand:SI 1 "register_operand"))
17230 (parallel [(set (match_dup 0)
17231 (match_operator:SI 3 "commutative_operator"
17233 (match_operand:SI 2 "memory_operand")]))
17234 (clobber (reg:CC FLAGS_REG))])]
17235 "REGNO (operands[0]) != REGNO (operands[1])
17236 && GENERAL_REGNO_P (REGNO (operands[0]))
17237 && GENERAL_REGNO_P (REGNO (operands[1]))"
17238 [(set (match_dup 0) (match_dup 4))
17239 (parallel [(set (match_dup 0)
17240 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17241 (clobber (reg:CC FLAGS_REG))])]
17242 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17245 [(set (match_operand 0 "register_operand")
17246 (match_operand 1 "register_operand"))
17248 (match_operator 3 "commutative_operator"
17250 (match_operand 2 "memory_operand")]))]
17251 "REGNO (operands[0]) != REGNO (operands[1])
17252 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17253 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17254 [(set (match_dup 0) (match_dup 2))
17256 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17258 ; Don't do logical operations with memory outputs
17260 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17261 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17262 ; the same decoder scheduling characteristics as the original.
17265 [(match_scratch:SI 2 "r")
17266 (parallel [(set (match_operand:SI 0 "memory_operand")
17267 (match_operator:SI 3 "arith_or_logical_operator"
17269 (match_operand:SI 1 "nonmemory_operand")]))
17270 (clobber (reg:CC FLAGS_REG))])]
17271 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17272 /* Do not split stack checking probes. */
17273 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17274 [(set (match_dup 2) (match_dup 0))
17275 (parallel [(set (match_dup 2)
17276 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17277 (clobber (reg:CC FLAGS_REG))])
17278 (set (match_dup 0) (match_dup 2))])
17281 [(match_scratch:SI 2 "r")
17282 (parallel [(set (match_operand:SI 0 "memory_operand")
17283 (match_operator:SI 3 "arith_or_logical_operator"
17284 [(match_operand:SI 1 "nonmemory_operand")
17286 (clobber (reg:CC FLAGS_REG))])]
17287 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17288 /* Do not split stack checking probes. */
17289 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17290 [(set (match_dup 2) (match_dup 0))
17291 (parallel [(set (match_dup 2)
17292 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17293 (clobber (reg:CC FLAGS_REG))])
17294 (set (match_dup 0) (match_dup 2))])
17296 ;; Attempt to use arith or logical operations with memory outputs with
17297 ;; setting of flags.
17299 [(set (match_operand:SWI 0 "register_operand")
17300 (match_operand:SWI 1 "memory_operand"))
17301 (parallel [(set (match_dup 0)
17302 (match_operator:SWI 3 "plusminuslogic_operator"
17304 (match_operand:SWI 2 "<nonmemory_operand>")]))
17305 (clobber (reg:CC FLAGS_REG))])
17306 (set (match_dup 1) (match_dup 0))
17307 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17308 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17309 && peep2_reg_dead_p (4, operands[0])
17310 && !reg_overlap_mentioned_p (operands[0], operands[1])
17311 && ix86_match_ccmode (peep2_next_insn (3),
17312 (GET_CODE (operands[3]) == PLUS
17313 || GET_CODE (operands[3]) == MINUS)
17314 ? CCGOCmode : CCNOmode)"
17315 [(parallel [(set (match_dup 4) (match_dup 5))
17316 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17317 (match_dup 2)]))])]
17319 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17320 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17321 copy_rtx (operands[1]),
17322 copy_rtx (operands[2]));
17323 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17324 operands[5], const0_rtx);
17328 [(parallel [(set (match_operand:SWI 0 "register_operand")
17329 (match_operator:SWI 2 "plusminuslogic_operator"
17331 (match_operand:SWI 1 "memory_operand")]))
17332 (clobber (reg:CC FLAGS_REG))])
17333 (set (match_dup 1) (match_dup 0))
17334 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17335 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17336 && GET_CODE (operands[2]) != MINUS
17337 && peep2_reg_dead_p (3, operands[0])
17338 && !reg_overlap_mentioned_p (operands[0], operands[1])
17339 && ix86_match_ccmode (peep2_next_insn (2),
17340 GET_CODE (operands[2]) == PLUS
17341 ? CCGOCmode : CCNOmode)"
17342 [(parallel [(set (match_dup 3) (match_dup 4))
17343 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17344 (match_dup 0)]))])]
17346 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17347 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17348 copy_rtx (operands[1]),
17349 copy_rtx (operands[0]));
17350 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17351 operands[4], const0_rtx);
17355 [(set (match_operand:SWI12 0 "register_operand")
17356 (match_operand:SWI12 1 "memory_operand"))
17357 (parallel [(set (match_operand:SI 4 "register_operand")
17358 (match_operator:SI 3 "plusminuslogic_operator"
17360 (match_operand:SI 2 "nonmemory_operand")]))
17361 (clobber (reg:CC FLAGS_REG))])
17362 (set (match_dup 1) (match_dup 0))
17363 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17364 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17365 && REG_P (operands[0]) && REG_P (operands[4])
17366 && REGNO (operands[0]) == REGNO (operands[4])
17367 && peep2_reg_dead_p (4, operands[0])
17368 && (<MODE>mode != QImode
17369 || immediate_operand (operands[2], SImode)
17370 || q_regs_operand (operands[2], SImode))
17371 && !reg_overlap_mentioned_p (operands[0], operands[1])
17372 && ix86_match_ccmode (peep2_next_insn (3),
17373 (GET_CODE (operands[3]) == PLUS
17374 || GET_CODE (operands[3]) == MINUS)
17375 ? CCGOCmode : CCNOmode)"
17376 [(parallel [(set (match_dup 4) (match_dup 5))
17377 (set (match_dup 1) (match_dup 6))])]
17379 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17380 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17381 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17382 copy_rtx (operands[1]), operands[2]);
17383 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17384 operands[5], const0_rtx);
17385 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17386 copy_rtx (operands[1]),
17387 copy_rtx (operands[2]));
17390 ;; Attempt to always use XOR for zeroing registers.
17392 [(set (match_operand 0 "register_operand")
17393 (match_operand 1 "const0_operand"))]
17394 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17395 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17396 && GENERAL_REG_P (operands[0])
17397 && peep2_regno_dead_p (0, FLAGS_REG)"
17398 [(parallel [(set (match_dup 0) (const_int 0))
17399 (clobber (reg:CC FLAGS_REG))])]
17400 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17403 [(set (strict_low_part (match_operand 0 "register_operand"))
17405 "(GET_MODE (operands[0]) == QImode
17406 || GET_MODE (operands[0]) == HImode)
17407 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17408 && peep2_regno_dead_p (0, FLAGS_REG)"
17409 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17410 (clobber (reg:CC FLAGS_REG))])])
17412 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17414 [(set (match_operand:SWI248 0 "register_operand")
17416 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17417 && peep2_regno_dead_p (0, FLAGS_REG)"
17418 [(parallel [(set (match_dup 0) (const_int -1))
17419 (clobber (reg:CC FLAGS_REG))])]
17421 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17422 operands[0] = gen_lowpart (SImode, operands[0]);
17425 ;; Attempt to convert simple lea to add/shift.
17426 ;; These can be created by move expanders.
17429 [(set (match_operand:SWI48 0 "register_operand")
17430 (plus:SWI48 (match_dup 0)
17431 (match_operand:SWI48 1 "<nonmemory_operand>")))]
17432 "peep2_regno_dead_p (0, FLAGS_REG)"
17433 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17434 (clobber (reg:CC FLAGS_REG))])])
17437 [(set (match_operand:SI 0 "register_operand")
17438 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand")
17439 (match_operand:DI 2 "nonmemory_operand")) 0))]
17441 && peep2_regno_dead_p (0, FLAGS_REG)
17442 && REGNO (operands[0]) == REGNO (operands[1])"
17443 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17444 (clobber (reg:CC FLAGS_REG))])]
17445 "operands[2] = gen_lowpart (SImode, operands[2]);")
17448 [(set (match_operand:SWI48 0 "register_operand")
17449 (mult:SWI48 (match_dup 0)
17450 (match_operand:SWI48 1 "const_int_operand")))]
17451 "exact_log2 (INTVAL (operands[1])) >= 0
17452 && peep2_regno_dead_p (0, FLAGS_REG)"
17453 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17454 (clobber (reg:CC FLAGS_REG))])]
17455 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17458 [(set (match_operand:SI 0 "register_operand")
17459 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand")
17460 (match_operand:DI 2 "const_int_operand")) 0))]
17462 && exact_log2 (INTVAL (operands[2])) >= 0
17463 && REGNO (operands[0]) == REGNO (operands[1])
17464 && peep2_regno_dead_p (0, FLAGS_REG)"
17465 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17466 (clobber (reg:CC FLAGS_REG))])]
17467 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17469 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17470 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17471 ;; On many CPUs it is also faster, since special hardware to avoid esp
17472 ;; dependencies is present.
17474 ;; While some of these conversions may be done using splitters, we use
17475 ;; peepholes in order to allow combine_stack_adjustments pass to see
17476 ;; nonobfuscated RTL.
17478 ;; Convert prologue esp subtractions to push.
17479 ;; We need register to push. In order to keep verify_flow_info happy we have
17481 ;; - use scratch and clobber it in order to avoid dependencies
17482 ;; - use already live register
17483 ;; We can't use the second way right now, since there is no reliable way how to
17484 ;; verify that given register is live. First choice will also most likely in
17485 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17486 ;; call clobbered registers are dead. We may want to use base pointer as an
17487 ;; alternative when no register is available later.
17490 [(match_scratch:W 1 "r")
17491 (parallel [(set (reg:P SP_REG)
17492 (plus:P (reg:P SP_REG)
17493 (match_operand:P 0 "const_int_operand")))
17494 (clobber (reg:CC FLAGS_REG))
17495 (clobber (mem:BLK (scratch)))])]
17496 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17497 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17498 [(clobber (match_dup 1))
17499 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17500 (clobber (mem:BLK (scratch)))])])
17503 [(match_scratch:W 1 "r")
17504 (parallel [(set (reg:P SP_REG)
17505 (plus:P (reg:P SP_REG)
17506 (match_operand:P 0 "const_int_operand")))
17507 (clobber (reg:CC FLAGS_REG))
17508 (clobber (mem:BLK (scratch)))])]
17509 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17510 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17511 [(clobber (match_dup 1))
17512 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17513 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17514 (clobber (mem:BLK (scratch)))])])
17516 ;; Convert esp subtractions to push.
17518 [(match_scratch:W 1 "r")
17519 (parallel [(set (reg:P SP_REG)
17520 (plus:P (reg:P SP_REG)
17521 (match_operand:P 0 "const_int_operand")))
17522 (clobber (reg:CC FLAGS_REG))])]
17523 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17524 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17525 [(clobber (match_dup 1))
17526 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17529 [(match_scratch:W 1 "r")
17530 (parallel [(set (reg:P SP_REG)
17531 (plus:P (reg:P SP_REG)
17532 (match_operand:P 0 "const_int_operand")))
17533 (clobber (reg:CC FLAGS_REG))])]
17534 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17535 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17536 [(clobber (match_dup 1))
17537 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17538 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17540 ;; Convert epilogue deallocator to pop.
17542 [(match_scratch:W 1 "r")
17543 (parallel [(set (reg:P SP_REG)
17544 (plus:P (reg:P SP_REG)
17545 (match_operand:P 0 "const_int_operand")))
17546 (clobber (reg:CC FLAGS_REG))
17547 (clobber (mem:BLK (scratch)))])]
17548 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17549 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17550 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17551 (clobber (mem:BLK (scratch)))])])
17553 ;; Two pops case is tricky, since pop causes dependency
17554 ;; on destination register. We use two registers if available.
17556 [(match_scratch:W 1 "r")
17557 (match_scratch:W 2 "r")
17558 (parallel [(set (reg:P SP_REG)
17559 (plus:P (reg:P SP_REG)
17560 (match_operand:P 0 "const_int_operand")))
17561 (clobber (reg:CC FLAGS_REG))
17562 (clobber (mem:BLK (scratch)))])]
17563 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17564 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17565 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17566 (clobber (mem:BLK (scratch)))])
17567 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17570 [(match_scratch:W 1 "r")
17571 (parallel [(set (reg:P SP_REG)
17572 (plus:P (reg:P SP_REG)
17573 (match_operand:P 0 "const_int_operand")))
17574 (clobber (reg:CC FLAGS_REG))
17575 (clobber (mem:BLK (scratch)))])]
17576 "optimize_insn_for_size_p ()
17577 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17578 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17579 (clobber (mem:BLK (scratch)))])
17580 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17582 ;; Convert esp additions to pop.
17584 [(match_scratch:W 1 "r")
17585 (parallel [(set (reg:P SP_REG)
17586 (plus:P (reg:P SP_REG)
17587 (match_operand:P 0 "const_int_operand")))
17588 (clobber (reg:CC FLAGS_REG))])]
17589 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17590 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17592 ;; Two pops case is tricky, since pop causes dependency
17593 ;; on destination register. We use two registers if available.
17595 [(match_scratch:W 1 "r")
17596 (match_scratch:W 2 "r")
17597 (parallel [(set (reg:P SP_REG)
17598 (plus:P (reg:P SP_REG)
17599 (match_operand:P 0 "const_int_operand")))
17600 (clobber (reg:CC FLAGS_REG))])]
17601 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17602 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17603 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17606 [(match_scratch:W 1 "r")
17607 (parallel [(set (reg:P SP_REG)
17608 (plus:P (reg:P SP_REG)
17609 (match_operand:P 0 "const_int_operand")))
17610 (clobber (reg:CC FLAGS_REG))])]
17611 "optimize_insn_for_size_p ()
17612 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17613 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17614 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17616 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17617 ;; required and register dies. Similarly for 128 to -128.
17619 [(set (match_operand 0 "flags_reg_operand")
17620 (match_operator 1 "compare_operator"
17621 [(match_operand 2 "register_operand")
17622 (match_operand 3 "const_int_operand")]))]
17623 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17624 && incdec_operand (operands[3], GET_MODE (operands[3])))
17625 || (!TARGET_FUSE_CMP_AND_BRANCH
17626 && INTVAL (operands[3]) == 128))
17627 && ix86_match_ccmode (insn, CCGCmode)
17628 && peep2_reg_dead_p (1, operands[2])"
17629 [(parallel [(set (match_dup 0)
17630 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17631 (clobber (match_dup 2))])])
17633 ;; Convert imul by three, five and nine into lea
17636 [(set (match_operand:SWI48 0 "register_operand")
17637 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
17638 (match_operand:SWI48 2 "const359_operand")))
17639 (clobber (reg:CC FLAGS_REG))])]
17640 "!TARGET_PARTIAL_REG_STALL
17641 || <MODE>mode == SImode
17642 || optimize_function_for_size_p (cfun)"
17643 [(set (match_dup 0)
17644 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17646 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17650 [(set (match_operand:SWI48 0 "register_operand")
17651 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17652 (match_operand:SWI48 2 "const359_operand")))
17653 (clobber (reg:CC FLAGS_REG))])]
17654 "optimize_insn_for_speed_p ()
17655 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17656 [(set (match_dup 0) (match_dup 1))
17658 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17660 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17662 ;; imul $32bit_imm, mem, reg is vector decoded, while
17663 ;; imul $32bit_imm, reg, reg is direct decoded.
17665 [(match_scratch:SWI48 3 "r")
17666 (parallel [(set (match_operand:SWI48 0 "register_operand")
17667 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
17668 (match_operand:SWI48 2 "immediate_operand")))
17669 (clobber (reg:CC FLAGS_REG))])]
17670 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17671 && !satisfies_constraint_K (operands[2])"
17672 [(set (match_dup 3) (match_dup 1))
17673 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17674 (clobber (reg:CC FLAGS_REG))])])
17677 [(match_scratch:SI 3 "r")
17678 (parallel [(set (match_operand:DI 0 "register_operand")
17680 (mult:SI (match_operand:SI 1 "memory_operand")
17681 (match_operand:SI 2 "immediate_operand"))))
17682 (clobber (reg:CC FLAGS_REG))])]
17684 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17685 && !satisfies_constraint_K (operands[2])"
17686 [(set (match_dup 3) (match_dup 1))
17687 (parallel [(set (match_dup 0)
17688 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17689 (clobber (reg:CC FLAGS_REG))])])
17691 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17692 ;; Convert it into imul reg, reg
17693 ;; It would be better to force assembler to encode instruction using long
17694 ;; immediate, but there is apparently no way to do so.
17696 [(parallel [(set (match_operand:SWI248 0 "register_operand")
17698 (match_operand:SWI248 1 "nonimmediate_operand")
17699 (match_operand:SWI248 2 "const_int_operand")))
17700 (clobber (reg:CC FLAGS_REG))])
17701 (match_scratch:SWI248 3 "r")]
17702 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17703 && satisfies_constraint_K (operands[2])"
17704 [(set (match_dup 3) (match_dup 2))
17705 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17706 (clobber (reg:CC FLAGS_REG))])]
17708 if (!rtx_equal_p (operands[0], operands[1]))
17709 emit_move_insn (operands[0], operands[1]);
17712 ;; After splitting up read-modify operations, array accesses with memory
17713 ;; operands might end up in form:
17715 ;; movl 4(%esp), %edx
17717 ;; instead of pre-splitting:
17719 ;; addl 4(%esp), %eax
17721 ;; movl 4(%esp), %edx
17722 ;; leal (%edx,%eax,4), %eax
17725 [(match_scratch:W 5 "r")
17726 (parallel [(set (match_operand 0 "register_operand")
17727 (ashift (match_operand 1 "register_operand")
17728 (match_operand 2 "const_int_operand")))
17729 (clobber (reg:CC FLAGS_REG))])
17730 (parallel [(set (match_operand 3 "register_operand")
17731 (plus (match_dup 0)
17732 (match_operand 4 "x86_64_general_operand")))
17733 (clobber (reg:CC FLAGS_REG))])]
17734 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17735 /* Validate MODE for lea. */
17736 && ((!TARGET_PARTIAL_REG_STALL
17737 && (GET_MODE (operands[0]) == QImode
17738 || GET_MODE (operands[0]) == HImode))
17739 || GET_MODE (operands[0]) == SImode
17740 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17741 && (rtx_equal_p (operands[0], operands[3])
17742 || peep2_reg_dead_p (2, operands[0]))
17743 /* We reorder load and the shift. */
17744 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17745 [(set (match_dup 5) (match_dup 4))
17746 (set (match_dup 0) (match_dup 1))]
17748 enum machine_mode op1mode = GET_MODE (operands[1]);
17749 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17750 int scale = 1 << INTVAL (operands[2]);
17751 rtx index = gen_lowpart (word_mode, operands[1]);
17752 rtx base = gen_lowpart (word_mode, operands[5]);
17753 rtx dest = gen_lowpart (mode, operands[3]);
17755 operands[1] = gen_rtx_PLUS (word_mode, base,
17756 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
17757 operands[5] = base;
17758 if (mode != word_mode)
17759 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17760 if (op1mode != word_mode)
17761 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17762 operands[0] = dest;
17765 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17766 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17767 ;; caught for use by garbage collectors and the like. Using an insn that
17768 ;; maps to SIGILL makes it more likely the program will rightfully die.
17769 ;; Keeping with tradition, "6" is in honor of #UD.
17770 (define_insn "trap"
17771 [(trap_if (const_int 1) (const_int 6))]
17773 { return ASM_SHORT "0x0b0f"; }
17774 [(set_attr "length" "2")])
17776 (define_expand "prefetch"
17777 [(prefetch (match_operand 0 "address_operand")
17778 (match_operand:SI 1 "const_int_operand")
17779 (match_operand:SI 2 "const_int_operand"))]
17780 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17782 int rw = INTVAL (operands[1]);
17783 int locality = INTVAL (operands[2]);
17785 gcc_assert (rw == 0 || rw == 1);
17786 gcc_assert (locality >= 0 && locality <= 3);
17787 gcc_assert (GET_MODE (operands[0]) == Pmode
17788 || GET_MODE (operands[0]) == VOIDmode);
17790 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17791 supported by SSE counterpart or the SSE prefetch is not available
17792 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17794 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17795 operands[2] = GEN_INT (3);
17797 operands[1] = const0_rtx;
17800 (define_insn "*prefetch_sse_<mode>"
17801 [(prefetch (match_operand:P 0 "address_operand" "p")
17803 (match_operand:SI 1 "const_int_operand"))]
17804 "TARGET_PREFETCH_SSE"
17806 static const char * const patterns[4] = {
17807 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17810 int locality = INTVAL (operands[1]);
17811 gcc_assert (locality >= 0 && locality <= 3);
17813 return patterns[locality];
17815 [(set_attr "type" "sse")
17816 (set_attr "atom_sse_attr" "prefetch")
17817 (set (attr "length_address")
17818 (symbol_ref "memory_address_length (operands[0])"))
17819 (set_attr "memory" "none")])
17821 (define_insn "*prefetch_3dnow_<mode>"
17822 [(prefetch (match_operand:P 0 "address_operand" "p")
17823 (match_operand:SI 1 "const_int_operand" "n")
17827 if (INTVAL (operands[1]) == 0)
17828 return "prefetch\t%a0";
17830 return "prefetchw\t%a0";
17832 [(set_attr "type" "mmx")
17833 (set (attr "length_address")
17834 (symbol_ref "memory_address_length (operands[0])"))
17835 (set_attr "memory" "none")])
17837 (define_expand "stack_protect_set"
17838 [(match_operand 0 "memory_operand")
17839 (match_operand 1 "memory_operand")]
17842 rtx (*insn)(rtx, rtx);
17844 #ifdef TARGET_THREAD_SSP_OFFSET
17845 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17846 insn = (TARGET_LP64
17847 ? gen_stack_tls_protect_set_di
17848 : gen_stack_tls_protect_set_si);
17850 insn = (TARGET_LP64
17851 ? gen_stack_protect_set_di
17852 : gen_stack_protect_set_si);
17855 emit_insn (insn (operands[0], operands[1]));
17859 (define_insn "stack_protect_set_<mode>"
17860 [(set (match_operand:PTR 0 "memory_operand" "=m")
17861 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17863 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17864 (clobber (reg:CC FLAGS_REG))]
17866 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17867 [(set_attr "type" "multi")])
17869 (define_insn "stack_tls_protect_set_<mode>"
17870 [(set (match_operand:PTR 0 "memory_operand" "=m")
17871 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17872 UNSPEC_SP_TLS_SET))
17873 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17874 (clobber (reg:CC FLAGS_REG))]
17876 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17877 [(set_attr "type" "multi")])
17879 (define_expand "stack_protect_test"
17880 [(match_operand 0 "memory_operand")
17881 (match_operand 1 "memory_operand")
17885 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17887 rtx (*insn)(rtx, rtx, rtx);
17889 #ifdef TARGET_THREAD_SSP_OFFSET
17890 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17891 insn = (TARGET_LP64
17892 ? gen_stack_tls_protect_test_di
17893 : gen_stack_tls_protect_test_si);
17895 insn = (TARGET_LP64
17896 ? gen_stack_protect_test_di
17897 : gen_stack_protect_test_si);
17900 emit_insn (insn (flags, operands[0], operands[1]));
17902 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17903 flags, const0_rtx, operands[2]));
17907 (define_insn "stack_protect_test_<mode>"
17908 [(set (match_operand:CCZ 0 "flags_reg_operand")
17909 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17910 (match_operand:PTR 2 "memory_operand" "m")]
17912 (clobber (match_scratch:PTR 3 "=&r"))]
17914 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17915 [(set_attr "type" "multi")])
17917 (define_insn "stack_tls_protect_test_<mode>"
17918 [(set (match_operand:CCZ 0 "flags_reg_operand")
17919 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17920 (match_operand:PTR 2 "const_int_operand" "i")]
17921 UNSPEC_SP_TLS_TEST))
17922 (clobber (match_scratch:PTR 3 "=r"))]
17924 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17925 [(set_attr "type" "multi")])
17927 (define_insn "sse4_2_crc32<mode>"
17928 [(set (match_operand:SI 0 "register_operand" "=r")
17930 [(match_operand:SI 1 "register_operand" "0")
17931 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17933 "TARGET_SSE4_2 || TARGET_CRC32"
17934 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17935 [(set_attr "type" "sselog1")
17936 (set_attr "prefix_rep" "1")
17937 (set_attr "prefix_extra" "1")
17938 (set (attr "prefix_data16")
17939 (if_then_else (match_operand:HI 2)
17941 (const_string "*")))
17942 (set (attr "prefix_rex")
17943 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
17945 (const_string "*")))
17946 (set_attr "mode" "SI")])
17948 (define_insn "sse4_2_crc32di"
17949 [(set (match_operand:DI 0 "register_operand" "=r")
17951 [(match_operand:DI 1 "register_operand" "0")
17952 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17954 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17955 "crc32{q}\t{%2, %0|%0, %2}"
17956 [(set_attr "type" "sselog1")
17957 (set_attr "prefix_rep" "1")
17958 (set_attr "prefix_extra" "1")
17959 (set_attr "mode" "DI")])
17961 (define_expand "rdpmc"
17962 [(match_operand:DI 0 "register_operand")
17963 (match_operand:SI 1 "register_operand")]
17966 rtx reg = gen_reg_rtx (DImode);
17969 /* Force operand 1 into ECX. */
17970 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17971 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17972 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17977 rtvec vec = rtvec_alloc (2);
17978 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17979 rtx upper = gen_reg_rtx (DImode);
17980 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17981 gen_rtvec (1, const0_rtx),
17983 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17984 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17986 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17987 NULL, 1, OPTAB_DIRECT);
17988 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17992 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17993 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17997 (define_insn "*rdpmc"
17998 [(set (match_operand:DI 0 "register_operand" "=A")
17999 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
18003 [(set_attr "type" "other")
18004 (set_attr "length" "2")])
18006 (define_insn "*rdpmc_rex64"
18007 [(set (match_operand:DI 0 "register_operand" "=a")
18008 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
18010 (set (match_operand:DI 1 "register_operand" "=d")
18011 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
18014 [(set_attr "type" "other")
18015 (set_attr "length" "2")])
18017 (define_expand "rdtsc"
18018 [(set (match_operand:DI 0 "register_operand")
18019 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18024 rtvec vec = rtvec_alloc (2);
18025 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18026 rtx upper = gen_reg_rtx (DImode);
18027 rtx lower = gen_reg_rtx (DImode);
18028 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
18029 gen_rtvec (1, const0_rtx),
18031 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
18032 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
18034 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18035 NULL, 1, OPTAB_DIRECT);
18036 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
18038 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
18043 (define_insn "*rdtsc"
18044 [(set (match_operand:DI 0 "register_operand" "=A")
18045 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18048 [(set_attr "type" "other")
18049 (set_attr "length" "2")])
18051 (define_insn "*rdtsc_rex64"
18052 [(set (match_operand:DI 0 "register_operand" "=a")
18053 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
18054 (set (match_operand:DI 1 "register_operand" "=d")
18055 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
18058 [(set_attr "type" "other")
18059 (set_attr "length" "2")])
18061 (define_expand "rdtscp"
18062 [(match_operand:DI 0 "register_operand")
18063 (match_operand:SI 1 "memory_operand")]
18066 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
18067 gen_rtvec (1, const0_rtx),
18069 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
18070 gen_rtvec (1, const0_rtx),
18072 rtx reg = gen_reg_rtx (DImode);
18073 rtx tmp = gen_reg_rtx (SImode);
18077 rtvec vec = rtvec_alloc (3);
18078 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18079 rtx upper = gen_reg_rtx (DImode);
18080 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18081 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18082 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
18084 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18085 NULL, 1, OPTAB_DIRECT);
18086 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18091 rtvec vec = rtvec_alloc (2);
18092 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18093 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18094 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
18097 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18098 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
18102 (define_insn "*rdtscp"
18103 [(set (match_operand:DI 0 "register_operand" "=A")
18104 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18105 (set (match_operand:SI 1 "register_operand" "=c")
18106 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18109 [(set_attr "type" "other")
18110 (set_attr "length" "3")])
18112 (define_insn "*rdtscp_rex64"
18113 [(set (match_operand:DI 0 "register_operand" "=a")
18114 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18115 (set (match_operand:DI 1 "register_operand" "=d")
18116 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18117 (set (match_operand:SI 2 "register_operand" "=c")
18118 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18121 [(set_attr "type" "other")
18122 (set_attr "length" "3")])
18124 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18126 ;; LWP instructions
18128 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18130 (define_expand "lwp_llwpcb"
18131 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18132 UNSPECV_LLWP_INTRINSIC)]
18135 (define_insn "*lwp_llwpcb<mode>1"
18136 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18137 UNSPECV_LLWP_INTRINSIC)]
18140 [(set_attr "type" "lwp")
18141 (set_attr "mode" "<MODE>")
18142 (set_attr "length" "5")])
18144 (define_expand "lwp_slwpcb"
18145 [(set (match_operand 0 "register_operand" "=r")
18146 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18151 insn = (Pmode == DImode
18153 : gen_lwp_slwpcbsi);
18155 emit_insn (insn (operands[0]));
18159 (define_insn "lwp_slwpcb<mode>"
18160 [(set (match_operand:P 0 "register_operand" "=r")
18161 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18164 [(set_attr "type" "lwp")
18165 (set_attr "mode" "<MODE>")
18166 (set_attr "length" "5")])
18168 (define_expand "lwp_lwpval<mode>3"
18169 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18170 (match_operand:SI 2 "nonimmediate_operand" "rm")
18171 (match_operand:SI 3 "const_int_operand" "i")]
18172 UNSPECV_LWPVAL_INTRINSIC)]
18174 ;; Avoid unused variable warning.
18175 "(void) operands[0];")
18177 (define_insn "*lwp_lwpval<mode>3_1"
18178 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18179 (match_operand:SI 1 "nonimmediate_operand" "rm")
18180 (match_operand:SI 2 "const_int_operand" "i")]
18181 UNSPECV_LWPVAL_INTRINSIC)]
18183 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18184 [(set_attr "type" "lwp")
18185 (set_attr "mode" "<MODE>")
18186 (set (attr "length")
18187 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18189 (define_expand "lwp_lwpins<mode>3"
18190 [(set (reg:CCC FLAGS_REG)
18191 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18192 (match_operand:SI 2 "nonimmediate_operand" "rm")
18193 (match_operand:SI 3 "const_int_operand" "i")]
18194 UNSPECV_LWPINS_INTRINSIC))
18195 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18196 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18199 (define_insn "*lwp_lwpins<mode>3_1"
18200 [(set (reg:CCC FLAGS_REG)
18201 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18202 (match_operand:SI 1 "nonimmediate_operand" "rm")
18203 (match_operand:SI 2 "const_int_operand" "i")]
18204 UNSPECV_LWPINS_INTRINSIC))]
18206 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18207 [(set_attr "type" "lwp")
18208 (set_attr "mode" "<MODE>")
18209 (set (attr "length")
18210 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18212 (define_insn "rdfsbase<mode>"
18213 [(set (match_operand:SWI48 0 "register_operand" "=r")
18214 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18215 "TARGET_64BIT && TARGET_FSGSBASE"
18217 [(set_attr "type" "other")
18218 (set_attr "prefix_extra" "2")])
18220 (define_insn "rdgsbase<mode>"
18221 [(set (match_operand:SWI48 0 "register_operand" "=r")
18222 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18223 "TARGET_64BIT && TARGET_FSGSBASE"
18225 [(set_attr "type" "other")
18226 (set_attr "prefix_extra" "2")])
18228 (define_insn "wrfsbase<mode>"
18229 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18231 "TARGET_64BIT && TARGET_FSGSBASE"
18233 [(set_attr "type" "other")
18234 (set_attr "prefix_extra" "2")])
18236 (define_insn "wrgsbase<mode>"
18237 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18239 "TARGET_64BIT && TARGET_FSGSBASE"
18241 [(set_attr "type" "other")
18242 (set_attr "prefix_extra" "2")])
18244 (define_insn "rdrand<mode>_1"
18245 [(set (match_operand:SWI248 0 "register_operand" "=r")
18246 (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
18247 (set (reg:CCC FLAGS_REG)
18248 (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
18251 [(set_attr "type" "other")
18252 (set_attr "prefix_extra" "1")])
18254 (define_expand "pause"
18255 [(set (match_dup 0)
18256 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18259 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18260 MEM_VOLATILE_P (operands[0]) = 1;
18263 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18264 ;; They have the same encoding.
18265 (define_insn "*pause"
18266 [(set (match_operand:BLK 0)
18267 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18270 [(set_attr "length" "2")
18271 (set_attr "memory" "unknown")])
18273 (define_expand "xbegin"
18274 [(set (match_operand:SI 0 "register_operand")
18275 (unspec_volatile:SI [(match_dup 1)] UNSPECV_XBEGIN))]
18278 rtx label = gen_label_rtx ();
18280 operands[1] = force_reg (SImode, constm1_rtx);
18282 emit_jump_insn (gen_xbegin_1 (operands[0], operands[1], label));
18284 emit_label (label);
18285 LABEL_NUSES (label) = 1;
18290 (define_insn "xbegin_1"
18292 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18294 (label_ref (match_operand 2))
18296 (set (match_operand:SI 0 "register_operand" "=a")
18297 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
18301 [(set_attr "type" "other")
18302 (set_attr "length" "6")])
18304 (define_insn "xend"
18305 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18308 [(set_attr "type" "other")
18309 (set_attr "length" "3")])
18311 (define_insn "xabort"
18312 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18316 [(set_attr "type" "other")
18317 (set_attr "length" "3")])
18319 (define_expand "xtest"
18320 [(set (match_operand:QI 0 "register_operand")
18321 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18324 emit_insn (gen_xtest_1 ());
18326 ix86_expand_setcc (operands[0], EQ,
18327 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18331 (define_insn "xtest_1"
18332 [(set (reg:CCZ FLAGS_REG)
18333 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18336 [(set_attr "type" "other")
18337 (set_attr "length" "3")])
18341 (include "sync.md")