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 ;; K -- print HLE lock prefix
62 ;; Y -- print condition for XOP pcom* instruction.
63 ;; + -- print a branch hint as 'cs' or 'ds' prefix
64 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
65 ;; ~ -- print "i" if TARGET_AVX2, "f" otherwise.
66 ;; @ -- print a segment register of thread base pointer load
67 ;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
69 (define_c_enum "unspec" [
70 ;; Relocation specifiers
81 UNSPEC_MACHOPIC_OFFSET
89 UNSPEC_MEMORY_BLOCKAGE
99 ;; Other random patterns
108 UNSPEC_LD_MPIC ; load_macho_picbase
110 UNSPEC_DIV_ALREADY_SPLIT
111 UNSPEC_MS_TO_SYSV_CALL
112 UNSPEC_CALL_NEEDS_VZEROUPPER
117 ;; For SSE/MMX support:
125 ;; Generic math support
127 UNSPEC_IEEE_MIN ; not commutative
128 UNSPEC_IEEE_MAX ; not commutative
130 ;; x87 Floating point
146 UNSPEC_FRNDINT_MASK_PM
150 ;; x87 Double output FP
185 (define_c_enum "unspecv" [
188 UNSPECV_PROBE_STACK_RANGE
191 UNSPECV_SPLIT_STACK_RETURN
197 UNSPECV_LLWP_INTRINSIC
198 UNSPECV_SLWP_INTRINSIC
199 UNSPECV_LWPVAL_INTRINSIC
200 UNSPECV_LWPINS_INTRINSIC
206 ;; For RDRAND support
216 ;; Constants to represent rounding modes in the ROUND instruction
225 ;; Constants to represent pcomtrue/pcomfalse variants
235 ;; Constants used in the XOP pperm instruction
237 [(PPERM_SRC 0x00) /* copy source */
238 (PPERM_INVERT 0x20) /* invert source */
239 (PPERM_REVERSE 0x40) /* bit reverse source */
240 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
241 (PPERM_ZERO 0x80) /* all 0's */
242 (PPERM_ONES 0xa0) /* all 1's */
243 (PPERM_SIGN 0xc0) /* propagate sign bit */
244 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
245 (PPERM_SRC1 0x00) /* use first source byte */
246 (PPERM_SRC2 0x10) /* use second source byte */
249 ;; Registers by name.
302 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
305 ;; In C guard expressions, put expressions which may be compile-time
306 ;; constants first. This allows for better optimization. For
307 ;; example, write "TARGET_64BIT && reload_completed", not
308 ;; "reload_completed && TARGET_64BIT".
312 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
313 atom,generic64,amdfam10,bdver1,bdver2,btver1,btver2"
314 (const (symbol_ref "ix86_schedule")))
316 ;; A basic instruction type. Refinements due to arguments to be
317 ;; provided in other attributes.
320 alu,alu1,negnot,imov,imovx,lea,
321 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,imul,imulx,idiv,
322 icmp,test,ibr,setcc,icmov,
323 push,pop,call,callv,leave,
325 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
326 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
327 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
328 ssemuladd,sse4arg,lwp,
329 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
330 (const_string "other"))
332 ;; Main data type used by the insn
334 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
335 (const_string "unknown"))
337 ;; The CPU unit operations uses.
338 (define_attr "unit" "integer,i387,sse,mmx,unknown"
339 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
340 (const_string "i387")
341 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
342 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
343 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
345 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
347 (eq_attr "type" "other")
348 (const_string "unknown")]
349 (const_string "integer")))
351 ;; The (bounding maximum) length of an instruction immediate.
352 (define_attr "length_immediate" ""
353 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
356 (eq_attr "unit" "i387,sse,mmx")
358 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
359 rotate,rotatex,rotate1,imul,icmp,push,pop")
360 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
361 (eq_attr "type" "imov,test")
362 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
363 (eq_attr "type" "call")
364 (if_then_else (match_operand 0 "constant_call_address_operand")
367 (eq_attr "type" "callv")
368 (if_then_else (match_operand 1 "constant_call_address_operand")
371 ;; We don't know the size before shorten_branches. Expect
372 ;; the instruction to fit for better scheduling.
373 (eq_attr "type" "ibr")
376 (symbol_ref "/* Update immediate_length and other attributes! */
377 gcc_unreachable (),1")))
379 ;; The (bounding maximum) length of an instruction address.
380 (define_attr "length_address" ""
381 (cond [(eq_attr "type" "str,other,multi,fxch")
383 (and (eq_attr "type" "call")
384 (match_operand 0 "constant_call_address_operand"))
386 (and (eq_attr "type" "callv")
387 (match_operand 1 "constant_call_address_operand"))
390 (symbol_ref "ix86_attr_length_address_default (insn)")))
392 ;; Set when length prefix is used.
393 (define_attr "prefix_data16" ""
394 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
396 (eq_attr "mode" "HI")
398 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
403 ;; Set when string REP prefix is used.
404 (define_attr "prefix_rep" ""
405 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
407 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
412 ;; Set when 0f opcode prefix is used.
413 (define_attr "prefix_0f" ""
415 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
416 (eq_attr "unit" "sse,mmx"))
420 ;; Set when REX opcode prefix is used.
421 (define_attr "prefix_rex" ""
422 (cond [(not (match_test "TARGET_64BIT"))
424 (and (eq_attr "mode" "DI")
425 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
426 (eq_attr "unit" "!mmx")))
428 (and (eq_attr "mode" "QI")
429 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
431 (match_test "x86_extended_reg_mentioned_p (insn)")
433 (and (eq_attr "type" "imovx")
434 (match_operand:QI 1 "ext_QIreg_operand"))
439 ;; There are also additional prefixes in 3DNOW, SSSE3.
440 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
441 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
442 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
443 (define_attr "prefix_extra" ""
444 (cond [(eq_attr "type" "ssemuladd,sse4arg")
446 (eq_attr "type" "sseiadd1,ssecvt1")
451 ;; Prefix used: original, VEX or maybe VEX.
452 (define_attr "prefix" "orig,vex,maybe_vex"
453 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
455 (const_string "orig")))
457 ;; VEX W bit is used.
458 (define_attr "prefix_vex_w" "" (const_int 0))
460 ;; The length of VEX prefix
461 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
462 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
463 ;; still prefix_0f 1, with prefix_extra 1.
464 (define_attr "length_vex" ""
465 (if_then_else (and (eq_attr "prefix_0f" "1")
466 (eq_attr "prefix_extra" "0"))
467 (if_then_else (eq_attr "prefix_vex_w" "1")
468 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
469 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
470 (if_then_else (eq_attr "prefix_vex_w" "1")
471 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
472 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
474 ;; Set when modrm byte is used.
475 (define_attr "modrm" ""
476 (cond [(eq_attr "type" "str,leave")
478 (eq_attr "unit" "i387")
480 (and (eq_attr "type" "incdec")
481 (and (not (match_test "TARGET_64BIT"))
482 (ior (match_operand:SI 1 "register_operand")
483 (match_operand:HI 1 "register_operand"))))
485 (and (eq_attr "type" "push")
486 (not (match_operand 1 "memory_operand")))
488 (and (eq_attr "type" "pop")
489 (not (match_operand 0 "memory_operand")))
491 (and (eq_attr "type" "imov")
492 (and (not (eq_attr "mode" "DI"))
493 (ior (and (match_operand 0 "register_operand")
494 (match_operand 1 "immediate_operand"))
495 (ior (and (match_operand 0 "ax_reg_operand")
496 (match_operand 1 "memory_displacement_only_operand"))
497 (and (match_operand 0 "memory_displacement_only_operand")
498 (match_operand 1 "ax_reg_operand"))))))
500 (and (eq_attr "type" "call")
501 (match_operand 0 "constant_call_address_operand"))
503 (and (eq_attr "type" "callv")
504 (match_operand 1 "constant_call_address_operand"))
506 (and (eq_attr "type" "alu,alu1,icmp,test")
507 (match_operand 0 "ax_reg_operand"))
508 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
512 ;; The (bounding maximum) length of an instruction in bytes.
513 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
514 ;; Later we may want to split them and compute proper length as for
516 (define_attr "length" ""
517 (cond [(eq_attr "type" "other,multi,fistp,frndint")
519 (eq_attr "type" "fcmp")
521 (eq_attr "unit" "i387")
523 (plus (attr "prefix_data16")
524 (attr "length_address")))
525 (ior (eq_attr "prefix" "vex")
526 (and (eq_attr "prefix" "maybe_vex")
527 (match_test "TARGET_AVX")))
528 (plus (attr "length_vex")
529 (plus (attr "length_immediate")
531 (attr "length_address"))))]
532 (plus (plus (attr "modrm")
533 (plus (attr "prefix_0f")
534 (plus (attr "prefix_rex")
535 (plus (attr "prefix_extra")
537 (plus (attr "prefix_rep")
538 (plus (attr "prefix_data16")
539 (plus (attr "length_immediate")
540 (attr "length_address")))))))
542 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
543 ;; `store' if there is a simple memory reference therein, or `unknown'
544 ;; if the instruction is complex.
546 (define_attr "memory" "none,load,store,both,unknown"
547 (cond [(eq_attr "type" "other,multi,str,lwp")
548 (const_string "unknown")
549 (eq_attr "type" "lea,fcmov,fpspc")
550 (const_string "none")
551 (eq_attr "type" "fistp,leave")
552 (const_string "both")
553 (eq_attr "type" "frndint")
554 (const_string "load")
555 (eq_attr "type" "push")
556 (if_then_else (match_operand 1 "memory_operand")
557 (const_string "both")
558 (const_string "store"))
559 (eq_attr "type" "pop")
560 (if_then_else (match_operand 0 "memory_operand")
561 (const_string "both")
562 (const_string "load"))
563 (eq_attr "type" "setcc")
564 (if_then_else (match_operand 0 "memory_operand")
565 (const_string "store")
566 (const_string "none"))
567 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
568 (if_then_else (ior (match_operand 0 "memory_operand")
569 (match_operand 1 "memory_operand"))
570 (const_string "load")
571 (const_string "none"))
572 (eq_attr "type" "ibr")
573 (if_then_else (match_operand 0 "memory_operand")
574 (const_string "load")
575 (const_string "none"))
576 (eq_attr "type" "call")
577 (if_then_else (match_operand 0 "constant_call_address_operand")
578 (const_string "none")
579 (const_string "load"))
580 (eq_attr "type" "callv")
581 (if_then_else (match_operand 1 "constant_call_address_operand")
582 (const_string "none")
583 (const_string "load"))
584 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
585 (match_operand 1 "memory_operand"))
586 (const_string "both")
587 (and (match_operand 0 "memory_operand")
588 (match_operand 1 "memory_operand"))
589 (const_string "both")
590 (match_operand 0 "memory_operand")
591 (const_string "store")
592 (match_operand 1 "memory_operand")
593 (const_string "load")
595 "!alu1,negnot,ishift1,
596 imov,imovx,icmp,test,bitmanip,
598 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
599 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
600 (match_operand 2 "memory_operand"))
601 (const_string "load")
602 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
603 (match_operand 3 "memory_operand"))
604 (const_string "load")
606 (const_string "none")))
608 ;; Indicates if an instruction has both an immediate and a displacement.
610 (define_attr "imm_disp" "false,true,unknown"
611 (cond [(eq_attr "type" "other,multi")
612 (const_string "unknown")
613 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
614 (and (match_operand 0 "memory_displacement_operand")
615 (match_operand 1 "immediate_operand")))
616 (const_string "true")
617 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
618 (and (match_operand 0 "memory_displacement_operand")
619 (match_operand 2 "immediate_operand")))
620 (const_string "true")
622 (const_string "false")))
624 ;; Indicates if an FP operation has an integer source.
626 (define_attr "fp_int_src" "false,true"
627 (const_string "false"))
629 ;; Defines rounding mode of an FP operation.
631 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
632 (const_string "any"))
634 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
635 (define_attr "use_carry" "0,1" (const_string "0"))
637 ;; Define attribute to indicate unaligned ssemov insns
638 (define_attr "movu" "0,1" (const_string "0"))
640 ;; Used to control the "enabled" attribute on a per-instruction basis.
641 (define_attr "isa" "base,sse2,sse2_noavx,sse3,sse4,sse4_noavx,noavx,avx,avx2,noavx2,bmi2"
642 (const_string "base"))
644 (define_attr "enabled" ""
645 (cond [(eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
646 (eq_attr "isa" "sse2_noavx")
647 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
648 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
649 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
650 (eq_attr "isa" "sse4_noavx")
651 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
652 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
653 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
654 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
655 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
656 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
660 ;; Describe a user's asm statement.
661 (define_asm_attributes
662 [(set_attr "length" "128")
663 (set_attr "type" "multi")])
665 (define_code_iterator plusminus [plus minus])
667 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
669 ;; Base name for define_insn
670 (define_code_attr plusminus_insn
671 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
672 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
674 ;; Base name for insn mnemonic.
675 (define_code_attr plusminus_mnemonic
676 [(plus "add") (ss_plus "adds") (us_plus "addus")
677 (minus "sub") (ss_minus "subs") (us_minus "subus")])
678 (define_code_attr plusminus_carry_mnemonic
679 [(plus "adc") (minus "sbb")])
681 ;; Mark commutative operators as such in constraints.
682 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
683 (minus "") (ss_minus "") (us_minus "")])
685 ;; Mapping of max and min
686 (define_code_iterator maxmin [smax smin umax umin])
688 ;; Mapping of signed max and min
689 (define_code_iterator smaxmin [smax smin])
691 ;; Mapping of unsigned max and min
692 (define_code_iterator umaxmin [umax umin])
694 ;; Base name for integer and FP insn mnemonic
695 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
696 (umax "maxu") (umin "minu")])
697 (define_code_attr maxmin_float [(smax "max") (smin "min")])
699 ;; Mapping of logic operators
700 (define_code_iterator any_logic [and ior xor])
701 (define_code_iterator any_or [ior xor])
703 ;; Base name for insn mnemonic.
704 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
706 ;; Mapping of logic-shift operators
707 (define_code_iterator any_lshift [ashift lshiftrt])
709 ;; Mapping of shift-right operators
710 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
712 ;; Mapping of all shift operators
713 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
715 ;; Base name for define_insn
716 (define_code_attr shift_insn
717 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
719 ;; Base name for insn mnemonic.
720 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
721 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
723 ;; Mapping of rotate operators
724 (define_code_iterator any_rotate [rotate rotatert])
726 ;; Base name for define_insn
727 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
729 ;; Base name for insn mnemonic.
730 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
732 ;; Mapping of abs neg operators
733 (define_code_iterator absneg [abs neg])
735 ;; Base name for x87 insn mnemonic.
736 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
738 ;; Used in signed and unsigned widening multiplications.
739 (define_code_iterator any_extend [sign_extend zero_extend])
741 ;; Prefix for insn menmonic.
742 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
744 ;; Prefix for define_insn
745 (define_code_attr u [(sign_extend "") (zero_extend "u")])
746 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
747 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
749 ;; All integer modes.
750 (define_mode_iterator SWI1248x [QI HI SI DI])
752 ;; All integer modes without QImode.
753 (define_mode_iterator SWI248x [HI SI DI])
755 ;; All integer modes without QImode and HImode.
756 (define_mode_iterator SWI48x [SI DI])
758 ;; All integer modes without SImode and DImode.
759 (define_mode_iterator SWI12 [QI HI])
761 ;; All integer modes without DImode.
762 (define_mode_iterator SWI124 [QI HI SI])
764 ;; All integer modes without QImode and DImode.
765 (define_mode_iterator SWI24 [HI SI])
767 ;; Single word integer modes.
768 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
770 ;; Single word integer modes without QImode.
771 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
773 ;; Single word integer modes without QImode and HImode.
774 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
776 ;; All math-dependant single and double word integer modes.
777 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
778 (HI "TARGET_HIMODE_MATH")
779 SI DI (TI "TARGET_64BIT")])
781 ;; Math-dependant single word integer modes.
782 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
783 (HI "TARGET_HIMODE_MATH")
784 SI (DI "TARGET_64BIT")])
786 ;; Math-dependant integer modes without DImode.
787 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
788 (HI "TARGET_HIMODE_MATH")
791 ;; Math-dependant single word integer modes without QImode.
792 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
793 SI (DI "TARGET_64BIT")])
795 ;; Double word integer modes.
796 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
797 (TI "TARGET_64BIT")])
799 ;; Double word integer modes as mode attribute.
800 (define_mode_attr DWI [(SI "DI") (DI "TI")])
801 (define_mode_attr dwi [(SI "di") (DI "ti")])
803 ;; Half mode for double word integer modes.
804 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
805 (DI "TARGET_64BIT")])
807 ;; Instruction suffix for integer modes.
808 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
810 ;; Pointer size prefix for integer modes (Intel asm dialect)
811 (define_mode_attr iptrsize [(QI "BYTE")
816 ;; Register class for integer modes.
817 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
819 ;; Immediate operand constraint for integer modes.
820 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
822 ;; General operand constraint for word modes.
823 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
825 ;; Immediate operand constraint for double integer modes.
826 (define_mode_attr di [(SI "nF") (DI "e")])
828 ;; Immediate operand constraint for shifts.
829 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
831 ;; General operand predicate for integer modes.
832 (define_mode_attr general_operand
833 [(QI "general_operand")
834 (HI "general_operand")
835 (SI "x86_64_general_operand")
836 (DI "x86_64_general_operand")
837 (TI "x86_64_general_operand")])
839 ;; General sign/zero extend operand predicate for integer modes.
840 (define_mode_attr general_szext_operand
841 [(QI "general_operand")
842 (HI "general_operand")
843 (SI "x86_64_szext_general_operand")
844 (DI "x86_64_szext_general_operand")])
846 ;; Immediate operand predicate for integer modes.
847 (define_mode_attr immediate_operand
848 [(QI "immediate_operand")
849 (HI "immediate_operand")
850 (SI "x86_64_immediate_operand")
851 (DI "x86_64_immediate_operand")])
853 ;; Nonmemory operand predicate for integer modes.
854 (define_mode_attr nonmemory_operand
855 [(QI "nonmemory_operand")
856 (HI "nonmemory_operand")
857 (SI "x86_64_nonmemory_operand")
858 (DI "x86_64_nonmemory_operand")])
860 ;; Operand predicate for shifts.
861 (define_mode_attr shift_operand
862 [(QI "nonimmediate_operand")
863 (HI "nonimmediate_operand")
864 (SI "nonimmediate_operand")
865 (DI "shiftdi_operand")
866 (TI "register_operand")])
868 ;; Operand predicate for shift argument.
869 (define_mode_attr shift_immediate_operand
870 [(QI "const_1_to_31_operand")
871 (HI "const_1_to_31_operand")
872 (SI "const_1_to_31_operand")
873 (DI "const_1_to_63_operand")])
875 ;; Input operand predicate for arithmetic left shifts.
876 (define_mode_attr ashl_input_operand
877 [(QI "nonimmediate_operand")
878 (HI "nonimmediate_operand")
879 (SI "nonimmediate_operand")
880 (DI "ashldi_input_operand")
881 (TI "reg_or_pm1_operand")])
883 ;; SSE and x87 SFmode and DFmode floating point modes
884 (define_mode_iterator MODEF [SF DF])
886 ;; All x87 floating point modes
887 (define_mode_iterator X87MODEF [SF DF XF])
889 ;; SSE instruction suffix for various modes
890 (define_mode_attr ssemodesuffix
892 (V8SF "ps") (V4DF "pd")
893 (V4SF "ps") (V2DF "pd")
894 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
895 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
897 ;; SSE vector suffix for floating point modes
898 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
900 ;; SSE vector mode corresponding to a scalar mode
901 (define_mode_attr ssevecmode
902 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
904 ;; Instruction suffix for REX 64bit operators.
905 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
907 ;; This mode iterator allows :P to be used for patterns that operate on
908 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
909 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
911 ;; This mode iterator allows :W to be used for patterns that operate on
912 ;; word_mode sized quantities.
913 (define_mode_iterator W
914 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
916 ;; This mode iterator allows :PTR to be used for patterns that operate on
917 ;; ptr_mode sized quantities.
918 (define_mode_iterator PTR
919 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
921 ;; Scheduling descriptions
923 (include "pentium.md")
926 (include "athlon.md")
927 (include "bdver1.md")
933 ;; Operand and operator predicates and constraints
935 (include "predicates.md")
936 (include "constraints.md")
939 ;; Compare and branch/compare and store instructions.
941 (define_expand "cbranch<mode>4"
942 [(set (reg:CC FLAGS_REG)
943 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
944 (match_operand:SDWIM 2 "<general_operand>")))
945 (set (pc) (if_then_else
946 (match_operator 0 "ordered_comparison_operator"
947 [(reg:CC FLAGS_REG) (const_int 0)])
948 (label_ref (match_operand 3))
952 if (MEM_P (operands[1]) && MEM_P (operands[2]))
953 operands[1] = force_reg (<MODE>mode, operands[1]);
954 ix86_expand_branch (GET_CODE (operands[0]),
955 operands[1], operands[2], operands[3]);
959 (define_expand "cstore<mode>4"
960 [(set (reg:CC FLAGS_REG)
961 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
962 (match_operand:SWIM 3 "<general_operand>")))
963 (set (match_operand:QI 0 "register_operand")
964 (match_operator 1 "ordered_comparison_operator"
965 [(reg:CC FLAGS_REG) (const_int 0)]))]
968 if (MEM_P (operands[2]) && MEM_P (operands[3]))
969 operands[2] = force_reg (<MODE>mode, operands[2]);
970 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
971 operands[2], operands[3]);
975 (define_expand "cmp<mode>_1"
976 [(set (reg:CC FLAGS_REG)
977 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
978 (match_operand:SWI48 1 "<general_operand>")))])
980 (define_insn "*cmp<mode>_ccno_1"
981 [(set (reg FLAGS_REG)
982 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
983 (match_operand:SWI 1 "const0_operand")))]
984 "ix86_match_ccmode (insn, CCNOmode)"
986 test{<imodesuffix>}\t%0, %0
987 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
988 [(set_attr "type" "test,icmp")
989 (set_attr "length_immediate" "0,1")
990 (set_attr "mode" "<MODE>")])
992 (define_insn "*cmp<mode>_1"
993 [(set (reg FLAGS_REG)
994 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
995 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
996 "ix86_match_ccmode (insn, CCmode)"
997 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
998 [(set_attr "type" "icmp")
999 (set_attr "mode" "<MODE>")])
1001 (define_insn "*cmp<mode>_minus_1"
1002 [(set (reg FLAGS_REG)
1004 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1005 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1007 "ix86_match_ccmode (insn, CCGOCmode)"
1008 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1009 [(set_attr "type" "icmp")
1010 (set_attr "mode" "<MODE>")])
1012 (define_insn "*cmpqi_ext_1"
1013 [(set (reg FLAGS_REG)
1015 (match_operand:QI 0 "general_operand" "Qm")
1018 (match_operand 1 "ext_register_operand" "Q")
1020 (const_int 8)) 0)))]
1021 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1022 "cmp{b}\t{%h1, %0|%0, %h1}"
1023 [(set_attr "type" "icmp")
1024 (set_attr "mode" "QI")])
1026 (define_insn "*cmpqi_ext_1_rex64"
1027 [(set (reg FLAGS_REG)
1029 (match_operand:QI 0 "register_operand" "Q")
1032 (match_operand 1 "ext_register_operand" "Q")
1034 (const_int 8)) 0)))]
1035 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1036 "cmp{b}\t{%h1, %0|%0, %h1}"
1037 [(set_attr "type" "icmp")
1038 (set_attr "mode" "QI")])
1040 (define_insn "*cmpqi_ext_2"
1041 [(set (reg FLAGS_REG)
1045 (match_operand 0 "ext_register_operand" "Q")
1048 (match_operand:QI 1 "const0_operand")))]
1049 "ix86_match_ccmode (insn, CCNOmode)"
1051 [(set_attr "type" "test")
1052 (set_attr "length_immediate" "0")
1053 (set_attr "mode" "QI")])
1055 (define_expand "cmpqi_ext_3"
1056 [(set (reg:CC FLAGS_REG)
1060 (match_operand 0 "ext_register_operand")
1063 (match_operand:QI 1 "immediate_operand")))])
1065 (define_insn "*cmpqi_ext_3_insn"
1066 [(set (reg FLAGS_REG)
1070 (match_operand 0 "ext_register_operand" "Q")
1073 (match_operand:QI 1 "general_operand" "Qmn")))]
1074 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1075 "cmp{b}\t{%1, %h0|%h0, %1}"
1076 [(set_attr "type" "icmp")
1077 (set_attr "modrm" "1")
1078 (set_attr "mode" "QI")])
1080 (define_insn "*cmpqi_ext_3_insn_rex64"
1081 [(set (reg FLAGS_REG)
1085 (match_operand 0 "ext_register_operand" "Q")
1088 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1089 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1090 "cmp{b}\t{%1, %h0|%h0, %1}"
1091 [(set_attr "type" "icmp")
1092 (set_attr "modrm" "1")
1093 (set_attr "mode" "QI")])
1095 (define_insn "*cmpqi_ext_4"
1096 [(set (reg FLAGS_REG)
1100 (match_operand 0 "ext_register_operand" "Q")
1105 (match_operand 1 "ext_register_operand" "Q")
1107 (const_int 8)) 0)))]
1108 "ix86_match_ccmode (insn, CCmode)"
1109 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1110 [(set_attr "type" "icmp")
1111 (set_attr "mode" "QI")])
1113 ;; These implement float point compares.
1114 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1115 ;; which would allow mix and match FP modes on the compares. Which is what
1116 ;; the old patterns did, but with many more of them.
1118 (define_expand "cbranchxf4"
1119 [(set (reg:CC FLAGS_REG)
1120 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1121 (match_operand:XF 2 "nonmemory_operand")))
1122 (set (pc) (if_then_else
1123 (match_operator 0 "ix86_fp_comparison_operator"
1126 (label_ref (match_operand 3))
1130 ix86_expand_branch (GET_CODE (operands[0]),
1131 operands[1], operands[2], operands[3]);
1135 (define_expand "cstorexf4"
1136 [(set (reg:CC FLAGS_REG)
1137 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1138 (match_operand:XF 3 "nonmemory_operand")))
1139 (set (match_operand:QI 0 "register_operand")
1140 (match_operator 1 "ix86_fp_comparison_operator"
1145 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1146 operands[2], operands[3]);
1150 (define_expand "cbranch<mode>4"
1151 [(set (reg:CC FLAGS_REG)
1152 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1153 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1154 (set (pc) (if_then_else
1155 (match_operator 0 "ix86_fp_comparison_operator"
1158 (label_ref (match_operand 3))
1160 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1162 ix86_expand_branch (GET_CODE (operands[0]),
1163 operands[1], operands[2], operands[3]);
1167 (define_expand "cstore<mode>4"
1168 [(set (reg:CC FLAGS_REG)
1169 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1170 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1171 (set (match_operand:QI 0 "register_operand")
1172 (match_operator 1 "ix86_fp_comparison_operator"
1175 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1177 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1178 operands[2], operands[3]);
1182 (define_expand "cbranchcc4"
1183 [(set (pc) (if_then_else
1184 (match_operator 0 "comparison_operator"
1185 [(match_operand 1 "flags_reg_operand")
1186 (match_operand 2 "const0_operand")])
1187 (label_ref (match_operand 3))
1191 ix86_expand_branch (GET_CODE (operands[0]),
1192 operands[1], operands[2], operands[3]);
1196 (define_expand "cstorecc4"
1197 [(set (match_operand:QI 0 "register_operand")
1198 (match_operator 1 "comparison_operator"
1199 [(match_operand 2 "flags_reg_operand")
1200 (match_operand 3 "const0_operand")]))]
1203 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1204 operands[2], operands[3]);
1209 ;; FP compares, step 1:
1210 ;; Set the FP condition codes.
1212 ;; CCFPmode compare with exceptions
1213 ;; CCFPUmode compare with no exceptions
1215 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1216 ;; used to manage the reg stack popping would not be preserved.
1218 (define_insn "*cmpfp_0"
1219 [(set (match_operand:HI 0 "register_operand" "=a")
1222 (match_operand 1 "register_operand" "f")
1223 (match_operand 2 "const0_operand"))]
1225 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1226 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1227 "* return output_fp_compare (insn, operands, false, false);"
1228 [(set_attr "type" "multi")
1229 (set_attr "unit" "i387")
1231 (cond [(match_operand:SF 1)
1233 (match_operand:DF 1)
1236 (const_string "XF")))])
1238 (define_insn_and_split "*cmpfp_0_cc"
1239 [(set (reg:CCFP FLAGS_REG)
1241 (match_operand 1 "register_operand" "f")
1242 (match_operand 2 "const0_operand")))
1243 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1244 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1245 && TARGET_SAHF && !TARGET_CMOVE
1246 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1248 "&& reload_completed"
1251 [(compare:CCFP (match_dup 1)(match_dup 2))]
1253 (set (reg:CC FLAGS_REG)
1254 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1256 [(set_attr "type" "multi")
1257 (set_attr "unit" "i387")
1259 (cond [(match_operand:SF 1)
1261 (match_operand:DF 1)
1264 (const_string "XF")))])
1266 (define_insn "*cmpfp_xf"
1267 [(set (match_operand:HI 0 "register_operand" "=a")
1270 (match_operand:XF 1 "register_operand" "f")
1271 (match_operand:XF 2 "register_operand" "f"))]
1274 "* return output_fp_compare (insn, operands, false, false);"
1275 [(set_attr "type" "multi")
1276 (set_attr "unit" "i387")
1277 (set_attr "mode" "XF")])
1279 (define_insn_and_split "*cmpfp_xf_cc"
1280 [(set (reg:CCFP FLAGS_REG)
1282 (match_operand:XF 1 "register_operand" "f")
1283 (match_operand:XF 2 "register_operand" "f")))
1284 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1286 && TARGET_SAHF && !TARGET_CMOVE"
1288 "&& reload_completed"
1291 [(compare:CCFP (match_dup 1)(match_dup 2))]
1293 (set (reg:CC FLAGS_REG)
1294 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1296 [(set_attr "type" "multi")
1297 (set_attr "unit" "i387")
1298 (set_attr "mode" "XF")])
1300 (define_insn "*cmpfp_<mode>"
1301 [(set (match_operand:HI 0 "register_operand" "=a")
1304 (match_operand:MODEF 1 "register_operand" "f")
1305 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1308 "* return output_fp_compare (insn, operands, false, false);"
1309 [(set_attr "type" "multi")
1310 (set_attr "unit" "i387")
1311 (set_attr "mode" "<MODE>")])
1313 (define_insn_and_split "*cmpfp_<mode>_cc"
1314 [(set (reg:CCFP FLAGS_REG)
1316 (match_operand:MODEF 1 "register_operand" "f")
1317 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1318 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1320 && TARGET_SAHF && !TARGET_CMOVE"
1322 "&& reload_completed"
1325 [(compare:CCFP (match_dup 1)(match_dup 2))]
1327 (set (reg:CC FLAGS_REG)
1328 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1330 [(set_attr "type" "multi")
1331 (set_attr "unit" "i387")
1332 (set_attr "mode" "<MODE>")])
1334 (define_insn "*cmpfp_u"
1335 [(set (match_operand:HI 0 "register_operand" "=a")
1338 (match_operand 1 "register_operand" "f")
1339 (match_operand 2 "register_operand" "f"))]
1341 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1342 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1343 "* return output_fp_compare (insn, operands, false, true);"
1344 [(set_attr "type" "multi")
1345 (set_attr "unit" "i387")
1347 (cond [(match_operand:SF 1)
1349 (match_operand:DF 1)
1352 (const_string "XF")))])
1354 (define_insn_and_split "*cmpfp_u_cc"
1355 [(set (reg:CCFPU FLAGS_REG)
1357 (match_operand 1 "register_operand" "f")
1358 (match_operand 2 "register_operand" "f")))
1359 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1360 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1361 && TARGET_SAHF && !TARGET_CMOVE
1362 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1364 "&& reload_completed"
1367 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1369 (set (reg:CC FLAGS_REG)
1370 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1372 [(set_attr "type" "multi")
1373 (set_attr "unit" "i387")
1375 (cond [(match_operand:SF 1)
1377 (match_operand:DF 1)
1380 (const_string "XF")))])
1382 (define_insn "*cmpfp_<mode>"
1383 [(set (match_operand:HI 0 "register_operand" "=a")
1386 (match_operand 1 "register_operand" "f")
1387 (match_operator 3 "float_operator"
1388 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1390 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1391 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1392 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1393 "* return output_fp_compare (insn, operands, false, false);"
1394 [(set_attr "type" "multi")
1395 (set_attr "unit" "i387")
1396 (set_attr "fp_int_src" "true")
1397 (set_attr "mode" "<MODE>")])
1399 (define_insn_and_split "*cmpfp_<mode>_cc"
1400 [(set (reg:CCFP FLAGS_REG)
1402 (match_operand 1 "register_operand" "f")
1403 (match_operator 3 "float_operator"
1404 [(match_operand:SWI24 2 "memory_operand" "m")])))
1405 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1406 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1407 && TARGET_SAHF && !TARGET_CMOVE
1408 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1409 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1411 "&& reload_completed"
1416 (match_op_dup 3 [(match_dup 2)]))]
1418 (set (reg:CC FLAGS_REG)
1419 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1421 [(set_attr "type" "multi")
1422 (set_attr "unit" "i387")
1423 (set_attr "fp_int_src" "true")
1424 (set_attr "mode" "<MODE>")])
1426 ;; FP compares, step 2
1427 ;; Move the fpsw to ax.
1429 (define_insn "x86_fnstsw_1"
1430 [(set (match_operand:HI 0 "register_operand" "=a")
1431 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1434 [(set (attr "length")
1435 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1436 (set_attr "mode" "SI")
1437 (set_attr "unit" "i387")])
1439 ;; FP compares, step 3
1440 ;; Get ax into flags, general case.
1442 (define_insn "x86_sahf_1"
1443 [(set (reg:CC FLAGS_REG)
1444 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1448 #ifndef HAVE_AS_IX86_SAHF
1450 return ASM_BYTE "0x9e";
1455 [(set_attr "length" "1")
1456 (set_attr "athlon_decode" "vector")
1457 (set_attr "amdfam10_decode" "direct")
1458 (set_attr "bdver1_decode" "direct")
1459 (set_attr "mode" "SI")])
1461 ;; Pentium Pro can do steps 1 through 3 in one go.
1462 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1463 ;; (these i387 instructions set flags directly)
1464 (define_insn "*cmpfp_i_mixed"
1465 [(set (reg:CCFP FLAGS_REG)
1466 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1467 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1468 "TARGET_MIX_SSE_I387
1469 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1470 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1471 "* return output_fp_compare (insn, operands, true, false);"
1472 [(set_attr "type" "fcmp,ssecomi")
1473 (set_attr "prefix" "orig,maybe_vex")
1475 (if_then_else (match_operand:SF 1)
1477 (const_string "DF")))
1478 (set (attr "prefix_rep")
1479 (if_then_else (eq_attr "type" "ssecomi")
1481 (const_string "*")))
1482 (set (attr "prefix_data16")
1483 (cond [(eq_attr "type" "fcmp")
1485 (eq_attr "mode" "DF")
1488 (const_string "0")))
1489 (set_attr "athlon_decode" "vector")
1490 (set_attr "amdfam10_decode" "direct")
1491 (set_attr "bdver1_decode" "double")])
1493 (define_insn "*cmpfp_i_sse"
1494 [(set (reg:CCFP FLAGS_REG)
1495 (compare:CCFP (match_operand 0 "register_operand" "x")
1496 (match_operand 1 "nonimmediate_operand" "xm")))]
1498 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1499 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1500 "* return output_fp_compare (insn, operands, true, false);"
1501 [(set_attr "type" "ssecomi")
1502 (set_attr "prefix" "maybe_vex")
1504 (if_then_else (match_operand:SF 1)
1506 (const_string "DF")))
1507 (set_attr "prefix_rep" "0")
1508 (set (attr "prefix_data16")
1509 (if_then_else (eq_attr "mode" "DF")
1511 (const_string "0")))
1512 (set_attr "athlon_decode" "vector")
1513 (set_attr "amdfam10_decode" "direct")
1514 (set_attr "bdver1_decode" "double")])
1516 (define_insn "*cmpfp_i_i387"
1517 [(set (reg:CCFP FLAGS_REG)
1518 (compare:CCFP (match_operand 0 "register_operand" "f")
1519 (match_operand 1 "register_operand" "f")))]
1520 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1522 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1523 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1524 "* return output_fp_compare (insn, operands, true, false);"
1525 [(set_attr "type" "fcmp")
1527 (cond [(match_operand:SF 1)
1529 (match_operand:DF 1)
1532 (const_string "XF")))
1533 (set_attr "athlon_decode" "vector")
1534 (set_attr "amdfam10_decode" "direct")
1535 (set_attr "bdver1_decode" "double")])
1537 (define_insn "*cmpfp_iu_mixed"
1538 [(set (reg:CCFPU FLAGS_REG)
1539 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1540 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1541 "TARGET_MIX_SSE_I387
1542 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1543 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1544 "* return output_fp_compare (insn, operands, true, true);"
1545 [(set_attr "type" "fcmp,ssecomi")
1546 (set_attr "prefix" "orig,maybe_vex")
1548 (if_then_else (match_operand:SF 1)
1550 (const_string "DF")))
1551 (set (attr "prefix_rep")
1552 (if_then_else (eq_attr "type" "ssecomi")
1554 (const_string "*")))
1555 (set (attr "prefix_data16")
1556 (cond [(eq_attr "type" "fcmp")
1558 (eq_attr "mode" "DF")
1561 (const_string "0")))
1562 (set_attr "athlon_decode" "vector")
1563 (set_attr "amdfam10_decode" "direct")
1564 (set_attr "bdver1_decode" "double")])
1566 (define_insn "*cmpfp_iu_sse"
1567 [(set (reg:CCFPU FLAGS_REG)
1568 (compare:CCFPU (match_operand 0 "register_operand" "x")
1569 (match_operand 1 "nonimmediate_operand" "xm")))]
1571 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1572 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1573 "* return output_fp_compare (insn, operands, true, true);"
1574 [(set_attr "type" "ssecomi")
1575 (set_attr "prefix" "maybe_vex")
1577 (if_then_else (match_operand:SF 1)
1579 (const_string "DF")))
1580 (set_attr "prefix_rep" "0")
1581 (set (attr "prefix_data16")
1582 (if_then_else (eq_attr "mode" "DF")
1584 (const_string "0")))
1585 (set_attr "athlon_decode" "vector")
1586 (set_attr "amdfam10_decode" "direct")
1587 (set_attr "bdver1_decode" "double")])
1589 (define_insn "*cmpfp_iu_387"
1590 [(set (reg:CCFPU FLAGS_REG)
1591 (compare:CCFPU (match_operand 0 "register_operand" "f")
1592 (match_operand 1 "register_operand" "f")))]
1593 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1595 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1596 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1597 "* return output_fp_compare (insn, operands, true, true);"
1598 [(set_attr "type" "fcmp")
1600 (cond [(match_operand:SF 1)
1602 (match_operand:DF 1)
1605 (const_string "XF")))
1606 (set_attr "athlon_decode" "vector")
1607 (set_attr "amdfam10_decode" "direct")
1608 (set_attr "bdver1_decode" "direct")])
1610 ;; Push/pop instructions.
1612 (define_insn "*push<mode>2"
1613 [(set (match_operand:DWI 0 "push_operand" "=<")
1614 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1617 [(set_attr "type" "multi")
1618 (set_attr "mode" "<MODE>")])
1621 [(set (match_operand:TI 0 "push_operand")
1622 (match_operand:TI 1 "general_operand"))]
1623 "TARGET_64BIT && reload_completed
1624 && !SSE_REG_P (operands[1])"
1626 "ix86_split_long_move (operands); DONE;")
1628 (define_insn "*pushdi2_rex64"
1629 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1630 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1635 [(set_attr "type" "push,multi")
1636 (set_attr "mode" "DI")])
1638 ;; Convert impossible pushes of immediate to existing instructions.
1639 ;; First try to get scratch register and go through it. In case this
1640 ;; fails, push sign extended lower part first and then overwrite
1641 ;; upper part by 32bit move.
1643 [(match_scratch:DI 2 "r")
1644 (set (match_operand:DI 0 "push_operand")
1645 (match_operand:DI 1 "immediate_operand"))]
1646 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1647 && !x86_64_immediate_operand (operands[1], DImode)"
1648 [(set (match_dup 2) (match_dup 1))
1649 (set (match_dup 0) (match_dup 2))])
1651 ;; We need to define this as both peepholer and splitter for case
1652 ;; peephole2 pass is not run.
1653 ;; "&& 1" is needed to keep it from matching the previous pattern.
1655 [(set (match_operand:DI 0 "push_operand")
1656 (match_operand:DI 1 "immediate_operand"))]
1657 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1658 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1659 [(set (match_dup 0) (match_dup 1))
1660 (set (match_dup 2) (match_dup 3))]
1662 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1664 operands[1] = gen_lowpart (DImode, operands[2]);
1665 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1670 [(set (match_operand:DI 0 "push_operand")
1671 (match_operand:DI 1 "immediate_operand"))]
1672 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1673 ? epilogue_completed : reload_completed)
1674 && !symbolic_operand (operands[1], DImode)
1675 && !x86_64_immediate_operand (operands[1], DImode)"
1676 [(set (match_dup 0) (match_dup 1))
1677 (set (match_dup 2) (match_dup 3))]
1679 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1681 operands[1] = gen_lowpart (DImode, operands[2]);
1682 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1687 [(set (match_operand:DI 0 "push_operand")
1688 (match_operand:DI 1 "general_operand"))]
1689 "!TARGET_64BIT && reload_completed
1690 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1692 "ix86_split_long_move (operands); DONE;")
1694 (define_insn "*pushsi2"
1695 [(set (match_operand:SI 0 "push_operand" "=<")
1696 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1699 [(set_attr "type" "push")
1700 (set_attr "mode" "SI")])
1702 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1703 ;; "push a byte/word". But actually we use pushl, which has the effect
1704 ;; of rounding the amount pushed up to a word.
1706 ;; For TARGET_64BIT we always round up to 8 bytes.
1707 (define_insn "*push<mode>2_rex64"
1708 [(set (match_operand:SWI124 0 "push_operand" "=X")
1709 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1712 [(set_attr "type" "push")
1713 (set_attr "mode" "DI")])
1715 (define_insn "*push<mode>2"
1716 [(set (match_operand:SWI12 0 "push_operand" "=X")
1717 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1720 [(set_attr "type" "push")
1721 (set_attr "mode" "SI")])
1723 (define_insn "*push<mode>2_prologue"
1724 [(set (match_operand:W 0 "push_operand" "=<")
1725 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1726 (clobber (mem:BLK (scratch)))]
1728 "push{<imodesuffix>}\t%1"
1729 [(set_attr "type" "push")
1730 (set_attr "mode" "<MODE>")])
1732 (define_insn "*pop<mode>1"
1733 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1734 (match_operand:W 1 "pop_operand" ">"))]
1736 "pop{<imodesuffix>}\t%0"
1737 [(set_attr "type" "pop")
1738 (set_attr "mode" "<MODE>")])
1740 (define_insn "*pop<mode>1_epilogue"
1741 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1742 (match_operand:W 1 "pop_operand" ">"))
1743 (clobber (mem:BLK (scratch)))]
1745 "pop{<imodesuffix>}\t%0"
1746 [(set_attr "type" "pop")
1747 (set_attr "mode" "<MODE>")])
1749 ;; Move instructions.
1751 (define_expand "movoi"
1752 [(set (match_operand:OI 0 "nonimmediate_operand")
1753 (match_operand:OI 1 "general_operand"))]
1755 "ix86_expand_move (OImode, operands); DONE;")
1757 (define_expand "movti"
1758 [(set (match_operand:TI 0 "nonimmediate_operand")
1759 (match_operand:TI 1 "nonimmediate_operand"))]
1760 "TARGET_64BIT || TARGET_SSE"
1763 ix86_expand_move (TImode, operands);
1764 else if (push_operand (operands[0], TImode))
1765 ix86_expand_push (TImode, operands[1]);
1767 ix86_expand_vector_move (TImode, operands);
1771 ;; This expands to what emit_move_complex would generate if we didn't
1772 ;; have a movti pattern. Having this avoids problems with reload on
1773 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1774 ;; to have around all the time.
1775 (define_expand "movcdi"
1776 [(set (match_operand:CDI 0 "nonimmediate_operand")
1777 (match_operand:CDI 1 "general_operand"))]
1780 if (push_operand (operands[0], CDImode))
1781 emit_move_complex_push (CDImode, operands[0], operands[1]);
1783 emit_move_complex_parts (operands[0], operands[1]);
1787 (define_expand "mov<mode>"
1788 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1789 (match_operand:SWI1248x 1 "general_operand"))]
1791 "ix86_expand_move (<MODE>mode, operands); DONE;")
1793 (define_insn "*mov<mode>_xor"
1794 [(set (match_operand:SWI48 0 "register_operand" "=r")
1795 (match_operand:SWI48 1 "const0_operand"))
1796 (clobber (reg:CC FLAGS_REG))]
1799 [(set_attr "type" "alu1")
1800 (set_attr "mode" "SI")
1801 (set_attr "length_immediate" "0")])
1803 (define_insn "*mov<mode>_or"
1804 [(set (match_operand:SWI48 0 "register_operand" "=r")
1805 (match_operand:SWI48 1 "const_int_operand"))
1806 (clobber (reg:CC FLAGS_REG))]
1808 && operands[1] == constm1_rtx"
1809 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1810 [(set_attr "type" "alu1")
1811 (set_attr "mode" "<MODE>")
1812 (set_attr "length_immediate" "1")])
1814 (define_insn "*movoi_internal_avx"
1815 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x ,m")
1816 (match_operand:OI 1 "vector_move_operand" "C ,xm,x"))]
1817 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1819 switch (which_alternative)
1822 return standard_sse_constant_opcode (insn, operands[1]);
1825 if (misaligned_operand (operands[0], OImode)
1826 || misaligned_operand (operands[1], OImode))
1828 if (get_attr_mode (insn) == MODE_V8SF)
1829 return "vmovups\t{%1, %0|%0, %1}";
1831 return "vmovdqu\t{%1, %0|%0, %1}";
1835 if (get_attr_mode (insn) == MODE_V8SF)
1836 return "vmovaps\t{%1, %0|%0, %1}";
1838 return "vmovdqa\t{%1, %0|%0, %1}";
1844 [(set_attr "type" "sselog1,ssemov,ssemov")
1845 (set_attr "prefix" "vex")
1847 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1848 (const_string "V8SF")
1849 (and (eq_attr "alternative" "2")
1850 (match_test "TARGET_SSE_TYPELESS_STORES"))
1851 (const_string "V8SF")
1853 (const_string "OI")))])
1855 (define_insn "*movti_internal_rex64"
1856 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,x,x ,m")
1857 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1858 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1860 switch (which_alternative)
1866 return standard_sse_constant_opcode (insn, operands[1]);
1869 /* TDmode values are passed as TImode on the stack. Moving them
1870 to stack may result in unaligned memory access. */
1871 if (misaligned_operand (operands[0], TImode)
1872 || misaligned_operand (operands[1], TImode))
1874 if (get_attr_mode (insn) == MODE_V4SF)
1875 return "%vmovups\t{%1, %0|%0, %1}";
1877 return "%vmovdqu\t{%1, %0|%0, %1}";
1881 if (get_attr_mode (insn) == MODE_V4SF)
1882 return "%vmovaps\t{%1, %0|%0, %1}";
1884 return "%vmovdqa\t{%1, %0|%0, %1}";
1890 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1891 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1893 (cond [(eq_attr "alternative" "0,1")
1895 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1896 (const_string "V4SF")
1897 (and (eq_attr "alternative" "4")
1898 (match_test "TARGET_SSE_TYPELESS_STORES"))
1899 (const_string "V4SF")
1900 (match_test "TARGET_AVX")
1902 (match_test "optimize_function_for_size_p (cfun)")
1903 (const_string "V4SF")
1905 (const_string "TI")))])
1908 [(set (match_operand:TI 0 "nonimmediate_operand")
1909 (match_operand:TI 1 "general_operand"))]
1911 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1913 "ix86_split_long_move (operands); DONE;")
1915 (define_insn "*movti_internal_sse"
1916 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x ,m")
1917 (match_operand:TI 1 "vector_move_operand" "C ,xm,x"))]
1918 "TARGET_SSE && !TARGET_64BIT
1919 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1921 switch (which_alternative)
1924 return standard_sse_constant_opcode (insn, operands[1]);
1927 /* TDmode values are passed as TImode on the stack. Moving them
1928 to stack may result in unaligned memory access. */
1929 if (misaligned_operand (operands[0], TImode)
1930 || misaligned_operand (operands[1], TImode))
1932 if (get_attr_mode (insn) == MODE_V4SF)
1933 return "%vmovups\t{%1, %0|%0, %1}";
1935 return "%vmovdqu\t{%1, %0|%0, %1}";
1939 if (get_attr_mode (insn) == MODE_V4SF)
1940 return "%vmovaps\t{%1, %0|%0, %1}";
1942 return "%vmovdqa\t{%1, %0|%0, %1}";
1948 [(set_attr "type" "sselog1,ssemov,ssemov")
1949 (set_attr "prefix" "maybe_vex")
1951 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1952 (const_string "V4SF")
1953 (and (eq_attr "alternative" "2")
1954 (match_test "TARGET_SSE_TYPELESS_STORES"))
1955 (const_string "V4SF")
1956 (match_test "TARGET_AVX")
1958 (ior (not (match_test "TARGET_SSE2"))
1959 (match_test "optimize_function_for_size_p (cfun)"))
1960 (const_string "V4SF")
1962 (const_string "TI")))])
1964 (define_insn "*movdi_internal_rex64"
1965 [(set (match_operand:DI 0 "nonimmediate_operand"
1966 "=r,r ,r,m ,!o,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1967 (match_operand:DI 1 "general_operand"
1968 "Z ,rem,i,re,n ,C ,*y ,m ,*Ym,r ,C ,*x,*x,m ,*Yi,r ,*Ym,*x"))]
1969 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1971 switch (get_attr_type (insn))
1974 if (SSE_REG_P (operands[0]))
1975 return "movq2dq\t{%1, %0|%0, %1}";
1977 return "movdq2q\t{%1, %0|%0, %1}";
1980 if (get_attr_mode (insn) == MODE_V4SF)
1981 return "%vmovaps\t{%1, %0|%0, %1}";
1982 else if (get_attr_mode (insn) == MODE_TI)
1983 return "%vmovdqa\t{%1, %0|%0, %1}";
1985 /* Handle broken assemblers that require movd instead of movq. */
1986 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1987 return "%vmovd\t{%1, %0|%0, %1}";
1989 return "%vmovq\t{%1, %0|%0, %1}";
1992 /* Handle broken assemblers that require movd instead of movq. */
1993 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1994 return "movd\t{%1, %0|%0, %1}";
1996 return "movq\t{%1, %0|%0, %1}";
1999 return standard_sse_constant_opcode (insn, operands[1]);
2002 return "pxor\t%0, %0";
2008 return "lea{q}\t{%E1, %0|%0, %E1}";
2011 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2012 if (get_attr_mode (insn) == MODE_SI)
2013 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2014 else if (which_alternative == 2)
2015 return "movabs{q}\t{%1, %0|%0, %1}";
2016 else if (ix86_use_lea_for_mov (insn, operands))
2017 return "lea{q}\t{%E1, %0|%0, %E1}";
2019 return "mov{q}\t{%1, %0|%0, %1}";
2023 (cond [(eq_attr "alternative" "4")
2024 (const_string "multi")
2025 (eq_attr "alternative" "5")
2026 (const_string "mmx")
2027 (eq_attr "alternative" "6,7,8,9")
2028 (const_string "mmxmov")
2029 (eq_attr "alternative" "10")
2030 (const_string "sselog1")
2031 (eq_attr "alternative" "11,12,13,14,15")
2032 (const_string "ssemov")
2033 (eq_attr "alternative" "16,17")
2034 (const_string "ssecvt")
2035 (match_operand 1 "pic_32bit_operand")
2036 (const_string "lea")
2038 (const_string "imov")))
2041 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2043 (const_string "*")))
2044 (set (attr "length_immediate")
2046 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2048 (const_string "*")))
2049 (set (attr "prefix_rex")
2050 (if_then_else (eq_attr "alternative" "8,9")
2052 (const_string "*")))
2053 (set (attr "prefix_data16")
2054 (if_then_else (eq_attr "alternative" "11")
2056 (const_string "*")))
2057 (set (attr "prefix")
2058 (if_then_else (eq_attr "alternative" "10,11,12,13,14,15")
2059 (const_string "maybe_vex")
2060 (const_string "orig")))
2062 (cond [(eq_attr "alternative" "0,4")
2064 (eq_attr "alternative" "10,12")
2065 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2066 (const_string "V4SF")
2067 (match_test "TARGET_AVX")
2069 (match_test "optimize_function_for_size_p (cfun)")
2070 (const_string "V4SF")
2072 (const_string "TI"))
2074 (const_string "DI")))])
2076 ;; Reload patterns to support multi-word load/store
2077 ;; with non-offsetable address.
2078 (define_expand "reload_noff_store"
2079 [(parallel [(match_operand 0 "memory_operand" "=m")
2080 (match_operand 1 "register_operand" "r")
2081 (match_operand:DI 2 "register_operand" "=&r")])]
2084 rtx mem = operands[0];
2085 rtx addr = XEXP (mem, 0);
2087 emit_move_insn (operands[2], addr);
2088 mem = replace_equiv_address_nv (mem, operands[2]);
2090 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
2094 (define_expand "reload_noff_load"
2095 [(parallel [(match_operand 0 "register_operand" "=r")
2096 (match_operand 1 "memory_operand" "m")
2097 (match_operand:DI 2 "register_operand" "=r")])]
2100 rtx mem = operands[1];
2101 rtx addr = XEXP (mem, 0);
2103 emit_move_insn (operands[2], addr);
2104 mem = replace_equiv_address_nv (mem, operands[2]);
2106 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
2110 ;; Convert impossible stores of immediate to existing instructions.
2111 ;; First try to get scratch register and go through it. In case this
2112 ;; fails, move by 32bit parts.
2114 [(match_scratch:DI 2 "r")
2115 (set (match_operand:DI 0 "memory_operand")
2116 (match_operand:DI 1 "immediate_operand"))]
2117 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2118 && !x86_64_immediate_operand (operands[1], DImode)"
2119 [(set (match_dup 2) (match_dup 1))
2120 (set (match_dup 0) (match_dup 2))])
2122 ;; We need to define this as both peepholer and splitter for case
2123 ;; peephole2 pass is not run.
2124 ;; "&& 1" is needed to keep it from matching the previous pattern.
2126 [(set (match_operand:DI 0 "memory_operand")
2127 (match_operand:DI 1 "immediate_operand"))]
2128 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2129 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2130 [(set (match_dup 2) (match_dup 3))
2131 (set (match_dup 4) (match_dup 5))]
2132 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2135 [(set (match_operand:DI 0 "memory_operand")
2136 (match_operand:DI 1 "immediate_operand"))]
2137 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2138 ? epilogue_completed : reload_completed)
2139 && !symbolic_operand (operands[1], DImode)
2140 && !x86_64_immediate_operand (operands[1], DImode)"
2141 [(set (match_dup 2) (match_dup 3))
2142 (set (match_dup 4) (match_dup 5))]
2143 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2145 (define_insn "*movdi_internal"
2146 [(set (match_operand:DI 0 "nonimmediate_operand"
2147 "=r ,o ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym")
2148 (match_operand:DI 1 "general_operand"
2149 "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))]
2150 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2152 switch (get_attr_type (insn))
2155 if (SSE_REG_P (operands[0]))
2156 return "movq2dq\t{%1, %0|%0, %1}";
2158 return "movdq2q\t{%1, %0|%0, %1}";
2161 switch (get_attr_mode (insn))
2164 return "%vmovdqa\t{%1, %0|%0, %1}";
2166 return "%vmovq\t{%1, %0|%0, %1}";
2168 return "%vmovaps\t{%1, %0|%0, %1}";
2170 return "movlps\t{%1, %0|%0, %1}";
2176 return "movq\t{%1, %0|%0, %1}";
2179 return standard_sse_constant_opcode (insn, operands[1]);
2182 return "pxor\t%0, %0";
2192 (cond [(eq_attr "alternative" "5,6,7,8,13,14")
2193 (const_string "sse2")
2194 (eq_attr "alternative" "9,10,11,12")
2195 (const_string "noavx")
2197 (const_string "*")))
2199 (cond [(eq_attr "alternative" "0,1")
2200 (const_string "multi")
2201 (eq_attr "alternative" "2")
2202 (const_string "mmx")
2203 (eq_attr "alternative" "3,4")
2204 (const_string "mmxmov")
2205 (eq_attr "alternative" "5,9")
2206 (const_string "sselog1")
2207 (eq_attr "alternative" "13,14")
2208 (const_string "ssecvt")
2210 (const_string "ssemov")))
2211 (set (attr "prefix")
2212 (if_then_else (eq_attr "alternative" "5,6,7,8")
2213 (const_string "maybe_vex")
2214 (const_string "orig")))
2216 (cond [(eq_attr "alternative" "9,11")
2217 (const_string "V4SF")
2218 (eq_attr "alternative" "10,12")
2219 (const_string "V2SF")
2220 (eq_attr "alternative" "5,7")
2221 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2222 (const_string "V4SF")
2223 (match_test "TARGET_AVX")
2225 (match_test "optimize_function_for_size_p (cfun)")
2226 (const_string "V4SF")
2228 (const_string "TI"))
2230 (const_string "DI")))])
2233 [(set (match_operand:DI 0 "nonimmediate_operand")
2234 (match_operand:DI 1 "general_operand"))]
2235 "!TARGET_64BIT && reload_completed
2236 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2237 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2239 "ix86_split_long_move (operands); DONE;")
2241 (define_insn "*movsi_internal"
2242 [(set (match_operand:SI 0 "nonimmediate_operand"
2243 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2244 (match_operand:SI 1 "general_operand"
2245 "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2246 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2248 switch (get_attr_type (insn))
2251 return standard_sse_constant_opcode (insn, operands[1]);
2254 switch (get_attr_mode (insn))
2257 return "%vmovdqa\t{%1, %0|%0, %1}";
2259 return "%vmovaps\t{%1, %0|%0, %1}";
2261 return "%vmovd\t{%1, %0|%0, %1}";
2263 return "%vmovss\t{%1, %0|%0, %1}";
2269 return "pxor\t%0, %0";
2272 if (get_attr_mode (insn) == MODE_DI)
2273 return "movq\t{%1, %0|%0, %1}";
2274 return "movd\t{%1, %0|%0, %1}";
2277 return "lea{l}\t{%E1, %0|%0, %E1}";
2280 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2281 if (ix86_use_lea_for_mov (insn, operands))
2282 return "lea{l}\t{%E1, %0|%0, %E1}";
2284 return "mov{l}\t{%1, %0|%0, %1}";
2288 (cond [(eq_attr "alternative" "2")
2289 (const_string "mmx")
2290 (eq_attr "alternative" "3,4,5")
2291 (const_string "mmxmov")
2292 (eq_attr "alternative" "6")
2293 (const_string "sselog1")
2294 (eq_attr "alternative" "7,8,9,10,11")
2295 (const_string "ssemov")
2296 (match_operand 1 "pic_32bit_operand")
2297 (const_string "lea")
2299 (const_string "imov")))
2300 (set (attr "prefix")
2301 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2302 (const_string "orig")
2303 (const_string "maybe_vex")))
2304 (set (attr "prefix_data16")
2305 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2307 (const_string "*")))
2309 (cond [(eq_attr "alternative" "2,3")
2311 (eq_attr "alternative" "6,7")
2312 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2313 (const_string "V4SF")
2314 (match_test "TARGET_AVX")
2316 (ior (not (match_test "TARGET_SSE2"))
2317 (match_test "optimize_function_for_size_p (cfun)"))
2318 (const_string "V4SF")
2320 (const_string "TI"))
2321 (and (eq_attr "alternative" "8,9,10,11")
2322 (not (match_test "TARGET_SSE2")))
2325 (const_string "SI")))])
2327 (define_insn "*movhi_internal"
2328 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2329 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2330 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2332 switch (get_attr_type (insn))
2335 /* movzwl is faster than movw on p2 due to partial word stalls,
2336 though not as fast as an aligned movl. */
2337 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2339 if (get_attr_mode (insn) == MODE_SI)
2340 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2342 return "mov{w}\t{%1, %0|%0, %1}";
2346 (cond [(match_test "optimize_function_for_size_p (cfun)")
2347 (const_string "imov")
2348 (and (eq_attr "alternative" "0")
2349 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2350 (not (match_test "TARGET_HIMODE_MATH"))))
2351 (const_string "imov")
2352 (and (eq_attr "alternative" "1,2")
2353 (match_operand:HI 1 "aligned_operand"))
2354 (const_string "imov")
2355 (and (match_test "TARGET_MOVX")
2356 (eq_attr "alternative" "0,2"))
2357 (const_string "imovx")
2359 (const_string "imov")))
2361 (cond [(eq_attr "type" "imovx")
2363 (and (eq_attr "alternative" "1,2")
2364 (match_operand:HI 1 "aligned_operand"))
2366 (and (eq_attr "alternative" "0")
2367 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2368 (not (match_test "TARGET_HIMODE_MATH"))))
2371 (const_string "HI")))])
2373 ;; Situation is quite tricky about when to choose full sized (SImode) move
2374 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2375 ;; partial register dependency machines (such as AMD Athlon), where QImode
2376 ;; moves issue extra dependency and for partial register stalls machines
2377 ;; that don't use QImode patterns (and QImode move cause stall on the next
2380 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2381 ;; register stall machines with, where we use QImode instructions, since
2382 ;; partial register stall can be caused there. Then we use movzx.
2383 (define_insn "*movqi_internal"
2384 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2385 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2386 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2388 switch (get_attr_type (insn))
2391 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2392 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2394 if (get_attr_mode (insn) == MODE_SI)
2395 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2397 return "mov{b}\t{%1, %0|%0, %1}";
2401 (cond [(and (eq_attr "alternative" "5")
2402 (not (match_operand:QI 1 "aligned_operand")))
2403 (const_string "imovx")
2404 (match_test "optimize_function_for_size_p (cfun)")
2405 (const_string "imov")
2406 (and (eq_attr "alternative" "3")
2407 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2408 (not (match_test "TARGET_QIMODE_MATH"))))
2409 (const_string "imov")
2410 (eq_attr "alternative" "3,5")
2411 (const_string "imovx")
2412 (and (match_test "TARGET_MOVX")
2413 (eq_attr "alternative" "2"))
2414 (const_string "imovx")
2416 (const_string "imov")))
2418 (cond [(eq_attr "alternative" "3,4,5")
2420 (eq_attr "alternative" "6")
2422 (eq_attr "type" "imovx")
2424 (and (eq_attr "type" "imov")
2425 (and (eq_attr "alternative" "0,1")
2426 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2427 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2428 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2430 ;; Avoid partial register stalls when not using QImode arithmetic
2431 (and (eq_attr "type" "imov")
2432 (and (eq_attr "alternative" "0,1")
2433 (and (match_test "TARGET_PARTIAL_REG_STALL")
2434 (not (match_test "TARGET_QIMODE_MATH")))))
2437 (const_string "QI")))])
2439 ;; Stores and loads of ax to arbitrary constant address.
2440 ;; We fake an second form of instruction to force reload to load address
2441 ;; into register when rax is not available
2442 (define_insn "*movabs<mode>_1"
2443 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2444 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2445 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2447 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2448 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2449 [(set_attr "type" "imov")
2450 (set_attr "modrm" "0,*")
2451 (set_attr "length_address" "8,0")
2452 (set_attr "length_immediate" "0,*")
2453 (set_attr "memory" "store")
2454 (set_attr "mode" "<MODE>")])
2456 (define_insn "*movabs<mode>_2"
2457 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2458 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2459 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2461 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2462 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2463 [(set_attr "type" "imov")
2464 (set_attr "modrm" "0,*")
2465 (set_attr "length_address" "8,0")
2466 (set_attr "length_immediate" "0")
2467 (set_attr "memory" "load")
2468 (set_attr "mode" "<MODE>")])
2470 (define_insn "swap<mode>"
2471 [(set (match_operand:SWI48 0 "register_operand" "+r")
2472 (match_operand:SWI48 1 "register_operand" "+r"))
2476 "xchg{<imodesuffix>}\t%1, %0"
2477 [(set_attr "type" "imov")
2478 (set_attr "mode" "<MODE>")
2479 (set_attr "pent_pair" "np")
2480 (set_attr "athlon_decode" "vector")
2481 (set_attr "amdfam10_decode" "double")
2482 (set_attr "bdver1_decode" "double")])
2484 (define_insn "*swap<mode>_1"
2485 [(set (match_operand:SWI12 0 "register_operand" "+r")
2486 (match_operand:SWI12 1 "register_operand" "+r"))
2489 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2491 [(set_attr "type" "imov")
2492 (set_attr "mode" "SI")
2493 (set_attr "pent_pair" "np")
2494 (set_attr "athlon_decode" "vector")
2495 (set_attr "amdfam10_decode" "double")
2496 (set_attr "bdver1_decode" "double")])
2498 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2499 ;; is disabled for AMDFAM10
2500 (define_insn "*swap<mode>_2"
2501 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2502 (match_operand:SWI12 1 "register_operand" "+<r>"))
2505 "TARGET_PARTIAL_REG_STALL"
2506 "xchg{<imodesuffix>}\t%1, %0"
2507 [(set_attr "type" "imov")
2508 (set_attr "mode" "<MODE>")
2509 (set_attr "pent_pair" "np")
2510 (set_attr "athlon_decode" "vector")])
2512 (define_expand "movstrict<mode>"
2513 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2514 (match_operand:SWI12 1 "general_operand"))]
2517 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2519 if (GET_CODE (operands[0]) == SUBREG
2520 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2522 /* Don't generate memory->memory moves, go through a register */
2523 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2524 operands[1] = force_reg (<MODE>mode, operands[1]);
2527 (define_insn "*movstrict<mode>_1"
2528 [(set (strict_low_part
2529 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2530 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2531 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2532 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2533 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2534 [(set_attr "type" "imov")
2535 (set_attr "mode" "<MODE>")])
2537 (define_insn "*movstrict<mode>_xor"
2538 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2539 (match_operand:SWI12 1 "const0_operand"))
2540 (clobber (reg:CC FLAGS_REG))]
2542 "xor{<imodesuffix>}\t%0, %0"
2543 [(set_attr "type" "alu1")
2544 (set_attr "mode" "<MODE>")
2545 (set_attr "length_immediate" "0")])
2547 (define_insn "*mov<mode>_extv_1"
2548 [(set (match_operand:SWI24 0 "register_operand" "=R")
2549 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2553 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2554 [(set_attr "type" "imovx")
2555 (set_attr "mode" "SI")])
2557 (define_insn "*movqi_extv_1_rex64"
2558 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2559 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2564 switch (get_attr_type (insn))
2567 return "movs{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_extv_1"
2583 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2584 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2589 switch (get_attr_type (insn))
2592 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2594 return "mov{b}\t{%h1, %0|%0, %h1}";
2598 (if_then_else (and (match_operand:QI 0 "register_operand")
2599 (ior (not (match_operand:QI 0 "QIreg_operand"))
2600 (match_test "TARGET_MOVX")))
2601 (const_string "imovx")
2602 (const_string "imov")))
2604 (if_then_else (eq_attr "type" "imovx")
2606 (const_string "QI")))])
2608 (define_insn "*mov<mode>_extzv_1"
2609 [(set (match_operand:SWI48 0 "register_operand" "=R")
2610 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2614 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2615 [(set_attr "type" "imovx")
2616 (set_attr "mode" "SI")])
2618 (define_insn "*movqi_extzv_2_rex64"
2619 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2621 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2626 switch (get_attr_type (insn))
2629 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2631 return "mov{b}\t{%h1, %0|%0, %h1}";
2635 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand"))
2636 (match_test "TARGET_MOVX"))
2637 (const_string "imovx")
2638 (const_string "imov")))
2640 (if_then_else (eq_attr "type" "imovx")
2642 (const_string "QI")))])
2644 (define_insn "*movqi_extzv_2"
2645 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2647 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2652 switch (get_attr_type (insn))
2655 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2657 return "mov{b}\t{%h1, %0|%0, %h1}";
2661 (if_then_else (and (match_operand:QI 0 "register_operand")
2662 (ior (not (match_operand:QI 0 "QIreg_operand"))
2663 (match_test "TARGET_MOVX")))
2664 (const_string "imovx")
2665 (const_string "imov")))
2667 (if_then_else (eq_attr "type" "imovx")
2669 (const_string "QI")))])
2671 (define_expand "mov<mode>_insv_1"
2672 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand")
2675 (match_operand:SWI48 1 "nonmemory_operand"))])
2677 (define_insn "*mov<mode>_insv_1_rex64"
2678 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2681 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2683 "mov{b}\t{%b1, %h0|%h0, %b1}"
2684 [(set_attr "type" "imov")
2685 (set_attr "mode" "QI")])
2687 (define_insn "*movsi_insv_1"
2688 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2691 (match_operand:SI 1 "general_operand" "Qmn"))]
2693 "mov{b}\t{%b1, %h0|%h0, %b1}"
2694 [(set_attr "type" "imov")
2695 (set_attr "mode" "QI")])
2697 (define_insn "*movqi_insv_2"
2698 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2701 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2704 "mov{b}\t{%h1, %h0|%h0, %h1}"
2705 [(set_attr "type" "imov")
2706 (set_attr "mode" "QI")])
2708 ;; Floating point push instructions.
2710 (define_insn "*pushtf"
2711 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2712 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2715 /* This insn should be already split before reg-stack. */
2718 [(set_attr "type" "multi")
2719 (set_attr "unit" "sse,*,*")
2720 (set_attr "mode" "TF,SI,SI")])
2722 ;; %%% Kill this when call knows how to work this out.
2724 [(set (match_operand:TF 0 "push_operand")
2725 (match_operand:TF 1 "sse_reg_operand"))]
2726 "TARGET_SSE && reload_completed"
2727 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2728 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2730 (define_insn "*pushxf"
2731 [(set (match_operand:XF 0 "push_operand" "=<,<")
2732 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2733 "optimize_function_for_speed_p (cfun)"
2735 /* This insn should be already split before reg-stack. */
2738 [(set_attr "type" "multi")
2739 (set_attr "unit" "i387,*")
2740 (set_attr "mode" "XF,SI")])
2742 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2743 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2744 ;; Pushing using integer instructions is longer except for constants
2745 ;; and direct memory references (assuming that any given constant is pushed
2746 ;; only once, but this ought to be handled elsewhere).
2748 (define_insn "*pushxf_nointeger"
2749 [(set (match_operand:XF 0 "push_operand" "=<,<")
2750 (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2751 "optimize_function_for_size_p (cfun)"
2753 /* This insn should be already split before reg-stack. */
2756 [(set_attr "type" "multi")
2757 (set_attr "unit" "i387,*")
2758 (set_attr "mode" "XF,SI")])
2760 ;; %%% Kill this when call knows how to work this out.
2762 [(set (match_operand:XF 0 "push_operand")
2763 (match_operand:XF 1 "fp_register_operand"))]
2765 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2766 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2767 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2769 (define_insn "*pushdf_rex64"
2770 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2771 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
2774 /* This insn should be already split before reg-stack. */
2777 [(set_attr "type" "multi")
2778 (set_attr "unit" "i387,*,*")
2779 (set_attr "mode" "DF,DI,DF")])
2781 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2782 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2783 ;; On the average, pushdf using integers can be still shorter.
2785 (define_insn "*pushdf"
2786 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2787 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
2790 /* This insn should be already split before reg-stack. */
2793 [(set_attr "isa" "*,*,sse2")
2794 (set_attr "type" "multi")
2795 (set_attr "unit" "i387,*,*")
2796 (set_attr "mode" "DF,DI,DF")])
2798 ;; %%% Kill this when call knows how to work this out.
2800 [(set (match_operand:DF 0 "push_operand")
2801 (match_operand:DF 1 "any_fp_register_operand"))]
2803 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2804 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2806 (define_insn "*pushsf_rex64"
2807 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2808 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2811 /* Anything else should be already split before reg-stack. */
2812 gcc_assert (which_alternative == 1);
2813 return "push{q}\t%q1";
2815 [(set_attr "type" "multi,push,multi")
2816 (set_attr "unit" "i387,*,*")
2817 (set_attr "mode" "SF,DI,SF")])
2819 (define_insn "*pushsf"
2820 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2821 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2824 /* Anything else should be already split before reg-stack. */
2825 gcc_assert (which_alternative == 1);
2826 return "push{l}\t%1";
2828 [(set_attr "type" "multi,push,multi")
2829 (set_attr "unit" "i387,*,*")
2830 (set_attr "mode" "SF,SI,SF")])
2832 ;; %%% Kill this when call knows how to work this out.
2834 [(set (match_operand:SF 0 "push_operand")
2835 (match_operand:SF 1 "any_fp_register_operand"))]
2837 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2838 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2839 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2842 [(set (match_operand:SF 0 "push_operand")
2843 (match_operand:SF 1 "memory_operand"))]
2845 && (operands[2] = find_constant_src (insn))"
2846 [(set (match_dup 0) (match_dup 2))])
2849 [(set (match_operand 0 "push_operand")
2850 (match_operand 1 "general_operand"))]
2852 && (GET_MODE (operands[0]) == TFmode
2853 || GET_MODE (operands[0]) == XFmode
2854 || GET_MODE (operands[0]) == DFmode)
2855 && !ANY_FP_REG_P (operands[1])"
2857 "ix86_split_long_move (operands); DONE;")
2859 ;; Floating point move instructions.
2861 (define_expand "movtf"
2862 [(set (match_operand:TF 0 "nonimmediate_operand")
2863 (match_operand:TF 1 "nonimmediate_operand"))]
2866 ix86_expand_move (TFmode, operands);
2870 (define_expand "mov<mode>"
2871 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2872 (match_operand:X87MODEF 1 "general_operand"))]
2874 "ix86_expand_move (<MODE>mode, operands); DONE;")
2876 (define_insn "*movtf_internal"
2877 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
2878 (match_operand:TF 1 "general_operand" "C ,xm,x,*roF,F*r"))]
2880 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2881 && (!can_create_pseudo_p ()
2882 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2883 || GET_CODE (operands[1]) != CONST_DOUBLE
2884 || (optimize_function_for_size_p (cfun)
2885 && standard_sse_constant_p (operands[1])
2886 && !memory_operand (operands[0], TFmode))
2887 || (!TARGET_MEMORY_MISMATCH_STALL
2888 && memory_operand (operands[0], TFmode)))"
2890 switch (which_alternative)
2893 return standard_sse_constant_opcode (insn, operands[1]);
2896 /* Handle misaligned load/store since we
2897 don't have movmisaligntf pattern. */
2898 if (misaligned_operand (operands[0], TFmode)
2899 || misaligned_operand (operands[1], TFmode))
2901 if (get_attr_mode (insn) == MODE_V4SF)
2902 return "%vmovups\t{%1, %0|%0, %1}";
2904 return "%vmovdqu\t{%1, %0|%0, %1}";
2908 if (get_attr_mode (insn) == MODE_V4SF)
2909 return "%vmovaps\t{%1, %0|%0, %1}";
2911 return "%vmovdqa\t{%1, %0|%0, %1}";
2922 [(set_attr "type" "sselog1,ssemov,ssemov,*,*")
2923 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2925 (cond [(eq_attr "alternative" "3,4")
2927 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2928 (const_string "V4SF")
2929 (and (eq_attr "alternative" "2")
2930 (match_test "TARGET_SSE_TYPELESS_STORES"))
2931 (const_string "V4SF")
2932 (match_test "TARGET_AVX")
2934 (ior (not (match_test "TARGET_SSE2"))
2935 (match_test "optimize_function_for_size_p (cfun)"))
2936 (const_string "V4SF")
2938 (const_string "TI")))])
2940 ;; Possible store forwarding (partial memory) stall in alternative 4.
2941 (define_insn "*movxf_internal"
2942 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2943 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,FYx*r"))]
2944 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2945 && (!can_create_pseudo_p ()
2946 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2947 || GET_CODE (operands[1]) != CONST_DOUBLE
2948 || (optimize_function_for_size_p (cfun)
2949 && standard_80387_constant_p (operands[1]) > 0
2950 && !memory_operand (operands[0], XFmode))
2951 || (!TARGET_MEMORY_MISMATCH_STALL
2952 && memory_operand (operands[0], XFmode)))"
2954 switch (which_alternative)
2958 return output_387_reg_move (insn, operands);
2961 return standard_80387_constant_opcode (operands[1]);
2971 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2972 (set_attr "mode" "XF,XF,XF,SI,SI")])
2974 (define_insn "*movdf_internal_rex64"
2975 [(set (match_operand:DF 0 "nonimmediate_operand"
2976 "=f,m,f,?r,?m,?r,!o,x,x,x,m,Yi,r ")
2977 (match_operand:DF 1 "general_operand"
2978 "fm,f,G,rm,r ,F ,F ,C,x,m,x,r ,Yi"))]
2979 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2980 && (!can_create_pseudo_p ()
2981 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2982 || GET_CODE (operands[1]) != CONST_DOUBLE
2983 || (optimize_function_for_size_p (cfun)
2984 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2985 && standard_80387_constant_p (operands[1]) > 0)
2986 || (TARGET_SSE2 && TARGET_SSE_MATH
2987 && standard_sse_constant_p (operands[1]))))
2988 || memory_operand (operands[0], DFmode))"
2990 switch (which_alternative)
2994 return output_387_reg_move (insn, operands);
2997 return standard_80387_constant_opcode (operands[1]);
3001 return "mov{q}\t{%1, %0|%0, %1}";
3004 return "movabs{q}\t{%1, %0|%0, %1}";
3010 return standard_sse_constant_opcode (insn, operands[1]);
3015 switch (get_attr_mode (insn))
3018 return "%vmovapd\t{%1, %0|%0, %1}";
3020 return "%vmovaps\t{%1, %0|%0, %1}";
3023 return "%vmovq\t{%1, %0|%0, %1}";
3025 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3026 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3027 return "%vmovsd\t{%1, %0|%0, %1}";
3029 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3031 return "%vmovlps\t{%1, %d0|%d0, %1}";
3038 /* Handle broken assemblers that require movd instead of movq. */
3039 return "%vmovd\t{%1, %0|%0, %1}";
3046 (cond [(eq_attr "alternative" "0,1,2")
3047 (const_string "fmov")
3048 (eq_attr "alternative" "3,4,5")
3049 (const_string "imov")
3050 (eq_attr "alternative" "6")
3051 (const_string "multi")
3052 (eq_attr "alternative" "7")
3053 (const_string "sselog1")
3055 (const_string "ssemov")))
3058 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3060 (const_string "*")))
3061 (set (attr "length_immediate")
3063 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3065 (const_string "*")))
3066 (set (attr "prefix")
3067 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3068 (const_string "orig")
3069 (const_string "maybe_vex")))
3070 (set (attr "prefix_data16")
3071 (if_then_else (eq_attr "mode" "V1DF")
3073 (const_string "*")))
3075 (cond [(eq_attr "alternative" "0,1,2")
3077 (eq_attr "alternative" "3,4,5,6,11,12")
3080 /* xorps is one byte shorter for !TARGET_AVX. */
3081 (eq_attr "alternative" "7")
3082 (cond [(match_test "TARGET_AVX")
3083 (const_string "V2DF")
3084 (match_test "optimize_function_for_size_p (cfun)")
3085 (const_string "V4SF")
3086 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3089 (const_string "V2DF"))
3091 /* For architectures resolving dependencies on
3092 whole SSE registers use APD move to break dependency
3093 chains, otherwise use short move to avoid extra work.
3095 movaps encodes one byte shorter for !TARGET_AVX. */
3096 (eq_attr "alternative" "8")
3097 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3098 (const_string "V4SF")
3099 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3100 (const_string "V2DF")
3101 (match_test "TARGET_AVX")
3103 (match_test "optimize_function_for_size_p (cfun)")
3104 (const_string "V4SF")
3106 (const_string "DF"))
3107 /* For architectures resolving dependencies on register
3108 parts we may avoid extra work to zero out upper part
3110 (eq_attr "alternative" "9")
3112 (match_test "TARGET_SSE_SPLIT_REGS")
3113 (const_string "V1DF")
3114 (const_string "DF"))
3116 (const_string "DF")))])
3118 ;; Possible store forwarding (partial memory) stall in alternative 4.
3119 (define_insn "*movdf_internal"
3120 [(set (match_operand:DF 0 "nonimmediate_operand"
3121 "=f,m,f,?Yd*r ,!o ,x,x,x,m,*x,*x,*x,m")
3122 (match_operand:DF 1 "general_operand"
3123 "fm,f,G,Yd*roF,FYd*r,C,x,m,x,C ,*x,m ,*x"))]
3124 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3125 && (!can_create_pseudo_p ()
3126 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3127 || GET_CODE (operands[1]) != CONST_DOUBLE
3128 || (optimize_function_for_size_p (cfun)
3129 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3130 && standard_80387_constant_p (operands[1]) > 0)
3131 || (TARGET_SSE2 && TARGET_SSE_MATH
3132 && standard_sse_constant_p (operands[1])))
3133 && !memory_operand (operands[0], DFmode))
3134 || (!TARGET_MEMORY_MISMATCH_STALL
3135 && memory_operand (operands[0], DFmode)))"
3137 switch (which_alternative)
3141 return output_387_reg_move (insn, operands);
3144 return standard_80387_constant_opcode (operands[1]);
3152 return standard_sse_constant_opcode (insn, operands[1]);
3160 switch (get_attr_mode (insn))
3163 return "%vmovapd\t{%1, %0|%0, %1}";
3165 return "%vmovaps\t{%1, %0|%0, %1}";
3168 return "%vmovq\t{%1, %0|%0, %1}";
3170 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3171 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3172 return "%vmovsd\t{%1, %0|%0, %1}";
3174 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3176 return "%vmovlps\t{%1, %d0|%d0, %1}";
3186 (if_then_else (eq_attr "alternative" "5,6,7,8")
3187 (const_string "sse2")
3188 (const_string "*")))
3190 (cond [(eq_attr "alternative" "0,1,2")
3191 (const_string "fmov")
3192 (eq_attr "alternative" "3,4")
3193 (const_string "multi")
3194 (eq_attr "alternative" "5,9")
3195 (const_string "sselog1")
3197 (const_string "ssemov")))
3198 (set (attr "prefix")
3199 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3200 (const_string "orig")
3201 (const_string "maybe_vex")))
3202 (set (attr "prefix_data16")
3203 (if_then_else (eq_attr "mode" "V1DF")
3205 (const_string "*")))
3207 (cond [(eq_attr "alternative" "0,1,2")
3209 (eq_attr "alternative" "3,4")
3212 /* For SSE1, we have many fewer alternatives. */
3213 (not (match_test "TARGET_SSE2"))
3215 (eq_attr "alternative" "5,6,9,10")
3216 (const_string "V4SF")
3217 (const_string "V2SF"))
3219 /* xorps is one byte shorter for !TARGET_AVX. */
3220 (eq_attr "alternative" "5,9")
3221 (cond [(match_test "TARGET_AVX")
3222 (const_string "V2DF")
3223 (match_test "optimize_function_for_size_p (cfun)")
3224 (const_string "V4SF")
3225 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3228 (const_string "V2DF"))
3230 /* For architectures resolving dependencies on
3231 whole SSE registers use APD move to break dependency
3232 chains, otherwise use short move to avoid extra work.
3234 movaps encodes one byte shorter for !TARGET_AVX. */
3235 (eq_attr "alternative" "6,10")
3236 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3237 (const_string "V4SF")
3238 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3239 (const_string "V2DF")
3240 (match_test "TARGET_AVX")
3242 (match_test "optimize_function_for_size_p (cfun)")
3243 (const_string "V4SF")
3245 (const_string "DF"))
3247 /* For architectures resolving dependencies on register
3248 parts we may avoid extra work to zero out upper part
3250 (eq_attr "alternative" "7,11")
3252 (match_test "TARGET_SSE_SPLIT_REGS")
3253 (const_string "V1DF")
3254 (const_string "DF"))
3256 (const_string "DF")))])
3258 (define_insn "*movsf_internal"
3259 [(set (match_operand:SF 0 "nonimmediate_operand"
3260 "=f,m,f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3261 (match_operand:SF 1 "general_operand"
3262 "fm,f,G,rmF,Fr,C,x,m,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3263 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3264 && (!can_create_pseudo_p ()
3265 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3266 || GET_CODE (operands[1]) != CONST_DOUBLE
3267 || (optimize_function_for_size_p (cfun)
3268 && ((!TARGET_SSE_MATH
3269 && standard_80387_constant_p (operands[1]) > 0)
3271 && standard_sse_constant_p (operands[1]))))
3272 || memory_operand (operands[0], SFmode))"
3274 switch (which_alternative)
3278 return output_387_reg_move (insn, operands);
3281 return standard_80387_constant_opcode (operands[1]);
3285 return "mov{l}\t{%1, %0|%0, %1}";
3288 return standard_sse_constant_opcode (insn, operands[1]);
3291 if (get_attr_mode (insn) == MODE_V4SF)
3292 return "%vmovaps\t{%1, %0|%0, %1}";
3294 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3298 return "%vmovss\t{%1, %0|%0, %1}";
3304 return "movd\t{%1, %0|%0, %1}";
3307 return "movq\t{%1, %0|%0, %1}";
3311 return "%vmovd\t{%1, %0|%0, %1}";
3318 (cond [(eq_attr "alternative" "0,1,2")
3319 (const_string "fmov")
3320 (eq_attr "alternative" "3,4")
3321 (const_string "multi")
3322 (eq_attr "alternative" "5")
3323 (const_string "sselog1")
3324 (eq_attr "alternative" "9,10,11,14,15")
3325 (const_string "mmxmov")
3327 (const_string "ssemov")))
3328 (set (attr "prefix")
3329 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3330 (const_string "maybe_vex")
3331 (const_string "orig")))
3333 (cond [(eq_attr "alternative" "3,4,9,10")
3335 (eq_attr "alternative" "5")
3336 (cond [(match_test "TARGET_AVX")
3337 (const_string "V4SF")
3338 (ior (not (match_test "TARGET_SSE2"))
3339 (match_test "optimize_function_for_size_p (cfun)"))
3340 (const_string "V4SF")
3341 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3344 (const_string "V4SF"))
3346 /* For architectures resolving dependencies on
3347 whole SSE registers use APS move to break dependency
3348 chains, otherwise use short move to avoid extra work.
3350 Do the same for architectures resolving dependencies on
3351 the parts. While in DF mode it is better to always handle
3352 just register parts, the SF mode is different due to lack
3353 of instructions to load just part of the register. It is
3354 better to maintain the whole registers in single format
3355 to avoid problems on using packed logical operations. */
3356 (eq_attr "alternative" "6")
3358 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3359 (match_test "TARGET_SSE_SPLIT_REGS"))
3360 (const_string "V4SF")
3361 (const_string "SF"))
3362 (eq_attr "alternative" "11")
3363 (const_string "DI")]
3364 (const_string "SF")))])
3367 [(set (match_operand 0 "any_fp_register_operand")
3368 (match_operand 1 "memory_operand"))]
3370 && (GET_MODE (operands[0]) == TFmode
3371 || GET_MODE (operands[0]) == XFmode
3372 || GET_MODE (operands[0]) == DFmode
3373 || GET_MODE (operands[0]) == SFmode)
3374 && (operands[2] = find_constant_src (insn))"
3375 [(set (match_dup 0) (match_dup 2))]
3377 rtx c = operands[2];
3378 int r = REGNO (operands[0]);
3380 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3381 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3386 [(set (match_operand 0 "any_fp_register_operand")
3387 (float_extend (match_operand 1 "memory_operand")))]
3389 && (GET_MODE (operands[0]) == TFmode
3390 || GET_MODE (operands[0]) == XFmode
3391 || GET_MODE (operands[0]) == DFmode)
3392 && (operands[2] = find_constant_src (insn))"
3393 [(set (match_dup 0) (match_dup 2))]
3395 rtx c = operands[2];
3396 int r = REGNO (operands[0]);
3398 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3399 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3403 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3405 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3406 (match_operand:X87MODEF 1 "immediate_operand"))]
3408 && (standard_80387_constant_p (operands[1]) == 8
3409 || standard_80387_constant_p (operands[1]) == 9)"
3410 [(set (match_dup 0)(match_dup 1))
3412 (neg:X87MODEF (match_dup 0)))]
3416 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3417 if (real_isnegzero (&r))
3418 operands[1] = CONST0_RTX (<MODE>mode);
3420 operands[1] = CONST1_RTX (<MODE>mode);
3424 [(set (match_operand 0 "nonimmediate_operand")
3425 (match_operand 1 "general_operand"))]
3427 && (GET_MODE (operands[0]) == TFmode
3428 || GET_MODE (operands[0]) == XFmode
3429 || GET_MODE (operands[0]) == DFmode)
3430 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3432 "ix86_split_long_move (operands); DONE;")
3434 (define_insn "swapxf"
3435 [(set (match_operand:XF 0 "register_operand" "+f")
3436 (match_operand:XF 1 "register_operand" "+f"))
3441 if (STACK_TOP_P (operands[0]))
3446 [(set_attr "type" "fxch")
3447 (set_attr "mode" "XF")])
3449 (define_insn "*swap<mode>"
3450 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3451 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3454 "TARGET_80387 || reload_completed"
3456 if (STACK_TOP_P (operands[0]))
3461 [(set_attr "type" "fxch")
3462 (set_attr "mode" "<MODE>")])
3464 ;; Zero extension instructions
3466 (define_expand "zero_extendsidi2"
3467 [(set (match_operand:DI 0 "nonimmediate_operand")
3468 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3470 (define_insn "*zero_extendsidi2_rex64"
3471 [(set (match_operand:DI 0 "nonimmediate_operand"
3472 "=r ,o,?*Ym,?*y,?*Yi,?*x")
3474 (match_operand:SI 1 "x86_64_zext_general_operand"
3475 "rmWz,0,r ,m ,r ,m")))]
3478 mov{l}\t{%1, %k0|%k0, %1}
3480 movd\t{%1, %0|%0, %1}
3481 movd\t{%1, %0|%0, %1}
3482 %vmovd\t{%1, %0|%0, %1}
3483 %vmovd\t{%1, %0|%0, %1}"
3484 [(set_attr "type" "imovx,multi,mmxmov,mmxmov,ssemov,ssemov")
3485 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3486 (set_attr "prefix_0f" "0,*,*,*,*,*")
3487 (set_attr "mode" "SI,SI,DI,DI,TI,TI")])
3489 (define_insn "*zero_extendsidi2"
3490 [(set (match_operand:DI 0 "nonimmediate_operand"
3491 "=ro,?r,?o,?*Ym,?*y,?*Yi,?*x")
3492 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand"
3493 "0 ,rm,r ,r ,m ,r ,m")))]
3499 movd\t{%1, %0|%0, %1}
3500 movd\t{%1, %0|%0, %1}
3501 %vmovd\t{%1, %0|%0, %1}
3502 %vmovd\t{%1, %0|%0, %1}"
3503 [(set_attr "isa" "*,*,*,*,*,*,sse2")
3504 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3505 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3506 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3509 [(set (match_operand:DI 0 "memory_operand")
3510 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3512 [(set (match_dup 4) (const_int 0))]
3513 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3516 [(set (match_operand:DI 0 "register_operand")
3517 (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3518 "!TARGET_64BIT && reload_completed
3519 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3520 && true_regnum (operands[0]) == true_regnum (operands[1])"
3521 [(set (match_dup 4) (const_int 0))]
3522 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3525 [(set (match_operand:DI 0 "nonimmediate_operand")
3526 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3527 "!TARGET_64BIT && reload_completed
3528 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3529 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3530 [(set (match_dup 3) (match_dup 1))
3531 (set (match_dup 4) (const_int 0))]
3532 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3534 (define_insn "zero_extend<mode>di2"
3535 [(set (match_operand:DI 0 "register_operand" "=r")
3537 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3539 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3540 [(set_attr "type" "imovx")
3541 (set_attr "mode" "SI")])
3543 (define_expand "zero_extend<mode>si2"
3544 [(set (match_operand:SI 0 "register_operand")
3545 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3548 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3550 operands[1] = force_reg (<MODE>mode, operands[1]);
3551 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3556 (define_insn_and_split "zero_extend<mode>si2_and"
3557 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3559 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3560 (clobber (reg:CC FLAGS_REG))]
3561 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3563 "&& reload_completed"
3564 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3565 (clobber (reg:CC FLAGS_REG))])]
3567 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3569 ix86_expand_clear (operands[0]);
3571 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3572 emit_insn (gen_movstrict<mode>
3573 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3577 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3579 [(set_attr "type" "alu1")
3580 (set_attr "mode" "SI")])
3582 (define_insn "*zero_extend<mode>si2"
3583 [(set (match_operand:SI 0 "register_operand" "=r")
3585 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3586 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3587 "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3588 [(set_attr "type" "imovx")
3589 (set_attr "mode" "SI")])
3591 (define_expand "zero_extendqihi2"
3592 [(set (match_operand:HI 0 "register_operand")
3593 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3596 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3598 operands[1] = force_reg (QImode, operands[1]);
3599 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3604 (define_insn_and_split "zero_extendqihi2_and"
3605 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3606 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3607 (clobber (reg:CC FLAGS_REG))]
3608 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3610 "&& reload_completed"
3611 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3612 (clobber (reg:CC FLAGS_REG))])]
3614 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3616 ix86_expand_clear (operands[0]);
3618 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3619 emit_insn (gen_movstrictqi
3620 (gen_lowpart (QImode, operands[0]), operands[1]));
3624 operands[0] = gen_lowpart (SImode, operands[0]);
3626 [(set_attr "type" "alu1")
3627 (set_attr "mode" "SI")])
3629 ; zero extend to SImode to avoid partial register stalls
3630 (define_insn "*zero_extendqihi2"
3631 [(set (match_operand:HI 0 "register_operand" "=r")
3632 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3633 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3634 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3635 [(set_attr "type" "imovx")
3636 (set_attr "mode" "SI")])
3638 ;; Sign extension instructions
3640 (define_expand "extendsidi2"
3641 [(set (match_operand:DI 0 "register_operand")
3642 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3647 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3652 (define_insn "*extendsidi2_rex64"
3653 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3654 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3658 movs{lq|x}\t{%1, %0|%0, %1}"
3659 [(set_attr "type" "imovx")
3660 (set_attr "mode" "DI")
3661 (set_attr "prefix_0f" "0")
3662 (set_attr "modrm" "0,1")])
3664 (define_insn "extendsidi2_1"
3665 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3666 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3667 (clobber (reg:CC FLAGS_REG))
3668 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3672 ;; Extend to memory case when source register does die.
3674 [(set (match_operand:DI 0 "memory_operand")
3675 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3676 (clobber (reg:CC FLAGS_REG))
3677 (clobber (match_operand:SI 2 "register_operand"))]
3679 && dead_or_set_p (insn, operands[1])
3680 && !reg_mentioned_p (operands[1], operands[0]))"
3681 [(set (match_dup 3) (match_dup 1))
3682 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3683 (clobber (reg:CC FLAGS_REG))])
3684 (set (match_dup 4) (match_dup 1))]
3685 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3687 ;; Extend to memory case when source register does not die.
3689 [(set (match_operand:DI 0 "memory_operand")
3690 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3691 (clobber (reg:CC FLAGS_REG))
3692 (clobber (match_operand:SI 2 "register_operand"))]
3696 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3698 emit_move_insn (operands[3], operands[1]);
3700 /* Generate a cltd if possible and doing so it profitable. */
3701 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3702 && true_regnum (operands[1]) == AX_REG
3703 && true_regnum (operands[2]) == DX_REG)
3705 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3709 emit_move_insn (operands[2], operands[1]);
3710 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3712 emit_move_insn (operands[4], operands[2]);
3716 ;; Extend to register case. Optimize case where source and destination
3717 ;; registers match and cases where we can use cltd.
3719 [(set (match_operand:DI 0 "register_operand")
3720 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3721 (clobber (reg:CC FLAGS_REG))
3722 (clobber (match_scratch:SI 2))]
3726 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3728 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3729 emit_move_insn (operands[3], operands[1]);
3731 /* Generate a cltd if possible and doing so it profitable. */
3732 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3733 && true_regnum (operands[3]) == AX_REG
3734 && true_regnum (operands[4]) == DX_REG)
3736 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3740 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3741 emit_move_insn (operands[4], operands[1]);
3743 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3747 (define_insn "extend<mode>di2"
3748 [(set (match_operand:DI 0 "register_operand" "=r")
3750 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3752 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3753 [(set_attr "type" "imovx")
3754 (set_attr "mode" "DI")])
3756 (define_insn "extendhisi2"
3757 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3758 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3761 switch (get_attr_prefix_0f (insn))
3764 return "{cwtl|cwde}";
3766 return "movs{wl|x}\t{%1, %0|%0, %1}";
3769 [(set_attr "type" "imovx")
3770 (set_attr "mode" "SI")
3771 (set (attr "prefix_0f")
3772 ;; movsx is short decodable while cwtl is vector decoded.
3773 (if_then_else (and (eq_attr "cpu" "!k6")
3774 (eq_attr "alternative" "0"))
3776 (const_string "1")))
3778 (if_then_else (eq_attr "prefix_0f" "0")
3780 (const_string "1")))])
3782 (define_insn "*extendhisi2_zext"
3783 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3786 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3789 switch (get_attr_prefix_0f (insn))
3792 return "{cwtl|cwde}";
3794 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3797 [(set_attr "type" "imovx")
3798 (set_attr "mode" "SI")
3799 (set (attr "prefix_0f")
3800 ;; movsx is short decodable while cwtl is vector decoded.
3801 (if_then_else (and (eq_attr "cpu" "!k6")
3802 (eq_attr "alternative" "0"))
3804 (const_string "1")))
3806 (if_then_else (eq_attr "prefix_0f" "0")
3808 (const_string "1")))])
3810 (define_insn "extendqisi2"
3811 [(set (match_operand:SI 0 "register_operand" "=r")
3812 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3814 "movs{bl|x}\t{%1, %0|%0, %1}"
3815 [(set_attr "type" "imovx")
3816 (set_attr "mode" "SI")])
3818 (define_insn "*extendqisi2_zext"
3819 [(set (match_operand:DI 0 "register_operand" "=r")
3821 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3823 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3824 [(set_attr "type" "imovx")
3825 (set_attr "mode" "SI")])
3827 (define_insn "extendqihi2"
3828 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3829 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3832 switch (get_attr_prefix_0f (insn))
3835 return "{cbtw|cbw}";
3837 return "movs{bw|x}\t{%1, %0|%0, %1}";
3840 [(set_attr "type" "imovx")
3841 (set_attr "mode" "HI")
3842 (set (attr "prefix_0f")
3843 ;; movsx is short decodable while cwtl is vector decoded.
3844 (if_then_else (and (eq_attr "cpu" "!k6")
3845 (eq_attr "alternative" "0"))
3847 (const_string "1")))
3849 (if_then_else (eq_attr "prefix_0f" "0")
3851 (const_string "1")))])
3853 ;; Conversions between float and double.
3855 ;; These are all no-ops in the model used for the 80387.
3856 ;; So just emit moves.
3858 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3860 [(set (match_operand:DF 0 "push_operand")
3861 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3863 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3864 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3867 [(set (match_operand:XF 0 "push_operand")
3868 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3870 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3871 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3872 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3874 (define_expand "extendsfdf2"
3875 [(set (match_operand:DF 0 "nonimmediate_operand")
3876 (float_extend:DF (match_operand:SF 1 "general_operand")))]
3877 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3879 /* ??? Needed for compress_float_constant since all fp constants
3880 are TARGET_LEGITIMATE_CONSTANT_P. */
3881 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3883 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3884 && standard_80387_constant_p (operands[1]) > 0)
3886 operands[1] = simplify_const_unary_operation
3887 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3888 emit_move_insn_1 (operands[0], operands[1]);
3891 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3895 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3897 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3899 We do the conversion post reload to avoid producing of 128bit spills
3900 that might lead to ICE on 32bit target. The sequence unlikely combine
3903 [(set (match_operand:DF 0 "register_operand")
3905 (match_operand:SF 1 "nonimmediate_operand")))]
3906 "TARGET_USE_VECTOR_FP_CONVERTS
3907 && optimize_insn_for_speed_p ()
3908 && reload_completed && SSE_REG_P (operands[0])"
3913 (parallel [(const_int 0) (const_int 1)]))))]
3915 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3916 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3917 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3918 Try to avoid move when unpacking can be done in source. */
3919 if (REG_P (operands[1]))
3921 /* If it is unsafe to overwrite upper half of source, we need
3922 to move to destination and unpack there. */
3923 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3924 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3925 && true_regnum (operands[0]) != true_regnum (operands[1]))
3927 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3928 emit_move_insn (tmp, operands[1]);
3931 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3932 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3936 emit_insn (gen_vec_setv4sf_0 (operands[3],
3937 CONST0_RTX (V4SFmode), operands[1]));
3940 (define_insn "*extendsfdf2_mixed"
3941 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3943 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3944 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3946 switch (which_alternative)
3950 return output_387_reg_move (insn, operands);
3953 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3959 [(set_attr "type" "fmov,fmov,ssecvt")
3960 (set_attr "prefix" "orig,orig,maybe_vex")
3961 (set_attr "mode" "SF,XF,DF")])
3963 (define_insn "*extendsfdf2_sse"
3964 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3965 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3966 "TARGET_SSE2 && TARGET_SSE_MATH"
3967 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3968 [(set_attr "type" "ssecvt")
3969 (set_attr "prefix" "maybe_vex")
3970 (set_attr "mode" "DF")])
3972 (define_insn "*extendsfdf2_i387"
3973 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3974 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3976 "* return output_387_reg_move (insn, operands);"
3977 [(set_attr "type" "fmov")
3978 (set_attr "mode" "SF,XF")])
3980 (define_expand "extend<mode>xf2"
3981 [(set (match_operand:XF 0 "nonimmediate_operand")
3982 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
3985 /* ??? Needed for compress_float_constant since all fp constants
3986 are TARGET_LEGITIMATE_CONSTANT_P. */
3987 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3989 if (standard_80387_constant_p (operands[1]) > 0)
3991 operands[1] = simplify_const_unary_operation
3992 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3993 emit_move_insn_1 (operands[0], operands[1]);
3996 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4000 (define_insn "*extend<mode>xf2_i387"
4001 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4003 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4005 "* return output_387_reg_move (insn, operands);"
4006 [(set_attr "type" "fmov")
4007 (set_attr "mode" "<MODE>,XF")])
4009 ;; %%% This seems bad bad news.
4010 ;; This cannot output into an f-reg because there is no way to be sure
4011 ;; of truncating in that case. Otherwise this is just like a simple move
4012 ;; insn. So we pretend we can output to a reg in order to get better
4013 ;; register preferencing, but we really use a stack slot.
4015 ;; Conversion from DFmode to SFmode.
4017 (define_expand "truncdfsf2"
4018 [(set (match_operand:SF 0 "nonimmediate_operand")
4020 (match_operand:DF 1 "nonimmediate_operand")))]
4021 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4023 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4025 else if (flag_unsafe_math_optimizations)
4029 enum ix86_stack_slot slot = (virtuals_instantiated
4032 rtx temp = assign_386_stack_local (SFmode, slot);
4033 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4038 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4040 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4042 We do the conversion post reload to avoid producing of 128bit spills
4043 that might lead to ICE on 32bit target. The sequence unlikely combine
4046 [(set (match_operand:SF 0 "register_operand")
4048 (match_operand:DF 1 "nonimmediate_operand")))]
4049 "TARGET_USE_VECTOR_FP_CONVERTS
4050 && optimize_insn_for_speed_p ()
4051 && reload_completed && SSE_REG_P (operands[0])"
4054 (float_truncate:V2SF
4058 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4059 operands[3] = CONST0_RTX (V2SFmode);
4060 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4061 /* Use movsd for loading from memory, unpcklpd for registers.
4062 Try to avoid move when unpacking can be done in source, or SSE3
4063 movddup is available. */
4064 if (REG_P (operands[1]))
4067 && true_regnum (operands[0]) != true_regnum (operands[1])
4068 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4069 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4071 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4072 emit_move_insn (tmp, operands[1]);
4075 else if (!TARGET_SSE3)
4076 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4077 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4080 emit_insn (gen_sse2_loadlpd (operands[4],
4081 CONST0_RTX (V2DFmode), operands[1]));
4084 (define_expand "truncdfsf2_with_temp"
4085 [(parallel [(set (match_operand:SF 0)
4086 (float_truncate:SF (match_operand:DF 1)))
4087 (clobber (match_operand:SF 2))])])
4089 (define_insn "*truncdfsf_fast_mixed"
4090 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4092 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4093 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4095 switch (which_alternative)
4098 return output_387_reg_move (insn, operands);
4100 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4105 [(set_attr "type" "fmov,ssecvt")
4106 (set_attr "prefix" "orig,maybe_vex")
4107 (set_attr "mode" "SF")])
4109 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4110 ;; because nothing we do here is unsafe.
4111 (define_insn "*truncdfsf_fast_sse"
4112 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4114 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4115 "TARGET_SSE2 && TARGET_SSE_MATH"
4116 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4117 [(set_attr "type" "ssecvt")
4118 (set_attr "prefix" "maybe_vex")
4119 (set_attr "mode" "SF")])
4121 (define_insn "*truncdfsf_fast_i387"
4122 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4124 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4125 "TARGET_80387 && flag_unsafe_math_optimizations"
4126 "* return output_387_reg_move (insn, operands);"
4127 [(set_attr "type" "fmov")
4128 (set_attr "mode" "SF")])
4130 (define_insn "*truncdfsf_mixed"
4131 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4133 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4134 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4135 "TARGET_MIX_SSE_I387"
4137 switch (which_alternative)
4140 return output_387_reg_move (insn, operands);
4142 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4148 [(set_attr "isa" "*,sse2,*,*,*")
4149 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4150 (set_attr "unit" "*,*,i387,i387,i387")
4151 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4152 (set_attr "mode" "SF")])
4154 (define_insn "*truncdfsf_i387"
4155 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4157 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4158 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4161 switch (which_alternative)
4164 return output_387_reg_move (insn, operands);
4170 [(set_attr "type" "fmov,multi,multi,multi")
4171 (set_attr "unit" "*,i387,i387,i387")
4172 (set_attr "mode" "SF")])
4174 (define_insn "*truncdfsf2_i387_1"
4175 [(set (match_operand:SF 0 "memory_operand" "=m")
4177 (match_operand:DF 1 "register_operand" "f")))]
4179 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4180 && !TARGET_MIX_SSE_I387"
4181 "* return output_387_reg_move (insn, operands);"
4182 [(set_attr "type" "fmov")
4183 (set_attr "mode" "SF")])
4186 [(set (match_operand:SF 0 "register_operand")
4188 (match_operand:DF 1 "fp_register_operand")))
4189 (clobber (match_operand 2))]
4191 [(set (match_dup 2) (match_dup 1))
4192 (set (match_dup 0) (match_dup 2))]
4193 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4195 ;; Conversion from XFmode to {SF,DF}mode
4197 (define_expand "truncxf<mode>2"
4198 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4199 (float_truncate:MODEF
4200 (match_operand:XF 1 "register_operand")))
4201 (clobber (match_dup 2))])]
4204 if (flag_unsafe_math_optimizations)
4206 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4207 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4208 if (reg != operands[0])
4209 emit_move_insn (operands[0], reg);
4214 enum ix86_stack_slot slot = (virtuals_instantiated
4217 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4221 (define_insn "*truncxfsf2_mixed"
4222 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4224 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4225 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4228 gcc_assert (!which_alternative);
4229 return output_387_reg_move (insn, operands);
4231 [(set_attr "type" "fmov,multi,multi,multi")
4232 (set_attr "unit" "*,i387,i387,i387")
4233 (set_attr "mode" "SF")])
4235 (define_insn "*truncxfdf2_mixed"
4236 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4238 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4239 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4242 gcc_assert (!which_alternative);
4243 return output_387_reg_move (insn, operands);
4245 [(set_attr "isa" "*,*,sse2,*")
4246 (set_attr "type" "fmov,multi,multi,multi")
4247 (set_attr "unit" "*,i387,i387,i387")
4248 (set_attr "mode" "DF")])
4250 (define_insn "truncxf<mode>2_i387_noop"
4251 [(set (match_operand:MODEF 0 "register_operand" "=f")
4252 (float_truncate:MODEF
4253 (match_operand:XF 1 "register_operand" "f")))]
4254 "TARGET_80387 && flag_unsafe_math_optimizations"
4255 "* return output_387_reg_move (insn, operands);"
4256 [(set_attr "type" "fmov")
4257 (set_attr "mode" "<MODE>")])
4259 (define_insn "*truncxf<mode>2_i387"
4260 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4261 (float_truncate:MODEF
4262 (match_operand:XF 1 "register_operand" "f")))]
4264 "* return output_387_reg_move (insn, operands);"
4265 [(set_attr "type" "fmov")
4266 (set_attr "mode" "<MODE>")])
4269 [(set (match_operand:MODEF 0 "register_operand")
4270 (float_truncate:MODEF
4271 (match_operand:XF 1 "register_operand")))
4272 (clobber (match_operand:MODEF 2 "memory_operand"))]
4273 "TARGET_80387 && reload_completed"
4274 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4275 (set (match_dup 0) (match_dup 2))])
4278 [(set (match_operand:MODEF 0 "memory_operand")
4279 (float_truncate:MODEF
4280 (match_operand:XF 1 "register_operand")))
4281 (clobber (match_operand:MODEF 2 "memory_operand"))]
4283 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4285 ;; Signed conversion to DImode.
4287 (define_expand "fix_truncxfdi2"
4288 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4289 (fix:DI (match_operand:XF 1 "register_operand")))
4290 (clobber (reg:CC FLAGS_REG))])]
4295 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4300 (define_expand "fix_trunc<mode>di2"
4301 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4302 (fix:DI (match_operand:MODEF 1 "register_operand")))
4303 (clobber (reg:CC FLAGS_REG))])]
4304 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4307 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4309 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4312 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4314 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4315 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4316 if (out != operands[0])
4317 emit_move_insn (operands[0], out);
4322 ;; Signed conversion to SImode.
4324 (define_expand "fix_truncxfsi2"
4325 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4326 (fix:SI (match_operand:XF 1 "register_operand")))
4327 (clobber (reg:CC FLAGS_REG))])]
4332 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4337 (define_expand "fix_trunc<mode>si2"
4338 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4339 (fix:SI (match_operand:MODEF 1 "register_operand")))
4340 (clobber (reg:CC FLAGS_REG))])]
4341 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4344 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4346 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4349 if (SSE_FLOAT_MODE_P (<MODE>mode))
4351 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4352 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4353 if (out != operands[0])
4354 emit_move_insn (operands[0], out);
4359 ;; Signed conversion to HImode.
4361 (define_expand "fix_trunc<mode>hi2"
4362 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4363 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4364 (clobber (reg:CC FLAGS_REG))])]
4366 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4370 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4375 ;; Unsigned conversion to SImode.
4377 (define_expand "fixuns_trunc<mode>si2"
4379 [(set (match_operand:SI 0 "register_operand")
4381 (match_operand:MODEF 1 "nonimmediate_operand")))
4383 (clobber (match_scratch:<ssevecmode> 3))
4384 (clobber (match_scratch:<ssevecmode> 4))])]
4385 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4387 enum machine_mode mode = <MODE>mode;
4388 enum machine_mode vecmode = <ssevecmode>mode;
4389 REAL_VALUE_TYPE TWO31r;
4392 if (optimize_insn_for_size_p ())
4395 real_ldexp (&TWO31r, &dconst1, 31);
4396 two31 = const_double_from_real_value (TWO31r, mode);
4397 two31 = ix86_build_const_vector (vecmode, true, two31);
4398 operands[2] = force_reg (vecmode, two31);
4401 (define_insn_and_split "*fixuns_trunc<mode>_1"
4402 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4404 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4405 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4406 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4407 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4408 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4409 && optimize_function_for_speed_p (cfun)"
4411 "&& reload_completed"
4414 ix86_split_convert_uns_si_sse (operands);
4418 ;; Unsigned conversion to HImode.
4419 ;; Without these patterns, we'll try the unsigned SI conversion which
4420 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4422 (define_expand "fixuns_trunc<mode>hi2"
4424 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4425 (set (match_operand:HI 0 "nonimmediate_operand")
4426 (subreg:HI (match_dup 2) 0))]
4427 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4428 "operands[2] = gen_reg_rtx (SImode);")
4430 ;; When SSE is available, it is always faster to use it!
4431 (define_insn "fix_trunc<mode>di_sse"
4432 [(set (match_operand:DI 0 "register_operand" "=r,r")
4433 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4434 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4435 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4436 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4437 [(set_attr "type" "sseicvt")
4438 (set_attr "prefix" "maybe_vex")
4439 (set_attr "prefix_rex" "1")
4440 (set_attr "mode" "<MODE>")
4441 (set_attr "athlon_decode" "double,vector")
4442 (set_attr "amdfam10_decode" "double,double")
4443 (set_attr "bdver1_decode" "double,double")])
4445 (define_insn "fix_trunc<mode>si_sse"
4446 [(set (match_operand:SI 0 "register_operand" "=r,r")
4447 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4448 "SSE_FLOAT_MODE_P (<MODE>mode)
4449 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4450 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4451 [(set_attr "type" "sseicvt")
4452 (set_attr "prefix" "maybe_vex")
4453 (set_attr "mode" "<MODE>")
4454 (set_attr "athlon_decode" "double,vector")
4455 (set_attr "amdfam10_decode" "double,double")
4456 (set_attr "bdver1_decode" "double,double")])
4458 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4460 [(set (match_operand:MODEF 0 "register_operand")
4461 (match_operand:MODEF 1 "memory_operand"))
4462 (set (match_operand:SWI48x 2 "register_operand")
4463 (fix:SWI48x (match_dup 0)))]
4464 "TARGET_SHORTEN_X87_SSE
4465 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4466 && peep2_reg_dead_p (2, operands[0])"
4467 [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4469 ;; Avoid vector decoded forms of the instruction.
4471 [(match_scratch:DF 2 "x")
4472 (set (match_operand:SWI48x 0 "register_operand")
4473 (fix:SWI48x (match_operand:DF 1 "memory_operand")))]
4474 "TARGET_SSE2 && TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4475 [(set (match_dup 2) (match_dup 1))
4476 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4479 [(match_scratch:SF 2 "x")
4480 (set (match_operand:SWI48x 0 "register_operand")
4481 (fix:SWI48x (match_operand:SF 1 "memory_operand")))]
4482 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4483 [(set (match_dup 2) (match_dup 1))
4484 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4486 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4487 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4488 (fix:SWI248x (match_operand 1 "register_operand")))]
4489 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4491 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4492 && (TARGET_64BIT || <MODE>mode != DImode))
4494 && can_create_pseudo_p ()"
4499 if (memory_operand (operands[0], VOIDmode))
4500 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4503 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4504 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4510 [(set_attr "type" "fisttp")
4511 (set_attr "mode" "<MODE>")])
4513 (define_insn "fix_trunc<mode>_i387_fisttp"
4514 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4515 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4516 (clobber (match_scratch:XF 2 "=&1f"))]
4517 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4519 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4520 && (TARGET_64BIT || <MODE>mode != DImode))
4521 && TARGET_SSE_MATH)"
4522 "* return output_fix_trunc (insn, operands, true);"
4523 [(set_attr "type" "fisttp")
4524 (set_attr "mode" "<MODE>")])
4526 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4527 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4528 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4529 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4530 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4531 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4533 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4534 && (TARGET_64BIT || <MODE>mode != DImode))
4535 && TARGET_SSE_MATH)"
4537 [(set_attr "type" "fisttp")
4538 (set_attr "mode" "<MODE>")])
4541 [(set (match_operand:SWI248x 0 "register_operand")
4542 (fix:SWI248x (match_operand 1 "register_operand")))
4543 (clobber (match_operand:SWI248x 2 "memory_operand"))
4544 (clobber (match_scratch 3))]
4546 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4547 (clobber (match_dup 3))])
4548 (set (match_dup 0) (match_dup 2))])
4551 [(set (match_operand:SWI248x 0 "memory_operand")
4552 (fix:SWI248x (match_operand 1 "register_operand")))
4553 (clobber (match_operand:SWI248x 2 "memory_operand"))
4554 (clobber (match_scratch 3))]
4556 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4557 (clobber (match_dup 3))])])
4559 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4560 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4561 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4562 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4563 ;; function in i386.c.
4564 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4565 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4566 (fix:SWI248x (match_operand 1 "register_operand")))
4567 (clobber (reg:CC FLAGS_REG))]
4568 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4570 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4571 && (TARGET_64BIT || <MODE>mode != DImode))
4572 && can_create_pseudo_p ()"
4577 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4579 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4580 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4581 if (memory_operand (operands[0], VOIDmode))
4582 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4583 operands[2], operands[3]));
4586 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4587 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4588 operands[2], operands[3],
4593 [(set_attr "type" "fistp")
4594 (set_attr "i387_cw" "trunc")
4595 (set_attr "mode" "<MODE>")])
4597 (define_insn "fix_truncdi_i387"
4598 [(set (match_operand:DI 0 "memory_operand" "=m")
4599 (fix:DI (match_operand 1 "register_operand" "f")))
4600 (use (match_operand:HI 2 "memory_operand" "m"))
4601 (use (match_operand:HI 3 "memory_operand" "m"))
4602 (clobber (match_scratch:XF 4 "=&1f"))]
4603 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4605 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4606 "* return output_fix_trunc (insn, operands, false);"
4607 [(set_attr "type" "fistp")
4608 (set_attr "i387_cw" "trunc")
4609 (set_attr "mode" "DI")])
4611 (define_insn "fix_truncdi_i387_with_temp"
4612 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4613 (fix:DI (match_operand 1 "register_operand" "f,f")))
4614 (use (match_operand:HI 2 "memory_operand" "m,m"))
4615 (use (match_operand:HI 3 "memory_operand" "m,m"))
4616 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4617 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4618 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4620 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4622 [(set_attr "type" "fistp")
4623 (set_attr "i387_cw" "trunc")
4624 (set_attr "mode" "DI")])
4627 [(set (match_operand:DI 0 "register_operand")
4628 (fix:DI (match_operand 1 "register_operand")))
4629 (use (match_operand:HI 2 "memory_operand"))
4630 (use (match_operand:HI 3 "memory_operand"))
4631 (clobber (match_operand:DI 4 "memory_operand"))
4632 (clobber (match_scratch 5))]
4634 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4637 (clobber (match_dup 5))])
4638 (set (match_dup 0) (match_dup 4))])
4641 [(set (match_operand:DI 0 "memory_operand")
4642 (fix:DI (match_operand 1 "register_operand")))
4643 (use (match_operand:HI 2 "memory_operand"))
4644 (use (match_operand:HI 3 "memory_operand"))
4645 (clobber (match_operand:DI 4 "memory_operand"))
4646 (clobber (match_scratch 5))]
4648 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4651 (clobber (match_dup 5))])])
4653 (define_insn "fix_trunc<mode>_i387"
4654 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4655 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4656 (use (match_operand:HI 2 "memory_operand" "m"))
4657 (use (match_operand:HI 3 "memory_operand" "m"))]
4658 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4660 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4661 "* return output_fix_trunc (insn, operands, false);"
4662 [(set_attr "type" "fistp")
4663 (set_attr "i387_cw" "trunc")
4664 (set_attr "mode" "<MODE>")])
4666 (define_insn "fix_trunc<mode>_i387_with_temp"
4667 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4668 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4669 (use (match_operand:HI 2 "memory_operand" "m,m"))
4670 (use (match_operand:HI 3 "memory_operand" "m,m"))
4671 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4672 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4674 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4676 [(set_attr "type" "fistp")
4677 (set_attr "i387_cw" "trunc")
4678 (set_attr "mode" "<MODE>")])
4681 [(set (match_operand:SWI24 0 "register_operand")
4682 (fix:SWI24 (match_operand 1 "register_operand")))
4683 (use (match_operand:HI 2 "memory_operand"))
4684 (use (match_operand:HI 3 "memory_operand"))
4685 (clobber (match_operand:SWI24 4 "memory_operand"))]
4687 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4689 (use (match_dup 3))])
4690 (set (match_dup 0) (match_dup 4))])
4693 [(set (match_operand:SWI24 0 "memory_operand")
4694 (fix:SWI24 (match_operand 1 "register_operand")))
4695 (use (match_operand:HI 2 "memory_operand"))
4696 (use (match_operand:HI 3 "memory_operand"))
4697 (clobber (match_operand:SWI24 4 "memory_operand"))]
4699 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4701 (use (match_dup 3))])])
4703 (define_insn "x86_fnstcw_1"
4704 [(set (match_operand:HI 0 "memory_operand" "=m")
4705 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4708 [(set (attr "length")
4709 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4710 (set_attr "mode" "HI")
4711 (set_attr "unit" "i387")
4712 (set_attr "bdver1_decode" "vector")])
4714 (define_insn "x86_fldcw_1"
4715 [(set (reg:HI FPCR_REG)
4716 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4719 [(set (attr "length")
4720 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4721 (set_attr "mode" "HI")
4722 (set_attr "unit" "i387")
4723 (set_attr "athlon_decode" "vector")
4724 (set_attr "amdfam10_decode" "vector")
4725 (set_attr "bdver1_decode" "vector")])
4727 ;; Conversion between fixed point and floating point.
4729 ;; Even though we only accept memory inputs, the backend _really_
4730 ;; wants to be able to do this between registers.
4732 (define_expand "floathi<mode>2"
4733 [(set (match_operand:X87MODEF 0 "register_operand")
4734 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand")))]
4736 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4737 || TARGET_MIX_SSE_I387)")
4739 ;; Pre-reload splitter to add memory clobber to the pattern.
4740 (define_insn_and_split "*floathi<mode>2_1"
4741 [(set (match_operand:X87MODEF 0 "register_operand")
4742 (float:X87MODEF (match_operand:HI 1 "register_operand")))]
4744 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4745 || TARGET_MIX_SSE_I387)
4746 && can_create_pseudo_p ()"
4749 [(parallel [(set (match_dup 0)
4750 (float:X87MODEF (match_dup 1)))
4751 (clobber (match_dup 2))])]
4752 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4754 (define_insn "*floathi<mode>2_i387_with_temp"
4755 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4756 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4757 (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4759 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4760 || TARGET_MIX_SSE_I387)"
4762 [(set_attr "type" "fmov,multi")
4763 (set_attr "mode" "<MODE>")
4764 (set_attr "unit" "*,i387")
4765 (set_attr "fp_int_src" "true")])
4767 (define_insn "*floathi<mode>2_i387"
4768 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4769 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4771 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4772 || TARGET_MIX_SSE_I387)"
4774 [(set_attr "type" "fmov")
4775 (set_attr "mode" "<MODE>")
4776 (set_attr "fp_int_src" "true")])
4779 [(set (match_operand:X87MODEF 0 "register_operand")
4780 (float:X87MODEF (match_operand:HI 1 "register_operand")))
4781 (clobber (match_operand:HI 2 "memory_operand"))]
4783 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4784 || TARGET_MIX_SSE_I387)
4785 && reload_completed"
4786 [(set (match_dup 2) (match_dup 1))
4787 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4790 [(set (match_operand:X87MODEF 0 "register_operand")
4791 (float:X87MODEF (match_operand:HI 1 "memory_operand")))
4792 (clobber (match_operand:HI 2 "memory_operand"))]
4794 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4795 || TARGET_MIX_SSE_I387)
4796 && reload_completed"
4797 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4799 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4800 [(set (match_operand:X87MODEF 0 "register_operand")
4802 (match_operand:SWI48x 1 "nonimmediate_operand")))]
4804 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4805 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4807 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4808 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4809 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4811 rtx reg = gen_reg_rtx (XFmode);
4812 rtx (*insn)(rtx, rtx);
4814 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4816 if (<X87MODEF:MODE>mode == SFmode)
4817 insn = gen_truncxfsf2;
4818 else if (<X87MODEF:MODE>mode == DFmode)
4819 insn = gen_truncxfdf2;
4823 emit_insn (insn (operands[0], reg));
4828 ;; Pre-reload splitter to add memory clobber to the pattern.
4829 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4830 [(set (match_operand:X87MODEF 0 "register_operand")
4831 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))]
4833 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4834 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4835 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4836 || TARGET_MIX_SSE_I387))
4837 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4838 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4839 && ((<SWI48x:MODE>mode == SImode
4840 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4841 && optimize_function_for_speed_p (cfun)
4842 && flag_trapping_math)
4843 || !(TARGET_INTER_UNIT_CONVERSIONS
4844 || optimize_function_for_size_p (cfun)))))
4845 && can_create_pseudo_p ()"
4848 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4849 (clobber (match_dup 2))])]
4851 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4853 /* Avoid store forwarding (partial memory) stall penalty
4854 by passing DImode value through XMM registers. */
4855 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4856 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4857 && optimize_function_for_speed_p (cfun))
4859 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4866 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4867 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4869 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4870 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4871 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4872 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4874 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4875 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4876 (set_attr "unit" "*,i387,*,*,*")
4877 (set_attr "athlon_decode" "*,*,double,direct,double")
4878 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4879 (set_attr "bdver1_decode" "*,*,double,direct,double")
4880 (set_attr "fp_int_src" "true")])
4882 (define_insn "*floatsi<mode>2_vector_mixed"
4883 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4884 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4885 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4886 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4890 [(set_attr "type" "fmov,sseicvt")
4891 (set_attr "mode" "<MODE>,<ssevecmode>")
4892 (set_attr "unit" "i387,*")
4893 (set_attr "athlon_decode" "*,direct")
4894 (set_attr "amdfam10_decode" "*,double")
4895 (set_attr "bdver1_decode" "*,direct")
4896 (set_attr "fp_int_src" "true")])
4898 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4899 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4901 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4902 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4903 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4904 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4906 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4907 (set_attr "mode" "<MODEF:MODE>")
4908 (set_attr "unit" "*,i387,*,*")
4909 (set_attr "athlon_decode" "*,*,double,direct")
4910 (set_attr "amdfam10_decode" "*,*,vector,double")
4911 (set_attr "bdver1_decode" "*,*,double,direct")
4912 (set_attr "fp_int_src" "true")])
4915 [(set (match_operand:MODEF 0 "register_operand")
4916 (float:MODEF (match_operand:SWI48x 1 "register_operand")))
4917 (clobber (match_operand:SWI48x 2 "memory_operand"))]
4918 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4919 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4920 && TARGET_INTER_UNIT_CONVERSIONS
4922 && (SSE_REG_P (operands[0])
4923 || (GET_CODE (operands[0]) == SUBREG
4924 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4925 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4928 [(set (match_operand:MODEF 0 "register_operand")
4929 (float:MODEF (match_operand:SWI48x 1 "register_operand")))
4930 (clobber (match_operand:SWI48x 2 "memory_operand"))]
4931 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4932 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4933 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4935 && (SSE_REG_P (operands[0])
4936 || (GET_CODE (operands[0]) == SUBREG
4937 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4938 [(set (match_dup 2) (match_dup 1))
4939 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4941 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4942 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4944 (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4945 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4946 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4947 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4950 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4951 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4952 [(set_attr "type" "fmov,sseicvt,sseicvt")
4953 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4954 (set_attr "mode" "<MODEF:MODE>")
4955 (set (attr "prefix_rex")
4957 (and (eq_attr "prefix" "maybe_vex")
4958 (match_test "<SWI48x:MODE>mode == DImode"))
4960 (const_string "*")))
4961 (set_attr "unit" "i387,*,*")
4962 (set_attr "athlon_decode" "*,double,direct")
4963 (set_attr "amdfam10_decode" "*,vector,double")
4964 (set_attr "bdver1_decode" "*,double,direct")
4965 (set_attr "fp_int_src" "true")])
4967 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4968 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4970 (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4971 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4972 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4973 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4976 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4977 [(set_attr "type" "fmov,sseicvt")
4978 (set_attr "prefix" "orig,maybe_vex")
4979 (set_attr "mode" "<MODEF:MODE>")
4980 (set (attr "prefix_rex")
4982 (and (eq_attr "prefix" "maybe_vex")
4983 (match_test "<SWI48x:MODE>mode == DImode"))
4985 (const_string "*")))
4986 (set_attr "athlon_decode" "*,direct")
4987 (set_attr "amdfam10_decode" "*,double")
4988 (set_attr "bdver1_decode" "*,direct")
4989 (set_attr "fp_int_src" "true")])
4991 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4992 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4994 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4995 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4996 "TARGET_SSE2 && TARGET_SSE_MATH
4997 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4999 [(set_attr "type" "sseicvt")
5000 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5001 (set_attr "athlon_decode" "double,direct,double")
5002 (set_attr "amdfam10_decode" "vector,double,double")
5003 (set_attr "bdver1_decode" "double,direct,double")
5004 (set_attr "fp_int_src" "true")])
5006 (define_insn "*floatsi<mode>2_vector_sse"
5007 [(set (match_operand:MODEF 0 "register_operand" "=x")
5008 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5009 "TARGET_SSE2 && TARGET_SSE_MATH
5010 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5012 [(set_attr "type" "sseicvt")
5013 (set_attr "mode" "<MODE>")
5014 (set_attr "athlon_decode" "direct")
5015 (set_attr "amdfam10_decode" "double")
5016 (set_attr "bdver1_decode" "direct")
5017 (set_attr "fp_int_src" "true")])
5020 [(set (match_operand:MODEF 0 "register_operand")
5021 (float:MODEF (match_operand:SI 1 "register_operand")))
5022 (clobber (match_operand:SI 2 "memory_operand"))]
5023 "TARGET_SSE2 && TARGET_SSE_MATH
5024 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5026 && (SSE_REG_P (operands[0])
5027 || (GET_CODE (operands[0]) == SUBREG
5028 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5031 rtx op1 = operands[1];
5033 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5035 if (GET_CODE (op1) == SUBREG)
5036 op1 = SUBREG_REG (op1);
5038 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5040 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5041 emit_insn (gen_sse2_loadld (operands[4],
5042 CONST0_RTX (V4SImode), operands[1]));
5044 /* We can ignore possible trapping value in the
5045 high part of SSE register for non-trapping math. */
5046 else if (SSE_REG_P (op1) && !flag_trapping_math)
5047 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5050 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5051 emit_move_insn (operands[2], operands[1]);
5052 emit_insn (gen_sse2_loadld (operands[4],
5053 CONST0_RTX (V4SImode), operands[2]));
5055 if (<ssevecmode>mode == V4SFmode)
5056 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5058 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5063 [(set (match_operand:MODEF 0 "register_operand")
5064 (float:MODEF (match_operand:SI 1 "memory_operand")))
5065 (clobber (match_operand:SI 2 "memory_operand"))]
5066 "TARGET_SSE2 && TARGET_SSE_MATH
5067 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5069 && (SSE_REG_P (operands[0])
5070 || (GET_CODE (operands[0]) == SUBREG
5071 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5074 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5076 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5078 emit_insn (gen_sse2_loadld (operands[4],
5079 CONST0_RTX (V4SImode), operands[1]));
5080 if (<ssevecmode>mode == V4SFmode)
5081 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5083 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5088 [(set (match_operand:MODEF 0 "register_operand")
5089 (float:MODEF (match_operand:SI 1 "register_operand")))]
5090 "TARGET_SSE2 && TARGET_SSE_MATH
5091 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5093 && (SSE_REG_P (operands[0])
5094 || (GET_CODE (operands[0]) == SUBREG
5095 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5098 rtx op1 = operands[1];
5100 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5102 if (GET_CODE (op1) == SUBREG)
5103 op1 = SUBREG_REG (op1);
5105 if (GENERAL_REG_P (op1))
5107 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5108 if (TARGET_INTER_UNIT_MOVES)
5109 emit_insn (gen_sse2_loadld (operands[4],
5110 CONST0_RTX (V4SImode), operands[1]));
5113 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5115 emit_insn (gen_sse2_loadld (operands[4],
5116 CONST0_RTX (V4SImode), operands[5]));
5117 ix86_free_from_memory (GET_MODE (operands[1]));
5120 /* We can ignore possible trapping value in the
5121 high part of SSE register for non-trapping math. */
5122 else if (SSE_REG_P (op1) && !flag_trapping_math)
5123 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5126 if (<ssevecmode>mode == V4SFmode)
5127 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5129 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5134 [(set (match_operand:MODEF 0 "register_operand")
5135 (float:MODEF (match_operand:SI 1 "memory_operand")))]
5136 "TARGET_SSE2 && TARGET_SSE_MATH
5137 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5139 && (SSE_REG_P (operands[0])
5140 || (GET_CODE (operands[0]) == SUBREG
5141 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5144 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5146 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5148 emit_insn (gen_sse2_loadld (operands[4],
5149 CONST0_RTX (V4SImode), operands[1]));
5150 if (<ssevecmode>mode == V4SFmode)
5151 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5153 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5157 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5158 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5160 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5161 (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5162 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5163 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5165 [(set_attr "type" "sseicvt")
5166 (set_attr "mode" "<MODEF:MODE>")
5167 (set_attr "athlon_decode" "double,direct")
5168 (set_attr "amdfam10_decode" "vector,double")
5169 (set_attr "bdver1_decode" "double,direct")
5170 (set_attr "fp_int_src" "true")])
5172 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5173 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5175 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5176 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5177 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5178 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5179 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5180 [(set_attr "type" "sseicvt")
5181 (set_attr "prefix" "maybe_vex")
5182 (set_attr "mode" "<MODEF:MODE>")
5183 (set (attr "prefix_rex")
5185 (and (eq_attr "prefix" "maybe_vex")
5186 (match_test "<SWI48x:MODE>mode == DImode"))
5188 (const_string "*")))
5189 (set_attr "athlon_decode" "double,direct")
5190 (set_attr "amdfam10_decode" "vector,double")
5191 (set_attr "bdver1_decode" "double,direct")
5192 (set_attr "fp_int_src" "true")])
5195 [(set (match_operand:MODEF 0 "register_operand")
5196 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand")))
5197 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5198 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5199 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5200 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5202 && (SSE_REG_P (operands[0])
5203 || (GET_CODE (operands[0]) == SUBREG
5204 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5205 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5207 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5208 [(set (match_operand:MODEF 0 "register_operand" "=x")
5210 (match_operand:SWI48x 1 "memory_operand" "m")))]
5211 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5212 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5213 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5214 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5215 [(set_attr "type" "sseicvt")
5216 (set_attr "prefix" "maybe_vex")
5217 (set_attr "mode" "<MODEF:MODE>")
5218 (set (attr "prefix_rex")
5220 (and (eq_attr "prefix" "maybe_vex")
5221 (match_test "<SWI48x:MODE>mode == DImode"))
5223 (const_string "*")))
5224 (set_attr "athlon_decode" "direct")
5225 (set_attr "amdfam10_decode" "double")
5226 (set_attr "bdver1_decode" "direct")
5227 (set_attr "fp_int_src" "true")])
5230 [(set (match_operand:MODEF 0 "register_operand")
5231 (float:MODEF (match_operand:SWI48x 1 "register_operand")))
5232 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5233 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5234 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5235 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5237 && (SSE_REG_P (operands[0])
5238 || (GET_CODE (operands[0]) == SUBREG
5239 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5240 [(set (match_dup 2) (match_dup 1))
5241 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5244 [(set (match_operand:MODEF 0 "register_operand")
5245 (float:MODEF (match_operand:SWI48x 1 "memory_operand")))
5246 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5247 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5248 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5250 && (SSE_REG_P (operands[0])
5251 || (GET_CODE (operands[0]) == SUBREG
5252 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5253 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5255 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5256 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5258 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5259 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5261 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5265 [(set_attr "type" "fmov,multi")
5266 (set_attr "mode" "<X87MODEF:MODE>")
5267 (set_attr "unit" "*,i387")
5268 (set_attr "fp_int_src" "true")])
5270 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5271 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5273 (match_operand:SWI48x 1 "memory_operand" "m")))]
5275 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5277 [(set_attr "type" "fmov")
5278 (set_attr "mode" "<X87MODEF:MODE>")
5279 (set_attr "fp_int_src" "true")])
5282 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5283 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))
5284 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5286 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5287 && reload_completed"
5288 [(set (match_dup 2) (match_dup 1))
5289 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5292 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5293 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand")))
5294 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5296 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5297 && reload_completed"
5298 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5300 ;; Avoid store forwarding (partial memory) stall penalty
5301 ;; by passing DImode value through XMM registers. */
5303 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5304 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5306 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5307 (clobber (match_scratch:V4SI 3 "=X,x"))
5308 (clobber (match_scratch:V4SI 4 "=X,x"))
5309 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5310 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5311 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5312 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5314 [(set_attr "type" "multi")
5315 (set_attr "mode" "<X87MODEF:MODE>")
5316 (set_attr "unit" "i387")
5317 (set_attr "fp_int_src" "true")])
5320 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5321 (float:X87MODEF (match_operand:DI 1 "register_operand")))
5322 (clobber (match_scratch:V4SI 3))
5323 (clobber (match_scratch:V4SI 4))
5324 (clobber (match_operand:DI 2 "memory_operand"))]
5325 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5326 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5327 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5328 && reload_completed"
5329 [(set (match_dup 2) (match_dup 3))
5330 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5332 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5333 Assemble the 64-bit DImode value in an xmm register. */
5334 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5335 gen_rtx_SUBREG (SImode, operands[1], 0)));
5336 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5337 gen_rtx_SUBREG (SImode, operands[1], 4)));
5338 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5341 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5345 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5346 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5347 (clobber (match_scratch:V4SI 3))
5348 (clobber (match_scratch:V4SI 4))
5349 (clobber (match_operand:DI 2 "memory_operand"))]
5350 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5351 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5352 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5353 && reload_completed"
5354 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5356 ;; Avoid store forwarding (partial memory) stall penalty by extending
5357 ;; SImode value to DImode through XMM register instead of pushing two
5358 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5359 ;; targets benefit from this optimization. Also note that fild
5360 ;; loads from memory only.
5362 (define_insn "*floatunssi<mode>2_1"
5363 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5364 (unsigned_float:X87MODEF
5365 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5366 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5367 (clobber (match_scratch:SI 3 "=X,x"))]
5369 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5372 [(set_attr "type" "multi")
5373 (set_attr "mode" "<MODE>")])
5376 [(set (match_operand:X87MODEF 0 "register_operand")
5377 (unsigned_float:X87MODEF
5378 (match_operand:SI 1 "register_operand")))
5379 (clobber (match_operand:DI 2 "memory_operand"))
5380 (clobber (match_scratch:SI 3))]
5382 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5384 && reload_completed"
5385 [(set (match_dup 2) (match_dup 1))
5387 (float:X87MODEF (match_dup 2)))]
5388 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5391 [(set (match_operand:X87MODEF 0 "register_operand")
5392 (unsigned_float:X87MODEF
5393 (match_operand:SI 1 "memory_operand")))
5394 (clobber (match_operand:DI 2 "memory_operand"))
5395 (clobber (match_scratch:SI 3))]
5397 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5399 && reload_completed"
5400 [(set (match_dup 2) (match_dup 3))
5402 (float:X87MODEF (match_dup 2)))]
5404 emit_move_insn (operands[3], operands[1]);
5405 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5408 (define_expand "floatunssi<mode>2"
5410 [(set (match_operand:X87MODEF 0 "register_operand")
5411 (unsigned_float:X87MODEF
5412 (match_operand:SI 1 "nonimmediate_operand")))
5413 (clobber (match_dup 2))
5414 (clobber (match_scratch:SI 3))])]
5416 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5418 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5420 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5422 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5427 enum ix86_stack_slot slot = (virtuals_instantiated
5430 operands[2] = assign_386_stack_local (DImode, slot);
5434 (define_expand "floatunsdisf2"
5435 [(use (match_operand:SF 0 "register_operand"))
5436 (use (match_operand:DI 1 "nonimmediate_operand"))]
5437 "TARGET_64BIT && TARGET_SSE_MATH"
5438 "x86_emit_floatuns (operands); DONE;")
5440 (define_expand "floatunsdidf2"
5441 [(use (match_operand:DF 0 "register_operand"))
5442 (use (match_operand:DI 1 "nonimmediate_operand"))]
5443 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5444 && TARGET_SSE2 && TARGET_SSE_MATH"
5447 x86_emit_floatuns (operands);
5449 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5453 ;; Load effective address instructions
5455 (define_insn_and_split "*lea<mode>"
5456 [(set (match_operand:SWI48 0 "register_operand" "=r")
5457 (match_operand:SWI48 1 "lea_address_operand" "p"))]
5460 rtx addr = operands[1];
5462 if (GET_CODE (addr) == SUBREG)
5464 gcc_assert (TARGET_64BIT);
5465 gcc_assert (<MODE>mode == SImode);
5466 gcc_assert (GET_MODE (SUBREG_REG (addr)) == DImode);
5467 return "lea{l}\t{%E1, %0|%0, %E1}";
5469 else if (GET_CODE (addr) == ZERO_EXTEND
5470 || GET_CODE (addr) == AND)
5472 gcc_assert (TARGET_64BIT);
5473 gcc_assert (<MODE>mode == DImode);
5474 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5477 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5479 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5482 ix86_split_lea_for_addr (operands, <MODE>mode);
5485 [(set_attr "type" "lea")
5486 (set_attr "mode" "<MODE>")])
5490 (define_expand "add<mode>3"
5491 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5492 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5493 (match_operand:SDWIM 2 "<general_operand>")))]
5495 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5497 (define_insn_and_split "*add<dwi>3_doubleword"
5498 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5500 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5501 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5502 (clobber (reg:CC FLAGS_REG))]
5503 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5506 [(parallel [(set (reg:CC FLAGS_REG)
5507 (unspec:CC [(match_dup 1) (match_dup 2)]
5510 (plus:DWIH (match_dup 1) (match_dup 2)))])
5511 (parallel [(set (match_dup 3)
5515 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5517 (clobber (reg:CC FLAGS_REG))])]
5518 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5520 (define_insn "*add<mode>3_cc"
5521 [(set (reg:CC FLAGS_REG)
5523 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5524 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5526 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5527 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5528 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5529 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5530 [(set_attr "type" "alu")
5531 (set_attr "mode" "<MODE>")])
5533 (define_insn "addqi3_cc"
5534 [(set (reg:CC FLAGS_REG)
5536 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5537 (match_operand:QI 2 "general_operand" "qn,qm")]
5539 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5540 (plus:QI (match_dup 1) (match_dup 2)))]
5541 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5542 "add{b}\t{%2, %0|%0, %2}"
5543 [(set_attr "type" "alu")
5544 (set_attr "mode" "QI")])
5546 (define_insn "*add<mode>_1"
5547 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5549 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5550 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5551 (clobber (reg:CC FLAGS_REG))]
5552 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5554 switch (get_attr_type (insn))
5560 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5561 if (operands[2] == const1_rtx)
5562 return "inc{<imodesuffix>}\t%0";
5565 gcc_assert (operands[2] == constm1_rtx);
5566 return "dec{<imodesuffix>}\t%0";
5570 /* For most processors, ADD is faster than LEA. This alternative
5571 was added to use ADD as much as possible. */
5572 if (which_alternative == 2)
5575 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5578 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5579 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5580 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5582 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5586 (cond [(eq_attr "alternative" "3")
5587 (const_string "lea")
5588 (match_operand:SWI48 2 "incdec_operand")
5589 (const_string "incdec")
5591 (const_string "alu")))
5592 (set (attr "length_immediate")
5594 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5596 (const_string "*")))
5597 (set_attr "mode" "<MODE>")])
5599 ;; It may seem that nonimmediate operand is proper one for operand 1.
5600 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5601 ;; we take care in ix86_binary_operator_ok to not allow two memory
5602 ;; operands so proper swapping will be done in reload. This allow
5603 ;; patterns constructed from addsi_1 to match.
5605 (define_insn "addsi_1_zext"
5606 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5608 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5609 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5610 (clobber (reg:CC FLAGS_REG))]
5611 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5613 switch (get_attr_type (insn))
5619 if (operands[2] == const1_rtx)
5620 return "inc{l}\t%k0";
5623 gcc_assert (operands[2] == constm1_rtx);
5624 return "dec{l}\t%k0";
5628 /* For most processors, ADD is faster than LEA. This alternative
5629 was added to use ADD as much as possible. */
5630 if (which_alternative == 1)
5633 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5636 if (x86_maybe_negate_const_int (&operands[2], SImode))
5637 return "sub{l}\t{%2, %k0|%k0, %2}";
5639 return "add{l}\t{%2, %k0|%k0, %2}";
5643 (cond [(eq_attr "alternative" "2")
5644 (const_string "lea")
5645 (match_operand:SI 2 "incdec_operand")
5646 (const_string "incdec")
5648 (const_string "alu")))
5649 (set (attr "length_immediate")
5651 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5653 (const_string "*")))
5654 (set_attr "mode" "SI")])
5656 (define_insn "*addhi_1"
5657 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5658 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5659 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5660 (clobber (reg:CC FLAGS_REG))]
5661 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5663 switch (get_attr_type (insn))
5669 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5670 if (operands[2] == const1_rtx)
5671 return "inc{w}\t%0";
5674 gcc_assert (operands[2] == constm1_rtx);
5675 return "dec{w}\t%0";
5679 /* For most processors, ADD is faster than LEA. This alternative
5680 was added to use ADD as much as possible. */
5681 if (which_alternative == 2)
5684 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5687 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5688 if (x86_maybe_negate_const_int (&operands[2], HImode))
5689 return "sub{w}\t{%2, %0|%0, %2}";
5691 return "add{w}\t{%2, %0|%0, %2}";
5695 (cond [(eq_attr "alternative" "3")
5696 (const_string "lea")
5697 (match_operand:HI 2 "incdec_operand")
5698 (const_string "incdec")
5700 (const_string "alu")))
5701 (set (attr "length_immediate")
5703 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5705 (const_string "*")))
5706 (set_attr "mode" "HI,HI,HI,SI")])
5708 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5709 (define_insn "*addqi_1"
5710 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5711 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5712 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5713 (clobber (reg:CC FLAGS_REG))]
5714 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5716 bool widen = (which_alternative == 3 || which_alternative == 4);
5718 switch (get_attr_type (insn))
5724 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5725 if (operands[2] == const1_rtx)
5726 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5729 gcc_assert (operands[2] == constm1_rtx);
5730 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5734 /* For most processors, ADD is faster than LEA. These alternatives
5735 were added to use ADD as much as possible. */
5736 if (which_alternative == 2 || which_alternative == 4)
5739 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5742 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5743 if (x86_maybe_negate_const_int (&operands[2], QImode))
5746 return "sub{l}\t{%2, %k0|%k0, %2}";
5748 return "sub{b}\t{%2, %0|%0, %2}";
5751 return "add{l}\t{%k2, %k0|%k0, %k2}";
5753 return "add{b}\t{%2, %0|%0, %2}";
5757 (cond [(eq_attr "alternative" "5")
5758 (const_string "lea")
5759 (match_operand:QI 2 "incdec_operand")
5760 (const_string "incdec")
5762 (const_string "alu")))
5763 (set (attr "length_immediate")
5765 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5767 (const_string "*")))
5768 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5770 (define_insn "*addqi_1_slp"
5771 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5772 (plus:QI (match_dup 0)
5773 (match_operand:QI 1 "general_operand" "qn,qm")))
5774 (clobber (reg:CC FLAGS_REG))]
5775 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5776 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5778 switch (get_attr_type (insn))
5781 if (operands[1] == const1_rtx)
5782 return "inc{b}\t%0";
5785 gcc_assert (operands[1] == constm1_rtx);
5786 return "dec{b}\t%0";
5790 if (x86_maybe_negate_const_int (&operands[1], QImode))
5791 return "sub{b}\t{%1, %0|%0, %1}";
5793 return "add{b}\t{%1, %0|%0, %1}";
5797 (if_then_else (match_operand:QI 1 "incdec_operand")
5798 (const_string "incdec")
5799 (const_string "alu1")))
5800 (set (attr "memory")
5801 (if_then_else (match_operand 1 "memory_operand")
5802 (const_string "load")
5803 (const_string "none")))
5804 (set_attr "mode" "QI")])
5806 ;; Split non destructive adds if we cannot use lea.
5808 [(set (match_operand:SWI48 0 "register_operand")
5809 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5810 (match_operand:SWI48 2 "nonmemory_operand")))
5811 (clobber (reg:CC FLAGS_REG))]
5812 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5813 [(set (match_dup 0) (match_dup 1))
5814 (parallel [(set (match_dup 0) (plus:<MODE> (match_dup 0) (match_dup 2)))
5815 (clobber (reg:CC FLAGS_REG))])])
5817 ;; Convert add to the lea pattern to avoid flags dependency.
5819 [(set (match_operand:SWI 0 "register_operand")
5820 (plus:SWI (match_operand:SWI 1 "register_operand")
5821 (match_operand:SWI 2 "<nonmemory_operand>")))
5822 (clobber (reg:CC FLAGS_REG))]
5823 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5826 enum machine_mode mode = <MODE>mode;
5829 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5832 operands[0] = gen_lowpart (mode, operands[0]);
5833 operands[1] = gen_lowpart (mode, operands[1]);
5834 operands[2] = gen_lowpart (mode, operands[2]);
5837 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5839 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5843 ;; Convert add to the lea pattern to avoid flags dependency.
5845 [(set (match_operand:DI 0 "register_operand")
5847 (plus:SI (match_operand:SI 1 "register_operand")
5848 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5849 (clobber (reg:CC FLAGS_REG))]
5850 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5852 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5854 (define_insn "*add<mode>_2"
5855 [(set (reg FLAGS_REG)
5858 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5859 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5861 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5862 (plus:SWI (match_dup 1) (match_dup 2)))]
5863 "ix86_match_ccmode (insn, CCGOCmode)
5864 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5866 switch (get_attr_type (insn))
5869 if (operands[2] == const1_rtx)
5870 return "inc{<imodesuffix>}\t%0";
5873 gcc_assert (operands[2] == constm1_rtx);
5874 return "dec{<imodesuffix>}\t%0";
5878 if (which_alternative == 2)
5881 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5884 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5885 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5886 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5888 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5892 (if_then_else (match_operand:SWI 2 "incdec_operand")
5893 (const_string "incdec")
5894 (const_string "alu")))
5895 (set (attr "length_immediate")
5897 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5899 (const_string "*")))
5900 (set_attr "mode" "<MODE>")])
5902 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5903 (define_insn "*addsi_2_zext"
5904 [(set (reg FLAGS_REG)
5906 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5907 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5909 (set (match_operand:DI 0 "register_operand" "=r,r")
5910 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5911 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5912 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5914 switch (get_attr_type (insn))
5917 if (operands[2] == const1_rtx)
5918 return "inc{l}\t%k0";
5921 gcc_assert (operands[2] == constm1_rtx);
5922 return "dec{l}\t%k0";
5926 if (which_alternative == 1)
5929 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5932 if (x86_maybe_negate_const_int (&operands[2], SImode))
5933 return "sub{l}\t{%2, %k0|%k0, %2}";
5935 return "add{l}\t{%2, %k0|%k0, %2}";
5939 (if_then_else (match_operand:SI 2 "incdec_operand")
5940 (const_string "incdec")
5941 (const_string "alu")))
5942 (set (attr "length_immediate")
5944 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5946 (const_string "*")))
5947 (set_attr "mode" "SI")])
5949 (define_insn "*add<mode>_3"
5950 [(set (reg FLAGS_REG)
5952 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5953 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5954 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5955 "ix86_match_ccmode (insn, CCZmode)
5956 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5958 switch (get_attr_type (insn))
5961 if (operands[2] == const1_rtx)
5962 return "inc{<imodesuffix>}\t%0";
5965 gcc_assert (operands[2] == constm1_rtx);
5966 return "dec{<imodesuffix>}\t%0";
5970 if (which_alternative == 1)
5973 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5976 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5977 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5978 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5980 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5984 (if_then_else (match_operand:SWI 2 "incdec_operand")
5985 (const_string "incdec")
5986 (const_string "alu")))
5987 (set (attr "length_immediate")
5989 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5991 (const_string "*")))
5992 (set_attr "mode" "<MODE>")])
5994 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5995 (define_insn "*addsi_3_zext"
5996 [(set (reg FLAGS_REG)
5998 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5999 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
6000 (set (match_operand:DI 0 "register_operand" "=r,r")
6001 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6002 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6003 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6005 switch (get_attr_type (insn))
6008 if (operands[2] == const1_rtx)
6009 return "inc{l}\t%k0";
6012 gcc_assert (operands[2] == constm1_rtx);
6013 return "dec{l}\t%k0";
6017 if (which_alternative == 1)
6020 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6023 if (x86_maybe_negate_const_int (&operands[2], SImode))
6024 return "sub{l}\t{%2, %k0|%k0, %2}";
6026 return "add{l}\t{%2, %k0|%k0, %2}";
6030 (if_then_else (match_operand:SI 2 "incdec_operand")
6031 (const_string "incdec")
6032 (const_string "alu")))
6033 (set (attr "length_immediate")
6035 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6037 (const_string "*")))
6038 (set_attr "mode" "SI")])
6040 ; For comparisons against 1, -1 and 128, we may generate better code
6041 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6042 ; is matched then. We can't accept general immediate, because for
6043 ; case of overflows, the result is messed up.
6044 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6045 ; only for comparisons not depending on it.
6047 (define_insn "*adddi_4"
6048 [(set (reg FLAGS_REG)
6050 (match_operand:DI 1 "nonimmediate_operand" "0")
6051 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6052 (clobber (match_scratch:DI 0 "=rm"))]
6054 && ix86_match_ccmode (insn, CCGCmode)"
6056 switch (get_attr_type (insn))
6059 if (operands[2] == constm1_rtx)
6060 return "inc{q}\t%0";
6063 gcc_assert (operands[2] == const1_rtx);
6064 return "dec{q}\t%0";
6068 if (x86_maybe_negate_const_int (&operands[2], DImode))
6069 return "add{q}\t{%2, %0|%0, %2}";
6071 return "sub{q}\t{%2, %0|%0, %2}";
6075 (if_then_else (match_operand:DI 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" "DI")])
6085 ; For comparisons against 1, -1 and 128, we may generate better code
6086 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6087 ; is matched then. We can't accept general immediate, because for
6088 ; case of overflows, the result is messed up.
6089 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6090 ; only for comparisons not depending on it.
6092 (define_insn "*add<mode>_4"
6093 [(set (reg FLAGS_REG)
6095 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6096 (match_operand:SWI124 2 "const_int_operand" "n")))
6097 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6098 "ix86_match_ccmode (insn, CCGCmode)"
6100 switch (get_attr_type (insn))
6103 if (operands[2] == constm1_rtx)
6104 return "inc{<imodesuffix>}\t%0";
6107 gcc_assert (operands[2] == const1_rtx);
6108 return "dec{<imodesuffix>}\t%0";
6112 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6113 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6115 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6119 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6120 (const_string "incdec")
6121 (const_string "alu")))
6122 (set (attr "length_immediate")
6124 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6126 (const_string "*")))
6127 (set_attr "mode" "<MODE>")])
6129 (define_insn "*add<mode>_5"
6130 [(set (reg FLAGS_REG)
6133 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6134 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6136 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6137 "ix86_match_ccmode (insn, CCGOCmode)
6138 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6140 switch (get_attr_type (insn))
6143 if (operands[2] == const1_rtx)
6144 return "inc{<imodesuffix>}\t%0";
6147 gcc_assert (operands[2] == constm1_rtx);
6148 return "dec{<imodesuffix>}\t%0";
6152 if (which_alternative == 1)
6155 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6158 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6159 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6160 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6162 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6166 (if_then_else (match_operand:SWI 2 "incdec_operand")
6167 (const_string "incdec")
6168 (const_string "alu")))
6169 (set (attr "length_immediate")
6171 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6173 (const_string "*")))
6174 (set_attr "mode" "<MODE>")])
6176 (define_insn "*addqi_ext_1_rex64"
6177 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6182 (match_operand 1 "ext_register_operand" "0")
6185 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6186 (clobber (reg:CC FLAGS_REG))]
6189 switch (get_attr_type (insn))
6192 if (operands[2] == const1_rtx)
6193 return "inc{b}\t%h0";
6196 gcc_assert (operands[2] == constm1_rtx);
6197 return "dec{b}\t%h0";
6201 return "add{b}\t{%2, %h0|%h0, %2}";
6205 (if_then_else (match_operand:QI 2 "incdec_operand")
6206 (const_string "incdec")
6207 (const_string "alu")))
6208 (set_attr "modrm" "1")
6209 (set_attr "mode" "QI")])
6211 (define_insn "addqi_ext_1"
6212 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6217 (match_operand 1 "ext_register_operand" "0")
6220 (match_operand:QI 2 "general_operand" "Qmn")))
6221 (clobber (reg:CC FLAGS_REG))]
6224 switch (get_attr_type (insn))
6227 if (operands[2] == const1_rtx)
6228 return "inc{b}\t%h0";
6231 gcc_assert (operands[2] == constm1_rtx);
6232 return "dec{b}\t%h0";
6236 return "add{b}\t{%2, %h0|%h0, %2}";
6240 (if_then_else (match_operand:QI 2 "incdec_operand")
6241 (const_string "incdec")
6242 (const_string "alu")))
6243 (set_attr "modrm" "1")
6244 (set_attr "mode" "QI")])
6246 (define_insn "*addqi_ext_2"
6247 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6252 (match_operand 1 "ext_register_operand" "%0")
6256 (match_operand 2 "ext_register_operand" "Q")
6259 (clobber (reg:CC FLAGS_REG))]
6261 "add{b}\t{%h2, %h0|%h0, %h2}"
6262 [(set_attr "type" "alu")
6263 (set_attr "mode" "QI")])
6265 ;; The lea patterns for modes less than 32 bits need to be matched by
6266 ;; several insns converted to real lea by splitters.
6268 (define_insn_and_split "*lea_general_1"
6269 [(set (match_operand 0 "register_operand" "=r")
6270 (plus (plus (match_operand 1 "index_register_operand" "l")
6271 (match_operand 2 "register_operand" "r"))
6272 (match_operand 3 "immediate_operand" "i")))]
6273 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6274 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6275 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6276 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6277 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6278 || GET_MODE (operands[3]) == VOIDmode)"
6280 "&& reload_completed"
6283 enum machine_mode mode = SImode;
6286 operands[0] = gen_lowpart (mode, operands[0]);
6287 operands[1] = gen_lowpart (mode, operands[1]);
6288 operands[2] = gen_lowpart (mode, operands[2]);
6289 operands[3] = gen_lowpart (mode, operands[3]);
6291 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6294 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6297 [(set_attr "type" "lea")
6298 (set_attr "mode" "SI")])
6300 (define_insn_and_split "*lea_general_2"
6301 [(set (match_operand 0 "register_operand" "=r")
6302 (plus (mult (match_operand 1 "index_register_operand" "l")
6303 (match_operand 2 "const248_operand" "n"))
6304 (match_operand 3 "nonmemory_operand" "ri")))]
6305 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6306 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6307 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6308 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6309 || GET_MODE (operands[3]) == VOIDmode)"
6311 "&& reload_completed"
6314 enum machine_mode mode = SImode;
6317 operands[0] = gen_lowpart (mode, operands[0]);
6318 operands[1] = gen_lowpart (mode, operands[1]);
6319 operands[3] = gen_lowpart (mode, operands[3]);
6321 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6324 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6327 [(set_attr "type" "lea")
6328 (set_attr "mode" "SI")])
6330 (define_insn_and_split "*lea_general_3"
6331 [(set (match_operand 0 "register_operand" "=r")
6332 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6333 (match_operand 2 "const248_operand" "n"))
6334 (match_operand 3 "register_operand" "r"))
6335 (match_operand 4 "immediate_operand" "i")))]
6336 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6337 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6338 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6339 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6341 "&& reload_completed"
6344 enum machine_mode mode = SImode;
6347 operands[0] = gen_lowpart (mode, operands[0]);
6348 operands[1] = gen_lowpart (mode, operands[1]);
6349 operands[3] = gen_lowpart (mode, operands[3]);
6350 operands[4] = gen_lowpart (mode, operands[4]);
6352 pat = gen_rtx_PLUS (mode,
6354 gen_rtx_MULT (mode, operands[1],
6359 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6362 [(set_attr "type" "lea")
6363 (set_attr "mode" "SI")])
6365 (define_insn_and_split "*lea_general_4"
6366 [(set (match_operand 0 "register_operand" "=r")
6368 (match_operand 1 "index_register_operand" "l")
6369 (match_operand 2 "const_int_operand" "n"))
6370 (match_operand 3 "const_int_operand" "n")))]
6371 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6372 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6373 || GET_MODE (operands[0]) == SImode
6374 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6375 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6376 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6377 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6378 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6380 "&& reload_completed"
6383 enum machine_mode mode = GET_MODE (operands[0]);
6386 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6389 operands[0] = gen_lowpart (mode, operands[0]);
6390 operands[1] = gen_lowpart (mode, operands[1]);
6393 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6395 pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6396 INTVAL (operands[3]));
6398 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6401 [(set_attr "type" "lea")
6403 (if_then_else (match_operand:DI 0)
6405 (const_string "SI")))])
6407 ;; Subtract instructions
6409 (define_expand "sub<mode>3"
6410 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6411 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6412 (match_operand:SDWIM 2 "<general_operand>")))]
6414 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6416 (define_insn_and_split "*sub<dwi>3_doubleword"
6417 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6419 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6420 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6421 (clobber (reg:CC FLAGS_REG))]
6422 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6425 [(parallel [(set (reg:CC FLAGS_REG)
6426 (compare:CC (match_dup 1) (match_dup 2)))
6428 (minus:DWIH (match_dup 1) (match_dup 2)))])
6429 (parallel [(set (match_dup 3)
6433 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6435 (clobber (reg:CC FLAGS_REG))])]
6436 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6438 (define_insn "*sub<mode>_1"
6439 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6441 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6442 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6443 (clobber (reg:CC FLAGS_REG))]
6444 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6445 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6446 [(set_attr "type" "alu")
6447 (set_attr "mode" "<MODE>")])
6449 (define_insn "*subsi_1_zext"
6450 [(set (match_operand:DI 0 "register_operand" "=r")
6452 (minus:SI (match_operand:SI 1 "register_operand" "0")
6453 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6454 (clobber (reg:CC FLAGS_REG))]
6455 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6456 "sub{l}\t{%2, %k0|%k0, %2}"
6457 [(set_attr "type" "alu")
6458 (set_attr "mode" "SI")])
6460 (define_insn "*subqi_1_slp"
6461 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6462 (minus:QI (match_dup 0)
6463 (match_operand:QI 1 "general_operand" "qn,qm")))
6464 (clobber (reg:CC FLAGS_REG))]
6465 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6466 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6467 "sub{b}\t{%1, %0|%0, %1}"
6468 [(set_attr "type" "alu1")
6469 (set_attr "mode" "QI")])
6471 (define_insn "*sub<mode>_2"
6472 [(set (reg FLAGS_REG)
6475 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6476 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6478 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6479 (minus:SWI (match_dup 1) (match_dup 2)))]
6480 "ix86_match_ccmode (insn, CCGOCmode)
6481 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6482 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6483 [(set_attr "type" "alu")
6484 (set_attr "mode" "<MODE>")])
6486 (define_insn "*subsi_2_zext"
6487 [(set (reg FLAGS_REG)
6489 (minus:SI (match_operand:SI 1 "register_operand" "0")
6490 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6492 (set (match_operand:DI 0 "register_operand" "=r")
6494 (minus:SI (match_dup 1)
6496 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6497 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6498 "sub{l}\t{%2, %k0|%k0, %2}"
6499 [(set_attr "type" "alu")
6500 (set_attr "mode" "SI")])
6502 (define_insn "*sub<mode>_3"
6503 [(set (reg FLAGS_REG)
6504 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6505 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6506 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6507 (minus:SWI (match_dup 1) (match_dup 2)))]
6508 "ix86_match_ccmode (insn, CCmode)
6509 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6510 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6511 [(set_attr "type" "alu")
6512 (set_attr "mode" "<MODE>")])
6514 (define_insn "*subsi_3_zext"
6515 [(set (reg FLAGS_REG)
6516 (compare (match_operand:SI 1 "register_operand" "0")
6517 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6518 (set (match_operand:DI 0 "register_operand" "=r")
6520 (minus:SI (match_dup 1)
6522 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6523 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6524 "sub{l}\t{%2, %1|%1, %2}"
6525 [(set_attr "type" "alu")
6526 (set_attr "mode" "SI")])
6528 ;; Add with carry and subtract with borrow
6530 (define_expand "<plusminus_insn><mode>3_carry"
6532 [(set (match_operand:SWI 0 "nonimmediate_operand")
6534 (match_operand:SWI 1 "nonimmediate_operand")
6535 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6536 [(match_operand 3 "flags_reg_operand")
6538 (match_operand:SWI 2 "<general_operand>"))))
6539 (clobber (reg:CC FLAGS_REG))])]
6540 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6542 (define_insn "*<plusminus_insn><mode>3_carry"
6543 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6545 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6547 (match_operator 3 "ix86_carry_flag_operator"
6548 [(reg FLAGS_REG) (const_int 0)])
6549 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6550 (clobber (reg:CC FLAGS_REG))]
6551 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6552 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6553 [(set_attr "type" "alu")
6554 (set_attr "use_carry" "1")
6555 (set_attr "pent_pair" "pu")
6556 (set_attr "mode" "<MODE>")])
6558 (define_insn "*addsi3_carry_zext"
6559 [(set (match_operand:DI 0 "register_operand" "=r")
6561 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6562 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6563 [(reg FLAGS_REG) (const_int 0)])
6564 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6565 (clobber (reg:CC FLAGS_REG))]
6566 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6567 "adc{l}\t{%2, %k0|%k0, %2}"
6568 [(set_attr "type" "alu")
6569 (set_attr "use_carry" "1")
6570 (set_attr "pent_pair" "pu")
6571 (set_attr "mode" "SI")])
6573 (define_insn "*subsi3_carry_zext"
6574 [(set (match_operand:DI 0 "register_operand" "=r")
6576 (minus:SI (match_operand:SI 1 "register_operand" "0")
6577 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6578 [(reg FLAGS_REG) (const_int 0)])
6579 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6580 (clobber (reg:CC FLAGS_REG))]
6581 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6582 "sbb{l}\t{%2, %k0|%k0, %2}"
6583 [(set_attr "type" "alu")
6584 (set_attr "pent_pair" "pu")
6585 (set_attr "mode" "SI")])
6587 ;; Overflow setting add and subtract instructions
6589 (define_insn "*add<mode>3_cconly_overflow"
6590 [(set (reg:CCC FLAGS_REG)
6593 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6594 (match_operand:SWI 2 "<general_operand>" "<g>"))
6596 (clobber (match_scratch:SWI 0 "=<r>"))]
6597 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6598 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6599 [(set_attr "type" "alu")
6600 (set_attr "mode" "<MODE>")])
6602 (define_insn "*sub<mode>3_cconly_overflow"
6603 [(set (reg:CCC FLAGS_REG)
6606 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6607 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6610 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6611 [(set_attr "type" "icmp")
6612 (set_attr "mode" "<MODE>")])
6614 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6615 [(set (reg:CCC FLAGS_REG)
6618 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6619 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6621 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6622 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6623 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6624 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6625 [(set_attr "type" "alu")
6626 (set_attr "mode" "<MODE>")])
6628 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6629 [(set (reg:CCC FLAGS_REG)
6632 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6633 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6635 (set (match_operand:DI 0 "register_operand" "=r")
6636 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6637 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6638 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6639 [(set_attr "type" "alu")
6640 (set_attr "mode" "SI")])
6642 ;; The patterns that match these are at the end of this file.
6644 (define_expand "<plusminus_insn>xf3"
6645 [(set (match_operand:XF 0 "register_operand")
6647 (match_operand:XF 1 "register_operand")
6648 (match_operand:XF 2 "register_operand")))]
6651 (define_expand "<plusminus_insn><mode>3"
6652 [(set (match_operand:MODEF 0 "register_operand")
6654 (match_operand:MODEF 1 "register_operand")
6655 (match_operand:MODEF 2 "nonimmediate_operand")))]
6656 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6657 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6659 ;; Multiply instructions
6661 (define_expand "mul<mode>3"
6662 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6664 (match_operand:SWIM248 1 "register_operand")
6665 (match_operand:SWIM248 2 "<general_operand>")))
6666 (clobber (reg:CC FLAGS_REG))])])
6668 (define_expand "mulqi3"
6669 [(parallel [(set (match_operand:QI 0 "register_operand")
6671 (match_operand:QI 1 "register_operand")
6672 (match_operand:QI 2 "nonimmediate_operand")))
6673 (clobber (reg:CC FLAGS_REG))])]
6674 "TARGET_QIMODE_MATH")
6677 ;; IMUL reg32/64, reg32/64, imm8 Direct
6678 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6679 ;; IMUL reg32/64, reg32/64, imm32 Direct
6680 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6681 ;; IMUL reg32/64, reg32/64 Direct
6682 ;; IMUL reg32/64, mem32/64 Direct
6684 ;; On BDVER1, all above IMULs use DirectPath
6686 (define_insn "*mul<mode>3_1"
6687 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6689 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6690 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6691 (clobber (reg:CC FLAGS_REG))]
6692 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6694 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6695 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6696 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6697 [(set_attr "type" "imul")
6698 (set_attr "prefix_0f" "0,0,1")
6699 (set (attr "athlon_decode")
6700 (cond [(eq_attr "cpu" "athlon")
6701 (const_string "vector")
6702 (eq_attr "alternative" "1")
6703 (const_string "vector")
6704 (and (eq_attr "alternative" "2")
6705 (match_operand 1 "memory_operand"))
6706 (const_string "vector")]
6707 (const_string "direct")))
6708 (set (attr "amdfam10_decode")
6709 (cond [(and (eq_attr "alternative" "0,1")
6710 (match_operand 1 "memory_operand"))
6711 (const_string "vector")]
6712 (const_string "direct")))
6713 (set_attr "bdver1_decode" "direct")
6714 (set_attr "mode" "<MODE>")])
6716 (define_insn "*mulsi3_1_zext"
6717 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6719 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6720 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6721 (clobber (reg:CC FLAGS_REG))]
6723 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6725 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6726 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6727 imul{l}\t{%2, %k0|%k0, %2}"
6728 [(set_attr "type" "imul")
6729 (set_attr "prefix_0f" "0,0,1")
6730 (set (attr "athlon_decode")
6731 (cond [(eq_attr "cpu" "athlon")
6732 (const_string "vector")
6733 (eq_attr "alternative" "1")
6734 (const_string "vector")
6735 (and (eq_attr "alternative" "2")
6736 (match_operand 1 "memory_operand"))
6737 (const_string "vector")]
6738 (const_string "direct")))
6739 (set (attr "amdfam10_decode")
6740 (cond [(and (eq_attr "alternative" "0,1")
6741 (match_operand 1 "memory_operand"))
6742 (const_string "vector")]
6743 (const_string "direct")))
6744 (set_attr "bdver1_decode" "direct")
6745 (set_attr "mode" "SI")])
6748 ;; IMUL reg16, reg16, imm8 VectorPath
6749 ;; IMUL reg16, mem16, imm8 VectorPath
6750 ;; IMUL reg16, reg16, imm16 VectorPath
6751 ;; IMUL reg16, mem16, imm16 VectorPath
6752 ;; IMUL reg16, reg16 Direct
6753 ;; IMUL reg16, mem16 Direct
6755 ;; On BDVER1, all HI MULs use DoublePath
6757 (define_insn "*mulhi3_1"
6758 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6759 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6760 (match_operand:HI 2 "general_operand" "K,n,mr")))
6761 (clobber (reg:CC FLAGS_REG))]
6763 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6765 imul{w}\t{%2, %1, %0|%0, %1, %2}
6766 imul{w}\t{%2, %1, %0|%0, %1, %2}
6767 imul{w}\t{%2, %0|%0, %2}"
6768 [(set_attr "type" "imul")
6769 (set_attr "prefix_0f" "0,0,1")
6770 (set (attr "athlon_decode")
6771 (cond [(eq_attr "cpu" "athlon")
6772 (const_string "vector")
6773 (eq_attr "alternative" "1,2")
6774 (const_string "vector")]
6775 (const_string "direct")))
6776 (set (attr "amdfam10_decode")
6777 (cond [(eq_attr "alternative" "0,1")
6778 (const_string "vector")]
6779 (const_string "direct")))
6780 (set_attr "bdver1_decode" "double")
6781 (set_attr "mode" "HI")])
6783 ;;On AMDFAM10 and BDVER1
6787 (define_insn "*mulqi3_1"
6788 [(set (match_operand:QI 0 "register_operand" "=a")
6789 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6790 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6791 (clobber (reg:CC FLAGS_REG))]
6793 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6795 [(set_attr "type" "imul")
6796 (set_attr "length_immediate" "0")
6797 (set (attr "athlon_decode")
6798 (if_then_else (eq_attr "cpu" "athlon")
6799 (const_string "vector")
6800 (const_string "direct")))
6801 (set_attr "amdfam10_decode" "direct")
6802 (set_attr "bdver1_decode" "direct")
6803 (set_attr "mode" "QI")])
6805 (define_expand "<u>mul<mode><dwi>3"
6806 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6809 (match_operand:DWIH 1 "nonimmediate_operand"))
6811 (match_operand:DWIH 2 "register_operand"))))
6812 (clobber (reg:CC FLAGS_REG))])])
6814 (define_expand "<u>mulqihi3"
6815 [(parallel [(set (match_operand:HI 0 "register_operand")
6818 (match_operand:QI 1 "nonimmediate_operand"))
6820 (match_operand:QI 2 "register_operand"))))
6821 (clobber (reg:CC FLAGS_REG))])]
6822 "TARGET_QIMODE_MATH")
6824 (define_insn "*bmi2_umulditi3_1"
6825 [(set (match_operand:DI 0 "register_operand" "=r")
6827 (match_operand:DI 2 "nonimmediate_operand" "%d")
6828 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6829 (set (match_operand:DI 1 "register_operand" "=r")
6832 (mult:TI (zero_extend:TI (match_dup 2))
6833 (zero_extend:TI (match_dup 3)))
6835 "TARGET_64BIT && TARGET_BMI2
6836 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6837 "mulx\t{%3, %0, %1|%1, %0, %3}"
6838 [(set_attr "type" "imulx")
6839 (set_attr "prefix" "vex")
6840 (set_attr "mode" "DI")])
6842 (define_insn "*bmi2_umulsidi3_1"
6843 [(set (match_operand:SI 0 "register_operand" "=r")
6845 (match_operand:SI 2 "nonimmediate_operand" "%d")
6846 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6847 (set (match_operand:SI 1 "register_operand" "=r")
6850 (mult:DI (zero_extend:DI (match_dup 2))
6851 (zero_extend:DI (match_dup 3)))
6853 "!TARGET_64BIT && TARGET_BMI2
6854 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6855 "mulx\t{%3, %0, %1|%1, %0, %3}"
6856 [(set_attr "type" "imulx")
6857 (set_attr "prefix" "vex")
6858 (set_attr "mode" "SI")])
6860 (define_insn "*umul<mode><dwi>3_1"
6861 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6864 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6866 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6867 (clobber (reg:CC FLAGS_REG))]
6868 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6871 mul{<imodesuffix>}\t%2"
6872 [(set_attr "isa" "bmi2,*")
6873 (set_attr "type" "imulx,imul")
6874 (set_attr "length_immediate" "*,0")
6875 (set (attr "athlon_decode")
6876 (cond [(eq_attr "alternative" "1")
6877 (if_then_else (eq_attr "cpu" "athlon")
6878 (const_string "vector")
6879 (const_string "double"))]
6880 (const_string "*")))
6881 (set_attr "amdfam10_decode" "*,double")
6882 (set_attr "bdver1_decode" "*,direct")
6883 (set_attr "prefix" "vex,orig")
6884 (set_attr "mode" "<MODE>")])
6886 ;; Convert mul to the mulx pattern to avoid flags dependency.
6888 [(set (match_operand:<DWI> 0 "register_operand")
6891 (match_operand:DWIH 1 "register_operand"))
6893 (match_operand:DWIH 2 "nonimmediate_operand"))))
6894 (clobber (reg:CC FLAGS_REG))]
6895 "TARGET_BMI2 && reload_completed
6896 && true_regnum (operands[1]) == DX_REG"
6897 [(parallel [(set (match_dup 3)
6898 (mult:DWIH (match_dup 1) (match_dup 2)))
6902 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6903 (zero_extend:<DWI> (match_dup 2)))
6906 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6908 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6911 (define_insn "*mul<mode><dwi>3_1"
6912 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6915 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6917 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6918 (clobber (reg:CC FLAGS_REG))]
6919 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6920 "imul{<imodesuffix>}\t%2"
6921 [(set_attr "type" "imul")
6922 (set_attr "length_immediate" "0")
6923 (set (attr "athlon_decode")
6924 (if_then_else (eq_attr "cpu" "athlon")
6925 (const_string "vector")
6926 (const_string "double")))
6927 (set_attr "amdfam10_decode" "double")
6928 (set_attr "bdver1_decode" "direct")
6929 (set_attr "mode" "<MODE>")])
6931 (define_insn "*<u>mulqihi3_1"
6932 [(set (match_operand:HI 0 "register_operand" "=a")
6935 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6937 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6938 (clobber (reg:CC FLAGS_REG))]
6940 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6941 "<sgnprefix>mul{b}\t%2"
6942 [(set_attr "type" "imul")
6943 (set_attr "length_immediate" "0")
6944 (set (attr "athlon_decode")
6945 (if_then_else (eq_attr "cpu" "athlon")
6946 (const_string "vector")
6947 (const_string "direct")))
6948 (set_attr "amdfam10_decode" "direct")
6949 (set_attr "bdver1_decode" "direct")
6950 (set_attr "mode" "QI")])
6952 (define_expand "<s>mul<mode>3_highpart"
6953 [(parallel [(set (match_operand:SWI48 0 "register_operand")
6958 (match_operand:SWI48 1 "nonimmediate_operand"))
6960 (match_operand:SWI48 2 "register_operand")))
6962 (clobber (match_scratch:SWI48 3))
6963 (clobber (reg:CC FLAGS_REG))])]
6965 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6967 (define_insn "*<s>muldi3_highpart_1"
6968 [(set (match_operand:DI 0 "register_operand" "=d")
6973 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6975 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6977 (clobber (match_scratch:DI 3 "=1"))
6978 (clobber (reg:CC FLAGS_REG))]
6980 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6981 "<sgnprefix>mul{q}\t%2"
6982 [(set_attr "type" "imul")
6983 (set_attr "length_immediate" "0")
6984 (set (attr "athlon_decode")
6985 (if_then_else (eq_attr "cpu" "athlon")
6986 (const_string "vector")
6987 (const_string "double")))
6988 (set_attr "amdfam10_decode" "double")
6989 (set_attr "bdver1_decode" "direct")
6990 (set_attr "mode" "DI")])
6992 (define_insn "*<s>mulsi3_highpart_1"
6993 [(set (match_operand:SI 0 "register_operand" "=d")
6998 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7000 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7002 (clobber (match_scratch:SI 3 "=1"))
7003 (clobber (reg:CC FLAGS_REG))]
7004 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7005 "<sgnprefix>mul{l}\t%2"
7006 [(set_attr "type" "imul")
7007 (set_attr "length_immediate" "0")
7008 (set (attr "athlon_decode")
7009 (if_then_else (eq_attr "cpu" "athlon")
7010 (const_string "vector")
7011 (const_string "double")))
7012 (set_attr "amdfam10_decode" "double")
7013 (set_attr "bdver1_decode" "direct")
7014 (set_attr "mode" "SI")])
7016 (define_insn "*<s>mulsi3_highpart_zext"
7017 [(set (match_operand:DI 0 "register_operand" "=d")
7018 (zero_extend:DI (truncate:SI
7020 (mult:DI (any_extend:DI
7021 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7023 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7025 (clobber (match_scratch:SI 3 "=1"))
7026 (clobber (reg:CC FLAGS_REG))]
7028 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7029 "<sgnprefix>mul{l}\t%2"
7030 [(set_attr "type" "imul")
7031 (set_attr "length_immediate" "0")
7032 (set (attr "athlon_decode")
7033 (if_then_else (eq_attr "cpu" "athlon")
7034 (const_string "vector")
7035 (const_string "double")))
7036 (set_attr "amdfam10_decode" "double")
7037 (set_attr "bdver1_decode" "direct")
7038 (set_attr "mode" "SI")])
7040 ;; The patterns that match these are at the end of this file.
7042 (define_expand "mulxf3"
7043 [(set (match_operand:XF 0 "register_operand")
7044 (mult:XF (match_operand:XF 1 "register_operand")
7045 (match_operand:XF 2 "register_operand")))]
7048 (define_expand "mul<mode>3"
7049 [(set (match_operand:MODEF 0 "register_operand")
7050 (mult:MODEF (match_operand:MODEF 1 "register_operand")
7051 (match_operand:MODEF 2 "nonimmediate_operand")))]
7052 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7053 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7055 ;; Divide instructions
7057 ;; The patterns that match these are at the end of this file.
7059 (define_expand "divxf3"
7060 [(set (match_operand:XF 0 "register_operand")
7061 (div:XF (match_operand:XF 1 "register_operand")
7062 (match_operand:XF 2 "register_operand")))]
7065 (define_expand "divdf3"
7066 [(set (match_operand:DF 0 "register_operand")
7067 (div:DF (match_operand:DF 1 "register_operand")
7068 (match_operand:DF 2 "nonimmediate_operand")))]
7069 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7070 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7072 (define_expand "divsf3"
7073 [(set (match_operand:SF 0 "register_operand")
7074 (div:SF (match_operand:SF 1 "register_operand")
7075 (match_operand:SF 2 "nonimmediate_operand")))]
7076 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7081 && optimize_insn_for_speed_p ()
7082 && flag_finite_math_only && !flag_trapping_math
7083 && flag_unsafe_math_optimizations)
7085 ix86_emit_swdivsf (operands[0], operands[1],
7086 operands[2], SFmode);
7091 ;; Divmod instructions.
7093 (define_expand "divmod<mode>4"
7094 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7096 (match_operand:SWIM248 1 "register_operand")
7097 (match_operand:SWIM248 2 "nonimmediate_operand")))
7098 (set (match_operand:SWIM248 3 "register_operand")
7099 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7100 (clobber (reg:CC FLAGS_REG))])])
7102 ;; Split with 8bit unsigned divide:
7103 ;; if (dividend an divisor are in [0-255])
7104 ;; use 8bit unsigned integer divide
7106 ;; use original integer divide
7108 [(set (match_operand:SWI48 0 "register_operand")
7109 (div:SWI48 (match_operand:SWI48 2 "register_operand")
7110 (match_operand:SWI48 3 "nonimmediate_operand")))
7111 (set (match_operand:SWI48 1 "register_operand")
7112 (mod:SWI48 (match_dup 2) (match_dup 3)))
7113 (clobber (reg:CC FLAGS_REG))]
7114 "TARGET_USE_8BIT_IDIV
7115 && TARGET_QIMODE_MATH
7116 && can_create_pseudo_p ()
7117 && !optimize_insn_for_size_p ()"
7119 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7121 (define_insn_and_split "divmod<mode>4_1"
7122 [(set (match_operand:SWI48 0 "register_operand" "=a")
7123 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7124 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7125 (set (match_operand:SWI48 1 "register_operand" "=&d")
7126 (mod:SWI48 (match_dup 2) (match_dup 3)))
7127 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7128 (clobber (reg:CC FLAGS_REG))]
7132 [(parallel [(set (match_dup 1)
7133 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7134 (clobber (reg:CC FLAGS_REG))])
7135 (parallel [(set (match_dup 0)
7136 (div:SWI48 (match_dup 2) (match_dup 3)))
7138 (mod:SWI48 (match_dup 2) (match_dup 3)))
7140 (clobber (reg:CC FLAGS_REG))])]
7142 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7144 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7145 operands[4] = operands[2];
7148 /* Avoid use of cltd in favor of a mov+shift. */
7149 emit_move_insn (operands[1], operands[2]);
7150 operands[4] = operands[1];
7153 [(set_attr "type" "multi")
7154 (set_attr "mode" "<MODE>")])
7156 (define_insn_and_split "*divmod<mode>4"
7157 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7158 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7159 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7160 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7161 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7162 (clobber (reg:CC FLAGS_REG))]
7166 [(parallel [(set (match_dup 1)
7167 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7168 (clobber (reg:CC FLAGS_REG))])
7169 (parallel [(set (match_dup 0)
7170 (div:SWIM248 (match_dup 2) (match_dup 3)))
7172 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7174 (clobber (reg:CC FLAGS_REG))])]
7176 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7178 if (<MODE>mode != HImode
7179 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7180 operands[4] = operands[2];
7183 /* Avoid use of cltd in favor of a mov+shift. */
7184 emit_move_insn (operands[1], operands[2]);
7185 operands[4] = operands[1];
7188 [(set_attr "type" "multi")
7189 (set_attr "mode" "<MODE>")])
7191 (define_insn "*divmod<mode>4_noext"
7192 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7193 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7194 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7195 (set (match_operand:SWIM248 1 "register_operand" "=d")
7196 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7197 (use (match_operand:SWIM248 4 "register_operand" "1"))
7198 (clobber (reg:CC FLAGS_REG))]
7200 "idiv{<imodesuffix>}\t%3"
7201 [(set_attr "type" "idiv")
7202 (set_attr "mode" "<MODE>")])
7204 (define_expand "divmodqi4"
7205 [(parallel [(set (match_operand:QI 0 "register_operand")
7207 (match_operand:QI 1 "register_operand")
7208 (match_operand:QI 2 "nonimmediate_operand")))
7209 (set (match_operand:QI 3 "register_operand")
7210 (mod:QI (match_dup 1) (match_dup 2)))
7211 (clobber (reg:CC FLAGS_REG))])]
7212 "TARGET_QIMODE_MATH"
7217 tmp0 = gen_reg_rtx (HImode);
7218 tmp1 = gen_reg_rtx (HImode);
7220 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7222 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7223 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7225 /* Extract remainder from AH. */
7226 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7227 insn = emit_move_insn (operands[3], tmp1);
7229 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7230 set_unique_reg_note (insn, REG_EQUAL, mod);
7232 /* Extract quotient from AL. */
7233 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7235 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7236 set_unique_reg_note (insn, REG_EQUAL, div);
7241 ;; Divide AX by r/m8, with result stored in
7244 ;; Change div/mod to HImode and extend the second argument to HImode
7245 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7246 ;; combine may fail.
7247 (define_insn "divmodhiqi3"
7248 [(set (match_operand:HI 0 "register_operand" "=a")
7253 (mod:HI (match_operand:HI 1 "register_operand" "0")
7255 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7259 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7260 (clobber (reg:CC FLAGS_REG))]
7261 "TARGET_QIMODE_MATH"
7263 [(set_attr "type" "idiv")
7264 (set_attr "mode" "QI")])
7266 (define_expand "udivmod<mode>4"
7267 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7269 (match_operand:SWIM248 1 "register_operand")
7270 (match_operand:SWIM248 2 "nonimmediate_operand")))
7271 (set (match_operand:SWIM248 3 "register_operand")
7272 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7273 (clobber (reg:CC FLAGS_REG))])])
7275 ;; Split with 8bit unsigned divide:
7276 ;; if (dividend an divisor are in [0-255])
7277 ;; use 8bit unsigned integer divide
7279 ;; use original integer divide
7281 [(set (match_operand:SWI48 0 "register_operand")
7282 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7283 (match_operand:SWI48 3 "nonimmediate_operand")))
7284 (set (match_operand:SWI48 1 "register_operand")
7285 (umod:SWI48 (match_dup 2) (match_dup 3)))
7286 (clobber (reg:CC FLAGS_REG))]
7287 "TARGET_USE_8BIT_IDIV
7288 && TARGET_QIMODE_MATH
7289 && can_create_pseudo_p ()
7290 && !optimize_insn_for_size_p ()"
7292 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7294 (define_insn_and_split "udivmod<mode>4_1"
7295 [(set (match_operand:SWI48 0 "register_operand" "=a")
7296 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7297 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7298 (set (match_operand:SWI48 1 "register_operand" "=&d")
7299 (umod:SWI48 (match_dup 2) (match_dup 3)))
7300 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7301 (clobber (reg:CC FLAGS_REG))]
7305 [(set (match_dup 1) (const_int 0))
7306 (parallel [(set (match_dup 0)
7307 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7309 (umod:SWI48 (match_dup 2) (match_dup 3)))
7311 (clobber (reg:CC FLAGS_REG))])]
7313 [(set_attr "type" "multi")
7314 (set_attr "mode" "<MODE>")])
7316 (define_insn_and_split "*udivmod<mode>4"
7317 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7318 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7319 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7320 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7321 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7322 (clobber (reg:CC FLAGS_REG))]
7326 [(set (match_dup 1) (const_int 0))
7327 (parallel [(set (match_dup 0)
7328 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7330 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7332 (clobber (reg:CC FLAGS_REG))])]
7334 [(set_attr "type" "multi")
7335 (set_attr "mode" "<MODE>")])
7337 (define_insn "*udivmod<mode>4_noext"
7338 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7339 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7340 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7341 (set (match_operand:SWIM248 1 "register_operand" "=d")
7342 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7343 (use (match_operand:SWIM248 4 "register_operand" "1"))
7344 (clobber (reg:CC FLAGS_REG))]
7346 "div{<imodesuffix>}\t%3"
7347 [(set_attr "type" "idiv")
7348 (set_attr "mode" "<MODE>")])
7350 (define_expand "udivmodqi4"
7351 [(parallel [(set (match_operand:QI 0 "register_operand")
7353 (match_operand:QI 1 "register_operand")
7354 (match_operand:QI 2 "nonimmediate_operand")))
7355 (set (match_operand:QI 3 "register_operand")
7356 (umod:QI (match_dup 1) (match_dup 2)))
7357 (clobber (reg:CC FLAGS_REG))])]
7358 "TARGET_QIMODE_MATH"
7363 tmp0 = gen_reg_rtx (HImode);
7364 tmp1 = gen_reg_rtx (HImode);
7366 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7368 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7369 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7371 /* Extract remainder from AH. */
7372 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7373 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7374 insn = emit_move_insn (operands[3], tmp1);
7376 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7377 set_unique_reg_note (insn, REG_EQUAL, mod);
7379 /* Extract quotient from AL. */
7380 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7382 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7383 set_unique_reg_note (insn, REG_EQUAL, div);
7388 (define_insn "udivmodhiqi3"
7389 [(set (match_operand:HI 0 "register_operand" "=a")
7394 (mod:HI (match_operand:HI 1 "register_operand" "0")
7396 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7400 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7401 (clobber (reg:CC FLAGS_REG))]
7402 "TARGET_QIMODE_MATH"
7404 [(set_attr "type" "idiv")
7405 (set_attr "mode" "QI")])
7407 ;; We cannot use div/idiv for double division, because it causes
7408 ;; "division by zero" on the overflow and that's not what we expect
7409 ;; from truncate. Because true (non truncating) double division is
7410 ;; never generated, we can't create this insn anyway.
7413 ; [(set (match_operand:SI 0 "register_operand" "=a")
7415 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7417 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7418 ; (set (match_operand:SI 3 "register_operand" "=d")
7420 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7421 ; (clobber (reg:CC FLAGS_REG))]
7423 ; "div{l}\t{%2, %0|%0, %2}"
7424 ; [(set_attr "type" "idiv")])
7426 ;;- Logical AND instructions
7428 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7429 ;; Note that this excludes ah.
7431 (define_expand "testsi_ccno_1"
7432 [(set (reg:CCNO FLAGS_REG)
7434 (and:SI (match_operand:SI 0 "nonimmediate_operand")
7435 (match_operand:SI 1 "x86_64_nonmemory_operand"))
7438 (define_expand "testqi_ccz_1"
7439 [(set (reg:CCZ FLAGS_REG)
7440 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7441 (match_operand:QI 1 "nonmemory_operand"))
7444 (define_expand "testdi_ccno_1"
7445 [(set (reg:CCNO FLAGS_REG)
7447 (and:DI (match_operand:DI 0 "nonimmediate_operand")
7448 (match_operand:DI 1 "x86_64_szext_general_operand"))
7450 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7452 (define_insn "*testdi_1"
7453 [(set (reg FLAGS_REG)
7456 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7457 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7459 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7460 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7462 test{l}\t{%k1, %k0|%k0, %k1}
7463 test{l}\t{%k1, %k0|%k0, %k1}
7464 test{q}\t{%1, %0|%0, %1}
7465 test{q}\t{%1, %0|%0, %1}
7466 test{q}\t{%1, %0|%0, %1}"
7467 [(set_attr "type" "test")
7468 (set_attr "modrm" "0,1,0,1,1")
7469 (set_attr "mode" "SI,SI,DI,DI,DI")])
7471 (define_insn "*testqi_1_maybe_si"
7472 [(set (reg FLAGS_REG)
7475 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7476 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7478 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7479 && ix86_match_ccmode (insn,
7480 CONST_INT_P (operands[1])
7481 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7483 if (which_alternative == 3)
7485 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7486 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7487 return "test{l}\t{%1, %k0|%k0, %1}";
7489 return "test{b}\t{%1, %0|%0, %1}";
7491 [(set_attr "type" "test")
7492 (set_attr "modrm" "0,1,1,1")
7493 (set_attr "mode" "QI,QI,QI,SI")
7494 (set_attr "pent_pair" "uv,np,uv,np")])
7496 (define_insn "*test<mode>_1"
7497 [(set (reg FLAGS_REG)
7500 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7501 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7503 "ix86_match_ccmode (insn, CCNOmode)
7504 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7505 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7506 [(set_attr "type" "test")
7507 (set_attr "modrm" "0,1,1")
7508 (set_attr "mode" "<MODE>")
7509 (set_attr "pent_pair" "uv,np,uv")])
7511 (define_expand "testqi_ext_ccno_0"
7512 [(set (reg:CCNO FLAGS_REG)
7516 (match_operand 0 "ext_register_operand")
7519 (match_operand 1 "const_int_operand"))
7522 (define_insn "*testqi_ext_0"
7523 [(set (reg FLAGS_REG)
7527 (match_operand 0 "ext_register_operand" "Q")
7530 (match_operand 1 "const_int_operand" "n"))
7532 "ix86_match_ccmode (insn, CCNOmode)"
7533 "test{b}\t{%1, %h0|%h0, %1}"
7534 [(set_attr "type" "test")
7535 (set_attr "mode" "QI")
7536 (set_attr "length_immediate" "1")
7537 (set_attr "modrm" "1")
7538 (set_attr "pent_pair" "np")])
7540 (define_insn "*testqi_ext_1_rex64"
7541 [(set (reg FLAGS_REG)
7545 (match_operand 0 "ext_register_operand" "Q")
7549 (match_operand:QI 1 "register_operand" "Q")))
7551 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7552 "test{b}\t{%1, %h0|%h0, %1}"
7553 [(set_attr "type" "test")
7554 (set_attr "mode" "QI")])
7556 (define_insn "*testqi_ext_1"
7557 [(set (reg FLAGS_REG)
7561 (match_operand 0 "ext_register_operand" "Q")
7565 (match_operand:QI 1 "general_operand" "Qm")))
7567 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7568 "test{b}\t{%1, %h0|%h0, %1}"
7569 [(set_attr "type" "test")
7570 (set_attr "mode" "QI")])
7572 (define_insn "*testqi_ext_2"
7573 [(set (reg FLAGS_REG)
7577 (match_operand 0 "ext_register_operand" "Q")
7581 (match_operand 1 "ext_register_operand" "Q")
7585 "ix86_match_ccmode (insn, CCNOmode)"
7586 "test{b}\t{%h1, %h0|%h0, %h1}"
7587 [(set_attr "type" "test")
7588 (set_attr "mode" "QI")])
7590 (define_insn "*testqi_ext_3_rex64"
7591 [(set (reg FLAGS_REG)
7592 (compare (zero_extract:DI
7593 (match_operand 0 "nonimmediate_operand" "rm")
7594 (match_operand:DI 1 "const_int_operand")
7595 (match_operand:DI 2 "const_int_operand"))
7598 && ix86_match_ccmode (insn, CCNOmode)
7599 && INTVAL (operands[1]) > 0
7600 && INTVAL (operands[2]) >= 0
7601 /* Ensure that resulting mask is zero or sign extended operand. */
7602 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7603 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7604 && INTVAL (operands[1]) > 32))
7605 && (GET_MODE (operands[0]) == SImode
7606 || GET_MODE (operands[0]) == DImode
7607 || GET_MODE (operands[0]) == HImode
7608 || GET_MODE (operands[0]) == QImode)"
7611 ;; Combine likes to form bit extractions for some tests. Humor it.
7612 (define_insn "*testqi_ext_3"
7613 [(set (reg FLAGS_REG)
7614 (compare (zero_extract:SI
7615 (match_operand 0 "nonimmediate_operand" "rm")
7616 (match_operand:SI 1 "const_int_operand")
7617 (match_operand:SI 2 "const_int_operand"))
7619 "ix86_match_ccmode (insn, CCNOmode)
7620 && INTVAL (operands[1]) > 0
7621 && INTVAL (operands[2]) >= 0
7622 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7623 && (GET_MODE (operands[0]) == SImode
7624 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7625 || GET_MODE (operands[0]) == HImode
7626 || GET_MODE (operands[0]) == QImode)"
7630 [(set (match_operand 0 "flags_reg_operand")
7631 (match_operator 1 "compare_operator"
7633 (match_operand 2 "nonimmediate_operand")
7634 (match_operand 3 "const_int_operand")
7635 (match_operand 4 "const_int_operand"))
7637 "ix86_match_ccmode (insn, CCNOmode)"
7638 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7640 rtx val = operands[2];
7641 HOST_WIDE_INT len = INTVAL (operands[3]);
7642 HOST_WIDE_INT pos = INTVAL (operands[4]);
7644 enum machine_mode mode, submode;
7646 mode = GET_MODE (val);
7649 /* ??? Combine likes to put non-volatile mem extractions in QImode
7650 no matter the size of the test. So find a mode that works. */
7651 if (! MEM_VOLATILE_P (val))
7653 mode = smallest_mode_for_size (pos + len, MODE_INT);
7654 val = adjust_address (val, mode, 0);
7657 else if (GET_CODE (val) == SUBREG
7658 && (submode = GET_MODE (SUBREG_REG (val)),
7659 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7660 && pos + len <= GET_MODE_BITSIZE (submode)
7661 && GET_MODE_CLASS (submode) == MODE_INT)
7663 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7665 val = SUBREG_REG (val);
7667 else if (mode == HImode && pos + len <= 8)
7669 /* Small HImode tests can be converted to QImode. */
7671 val = gen_lowpart (QImode, val);
7674 if (len == HOST_BITS_PER_WIDE_INT)
7677 mask = ((HOST_WIDE_INT)1 << len) - 1;
7680 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7683 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7684 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7685 ;; this is relatively important trick.
7686 ;; Do the conversion only post-reload to avoid limiting of the register class
7689 [(set (match_operand 0 "flags_reg_operand")
7690 (match_operator 1 "compare_operator"
7691 [(and (match_operand 2 "register_operand")
7692 (match_operand 3 "const_int_operand"))
7695 && QI_REG_P (operands[2])
7696 && GET_MODE (operands[2]) != QImode
7697 && ((ix86_match_ccmode (insn, CCZmode)
7698 && !(INTVAL (operands[3]) & ~(255 << 8)))
7699 || (ix86_match_ccmode (insn, CCNOmode)
7700 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7703 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7707 operands[2] = gen_lowpart (SImode, operands[2]);
7708 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7712 [(set (match_operand 0 "flags_reg_operand")
7713 (match_operator 1 "compare_operator"
7714 [(and (match_operand 2 "nonimmediate_operand")
7715 (match_operand 3 "const_int_operand"))
7718 && GET_MODE (operands[2]) != QImode
7719 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7720 && ((ix86_match_ccmode (insn, CCZmode)
7721 && !(INTVAL (operands[3]) & ~255))
7722 || (ix86_match_ccmode (insn, CCNOmode)
7723 && !(INTVAL (operands[3]) & ~127)))"
7725 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7728 operands[2] = gen_lowpart (QImode, operands[2]);
7729 operands[3] = gen_lowpart (QImode, operands[3]);
7732 ;; %%% This used to optimize known byte-wide and operations to memory,
7733 ;; and sometimes to QImode registers. If this is considered useful,
7734 ;; it should be done with splitters.
7736 (define_expand "and<mode>3"
7737 [(set (match_operand:SWIM 0 "nonimmediate_operand")
7738 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7739 (match_operand:SWIM 2 "<general_szext_operand>")))]
7742 enum machine_mode mode = <MODE>mode;
7743 rtx (*insn) (rtx, rtx);
7745 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7747 HOST_WIDE_INT ival = INTVAL (operands[2]);
7749 if (ival == (HOST_WIDE_INT) 0xffffffff)
7751 else if (ival == 0xffff)
7753 else if (ival == 0xff)
7757 if (mode == <MODE>mode)
7759 ix86_expand_binary_operator (AND, <MODE>mode, operands);
7763 if (<MODE>mode == DImode)
7764 insn = (mode == SImode)
7765 ? gen_zero_extendsidi2
7767 ? gen_zero_extendhidi2
7768 : gen_zero_extendqidi2;
7769 else if (<MODE>mode == SImode)
7770 insn = (mode == HImode)
7771 ? gen_zero_extendhisi2
7772 : gen_zero_extendqisi2;
7773 else if (<MODE>mode == HImode)
7774 insn = gen_zero_extendqihi2;
7778 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7782 (define_insn "*anddi_1"
7783 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7785 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7786 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7787 (clobber (reg:CC FLAGS_REG))]
7788 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7790 switch (get_attr_type (insn))
7796 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7797 if (get_attr_mode (insn) == MODE_SI)
7798 return "and{l}\t{%k2, %k0|%k0, %k2}";
7800 return "and{q}\t{%2, %0|%0, %2}";
7803 [(set_attr "type" "alu,alu,alu,imovx")
7804 (set_attr "length_immediate" "*,*,*,0")
7805 (set (attr "prefix_rex")
7807 (and (eq_attr "type" "imovx")
7808 (and (match_test "INTVAL (operands[2]) == 0xff")
7809 (match_operand 1 "ext_QIreg_operand")))
7811 (const_string "*")))
7812 (set_attr "mode" "SI,DI,DI,SI")])
7814 (define_insn "*andsi_1"
7815 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya")
7816 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7817 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7818 (clobber (reg:CC FLAGS_REG))]
7819 "ix86_binary_operator_ok (AND, SImode, operands)"
7821 switch (get_attr_type (insn))
7827 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7828 return "and{l}\t{%2, %0|%0, %2}";
7831 [(set_attr "type" "alu,alu,imovx")
7832 (set (attr "prefix_rex")
7834 (and (eq_attr "type" "imovx")
7835 (and (match_test "INTVAL (operands[2]) == 0xff")
7836 (match_operand 1 "ext_QIreg_operand")))
7838 (const_string "*")))
7839 (set_attr "length_immediate" "*,*,0")
7840 (set_attr "mode" "SI")])
7842 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7843 (define_insn "*andsi_1_zext"
7844 [(set (match_operand:DI 0 "register_operand" "=r")
7846 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7847 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7848 (clobber (reg:CC FLAGS_REG))]
7849 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7850 "and{l}\t{%2, %k0|%k0, %2}"
7851 [(set_attr "type" "alu")
7852 (set_attr "mode" "SI")])
7854 (define_insn "*andhi_1"
7855 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya")
7856 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7857 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7858 (clobber (reg:CC FLAGS_REG))]
7859 "ix86_binary_operator_ok (AND, HImode, operands)"
7861 switch (get_attr_type (insn))
7867 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7868 return "and{w}\t{%2, %0|%0, %2}";
7871 [(set_attr "type" "alu,alu,imovx")
7872 (set_attr "length_immediate" "*,*,0")
7873 (set (attr "prefix_rex")
7875 (and (eq_attr "type" "imovx")
7876 (match_operand 1 "ext_QIreg_operand"))
7878 (const_string "*")))
7879 (set_attr "mode" "HI,HI,SI")])
7881 ;; %%% Potential partial reg stall on alternative 2. What to do?
7882 (define_insn "*andqi_1"
7883 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7884 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7885 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7886 (clobber (reg:CC FLAGS_REG))]
7887 "ix86_binary_operator_ok (AND, QImode, operands)"
7889 and{b}\t{%2, %0|%0, %2}
7890 and{b}\t{%2, %0|%0, %2}
7891 and{l}\t{%k2, %k0|%k0, %k2}"
7892 [(set_attr "type" "alu")
7893 (set_attr "mode" "QI,QI,SI")])
7895 (define_insn "*andqi_1_slp"
7896 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7897 (and:QI (match_dup 0)
7898 (match_operand:QI 1 "general_operand" "qn,qmn")))
7899 (clobber (reg:CC FLAGS_REG))]
7900 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7901 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7902 "and{b}\t{%1, %0|%0, %1}"
7903 [(set_attr "type" "alu1")
7904 (set_attr "mode" "QI")])
7906 ;; Turn *anddi_1 into *andsi_1_zext if possible.
7908 [(set (match_operand:DI 0 "register_operand")
7909 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
7910 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
7911 (clobber (reg:CC FLAGS_REG))]
7913 [(parallel [(set (match_dup 0)
7914 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
7915 (clobber (reg:CC FLAGS_REG))])]
7916 "operands[2] = gen_lowpart (SImode, operands[2]);")
7919 [(set (match_operand:SWI248 0 "register_operand")
7920 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
7921 (match_operand:SWI248 2 "const_int_operand")))
7922 (clobber (reg:CC FLAGS_REG))]
7924 && true_regnum (operands[0]) != true_regnum (operands[1])"
7927 HOST_WIDE_INT ival = INTVAL (operands[2]);
7928 enum machine_mode mode;
7929 rtx (*insn) (rtx, rtx);
7931 if (ival == (HOST_WIDE_INT) 0xffffffff)
7933 else if (ival == 0xffff)
7937 gcc_assert (ival == 0xff);
7941 if (<MODE>mode == DImode)
7942 insn = (mode == SImode)
7943 ? gen_zero_extendsidi2
7945 ? gen_zero_extendhidi2
7946 : gen_zero_extendqidi2;
7949 if (<MODE>mode != SImode)
7950 /* Zero extend to SImode to avoid partial register stalls. */
7951 operands[0] = gen_lowpart (SImode, operands[0]);
7953 insn = (mode == HImode)
7954 ? gen_zero_extendhisi2
7955 : gen_zero_extendqisi2;
7957 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7962 [(set (match_operand 0 "register_operand")
7964 (const_int -65536)))
7965 (clobber (reg:CC FLAGS_REG))]
7966 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7967 || optimize_function_for_size_p (cfun)"
7968 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7969 "operands[1] = gen_lowpart (HImode, operands[0]);")
7972 [(set (match_operand 0 "ext_register_operand")
7975 (clobber (reg:CC FLAGS_REG))]
7976 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7977 && reload_completed"
7978 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7979 "operands[1] = gen_lowpart (QImode, operands[0]);")
7982 [(set (match_operand 0 "ext_register_operand")
7984 (const_int -65281)))
7985 (clobber (reg:CC FLAGS_REG))]
7986 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7987 && reload_completed"
7988 [(parallel [(set (zero_extract:SI (match_dup 0)
7992 (zero_extract:SI (match_dup 0)
7995 (zero_extract:SI (match_dup 0)
7998 (clobber (reg:CC FLAGS_REG))])]
7999 "operands[0] = gen_lowpart (SImode, operands[0]);")
8001 (define_insn "*anddi_2"
8002 [(set (reg FLAGS_REG)
8005 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8006 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8008 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8009 (and:DI (match_dup 1) (match_dup 2)))]
8010 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8011 && ix86_binary_operator_ok (AND, DImode, operands)"
8013 and{l}\t{%k2, %k0|%k0, %k2}
8014 and{q}\t{%2, %0|%0, %2}
8015 and{q}\t{%2, %0|%0, %2}"
8016 [(set_attr "type" "alu")
8017 (set_attr "mode" "SI,DI,DI")])
8019 (define_insn "*andqi_2_maybe_si"
8020 [(set (reg FLAGS_REG)
8022 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8023 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8025 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8026 (and:QI (match_dup 1) (match_dup 2)))]
8027 "ix86_binary_operator_ok (AND, QImode, operands)
8028 && ix86_match_ccmode (insn,
8029 CONST_INT_P (operands[2])
8030 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8032 if (which_alternative == 2)
8034 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8035 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8036 return "and{l}\t{%2, %k0|%k0, %2}";
8038 return "and{b}\t{%2, %0|%0, %2}";
8040 [(set_attr "type" "alu")
8041 (set_attr "mode" "QI,QI,SI")])
8043 (define_insn "*and<mode>_2"
8044 [(set (reg FLAGS_REG)
8045 (compare (and:SWI124
8046 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8047 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8049 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8050 (and:SWI124 (match_dup 1) (match_dup 2)))]
8051 "ix86_match_ccmode (insn, CCNOmode)
8052 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8053 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8054 [(set_attr "type" "alu")
8055 (set_attr "mode" "<MODE>")])
8057 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8058 (define_insn "*andsi_2_zext"
8059 [(set (reg FLAGS_REG)
8061 (match_operand:SI 1 "nonimmediate_operand" "%0")
8062 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8064 (set (match_operand:DI 0 "register_operand" "=r")
8065 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8066 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8067 && ix86_binary_operator_ok (AND, SImode, operands)"
8068 "and{l}\t{%2, %k0|%k0, %2}"
8069 [(set_attr "type" "alu")
8070 (set_attr "mode" "SI")])
8072 (define_insn "*andqi_2_slp"
8073 [(set (reg FLAGS_REG)
8075 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8076 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8078 (set (strict_low_part (match_dup 0))
8079 (and:QI (match_dup 0) (match_dup 1)))]
8080 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8081 && ix86_match_ccmode (insn, CCNOmode)
8082 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8083 "and{b}\t{%1, %0|%0, %1}"
8084 [(set_attr "type" "alu1")
8085 (set_attr "mode" "QI")])
8087 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8088 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8089 ;; for a QImode operand, which of course failed.
8090 (define_insn "andqi_ext_0"
8091 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8096 (match_operand 1 "ext_register_operand" "0")
8099 (match_operand 2 "const_int_operand" "n")))
8100 (clobber (reg:CC FLAGS_REG))]
8102 "and{b}\t{%2, %h0|%h0, %2}"
8103 [(set_attr "type" "alu")
8104 (set_attr "length_immediate" "1")
8105 (set_attr "modrm" "1")
8106 (set_attr "mode" "QI")])
8108 ;; Generated by peephole translating test to and. This shows up
8109 ;; often in fp comparisons.
8110 (define_insn "*andqi_ext_0_cc"
8111 [(set (reg FLAGS_REG)
8115 (match_operand 1 "ext_register_operand" "0")
8118 (match_operand 2 "const_int_operand" "n"))
8120 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8129 "ix86_match_ccmode (insn, CCNOmode)"
8130 "and{b}\t{%2, %h0|%h0, %2}"
8131 [(set_attr "type" "alu")
8132 (set_attr "length_immediate" "1")
8133 (set_attr "modrm" "1")
8134 (set_attr "mode" "QI")])
8136 (define_insn "*andqi_ext_1_rex64"
8137 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8142 (match_operand 1 "ext_register_operand" "0")
8146 (match_operand 2 "ext_register_operand" "Q"))))
8147 (clobber (reg:CC FLAGS_REG))]
8149 "and{b}\t{%2, %h0|%h0, %2}"
8150 [(set_attr "type" "alu")
8151 (set_attr "length_immediate" "0")
8152 (set_attr "mode" "QI")])
8154 (define_insn "*andqi_ext_1"
8155 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8160 (match_operand 1 "ext_register_operand" "0")
8164 (match_operand:QI 2 "general_operand" "Qm"))))
8165 (clobber (reg:CC FLAGS_REG))]
8167 "and{b}\t{%2, %h0|%h0, %2}"
8168 [(set_attr "type" "alu")
8169 (set_attr "length_immediate" "0")
8170 (set_attr "mode" "QI")])
8172 (define_insn "*andqi_ext_2"
8173 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8178 (match_operand 1 "ext_register_operand" "%0")
8182 (match_operand 2 "ext_register_operand" "Q")
8185 (clobber (reg:CC FLAGS_REG))]
8187 "and{b}\t{%h2, %h0|%h0, %h2}"
8188 [(set_attr "type" "alu")
8189 (set_attr "length_immediate" "0")
8190 (set_attr "mode" "QI")])
8192 ;; Convert wide AND instructions with immediate operand to shorter QImode
8193 ;; equivalents when possible.
8194 ;; Don't do the splitting with memory operands, since it introduces risk
8195 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8196 ;; for size, but that can (should?) be handled by generic code instead.
8198 [(set (match_operand 0 "register_operand")
8199 (and (match_operand 1 "register_operand")
8200 (match_operand 2 "const_int_operand")))
8201 (clobber (reg:CC FLAGS_REG))]
8203 && QI_REG_P (operands[0])
8204 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8205 && !(~INTVAL (operands[2]) & ~(255 << 8))
8206 && GET_MODE (operands[0]) != QImode"
8207 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8208 (and:SI (zero_extract:SI (match_dup 1)
8209 (const_int 8) (const_int 8))
8211 (clobber (reg:CC FLAGS_REG))])]
8213 operands[0] = gen_lowpart (SImode, operands[0]);
8214 operands[1] = gen_lowpart (SImode, operands[1]);
8215 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8218 ;; Since AND can be encoded with sign extended immediate, this is only
8219 ;; profitable when 7th bit is not set.
8221 [(set (match_operand 0 "register_operand")
8222 (and (match_operand 1 "general_operand")
8223 (match_operand 2 "const_int_operand")))
8224 (clobber (reg:CC FLAGS_REG))]
8226 && ANY_QI_REG_P (operands[0])
8227 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8228 && !(~INTVAL (operands[2]) & ~255)
8229 && !(INTVAL (operands[2]) & 128)
8230 && GET_MODE (operands[0]) != QImode"
8231 [(parallel [(set (strict_low_part (match_dup 0))
8232 (and:QI (match_dup 1)
8234 (clobber (reg:CC FLAGS_REG))])]
8236 operands[0] = gen_lowpart (QImode, operands[0]);
8237 operands[1] = gen_lowpart (QImode, operands[1]);
8238 operands[2] = gen_lowpart (QImode, operands[2]);
8241 ;; Logical inclusive and exclusive OR instructions
8243 ;; %%% This used to optimize known byte-wide and operations to memory.
8244 ;; If this is considered useful, it should be done with splitters.
8246 (define_expand "<code><mode>3"
8247 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8248 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
8249 (match_operand:SWIM 2 "<general_operand>")))]
8251 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8253 (define_insn "*<code><mode>_1"
8254 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8256 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8257 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8258 (clobber (reg:CC FLAGS_REG))]
8259 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8260 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8261 [(set_attr "type" "alu")
8262 (set_attr "mode" "<MODE>")])
8264 ;; %%% Potential partial reg stall on alternative 2. What to do?
8265 (define_insn "*<code>qi_1"
8266 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8267 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8268 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8269 (clobber (reg:CC FLAGS_REG))]
8270 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8272 <logic>{b}\t{%2, %0|%0, %2}
8273 <logic>{b}\t{%2, %0|%0, %2}
8274 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8275 [(set_attr "type" "alu")
8276 (set_attr "mode" "QI,QI,SI")])
8278 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8279 (define_insn "*<code>si_1_zext"
8280 [(set (match_operand:DI 0 "register_operand" "=r")
8282 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8283 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8284 (clobber (reg:CC FLAGS_REG))]
8285 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8286 "<logic>{l}\t{%2, %k0|%k0, %2}"
8287 [(set_attr "type" "alu")
8288 (set_attr "mode" "SI")])
8290 (define_insn "*<code>si_1_zext_imm"
8291 [(set (match_operand:DI 0 "register_operand" "=r")
8293 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8294 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8295 (clobber (reg:CC FLAGS_REG))]
8296 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8297 "<logic>{l}\t{%2, %k0|%k0, %2}"
8298 [(set_attr "type" "alu")
8299 (set_attr "mode" "SI")])
8301 (define_insn "*<code>qi_1_slp"
8302 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8303 (any_or:QI (match_dup 0)
8304 (match_operand:QI 1 "general_operand" "qmn,qn")))
8305 (clobber (reg:CC FLAGS_REG))]
8306 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8307 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8308 "<logic>{b}\t{%1, %0|%0, %1}"
8309 [(set_attr "type" "alu1")
8310 (set_attr "mode" "QI")])
8312 (define_insn "*<code><mode>_2"
8313 [(set (reg FLAGS_REG)
8314 (compare (any_or:SWI
8315 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8316 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8318 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8319 (any_or:SWI (match_dup 1) (match_dup 2)))]
8320 "ix86_match_ccmode (insn, CCNOmode)
8321 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8322 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8323 [(set_attr "type" "alu")
8324 (set_attr "mode" "<MODE>")])
8326 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8327 ;; ??? Special case for immediate operand is missing - it is tricky.
8328 (define_insn "*<code>si_2_zext"
8329 [(set (reg FLAGS_REG)
8330 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8331 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8333 (set (match_operand:DI 0 "register_operand" "=r")
8334 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8335 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8336 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8337 "<logic>{l}\t{%2, %k0|%k0, %2}"
8338 [(set_attr "type" "alu")
8339 (set_attr "mode" "SI")])
8341 (define_insn "*<code>si_2_zext_imm"
8342 [(set (reg FLAGS_REG)
8344 (match_operand:SI 1 "nonimmediate_operand" "%0")
8345 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8347 (set (match_operand:DI 0 "register_operand" "=r")
8348 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8349 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8350 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8351 "<logic>{l}\t{%2, %k0|%k0, %2}"
8352 [(set_attr "type" "alu")
8353 (set_attr "mode" "SI")])
8355 (define_insn "*<code>qi_2_slp"
8356 [(set (reg FLAGS_REG)
8357 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8358 (match_operand:QI 1 "general_operand" "qmn,qn"))
8360 (set (strict_low_part (match_dup 0))
8361 (any_or:QI (match_dup 0) (match_dup 1)))]
8362 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8363 && ix86_match_ccmode (insn, CCNOmode)
8364 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8365 "<logic>{b}\t{%1, %0|%0, %1}"
8366 [(set_attr "type" "alu1")
8367 (set_attr "mode" "QI")])
8369 (define_insn "*<code><mode>_3"
8370 [(set (reg FLAGS_REG)
8371 (compare (any_or:SWI
8372 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8373 (match_operand:SWI 2 "<general_operand>" "<g>"))
8375 (clobber (match_scratch:SWI 0 "=<r>"))]
8376 "ix86_match_ccmode (insn, CCNOmode)
8377 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8378 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8379 [(set_attr "type" "alu")
8380 (set_attr "mode" "<MODE>")])
8382 (define_insn "*<code>qi_ext_0"
8383 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8388 (match_operand 1 "ext_register_operand" "0")
8391 (match_operand 2 "const_int_operand" "n")))
8392 (clobber (reg:CC FLAGS_REG))]
8393 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8394 "<logic>{b}\t{%2, %h0|%h0, %2}"
8395 [(set_attr "type" "alu")
8396 (set_attr "length_immediate" "1")
8397 (set_attr "modrm" "1")
8398 (set_attr "mode" "QI")])
8400 (define_insn "*<code>qi_ext_1_rex64"
8401 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8406 (match_operand 1 "ext_register_operand" "0")
8410 (match_operand 2 "ext_register_operand" "Q"))))
8411 (clobber (reg:CC FLAGS_REG))]
8413 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8414 "<logic>{b}\t{%2, %h0|%h0, %2}"
8415 [(set_attr "type" "alu")
8416 (set_attr "length_immediate" "0")
8417 (set_attr "mode" "QI")])
8419 (define_insn "*<code>qi_ext_1"
8420 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8425 (match_operand 1 "ext_register_operand" "0")
8429 (match_operand:QI 2 "general_operand" "Qm"))))
8430 (clobber (reg:CC FLAGS_REG))]
8432 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8433 "<logic>{b}\t{%2, %h0|%h0, %2}"
8434 [(set_attr "type" "alu")
8435 (set_attr "length_immediate" "0")
8436 (set_attr "mode" "QI")])
8438 (define_insn "*<code>qi_ext_2"
8439 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8443 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8446 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8449 (clobber (reg:CC FLAGS_REG))]
8450 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8451 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8452 [(set_attr "type" "alu")
8453 (set_attr "length_immediate" "0")
8454 (set_attr "mode" "QI")])
8457 [(set (match_operand 0 "register_operand")
8458 (any_or (match_operand 1 "register_operand")
8459 (match_operand 2 "const_int_operand")))
8460 (clobber (reg:CC FLAGS_REG))]
8462 && QI_REG_P (operands[0])
8463 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8464 && !(INTVAL (operands[2]) & ~(255 << 8))
8465 && GET_MODE (operands[0]) != QImode"
8466 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8467 (any_or:SI (zero_extract:SI (match_dup 1)
8468 (const_int 8) (const_int 8))
8470 (clobber (reg:CC FLAGS_REG))])]
8472 operands[0] = gen_lowpart (SImode, operands[0]);
8473 operands[1] = gen_lowpart (SImode, operands[1]);
8474 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8477 ;; Since OR can be encoded with sign extended immediate, this is only
8478 ;; profitable when 7th bit is set.
8480 [(set (match_operand 0 "register_operand")
8481 (any_or (match_operand 1 "general_operand")
8482 (match_operand 2 "const_int_operand")))
8483 (clobber (reg:CC FLAGS_REG))]
8485 && ANY_QI_REG_P (operands[0])
8486 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8487 && !(INTVAL (operands[2]) & ~255)
8488 && (INTVAL (operands[2]) & 128)
8489 && GET_MODE (operands[0]) != QImode"
8490 [(parallel [(set (strict_low_part (match_dup 0))
8491 (any_or:QI (match_dup 1)
8493 (clobber (reg:CC FLAGS_REG))])]
8495 operands[0] = gen_lowpart (QImode, operands[0]);
8496 operands[1] = gen_lowpart (QImode, operands[1]);
8497 operands[2] = gen_lowpart (QImode, operands[2]);
8500 (define_expand "xorqi_cc_ext_1"
8502 (set (reg:CCNO FLAGS_REG)
8506 (match_operand 1 "ext_register_operand")
8509 (match_operand:QI 2 "general_operand"))
8511 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8521 (define_insn "*xorqi_cc_ext_1_rex64"
8522 [(set (reg FLAGS_REG)
8526 (match_operand 1 "ext_register_operand" "0")
8529 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8531 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8540 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8541 "xor{b}\t{%2, %h0|%h0, %2}"
8542 [(set_attr "type" "alu")
8543 (set_attr "modrm" "1")
8544 (set_attr "mode" "QI")])
8546 (define_insn "*xorqi_cc_ext_1"
8547 [(set (reg FLAGS_REG)
8551 (match_operand 1 "ext_register_operand" "0")
8554 (match_operand:QI 2 "general_operand" "qmn"))
8556 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8565 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8566 "xor{b}\t{%2, %h0|%h0, %2}"
8567 [(set_attr "type" "alu")
8568 (set_attr "modrm" "1")
8569 (set_attr "mode" "QI")])
8571 ;; Negation instructions
8573 (define_expand "neg<mode>2"
8574 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8575 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8577 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8579 (define_insn_and_split "*neg<dwi>2_doubleword"
8580 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8581 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8582 (clobber (reg:CC FLAGS_REG))]
8583 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8587 [(set (reg:CCZ FLAGS_REG)
8588 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8589 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8592 (plus:DWIH (match_dup 3)
8593 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8595 (clobber (reg:CC FLAGS_REG))])
8598 (neg:DWIH (match_dup 2)))
8599 (clobber (reg:CC FLAGS_REG))])]
8600 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8602 (define_insn "*neg<mode>2_1"
8603 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8604 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8605 (clobber (reg:CC FLAGS_REG))]
8606 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8607 "neg{<imodesuffix>}\t%0"
8608 [(set_attr "type" "negnot")
8609 (set_attr "mode" "<MODE>")])
8611 ;; Combine is quite creative about this pattern.
8612 (define_insn "*negsi2_1_zext"
8613 [(set (match_operand:DI 0 "register_operand" "=r")
8615 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8618 (clobber (reg:CC FLAGS_REG))]
8619 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8621 [(set_attr "type" "negnot")
8622 (set_attr "mode" "SI")])
8624 ;; The problem with neg is that it does not perform (compare x 0),
8625 ;; it really performs (compare 0 x), which leaves us with the zero
8626 ;; flag being the only useful item.
8628 (define_insn "*neg<mode>2_cmpz"
8629 [(set (reg:CCZ FLAGS_REG)
8631 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8633 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8634 (neg:SWI (match_dup 1)))]
8635 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8636 "neg{<imodesuffix>}\t%0"
8637 [(set_attr "type" "negnot")
8638 (set_attr "mode" "<MODE>")])
8640 (define_insn "*negsi2_cmpz_zext"
8641 [(set (reg:CCZ FLAGS_REG)
8645 (match_operand:DI 1 "register_operand" "0")
8649 (set (match_operand:DI 0 "register_operand" "=r")
8650 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8653 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8655 [(set_attr "type" "negnot")
8656 (set_attr "mode" "SI")])
8658 ;; Changing of sign for FP values is doable using integer unit too.
8660 (define_expand "<code><mode>2"
8661 [(set (match_operand:X87MODEF 0 "register_operand")
8662 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8663 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8664 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8666 (define_insn "*absneg<mode>2_mixed"
8667 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8668 (match_operator:MODEF 3 "absneg_operator"
8669 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8670 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8671 (clobber (reg:CC FLAGS_REG))]
8672 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8675 (define_insn "*absneg<mode>2_sse"
8676 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8677 (match_operator:MODEF 3 "absneg_operator"
8678 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8679 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8680 (clobber (reg:CC FLAGS_REG))]
8681 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8684 (define_insn "*absneg<mode>2_i387"
8685 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8686 (match_operator:X87MODEF 3 "absneg_operator"
8687 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8688 (use (match_operand 2))
8689 (clobber (reg:CC FLAGS_REG))]
8690 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8693 (define_expand "<code>tf2"
8694 [(set (match_operand:TF 0 "register_operand")
8695 (absneg:TF (match_operand:TF 1 "register_operand")))]
8697 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8699 (define_insn "*absnegtf2_sse"
8700 [(set (match_operand:TF 0 "register_operand" "=x,x")
8701 (match_operator:TF 3 "absneg_operator"
8702 [(match_operand:TF 1 "register_operand" "0,x")]))
8703 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8704 (clobber (reg:CC FLAGS_REG))]
8708 ;; Splitters for fp abs and neg.
8711 [(set (match_operand 0 "fp_register_operand")
8712 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8713 (use (match_operand 2))
8714 (clobber (reg:CC FLAGS_REG))]
8716 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8719 [(set (match_operand 0 "register_operand")
8720 (match_operator 3 "absneg_operator"
8721 [(match_operand 1 "register_operand")]))
8722 (use (match_operand 2 "nonimmediate_operand"))
8723 (clobber (reg:CC FLAGS_REG))]
8724 "reload_completed && SSE_REG_P (operands[0])"
8725 [(set (match_dup 0) (match_dup 3))]
8727 enum machine_mode mode = GET_MODE (operands[0]);
8728 enum machine_mode vmode = GET_MODE (operands[2]);
8731 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8732 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8733 if (operands_match_p (operands[0], operands[2]))
8736 operands[1] = operands[2];
8739 if (GET_CODE (operands[3]) == ABS)
8740 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8742 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8747 [(set (match_operand:SF 0 "register_operand")
8748 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8749 (use (match_operand:V4SF 2))
8750 (clobber (reg:CC FLAGS_REG))]
8752 [(parallel [(set (match_dup 0) (match_dup 1))
8753 (clobber (reg:CC FLAGS_REG))])]
8756 operands[0] = gen_lowpart (SImode, operands[0]);
8757 if (GET_CODE (operands[1]) == ABS)
8759 tmp = gen_int_mode (0x7fffffff, SImode);
8760 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8764 tmp = gen_int_mode (0x80000000, SImode);
8765 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8771 [(set (match_operand:DF 0 "register_operand")
8772 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8773 (use (match_operand 2))
8774 (clobber (reg:CC FLAGS_REG))]
8776 [(parallel [(set (match_dup 0) (match_dup 1))
8777 (clobber (reg:CC FLAGS_REG))])]
8782 tmp = gen_lowpart (DImode, operands[0]);
8783 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8786 if (GET_CODE (operands[1]) == ABS)
8789 tmp = gen_rtx_NOT (DImode, tmp);
8793 operands[0] = gen_highpart (SImode, operands[0]);
8794 if (GET_CODE (operands[1]) == ABS)
8796 tmp = gen_int_mode (0x7fffffff, SImode);
8797 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8801 tmp = gen_int_mode (0x80000000, SImode);
8802 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8809 [(set (match_operand:XF 0 "register_operand")
8810 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8811 (use (match_operand 2))
8812 (clobber (reg:CC FLAGS_REG))]
8814 [(parallel [(set (match_dup 0) (match_dup 1))
8815 (clobber (reg:CC FLAGS_REG))])]
8818 operands[0] = gen_rtx_REG (SImode,
8819 true_regnum (operands[0])
8820 + (TARGET_64BIT ? 1 : 2));
8821 if (GET_CODE (operands[1]) == ABS)
8823 tmp = GEN_INT (0x7fff);
8824 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8828 tmp = GEN_INT (0x8000);
8829 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8834 ;; Conditionalize these after reload. If they match before reload, we
8835 ;; lose the clobber and ability to use integer instructions.
8837 (define_insn "*<code><mode>2_1"
8838 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8839 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8841 && (reload_completed
8842 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8843 "f<absneg_mnemonic>"
8844 [(set_attr "type" "fsgn")
8845 (set_attr "mode" "<MODE>")])
8847 (define_insn "*<code>extendsfdf2"
8848 [(set (match_operand:DF 0 "register_operand" "=f")
8849 (absneg:DF (float_extend:DF
8850 (match_operand:SF 1 "register_operand" "0"))))]
8851 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8852 "f<absneg_mnemonic>"
8853 [(set_attr "type" "fsgn")
8854 (set_attr "mode" "DF")])
8856 (define_insn "*<code>extendsfxf2"
8857 [(set (match_operand:XF 0 "register_operand" "=f")
8858 (absneg:XF (float_extend:XF
8859 (match_operand:SF 1 "register_operand" "0"))))]
8861 "f<absneg_mnemonic>"
8862 [(set_attr "type" "fsgn")
8863 (set_attr "mode" "XF")])
8865 (define_insn "*<code>extenddfxf2"
8866 [(set (match_operand:XF 0 "register_operand" "=f")
8867 (absneg:XF (float_extend:XF
8868 (match_operand:DF 1 "register_operand" "0"))))]
8870 "f<absneg_mnemonic>"
8871 [(set_attr "type" "fsgn")
8872 (set_attr "mode" "XF")])
8874 ;; Copysign instructions
8876 (define_mode_iterator CSGNMODE [SF DF TF])
8877 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8879 (define_expand "copysign<mode>3"
8880 [(match_operand:CSGNMODE 0 "register_operand")
8881 (match_operand:CSGNMODE 1 "nonmemory_operand")
8882 (match_operand:CSGNMODE 2 "register_operand")]
8883 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8884 || (TARGET_SSE && (<MODE>mode == TFmode))"
8885 "ix86_expand_copysign (operands); DONE;")
8887 (define_insn_and_split "copysign<mode>3_const"
8888 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8890 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8891 (match_operand:CSGNMODE 2 "register_operand" "0")
8892 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8894 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8895 || (TARGET_SSE && (<MODE>mode == TFmode))"
8897 "&& reload_completed"
8899 "ix86_split_copysign_const (operands); DONE;")
8901 (define_insn "copysign<mode>3_var"
8902 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8904 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8905 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8906 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8907 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8909 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8910 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8911 || (TARGET_SSE && (<MODE>mode == TFmode))"
8915 [(set (match_operand:CSGNMODE 0 "register_operand")
8917 [(match_operand:CSGNMODE 2 "register_operand")
8918 (match_operand:CSGNMODE 3 "register_operand")
8919 (match_operand:<CSGNVMODE> 4)
8920 (match_operand:<CSGNVMODE> 5)]
8922 (clobber (match_scratch:<CSGNVMODE> 1))]
8923 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8924 || (TARGET_SSE && (<MODE>mode == TFmode)))
8925 && reload_completed"
8927 "ix86_split_copysign_var (operands); DONE;")
8929 ;; One complement instructions
8931 (define_expand "one_cmpl<mode>2"
8932 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8933 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
8935 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8937 (define_insn "*one_cmpl<mode>2_1"
8938 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8939 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8940 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8941 "not{<imodesuffix>}\t%0"
8942 [(set_attr "type" "negnot")
8943 (set_attr "mode" "<MODE>")])
8945 ;; %%% Potential partial reg stall on alternative 1. What to do?
8946 (define_insn "*one_cmplqi2_1"
8947 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8948 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8949 "ix86_unary_operator_ok (NOT, QImode, operands)"
8953 [(set_attr "type" "negnot")
8954 (set_attr "mode" "QI,SI")])
8956 ;; ??? Currently never generated - xor is used instead.
8957 (define_insn "*one_cmplsi2_1_zext"
8958 [(set (match_operand:DI 0 "register_operand" "=r")
8960 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8961 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8963 [(set_attr "type" "negnot")
8964 (set_attr "mode" "SI")])
8966 (define_insn "*one_cmpl<mode>2_2"
8967 [(set (reg FLAGS_REG)
8968 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8970 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8971 (not:SWI (match_dup 1)))]
8972 "ix86_match_ccmode (insn, CCNOmode)
8973 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8975 [(set_attr "type" "alu1")
8976 (set_attr "mode" "<MODE>")])
8979 [(set (match_operand 0 "flags_reg_operand")
8980 (match_operator 2 "compare_operator"
8981 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
8983 (set (match_operand:SWI 1 "nonimmediate_operand")
8984 (not:SWI (match_dup 3)))]
8985 "ix86_match_ccmode (insn, CCNOmode)"
8986 [(parallel [(set (match_dup 0)
8987 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8990 (xor:SWI (match_dup 3) (const_int -1)))])])
8992 ;; ??? Currently never generated - xor is used instead.
8993 (define_insn "*one_cmplsi2_2_zext"
8994 [(set (reg FLAGS_REG)
8995 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8997 (set (match_operand:DI 0 "register_operand" "=r")
8998 (zero_extend:DI (not:SI (match_dup 1))))]
8999 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9000 && ix86_unary_operator_ok (NOT, SImode, operands)"
9002 [(set_attr "type" "alu1")
9003 (set_attr "mode" "SI")])
9006 [(set (match_operand 0 "flags_reg_operand")
9007 (match_operator 2 "compare_operator"
9008 [(not:SI (match_operand:SI 3 "register_operand"))
9010 (set (match_operand:DI 1 "register_operand")
9011 (zero_extend:DI (not:SI (match_dup 3))))]
9012 "ix86_match_ccmode (insn, CCNOmode)"
9013 [(parallel [(set (match_dup 0)
9014 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9017 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9019 ;; Shift instructions
9021 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9022 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9023 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9024 ;; from the assembler input.
9026 ;; This instruction shifts the target reg/mem as usual, but instead of
9027 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9028 ;; is a left shift double, bits are taken from the high order bits of
9029 ;; reg, else if the insn is a shift right double, bits are taken from the
9030 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9031 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9033 ;; Since sh[lr]d does not change the `reg' operand, that is done
9034 ;; separately, making all shifts emit pairs of shift double and normal
9035 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9036 ;; support a 63 bit shift, each shift where the count is in a reg expands
9037 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9039 ;; If the shift count is a constant, we need never emit more than one
9040 ;; shift pair, instead using moves and sign extension for counts greater
9043 (define_expand "ashl<mode>3"
9044 [(set (match_operand:SDWIM 0 "<shift_operand>")
9045 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9046 (match_operand:QI 2 "nonmemory_operand")))]
9048 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9050 (define_insn "*ashl<mode>3_doubleword"
9051 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9052 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9053 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9054 (clobber (reg:CC FLAGS_REG))]
9057 [(set_attr "type" "multi")])
9060 [(set (match_operand:DWI 0 "register_operand")
9061 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9062 (match_operand:QI 2 "nonmemory_operand")))
9063 (clobber (reg:CC FLAGS_REG))]
9064 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9066 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9068 ;; By default we don't ask for a scratch register, because when DWImode
9069 ;; values are manipulated, registers are already at a premium. But if
9070 ;; we have one handy, we won't turn it away.
9073 [(match_scratch:DWIH 3 "r")
9074 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9076 (match_operand:<DWI> 1 "nonmemory_operand")
9077 (match_operand:QI 2 "nonmemory_operand")))
9078 (clobber (reg:CC FLAGS_REG))])
9082 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9084 (define_insn "x86_64_shld"
9085 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9086 (ior:DI (ashift:DI (match_dup 0)
9087 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9088 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9089 (minus:QI (const_int 64) (match_dup 2)))))
9090 (clobber (reg:CC FLAGS_REG))]
9092 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9093 [(set_attr "type" "ishift")
9094 (set_attr "prefix_0f" "1")
9095 (set_attr "mode" "DI")
9096 (set_attr "athlon_decode" "vector")
9097 (set_attr "amdfam10_decode" "vector")
9098 (set_attr "bdver1_decode" "vector")])
9100 (define_insn "x86_shld"
9101 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9102 (ior:SI (ashift:SI (match_dup 0)
9103 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9104 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9105 (minus:QI (const_int 32) (match_dup 2)))))
9106 (clobber (reg:CC FLAGS_REG))]
9108 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9109 [(set_attr "type" "ishift")
9110 (set_attr "prefix_0f" "1")
9111 (set_attr "mode" "SI")
9112 (set_attr "pent_pair" "np")
9113 (set_attr "athlon_decode" "vector")
9114 (set_attr "amdfam10_decode" "vector")
9115 (set_attr "bdver1_decode" "vector")])
9117 (define_expand "x86_shift<mode>_adj_1"
9118 [(set (reg:CCZ FLAGS_REG)
9119 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9122 (set (match_operand:SWI48 0 "register_operand")
9123 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9124 (match_operand:SWI48 1 "register_operand")
9127 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9128 (match_operand:SWI48 3 "register_operand")
9131 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9133 (define_expand "x86_shift<mode>_adj_2"
9134 [(use (match_operand:SWI48 0 "register_operand"))
9135 (use (match_operand:SWI48 1 "register_operand"))
9136 (use (match_operand:QI 2 "register_operand"))]
9139 rtx label = gen_label_rtx ();
9142 emit_insn (gen_testqi_ccz_1 (operands[2],
9143 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9145 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9146 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9147 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9148 gen_rtx_LABEL_REF (VOIDmode, label),
9150 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9151 JUMP_LABEL (tmp) = label;
9153 emit_move_insn (operands[0], operands[1]);
9154 ix86_expand_clear (operands[1]);
9157 LABEL_NUSES (label) = 1;
9162 ;; Avoid useless masking of count operand.
9163 (define_insn_and_split "*ashl<mode>3_mask"
9164 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9166 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9169 (match_operand:SI 2 "nonimmediate_operand" "c")
9170 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9171 (clobber (reg:CC FLAGS_REG))]
9172 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9173 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9174 == GET_MODE_BITSIZE (<MODE>mode)-1"
9177 [(parallel [(set (match_dup 0)
9178 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9179 (clobber (reg:CC FLAGS_REG))])]
9181 if (can_create_pseudo_p ())
9182 operands [2] = force_reg (SImode, operands[2]);
9184 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9186 [(set_attr "type" "ishift")
9187 (set_attr "mode" "<MODE>")])
9189 (define_insn "*bmi2_ashl<mode>3_1"
9190 [(set (match_operand:SWI48 0 "register_operand" "=r")
9191 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9192 (match_operand:SWI48 2 "register_operand" "r")))]
9194 "shlx\t{%2, %1, %0|%0, %1, %2}"
9195 [(set_attr "type" "ishiftx")
9196 (set_attr "mode" "<MODE>")])
9198 (define_insn "*ashl<mode>3_1"
9199 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9200 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9201 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9202 (clobber (reg:CC FLAGS_REG))]
9203 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9205 switch (get_attr_type (insn))
9212 gcc_assert (operands[2] == const1_rtx);
9213 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9214 return "add{<imodesuffix>}\t%0, %0";
9217 if (operands[2] == const1_rtx
9218 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9219 return "sal{<imodesuffix>}\t%0";
9221 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9224 [(set_attr "isa" "*,*,bmi2")
9226 (cond [(eq_attr "alternative" "1")
9227 (const_string "lea")
9228 (eq_attr "alternative" "2")
9229 (const_string "ishiftx")
9230 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9231 (match_operand 0 "register_operand"))
9232 (match_operand 2 "const1_operand"))
9233 (const_string "alu")
9235 (const_string "ishift")))
9236 (set (attr "length_immediate")
9238 (ior (eq_attr "type" "alu")
9239 (and (eq_attr "type" "ishift")
9240 (and (match_operand 2 "const1_operand")
9241 (ior (match_test "TARGET_SHIFT1")
9242 (match_test "optimize_function_for_size_p (cfun)")))))
9244 (const_string "*")))
9245 (set_attr "mode" "<MODE>")])
9247 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9249 [(set (match_operand:SWI48 0 "register_operand")
9250 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9251 (match_operand:QI 2 "register_operand")))
9252 (clobber (reg:CC FLAGS_REG))]
9253 "TARGET_BMI2 && reload_completed"
9255 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9256 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9258 (define_insn "*bmi2_ashlsi3_1_zext"
9259 [(set (match_operand:DI 0 "register_operand" "=r")
9261 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9262 (match_operand:SI 2 "register_operand" "r"))))]
9263 "TARGET_64BIT && TARGET_BMI2"
9264 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9265 [(set_attr "type" "ishiftx")
9266 (set_attr "mode" "SI")])
9268 (define_insn "*ashlsi3_1_zext"
9269 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9271 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9272 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9273 (clobber (reg:CC FLAGS_REG))]
9274 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9276 switch (get_attr_type (insn))
9283 gcc_assert (operands[2] == const1_rtx);
9284 return "add{l}\t%k0, %k0";
9287 if (operands[2] == const1_rtx
9288 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9289 return "sal{l}\t%k0";
9291 return "sal{l}\t{%2, %k0|%k0, %2}";
9294 [(set_attr "isa" "*,*,bmi2")
9296 (cond [(eq_attr "alternative" "1")
9297 (const_string "lea")
9298 (eq_attr "alternative" "2")
9299 (const_string "ishiftx")
9300 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9301 (match_operand 2 "const1_operand"))
9302 (const_string "alu")
9304 (const_string "ishift")))
9305 (set (attr "length_immediate")
9307 (ior (eq_attr "type" "alu")
9308 (and (eq_attr "type" "ishift")
9309 (and (match_operand 2 "const1_operand")
9310 (ior (match_test "TARGET_SHIFT1")
9311 (match_test "optimize_function_for_size_p (cfun)")))))
9313 (const_string "*")))
9314 (set_attr "mode" "SI")])
9316 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9318 [(set (match_operand:DI 0 "register_operand")
9320 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9321 (match_operand:QI 2 "register_operand"))))
9322 (clobber (reg:CC FLAGS_REG))]
9323 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9325 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9326 "operands[2] = gen_lowpart (SImode, operands[2]);")
9328 (define_insn "*ashlhi3_1"
9329 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9330 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9331 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9332 (clobber (reg:CC FLAGS_REG))]
9333 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9335 switch (get_attr_type (insn))
9341 gcc_assert (operands[2] == const1_rtx);
9342 return "add{w}\t%0, %0";
9345 if (operands[2] == const1_rtx
9346 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9347 return "sal{w}\t%0";
9349 return "sal{w}\t{%2, %0|%0, %2}";
9353 (cond [(eq_attr "alternative" "1")
9354 (const_string "lea")
9355 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9356 (match_operand 0 "register_operand"))
9357 (match_operand 2 "const1_operand"))
9358 (const_string "alu")
9360 (const_string "ishift")))
9361 (set (attr "length_immediate")
9363 (ior (eq_attr "type" "alu")
9364 (and (eq_attr "type" "ishift")
9365 (and (match_operand 2 "const1_operand")
9366 (ior (match_test "TARGET_SHIFT1")
9367 (match_test "optimize_function_for_size_p (cfun)")))))
9369 (const_string "*")))
9370 (set_attr "mode" "HI,SI")])
9372 ;; %%% Potential partial reg stall on alternative 1. What to do?
9373 (define_insn "*ashlqi3_1"
9374 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9375 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9376 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9377 (clobber (reg:CC FLAGS_REG))]
9378 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9380 switch (get_attr_type (insn))
9386 gcc_assert (operands[2] == const1_rtx);
9387 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9388 return "add{l}\t%k0, %k0";
9390 return "add{b}\t%0, %0";
9393 if (operands[2] == const1_rtx
9394 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9396 if (get_attr_mode (insn) == MODE_SI)
9397 return "sal{l}\t%k0";
9399 return "sal{b}\t%0";
9403 if (get_attr_mode (insn) == MODE_SI)
9404 return "sal{l}\t{%2, %k0|%k0, %2}";
9406 return "sal{b}\t{%2, %0|%0, %2}";
9411 (cond [(eq_attr "alternative" "2")
9412 (const_string "lea")
9413 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9414 (match_operand 0 "register_operand"))
9415 (match_operand 2 "const1_operand"))
9416 (const_string "alu")
9418 (const_string "ishift")))
9419 (set (attr "length_immediate")
9421 (ior (eq_attr "type" "alu")
9422 (and (eq_attr "type" "ishift")
9423 (and (match_operand 2 "const1_operand")
9424 (ior (match_test "TARGET_SHIFT1")
9425 (match_test "optimize_function_for_size_p (cfun)")))))
9427 (const_string "*")))
9428 (set_attr "mode" "QI,SI,SI")])
9430 (define_insn "*ashlqi3_1_slp"
9431 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9432 (ashift:QI (match_dup 0)
9433 (match_operand:QI 1 "nonmemory_operand" "cI")))
9434 (clobber (reg:CC FLAGS_REG))]
9435 "(optimize_function_for_size_p (cfun)
9436 || !TARGET_PARTIAL_FLAG_REG_STALL
9437 || (operands[1] == const1_rtx
9439 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9441 switch (get_attr_type (insn))
9444 gcc_assert (operands[1] == const1_rtx);
9445 return "add{b}\t%0, %0";
9448 if (operands[1] == const1_rtx
9449 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9450 return "sal{b}\t%0";
9452 return "sal{b}\t{%1, %0|%0, %1}";
9456 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9457 (match_operand 0 "register_operand"))
9458 (match_operand 1 "const1_operand"))
9459 (const_string "alu")
9461 (const_string "ishift1")))
9462 (set (attr "length_immediate")
9464 (ior (eq_attr "type" "alu")
9465 (and (eq_attr "type" "ishift1")
9466 (and (match_operand 1 "const1_operand")
9467 (ior (match_test "TARGET_SHIFT1")
9468 (match_test "optimize_function_for_size_p (cfun)")))))
9470 (const_string "*")))
9471 (set_attr "mode" "QI")])
9473 ;; Convert ashift to the lea pattern to avoid flags dependency.
9475 [(set (match_operand 0 "register_operand")
9476 (ashift (match_operand 1 "index_register_operand")
9477 (match_operand:QI 2 "const_int_operand")))
9478 (clobber (reg:CC FLAGS_REG))]
9479 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9481 && true_regnum (operands[0]) != true_regnum (operands[1])"
9484 enum machine_mode mode = GET_MODE (operands[0]);
9487 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9490 operands[0] = gen_lowpart (mode, operands[0]);
9491 operands[1] = gen_lowpart (mode, operands[1]);
9494 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9496 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9498 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9502 ;; Convert ashift to the lea pattern to avoid flags dependency.
9504 [(set (match_operand:DI 0 "register_operand")
9506 (ashift:SI (match_operand:SI 1 "index_register_operand")
9507 (match_operand:QI 2 "const_int_operand"))))
9508 (clobber (reg:CC FLAGS_REG))]
9509 "TARGET_64BIT && reload_completed
9510 && true_regnum (operands[0]) != true_regnum (operands[1])"
9512 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9514 operands[1] = gen_lowpart (DImode, operands[1]);
9515 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9518 ;; This pattern can't accept a variable shift count, since shifts by
9519 ;; zero don't affect the flags. We assume that shifts by constant
9520 ;; zero are optimized away.
9521 (define_insn "*ashl<mode>3_cmp"
9522 [(set (reg FLAGS_REG)
9524 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9525 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9527 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9528 (ashift:SWI (match_dup 1) (match_dup 2)))]
9529 "(optimize_function_for_size_p (cfun)
9530 || !TARGET_PARTIAL_FLAG_REG_STALL
9531 || (operands[2] == const1_rtx
9533 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9534 && ix86_match_ccmode (insn, CCGOCmode)
9535 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9537 switch (get_attr_type (insn))
9540 gcc_assert (operands[2] == const1_rtx);
9541 return "add{<imodesuffix>}\t%0, %0";
9544 if (operands[2] == const1_rtx
9545 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9546 return "sal{<imodesuffix>}\t%0";
9548 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9552 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9553 (match_operand 0 "register_operand"))
9554 (match_operand 2 "const1_operand"))
9555 (const_string "alu")
9557 (const_string "ishift")))
9558 (set (attr "length_immediate")
9560 (ior (eq_attr "type" "alu")
9561 (and (eq_attr "type" "ishift")
9562 (and (match_operand 2 "const1_operand")
9563 (ior (match_test "TARGET_SHIFT1")
9564 (match_test "optimize_function_for_size_p (cfun)")))))
9566 (const_string "*")))
9567 (set_attr "mode" "<MODE>")])
9569 (define_insn "*ashlsi3_cmp_zext"
9570 [(set (reg FLAGS_REG)
9572 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9573 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9575 (set (match_operand:DI 0 "register_operand" "=r")
9576 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9578 && (optimize_function_for_size_p (cfun)
9579 || !TARGET_PARTIAL_FLAG_REG_STALL
9580 || (operands[2] == const1_rtx
9582 || TARGET_DOUBLE_WITH_ADD)))
9583 && ix86_match_ccmode (insn, CCGOCmode)
9584 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9586 switch (get_attr_type (insn))
9589 gcc_assert (operands[2] == const1_rtx);
9590 return "add{l}\t%k0, %k0";
9593 if (operands[2] == const1_rtx
9594 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9595 return "sal{l}\t%k0";
9597 return "sal{l}\t{%2, %k0|%k0, %2}";
9601 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9602 (match_operand 2 "const1_operand"))
9603 (const_string "alu")
9605 (const_string "ishift")))
9606 (set (attr "length_immediate")
9608 (ior (eq_attr "type" "alu")
9609 (and (eq_attr "type" "ishift")
9610 (and (match_operand 2 "const1_operand")
9611 (ior (match_test "TARGET_SHIFT1")
9612 (match_test "optimize_function_for_size_p (cfun)")))))
9614 (const_string "*")))
9615 (set_attr "mode" "SI")])
9617 (define_insn "*ashl<mode>3_cconly"
9618 [(set (reg FLAGS_REG)
9620 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9621 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9623 (clobber (match_scratch:SWI 0 "=<r>"))]
9624 "(optimize_function_for_size_p (cfun)
9625 || !TARGET_PARTIAL_FLAG_REG_STALL
9626 || (operands[2] == const1_rtx
9628 || TARGET_DOUBLE_WITH_ADD)))
9629 && ix86_match_ccmode (insn, CCGOCmode)"
9631 switch (get_attr_type (insn))
9634 gcc_assert (operands[2] == const1_rtx);
9635 return "add{<imodesuffix>}\t%0, %0";
9638 if (operands[2] == const1_rtx
9639 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9640 return "sal{<imodesuffix>}\t%0";
9642 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9646 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9647 (match_operand 0 "register_operand"))
9648 (match_operand 2 "const1_operand"))
9649 (const_string "alu")
9651 (const_string "ishift")))
9652 (set (attr "length_immediate")
9654 (ior (eq_attr "type" "alu")
9655 (and (eq_attr "type" "ishift")
9656 (and (match_operand 2 "const1_operand")
9657 (ior (match_test "TARGET_SHIFT1")
9658 (match_test "optimize_function_for_size_p (cfun)")))))
9660 (const_string "*")))
9661 (set_attr "mode" "<MODE>")])
9663 ;; See comment above `ashl<mode>3' about how this works.
9665 (define_expand "<shift_insn><mode>3"
9666 [(set (match_operand:SDWIM 0 "<shift_operand>")
9667 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9668 (match_operand:QI 2 "nonmemory_operand")))]
9670 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9672 ;; Avoid useless masking of count operand.
9673 (define_insn_and_split "*<shift_insn><mode>3_mask"
9674 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9676 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9679 (match_operand:SI 2 "nonimmediate_operand" "c")
9680 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9681 (clobber (reg:CC FLAGS_REG))]
9682 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9683 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9684 == GET_MODE_BITSIZE (<MODE>mode)-1"
9687 [(parallel [(set (match_dup 0)
9688 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9689 (clobber (reg:CC FLAGS_REG))])]
9691 if (can_create_pseudo_p ())
9692 operands [2] = force_reg (SImode, operands[2]);
9694 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9696 [(set_attr "type" "ishift")
9697 (set_attr "mode" "<MODE>")])
9699 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9700 [(set (match_operand:DWI 0 "register_operand" "=r")
9701 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9702 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9703 (clobber (reg:CC FLAGS_REG))]
9706 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9708 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9709 [(set_attr "type" "multi")])
9711 ;; By default we don't ask for a scratch register, because when DWImode
9712 ;; values are manipulated, registers are already at a premium. But if
9713 ;; we have one handy, we won't turn it away.
9716 [(match_scratch:DWIH 3 "r")
9717 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9719 (match_operand:<DWI> 1 "register_operand")
9720 (match_operand:QI 2 "nonmemory_operand")))
9721 (clobber (reg:CC FLAGS_REG))])
9725 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9727 (define_insn "x86_64_shrd"
9728 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9729 (ior:DI (ashiftrt:DI (match_dup 0)
9730 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9731 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9732 (minus:QI (const_int 64) (match_dup 2)))))
9733 (clobber (reg:CC FLAGS_REG))]
9735 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9736 [(set_attr "type" "ishift")
9737 (set_attr "prefix_0f" "1")
9738 (set_attr "mode" "DI")
9739 (set_attr "athlon_decode" "vector")
9740 (set_attr "amdfam10_decode" "vector")
9741 (set_attr "bdver1_decode" "vector")])
9743 (define_insn "x86_shrd"
9744 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9745 (ior:SI (ashiftrt:SI (match_dup 0)
9746 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9747 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9748 (minus:QI (const_int 32) (match_dup 2)))))
9749 (clobber (reg:CC FLAGS_REG))]
9751 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9752 [(set_attr "type" "ishift")
9753 (set_attr "prefix_0f" "1")
9754 (set_attr "mode" "SI")
9755 (set_attr "pent_pair" "np")
9756 (set_attr "athlon_decode" "vector")
9757 (set_attr "amdfam10_decode" "vector")
9758 (set_attr "bdver1_decode" "vector")])
9760 (define_insn "ashrdi3_cvt"
9761 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9762 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9763 (match_operand:QI 2 "const_int_operand")))
9764 (clobber (reg:CC FLAGS_REG))]
9765 "TARGET_64BIT && INTVAL (operands[2]) == 63
9766 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9767 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9770 sar{q}\t{%2, %0|%0, %2}"
9771 [(set_attr "type" "imovx,ishift")
9772 (set_attr "prefix_0f" "0,*")
9773 (set_attr "length_immediate" "0,*")
9774 (set_attr "modrm" "0,1")
9775 (set_attr "mode" "DI")])
9777 (define_insn "ashrsi3_cvt"
9778 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9779 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9780 (match_operand:QI 2 "const_int_operand")))
9781 (clobber (reg:CC FLAGS_REG))]
9782 "INTVAL (operands[2]) == 31
9783 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9784 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9787 sar{l}\t{%2, %0|%0, %2}"
9788 [(set_attr "type" "imovx,ishift")
9789 (set_attr "prefix_0f" "0,*")
9790 (set_attr "length_immediate" "0,*")
9791 (set_attr "modrm" "0,1")
9792 (set_attr "mode" "SI")])
9794 (define_insn "*ashrsi3_cvt_zext"
9795 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9797 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9798 (match_operand:QI 2 "const_int_operand"))))
9799 (clobber (reg:CC FLAGS_REG))]
9800 "TARGET_64BIT && INTVAL (operands[2]) == 31
9801 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9802 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9805 sar{l}\t{%2, %k0|%k0, %2}"
9806 [(set_attr "type" "imovx,ishift")
9807 (set_attr "prefix_0f" "0,*")
9808 (set_attr "length_immediate" "0,*")
9809 (set_attr "modrm" "0,1")
9810 (set_attr "mode" "SI")])
9812 (define_expand "x86_shift<mode>_adj_3"
9813 [(use (match_operand:SWI48 0 "register_operand"))
9814 (use (match_operand:SWI48 1 "register_operand"))
9815 (use (match_operand:QI 2 "register_operand"))]
9818 rtx label = gen_label_rtx ();
9821 emit_insn (gen_testqi_ccz_1 (operands[2],
9822 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9824 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9825 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9826 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9827 gen_rtx_LABEL_REF (VOIDmode, label),
9829 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9830 JUMP_LABEL (tmp) = label;
9832 emit_move_insn (operands[0], operands[1]);
9833 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9834 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9836 LABEL_NUSES (label) = 1;
9841 (define_insn "*bmi2_<shift_insn><mode>3_1"
9842 [(set (match_operand:SWI48 0 "register_operand" "=r")
9843 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9844 (match_operand:SWI48 2 "register_operand" "r")))]
9846 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9847 [(set_attr "type" "ishiftx")
9848 (set_attr "mode" "<MODE>")])
9850 (define_insn "*<shift_insn><mode>3_1"
9851 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9853 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9854 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9855 (clobber (reg:CC FLAGS_REG))]
9856 "ix86_binary_operator_ok (<CODE>, <MODE>mode, 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>{<imodesuffix>}\t%0";
9868 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %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" "<MODE>")])
9882 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9884 [(set (match_operand:SWI48 0 "register_operand")
9885 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9886 (match_operand:QI 2 "register_operand")))
9887 (clobber (reg:CC FLAGS_REG))]
9888 "TARGET_BMI2 && reload_completed"
9890 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9891 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9893 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9894 [(set (match_operand:DI 0 "register_operand" "=r")
9896 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9897 (match_operand:SI 2 "register_operand" "r"))))]
9898 "TARGET_64BIT && TARGET_BMI2"
9899 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9900 [(set_attr "type" "ishiftx")
9901 (set_attr "mode" "SI")])
9903 (define_insn "*<shift_insn>si3_1_zext"
9904 [(set (match_operand:DI 0 "register_operand" "=r,r")
9906 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9907 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9908 (clobber (reg:CC FLAGS_REG))]
9909 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9911 switch (get_attr_type (insn))
9917 if (operands[2] == const1_rtx
9918 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9919 return "<shift>{l}\t%k0";
9921 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9924 [(set_attr "isa" "*,bmi2")
9925 (set_attr "type" "ishift,ishiftx")
9926 (set (attr "length_immediate")
9928 (and (match_operand 2 "const1_operand")
9929 (ior (match_test "TARGET_SHIFT1")
9930 (match_test "optimize_function_for_size_p (cfun)")))
9932 (const_string "*")))
9933 (set_attr "mode" "SI")])
9935 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9937 [(set (match_operand:DI 0 "register_operand")
9939 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
9940 (match_operand:QI 2 "register_operand"))))
9941 (clobber (reg:CC FLAGS_REG))]
9942 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9944 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9945 "operands[2] = gen_lowpart (SImode, operands[2]);")
9947 (define_insn "*<shift_insn><mode>3_1"
9948 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9950 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9951 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9952 (clobber (reg:CC FLAGS_REG))]
9953 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9955 if (operands[2] == const1_rtx
9956 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9957 return "<shift>{<imodesuffix>}\t%0";
9959 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9961 [(set_attr "type" "ishift")
9962 (set (attr "length_immediate")
9964 (and (match_operand 2 "const1_operand")
9965 (ior (match_test "TARGET_SHIFT1")
9966 (match_test "optimize_function_for_size_p (cfun)")))
9968 (const_string "*")))
9969 (set_attr "mode" "<MODE>")])
9971 (define_insn "*<shift_insn>qi3_1_slp"
9972 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9973 (any_shiftrt:QI (match_dup 0)
9974 (match_operand:QI 1 "nonmemory_operand" "cI")))
9975 (clobber (reg:CC FLAGS_REG))]
9976 "(optimize_function_for_size_p (cfun)
9977 || !TARGET_PARTIAL_REG_STALL
9978 || (operands[1] == const1_rtx
9981 if (operands[1] == const1_rtx
9982 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9983 return "<shift>{b}\t%0";
9985 return "<shift>{b}\t{%1, %0|%0, %1}";
9987 [(set_attr "type" "ishift1")
9988 (set (attr "length_immediate")
9990 (and (match_operand 1 "const1_operand")
9991 (ior (match_test "TARGET_SHIFT1")
9992 (match_test "optimize_function_for_size_p (cfun)")))
9994 (const_string "*")))
9995 (set_attr "mode" "QI")])
9997 ;; This pattern can't accept a variable shift count, since shifts by
9998 ;; zero don't affect the flags. We assume that shifts by constant
9999 ;; zero are optimized away.
10000 (define_insn "*<shift_insn><mode>3_cmp"
10001 [(set (reg FLAGS_REG)
10004 (match_operand:SWI 1 "nonimmediate_operand" "0")
10005 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10007 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10008 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10009 "(optimize_function_for_size_p (cfun)
10010 || !TARGET_PARTIAL_FLAG_REG_STALL
10011 || (operands[2] == const1_rtx
10013 && ix86_match_ccmode (insn, CCGOCmode)
10014 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10016 if (operands[2] == const1_rtx
10017 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10018 return "<shift>{<imodesuffix>}\t%0";
10020 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10022 [(set_attr "type" "ishift")
10023 (set (attr "length_immediate")
10025 (and (match_operand 2 "const1_operand")
10026 (ior (match_test "TARGET_SHIFT1")
10027 (match_test "optimize_function_for_size_p (cfun)")))
10029 (const_string "*")))
10030 (set_attr "mode" "<MODE>")])
10032 (define_insn "*<shift_insn>si3_cmp_zext"
10033 [(set (reg FLAGS_REG)
10035 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10036 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10038 (set (match_operand:DI 0 "register_operand" "=r")
10039 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10041 && (optimize_function_for_size_p (cfun)
10042 || !TARGET_PARTIAL_FLAG_REG_STALL
10043 || (operands[2] == const1_rtx
10045 && ix86_match_ccmode (insn, CCGOCmode)
10046 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10048 if (operands[2] == const1_rtx
10049 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10050 return "<shift>{l}\t%k0";
10052 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10054 [(set_attr "type" "ishift")
10055 (set (attr "length_immediate")
10057 (and (match_operand 2 "const1_operand")
10058 (ior (match_test "TARGET_SHIFT1")
10059 (match_test "optimize_function_for_size_p (cfun)")))
10061 (const_string "*")))
10062 (set_attr "mode" "SI")])
10064 (define_insn "*<shift_insn><mode>3_cconly"
10065 [(set (reg FLAGS_REG)
10068 (match_operand:SWI 1 "register_operand" "0")
10069 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10071 (clobber (match_scratch:SWI 0 "=<r>"))]
10072 "(optimize_function_for_size_p (cfun)
10073 || !TARGET_PARTIAL_FLAG_REG_STALL
10074 || (operands[2] == const1_rtx
10076 && ix86_match_ccmode (insn, CCGOCmode)"
10078 if (operands[2] == const1_rtx
10079 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10080 return "<shift>{<imodesuffix>}\t%0";
10082 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10084 [(set_attr "type" "ishift")
10085 (set (attr "length_immediate")
10087 (and (match_operand 2 "const1_operand")
10088 (ior (match_test "TARGET_SHIFT1")
10089 (match_test "optimize_function_for_size_p (cfun)")))
10091 (const_string "*")))
10092 (set_attr "mode" "<MODE>")])
10094 ;; Rotate instructions
10096 (define_expand "<rotate_insn>ti3"
10097 [(set (match_operand:TI 0 "register_operand")
10098 (any_rotate:TI (match_operand:TI 1 "register_operand")
10099 (match_operand:QI 2 "nonmemory_operand")))]
10102 if (const_1_to_63_operand (operands[2], VOIDmode))
10103 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10104 (operands[0], operands[1], operands[2]));
10111 (define_expand "<rotate_insn>di3"
10112 [(set (match_operand:DI 0 "shiftdi_operand")
10113 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10114 (match_operand:QI 2 "nonmemory_operand")))]
10118 ix86_expand_binary_operator (<CODE>, DImode, operands);
10119 else if (const_1_to_31_operand (operands[2], VOIDmode))
10120 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10121 (operands[0], operands[1], operands[2]));
10128 (define_expand "<rotate_insn><mode>3"
10129 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10130 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10131 (match_operand:QI 2 "nonmemory_operand")))]
10133 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10135 ;; Avoid useless masking of count operand.
10136 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10137 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10139 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10142 (match_operand:SI 2 "nonimmediate_operand" "c")
10143 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10144 (clobber (reg:CC FLAGS_REG))]
10145 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10146 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10147 == GET_MODE_BITSIZE (<MODE>mode)-1"
10150 [(parallel [(set (match_dup 0)
10151 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10152 (clobber (reg:CC FLAGS_REG))])]
10154 if (can_create_pseudo_p ())
10155 operands [2] = force_reg (SImode, operands[2]);
10157 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10159 [(set_attr "type" "rotate")
10160 (set_attr "mode" "<MODE>")])
10162 ;; Implement rotation using two double-precision
10163 ;; shift instructions and a scratch register.
10165 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10166 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10167 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10168 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10169 (clobber (reg:CC FLAGS_REG))
10170 (clobber (match_scratch:DWIH 3 "=&r"))]
10174 [(set (match_dup 3) (match_dup 4))
10176 [(set (match_dup 4)
10177 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10178 (lshiftrt:DWIH (match_dup 5)
10179 (minus:QI (match_dup 6) (match_dup 2)))))
10180 (clobber (reg:CC FLAGS_REG))])
10182 [(set (match_dup 5)
10183 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10184 (lshiftrt:DWIH (match_dup 3)
10185 (minus:QI (match_dup 6) (match_dup 2)))))
10186 (clobber (reg:CC FLAGS_REG))])]
10188 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10190 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10193 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10194 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10195 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10196 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10197 (clobber (reg:CC FLAGS_REG))
10198 (clobber (match_scratch:DWIH 3 "=&r"))]
10202 [(set (match_dup 3) (match_dup 4))
10204 [(set (match_dup 4)
10205 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10206 (ashift:DWIH (match_dup 5)
10207 (minus:QI (match_dup 6) (match_dup 2)))))
10208 (clobber (reg:CC FLAGS_REG))])
10210 [(set (match_dup 5)
10211 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10212 (ashift:DWIH (match_dup 3)
10213 (minus:QI (match_dup 6) (match_dup 2)))))
10214 (clobber (reg:CC FLAGS_REG))])]
10216 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10218 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10221 (define_insn "*bmi2_rorx<mode>3_1"
10222 [(set (match_operand:SWI48 0 "register_operand" "=r")
10223 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10224 (match_operand:QI 2 "immediate_operand" "<S>")))]
10226 "rorx\t{%2, %1, %0|%0, %1, %2}"
10227 [(set_attr "type" "rotatex")
10228 (set_attr "mode" "<MODE>")])
10230 (define_insn "*<rotate_insn><mode>3_1"
10231 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10233 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10234 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10235 (clobber (reg:CC FLAGS_REG))]
10236 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10238 switch (get_attr_type (insn))
10244 if (operands[2] == const1_rtx
10245 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10246 return "<rotate>{<imodesuffix>}\t%0";
10248 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10251 [(set_attr "isa" "*,bmi2")
10252 (set_attr "type" "rotate,rotatex")
10253 (set (attr "length_immediate")
10255 (and (eq_attr "type" "rotate")
10256 (and (match_operand 2 "const1_operand")
10257 (ior (match_test "TARGET_SHIFT1")
10258 (match_test "optimize_function_for_size_p (cfun)"))))
10260 (const_string "*")))
10261 (set_attr "mode" "<MODE>")])
10263 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10265 [(set (match_operand:SWI48 0 "register_operand")
10266 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10267 (match_operand:QI 2 "immediate_operand")))
10268 (clobber (reg:CC FLAGS_REG))]
10269 "TARGET_BMI2 && reload_completed"
10270 [(set (match_dup 0)
10271 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10274 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10278 [(set (match_operand:SWI48 0 "register_operand")
10279 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10280 (match_operand:QI 2 "immediate_operand")))
10281 (clobber (reg:CC FLAGS_REG))]
10282 "TARGET_BMI2 && reload_completed"
10283 [(set (match_dup 0)
10284 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10286 (define_insn "*bmi2_rorxsi3_1_zext"
10287 [(set (match_operand:DI 0 "register_operand" "=r")
10289 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10290 (match_operand:QI 2 "immediate_operand" "I"))))]
10291 "TARGET_64BIT && TARGET_BMI2"
10292 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10293 [(set_attr "type" "rotatex")
10294 (set_attr "mode" "SI")])
10296 (define_insn "*<rotate_insn>si3_1_zext"
10297 [(set (match_operand:DI 0 "register_operand" "=r,r")
10299 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10300 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10301 (clobber (reg:CC FLAGS_REG))]
10302 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10304 switch (get_attr_type (insn))
10310 if (operands[2] == const1_rtx
10311 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10312 return "<rotate>{l}\t%k0";
10314 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10317 [(set_attr "isa" "*,bmi2")
10318 (set_attr "type" "rotate,rotatex")
10319 (set (attr "length_immediate")
10321 (and (eq_attr "type" "rotate")
10322 (and (match_operand 2 "const1_operand")
10323 (ior (match_test "TARGET_SHIFT1")
10324 (match_test "optimize_function_for_size_p (cfun)"))))
10326 (const_string "*")))
10327 (set_attr "mode" "SI")])
10329 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10331 [(set (match_operand:DI 0 "register_operand")
10333 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10334 (match_operand:QI 2 "immediate_operand"))))
10335 (clobber (reg:CC FLAGS_REG))]
10336 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10337 [(set (match_dup 0)
10338 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10341 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10345 [(set (match_operand:DI 0 "register_operand")
10347 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10348 (match_operand:QI 2 "immediate_operand"))))
10349 (clobber (reg:CC FLAGS_REG))]
10350 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10351 [(set (match_dup 0)
10352 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10354 (define_insn "*<rotate_insn><mode>3_1"
10355 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10356 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10357 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10358 (clobber (reg:CC FLAGS_REG))]
10359 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10361 if (operands[2] == const1_rtx
10362 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10363 return "<rotate>{<imodesuffix>}\t%0";
10365 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10367 [(set_attr "type" "rotate")
10368 (set (attr "length_immediate")
10370 (and (match_operand 2 "const1_operand")
10371 (ior (match_test "TARGET_SHIFT1")
10372 (match_test "optimize_function_for_size_p (cfun)")))
10374 (const_string "*")))
10375 (set_attr "mode" "<MODE>")])
10377 (define_insn "*<rotate_insn>qi3_1_slp"
10378 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10379 (any_rotate:QI (match_dup 0)
10380 (match_operand:QI 1 "nonmemory_operand" "cI")))
10381 (clobber (reg:CC FLAGS_REG))]
10382 "(optimize_function_for_size_p (cfun)
10383 || !TARGET_PARTIAL_REG_STALL
10384 || (operands[1] == const1_rtx
10385 && TARGET_SHIFT1))"
10387 if (operands[1] == const1_rtx
10388 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10389 return "<rotate>{b}\t%0";
10391 return "<rotate>{b}\t{%1, %0|%0, %1}";
10393 [(set_attr "type" "rotate1")
10394 (set (attr "length_immediate")
10396 (and (match_operand 1 "const1_operand")
10397 (ior (match_test "TARGET_SHIFT1")
10398 (match_test "optimize_function_for_size_p (cfun)")))
10400 (const_string "*")))
10401 (set_attr "mode" "QI")])
10404 [(set (match_operand:HI 0 "register_operand")
10405 (any_rotate:HI (match_dup 0) (const_int 8)))
10406 (clobber (reg:CC FLAGS_REG))]
10408 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10409 [(parallel [(set (strict_low_part (match_dup 0))
10410 (bswap:HI (match_dup 0)))
10411 (clobber (reg:CC FLAGS_REG))])])
10413 ;; Bit set / bit test instructions
10415 (define_expand "extv"
10416 [(set (match_operand:SI 0 "register_operand")
10417 (sign_extract:SI (match_operand:SI 1 "register_operand")
10418 (match_operand:SI 2 "const8_operand")
10419 (match_operand:SI 3 "const8_operand")))]
10422 /* Handle extractions from %ah et al. */
10423 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10426 /* From mips.md: extract_bit_field doesn't verify that our source
10427 matches the predicate, so check it again here. */
10428 if (! ext_register_operand (operands[1], VOIDmode))
10432 (define_expand "extzv"
10433 [(set (match_operand:SI 0 "register_operand")
10434 (zero_extract:SI (match_operand 1 "ext_register_operand")
10435 (match_operand:SI 2 "const8_operand")
10436 (match_operand:SI 3 "const8_operand")))]
10439 /* Handle extractions from %ah et al. */
10440 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10443 /* From mips.md: extract_bit_field doesn't verify that our source
10444 matches the predicate, so check it again here. */
10445 if (! ext_register_operand (operands[1], VOIDmode))
10449 (define_expand "insv"
10450 [(set (zero_extract (match_operand 0 "register_operand")
10451 (match_operand 1 "const_int_operand")
10452 (match_operand 2 "const_int_operand"))
10453 (match_operand 3 "register_operand"))]
10456 rtx (*gen_mov_insv_1) (rtx, rtx);
10458 if (ix86_expand_pinsr (operands))
10461 /* Handle insertions to %ah et al. */
10462 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10465 /* From mips.md: insert_bit_field doesn't verify that our source
10466 matches the predicate, so check it again here. */
10467 if (! ext_register_operand (operands[0], VOIDmode))
10470 gen_mov_insv_1 = (TARGET_64BIT
10471 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10473 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10477 ;; %%% bts, btr, btc, bt.
10478 ;; In general these instructions are *slow* when applied to memory,
10479 ;; since they enforce atomic operation. When applied to registers,
10480 ;; it depends on the cpu implementation. They're never faster than
10481 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10482 ;; no point. But in 64-bit, we can't hold the relevant immediates
10483 ;; within the instruction itself, so operating on bits in the high
10484 ;; 32-bits of a register becomes easier.
10486 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10487 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10488 ;; negdf respectively, so they can never be disabled entirely.
10490 (define_insn "*btsq"
10491 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10493 (match_operand:DI 1 "const_0_to_63_operand"))
10495 (clobber (reg:CC FLAGS_REG))]
10496 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10497 "bts{q}\t{%1, %0|%0, %1}"
10498 [(set_attr "type" "alu1")
10499 (set_attr "prefix_0f" "1")
10500 (set_attr "mode" "DI")])
10502 (define_insn "*btrq"
10503 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10505 (match_operand:DI 1 "const_0_to_63_operand"))
10507 (clobber (reg:CC FLAGS_REG))]
10508 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10509 "btr{q}\t{%1, %0|%0, %1}"
10510 [(set_attr "type" "alu1")
10511 (set_attr "prefix_0f" "1")
10512 (set_attr "mode" "DI")])
10514 (define_insn "*btcq"
10515 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10517 (match_operand:DI 1 "const_0_to_63_operand"))
10518 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10519 (clobber (reg:CC FLAGS_REG))]
10520 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10521 "btc{q}\t{%1, %0|%0, %1}"
10522 [(set_attr "type" "alu1")
10523 (set_attr "prefix_0f" "1")
10524 (set_attr "mode" "DI")])
10526 ;; Allow Nocona to avoid these instructions if a register is available.
10529 [(match_scratch:DI 2 "r")
10530 (parallel [(set (zero_extract:DI
10531 (match_operand:DI 0 "register_operand")
10533 (match_operand:DI 1 "const_0_to_63_operand"))
10535 (clobber (reg:CC FLAGS_REG))])]
10536 "TARGET_64BIT && !TARGET_USE_BT"
10539 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10542 if (HOST_BITS_PER_WIDE_INT >= 64)
10543 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10544 else if (i < HOST_BITS_PER_WIDE_INT)
10545 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10547 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10549 op1 = immed_double_const (lo, hi, DImode);
10552 emit_move_insn (operands[2], op1);
10556 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10561 [(match_scratch:DI 2 "r")
10562 (parallel [(set (zero_extract:DI
10563 (match_operand:DI 0 "register_operand")
10565 (match_operand:DI 1 "const_0_to_63_operand"))
10567 (clobber (reg:CC FLAGS_REG))])]
10568 "TARGET_64BIT && !TARGET_USE_BT"
10571 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10574 if (HOST_BITS_PER_WIDE_INT >= 64)
10575 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10576 else if (i < HOST_BITS_PER_WIDE_INT)
10577 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10579 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10581 op1 = immed_double_const (~lo, ~hi, DImode);
10584 emit_move_insn (operands[2], op1);
10588 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10593 [(match_scratch:DI 2 "r")
10594 (parallel [(set (zero_extract:DI
10595 (match_operand:DI 0 "register_operand")
10597 (match_operand:DI 1 "const_0_to_63_operand"))
10598 (not:DI (zero_extract:DI
10599 (match_dup 0) (const_int 1) (match_dup 1))))
10600 (clobber (reg:CC FLAGS_REG))])]
10601 "TARGET_64BIT && !TARGET_USE_BT"
10604 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10607 if (HOST_BITS_PER_WIDE_INT >= 64)
10608 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10609 else if (i < HOST_BITS_PER_WIDE_INT)
10610 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10612 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10614 op1 = immed_double_const (lo, hi, DImode);
10617 emit_move_insn (operands[2], op1);
10621 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10625 (define_insn "*bt<mode>"
10626 [(set (reg:CCC FLAGS_REG)
10628 (zero_extract:SWI48
10629 (match_operand:SWI48 0 "register_operand" "r")
10631 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10633 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10634 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10635 [(set_attr "type" "alu1")
10636 (set_attr "prefix_0f" "1")
10637 (set_attr "mode" "<MODE>")])
10639 ;; Store-flag instructions.
10641 ;; For all sCOND expanders, also expand the compare or test insn that
10642 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10644 (define_insn_and_split "*setcc_di_1"
10645 [(set (match_operand:DI 0 "register_operand" "=q")
10646 (match_operator:DI 1 "ix86_comparison_operator"
10647 [(reg FLAGS_REG) (const_int 0)]))]
10648 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10650 "&& reload_completed"
10651 [(set (match_dup 2) (match_dup 1))
10652 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10654 PUT_MODE (operands[1], QImode);
10655 operands[2] = gen_lowpart (QImode, operands[0]);
10658 (define_insn_and_split "*setcc_si_1_and"
10659 [(set (match_operand:SI 0 "register_operand" "=q")
10660 (match_operator:SI 1 "ix86_comparison_operator"
10661 [(reg FLAGS_REG) (const_int 0)]))
10662 (clobber (reg:CC FLAGS_REG))]
10663 "!TARGET_PARTIAL_REG_STALL
10664 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10666 "&& reload_completed"
10667 [(set (match_dup 2) (match_dup 1))
10668 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10669 (clobber (reg:CC FLAGS_REG))])]
10671 PUT_MODE (operands[1], QImode);
10672 operands[2] = gen_lowpart (QImode, operands[0]);
10675 (define_insn_and_split "*setcc_si_1_movzbl"
10676 [(set (match_operand:SI 0 "register_operand" "=q")
10677 (match_operator:SI 1 "ix86_comparison_operator"
10678 [(reg FLAGS_REG) (const_int 0)]))]
10679 "!TARGET_PARTIAL_REG_STALL
10680 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10682 "&& reload_completed"
10683 [(set (match_dup 2) (match_dup 1))
10684 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10686 PUT_MODE (operands[1], QImode);
10687 operands[2] = gen_lowpart (QImode, operands[0]);
10690 (define_insn "*setcc_qi"
10691 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10692 (match_operator:QI 1 "ix86_comparison_operator"
10693 [(reg FLAGS_REG) (const_int 0)]))]
10696 [(set_attr "type" "setcc")
10697 (set_attr "mode" "QI")])
10699 (define_insn "*setcc_qi_slp"
10700 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10701 (match_operator:QI 1 "ix86_comparison_operator"
10702 [(reg FLAGS_REG) (const_int 0)]))]
10705 [(set_attr "type" "setcc")
10706 (set_attr "mode" "QI")])
10708 ;; In general it is not safe to assume too much about CCmode registers,
10709 ;; so simplify-rtx stops when it sees a second one. Under certain
10710 ;; conditions this is safe on x86, so help combine not create
10717 [(set (match_operand:QI 0 "nonimmediate_operand")
10718 (ne:QI (match_operator 1 "ix86_comparison_operator"
10719 [(reg FLAGS_REG) (const_int 0)])
10722 [(set (match_dup 0) (match_dup 1))]
10723 "PUT_MODE (operands[1], QImode);")
10726 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10727 (ne:QI (match_operator 1 "ix86_comparison_operator"
10728 [(reg FLAGS_REG) (const_int 0)])
10731 [(set (match_dup 0) (match_dup 1))]
10732 "PUT_MODE (operands[1], QImode);")
10735 [(set (match_operand:QI 0 "nonimmediate_operand")
10736 (eq:QI (match_operator 1 "ix86_comparison_operator"
10737 [(reg FLAGS_REG) (const_int 0)])
10740 [(set (match_dup 0) (match_dup 1))]
10742 rtx new_op1 = copy_rtx (operands[1]);
10743 operands[1] = new_op1;
10744 PUT_MODE (new_op1, QImode);
10745 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10746 GET_MODE (XEXP (new_op1, 0))));
10748 /* Make sure that (a) the CCmode we have for the flags is strong
10749 enough for the reversed compare or (b) we have a valid FP compare. */
10750 if (! ix86_comparison_operator (new_op1, VOIDmode))
10755 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10756 (eq:QI (match_operator 1 "ix86_comparison_operator"
10757 [(reg FLAGS_REG) (const_int 0)])
10760 [(set (match_dup 0) (match_dup 1))]
10762 rtx new_op1 = copy_rtx (operands[1]);
10763 operands[1] = new_op1;
10764 PUT_MODE (new_op1, QImode);
10765 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10766 GET_MODE (XEXP (new_op1, 0))));
10768 /* Make sure that (a) the CCmode we have for the flags is strong
10769 enough for the reversed compare or (b) we have a valid FP compare. */
10770 if (! ix86_comparison_operator (new_op1, VOIDmode))
10774 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10775 ;; subsequent logical operations are used to imitate conditional moves.
10776 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10779 (define_insn "setcc_<mode>_sse"
10780 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10781 (match_operator:MODEF 3 "sse_comparison_operator"
10782 [(match_operand:MODEF 1 "register_operand" "0,x")
10783 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10784 "SSE_FLOAT_MODE_P (<MODE>mode)"
10786 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10787 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10788 [(set_attr "isa" "noavx,avx")
10789 (set_attr "type" "ssecmp")
10790 (set_attr "length_immediate" "1")
10791 (set_attr "prefix" "orig,vex")
10792 (set_attr "mode" "<MODE>")])
10794 ;; Basic conditional jump instructions.
10795 ;; We ignore the overflow flag for signed branch instructions.
10797 (define_insn "*jcc_1"
10799 (if_then_else (match_operator 1 "ix86_comparison_operator"
10800 [(reg FLAGS_REG) (const_int 0)])
10801 (label_ref (match_operand 0))
10805 [(set_attr "type" "ibr")
10806 (set_attr "modrm" "0")
10807 (set (attr "length")
10808 (if_then_else (and (ge (minus (match_dup 0) (pc))
10810 (lt (minus (match_dup 0) (pc))
10815 (define_insn "*jcc_2"
10817 (if_then_else (match_operator 1 "ix86_comparison_operator"
10818 [(reg FLAGS_REG) (const_int 0)])
10820 (label_ref (match_operand 0))))]
10823 [(set_attr "type" "ibr")
10824 (set_attr "modrm" "0")
10825 (set (attr "length")
10826 (if_then_else (and (ge (minus (match_dup 0) (pc))
10828 (lt (minus (match_dup 0) (pc))
10833 ;; In general it is not safe to assume too much about CCmode registers,
10834 ;; so simplify-rtx stops when it sees a second one. Under certain
10835 ;; conditions this is safe on x86, so help combine not create
10843 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10844 [(reg FLAGS_REG) (const_int 0)])
10846 (label_ref (match_operand 1))
10850 (if_then_else (match_dup 0)
10851 (label_ref (match_dup 1))
10853 "PUT_MODE (operands[0], VOIDmode);")
10857 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10858 [(reg FLAGS_REG) (const_int 0)])
10860 (label_ref (match_operand 1))
10864 (if_then_else (match_dup 0)
10865 (label_ref (match_dup 1))
10868 rtx new_op0 = copy_rtx (operands[0]);
10869 operands[0] = new_op0;
10870 PUT_MODE (new_op0, VOIDmode);
10871 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10872 GET_MODE (XEXP (new_op0, 0))));
10874 /* Make sure that (a) the CCmode we have for the flags is strong
10875 enough for the reversed compare or (b) we have a valid FP compare. */
10876 if (! ix86_comparison_operator (new_op0, VOIDmode))
10880 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10881 ;; pass generates from shift insn with QImode operand. Actually, the mode
10882 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10883 ;; appropriate modulo of the bit offset value.
10885 (define_insn_and_split "*jcc_bt<mode>"
10887 (if_then_else (match_operator 0 "bt_comparison_operator"
10888 [(zero_extract:SWI48
10889 (match_operand:SWI48 1 "register_operand" "r")
10892 (match_operand:QI 2 "register_operand" "r")))
10894 (label_ref (match_operand 3))
10896 (clobber (reg:CC FLAGS_REG))]
10897 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10900 [(set (reg:CCC FLAGS_REG)
10902 (zero_extract:SWI48
10908 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10909 (label_ref (match_dup 3))
10912 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10914 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10917 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10918 ;; also for DImode, this is what combine produces.
10919 (define_insn_and_split "*jcc_bt<mode>_mask"
10921 (if_then_else (match_operator 0 "bt_comparison_operator"
10922 [(zero_extract:SWI48
10923 (match_operand:SWI48 1 "register_operand" "r")
10926 (match_operand:SI 2 "register_operand" "r")
10927 (match_operand:SI 3 "const_int_operand" "n")))])
10928 (label_ref (match_operand 4))
10930 (clobber (reg:CC FLAGS_REG))]
10931 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10932 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10933 == GET_MODE_BITSIZE (<MODE>mode)-1"
10936 [(set (reg:CCC FLAGS_REG)
10938 (zero_extract:SWI48
10944 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10945 (label_ref (match_dup 4))
10948 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10950 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10953 (define_insn_and_split "*jcc_btsi_1"
10955 (if_then_else (match_operator 0 "bt_comparison_operator"
10958 (match_operand:SI 1 "register_operand" "r")
10959 (match_operand:QI 2 "register_operand" "r"))
10962 (label_ref (match_operand 3))
10964 (clobber (reg:CC FLAGS_REG))]
10965 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10968 [(set (reg:CCC FLAGS_REG)
10976 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10977 (label_ref (match_dup 3))
10980 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10982 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10985 ;; avoid useless masking of bit offset operand
10986 (define_insn_and_split "*jcc_btsi_mask_1"
10989 (match_operator 0 "bt_comparison_operator"
10992 (match_operand:SI 1 "register_operand" "r")
10995 (match_operand:SI 2 "register_operand" "r")
10996 (match_operand:SI 3 "const_int_operand" "n")) 0))
10999 (label_ref (match_operand 4))
11001 (clobber (reg:CC FLAGS_REG))]
11002 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11003 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11006 [(set (reg:CCC FLAGS_REG)
11014 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11015 (label_ref (match_dup 4))
11017 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11019 ;; Define combination compare-and-branch fp compare instructions to help
11022 (define_insn "*fp_jcc_1_387"
11024 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11025 [(match_operand 1 "register_operand" "f")
11026 (match_operand 2 "nonimmediate_operand" "fm")])
11027 (label_ref (match_operand 3))
11029 (clobber (reg:CCFP FPSR_REG))
11030 (clobber (reg:CCFP FLAGS_REG))
11031 (clobber (match_scratch:HI 4 "=a"))]
11033 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11034 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11035 && SELECT_CC_MODE (GET_CODE (operands[0]),
11036 operands[1], operands[2]) == CCFPmode
11040 (define_insn "*fp_jcc_1r_387"
11042 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11043 [(match_operand 1 "register_operand" "f")
11044 (match_operand 2 "nonimmediate_operand" "fm")])
11046 (label_ref (match_operand 3))))
11047 (clobber (reg:CCFP FPSR_REG))
11048 (clobber (reg:CCFP FLAGS_REG))
11049 (clobber (match_scratch:HI 4 "=a"))]
11051 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11052 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11053 && SELECT_CC_MODE (GET_CODE (operands[0]),
11054 operands[1], operands[2]) == CCFPmode
11058 (define_insn "*fp_jcc_2_387"
11060 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11061 [(match_operand 1 "register_operand" "f")
11062 (match_operand 2 "register_operand" "f")])
11063 (label_ref (match_operand 3))
11065 (clobber (reg:CCFP FPSR_REG))
11066 (clobber (reg:CCFP FLAGS_REG))
11067 (clobber (match_scratch:HI 4 "=a"))]
11068 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11069 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11073 (define_insn "*fp_jcc_2r_387"
11075 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11076 [(match_operand 1 "register_operand" "f")
11077 (match_operand 2 "register_operand" "f")])
11079 (label_ref (match_operand 3))))
11080 (clobber (reg:CCFP FPSR_REG))
11081 (clobber (reg:CCFP FLAGS_REG))
11082 (clobber (match_scratch:HI 4 "=a"))]
11083 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11084 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11088 (define_insn "*fp_jcc_3_387"
11090 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11091 [(match_operand 1 "register_operand" "f")
11092 (match_operand 2 "const0_operand")])
11093 (label_ref (match_operand 3))
11095 (clobber (reg:CCFP FPSR_REG))
11096 (clobber (reg:CCFP FLAGS_REG))
11097 (clobber (match_scratch:HI 4 "=a"))]
11098 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11099 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11100 && SELECT_CC_MODE (GET_CODE (operands[0]),
11101 operands[1], operands[2]) == CCFPmode
11107 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11108 [(match_operand 1 "register_operand")
11109 (match_operand 2 "nonimmediate_operand")])
11111 (match_operand 4)))
11112 (clobber (reg:CCFP FPSR_REG))
11113 (clobber (reg:CCFP FLAGS_REG))]
11117 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11118 operands[3], operands[4], NULL_RTX, NULL_RTX);
11124 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11125 [(match_operand 1 "register_operand")
11126 (match_operand 2 "general_operand")])
11128 (match_operand 4)))
11129 (clobber (reg:CCFP FPSR_REG))
11130 (clobber (reg:CCFP FLAGS_REG))
11131 (clobber (match_scratch:HI 5 "=a"))]
11135 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11136 operands[3], operands[4], operands[5], NULL_RTX);
11140 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11141 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11142 ;; with a precedence over other operators and is always put in the first
11143 ;; place. Swap condition and operands to match ficom instruction.
11145 (define_insn "*fp_jcc_4_<mode>_387"
11148 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11149 [(match_operator 1 "float_operator"
11150 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11151 (match_operand 3 "register_operand" "f,f")])
11152 (label_ref (match_operand 4))
11154 (clobber (reg:CCFP FPSR_REG))
11155 (clobber (reg:CCFP FLAGS_REG))
11156 (clobber (match_scratch:HI 5 "=a,a"))]
11157 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11158 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11159 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11160 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11167 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11168 [(match_operator 1 "float_operator"
11169 [(match_operand:SWI24 2 "memory_operand")])
11170 (match_operand 3 "register_operand")])
11172 (match_operand 5)))
11173 (clobber (reg:CCFP FPSR_REG))
11174 (clobber (reg:CCFP FLAGS_REG))
11175 (clobber (match_scratch:HI 6 "=a"))]
11179 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11181 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11182 operands[3], operands[7],
11183 operands[4], operands[5], operands[6], NULL_RTX);
11187 ;; %%% Kill this when reload knows how to do it.
11191 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11192 [(match_operator 1 "float_operator"
11193 [(match_operand:SWI24 2 "register_operand")])
11194 (match_operand 3 "register_operand")])
11196 (match_operand 5)))
11197 (clobber (reg:CCFP FPSR_REG))
11198 (clobber (reg:CCFP FLAGS_REG))
11199 (clobber (match_scratch:HI 6 "=a"))]
11203 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11204 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11206 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11207 operands[3], operands[7],
11208 operands[4], operands[5], operands[6], operands[2]);
11212 ;; Unconditional and other jump instructions
11214 (define_insn "jump"
11216 (label_ref (match_operand 0)))]
11219 [(set_attr "type" "ibr")
11220 (set (attr "length")
11221 (if_then_else (and (ge (minus (match_dup 0) (pc))
11223 (lt (minus (match_dup 0) (pc))
11227 (set_attr "modrm" "0")])
11229 (define_expand "indirect_jump"
11230 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11234 operands[0] = convert_memory_address (word_mode, operands[0]);
11237 (define_insn "*indirect_jump"
11238 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))]
11241 [(set_attr "type" "ibr")
11242 (set_attr "length_immediate" "0")])
11244 (define_expand "tablejump"
11245 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11246 (use (label_ref (match_operand 1)))])]
11249 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11250 relative. Convert the relative address to an absolute address. */
11254 enum rtx_code code;
11256 /* We can't use @GOTOFF for text labels on VxWorks;
11257 see gotoff_operand. */
11258 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11262 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11264 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11268 op1 = pic_offset_table_rtx;
11273 op0 = pic_offset_table_rtx;
11277 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11282 operands[0] = convert_memory_address (word_mode, operands[0]);
11285 (define_insn "*tablejump_1"
11286 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))
11287 (use (label_ref (match_operand 1)))]
11290 [(set_attr "type" "ibr")
11291 (set_attr "length_immediate" "0")])
11293 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11296 [(set (reg FLAGS_REG) (match_operand 0))
11297 (set (match_operand:QI 1 "register_operand")
11298 (match_operator:QI 2 "ix86_comparison_operator"
11299 [(reg FLAGS_REG) (const_int 0)]))
11300 (set (match_operand 3 "q_regs_operand")
11301 (zero_extend (match_dup 1)))]
11302 "(peep2_reg_dead_p (3, operands[1])
11303 || operands_match_p (operands[1], operands[3]))
11304 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11305 [(set (match_dup 4) (match_dup 0))
11306 (set (strict_low_part (match_dup 5))
11309 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11310 operands[5] = gen_lowpart (QImode, operands[3]);
11311 ix86_expand_clear (operands[3]);
11315 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11316 (match_operand 4)])
11317 (set (match_operand:QI 1 "register_operand")
11318 (match_operator:QI 2 "ix86_comparison_operator"
11319 [(reg FLAGS_REG) (const_int 0)]))
11320 (set (match_operand 3 "q_regs_operand")
11321 (zero_extend (match_dup 1)))]
11322 "(peep2_reg_dead_p (3, operands[1])
11323 || operands_match_p (operands[1], operands[3]))
11324 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11325 [(parallel [(set (match_dup 5) (match_dup 0))
11327 (set (strict_low_part (match_dup 6))
11330 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11331 operands[6] = gen_lowpart (QImode, operands[3]);
11332 ix86_expand_clear (operands[3]);
11335 ;; Similar, but match zero extend with andsi3.
11338 [(set (reg FLAGS_REG) (match_operand 0))
11339 (set (match_operand:QI 1 "register_operand")
11340 (match_operator:QI 2 "ix86_comparison_operator"
11341 [(reg FLAGS_REG) (const_int 0)]))
11342 (parallel [(set (match_operand:SI 3 "q_regs_operand")
11343 (and:SI (match_dup 3) (const_int 255)))
11344 (clobber (reg:CC FLAGS_REG))])]
11345 "REGNO (operands[1]) == REGNO (operands[3])
11346 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11347 [(set (match_dup 4) (match_dup 0))
11348 (set (strict_low_part (match_dup 5))
11351 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11352 operands[5] = gen_lowpart (QImode, operands[3]);
11353 ix86_expand_clear (operands[3]);
11357 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11358 (match_operand 4)])
11359 (set (match_operand:QI 1 "register_operand")
11360 (match_operator:QI 2 "ix86_comparison_operator"
11361 [(reg FLAGS_REG) (const_int 0)]))
11362 (parallel [(set (match_operand 3 "q_regs_operand")
11363 (zero_extend (match_dup 1)))
11364 (clobber (reg:CC FLAGS_REG))])]
11365 "(peep2_reg_dead_p (3, operands[1])
11366 || operands_match_p (operands[1], operands[3]))
11367 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11368 [(parallel [(set (match_dup 5) (match_dup 0))
11370 (set (strict_low_part (match_dup 6))
11373 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11374 operands[6] = gen_lowpart (QImode, operands[3]);
11375 ix86_expand_clear (operands[3]);
11378 ;; Call instructions.
11380 ;; The predicates normally associated with named expanders are not properly
11381 ;; checked for calls. This is a bug in the generic code, but it isn't that
11382 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11384 ;; P6 processors will jump to the address after the decrement when %esp
11385 ;; is used as a call operand, so they will execute return address as a code.
11386 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11388 ;; Register constraint for call instruction.
11389 (define_mode_attr c [(SI "l") (DI "r")])
11391 ;; Call subroutine returning no value.
11393 (define_expand "call"
11394 [(call (match_operand:QI 0)
11396 (use (match_operand 2))]
11399 ix86_expand_call (NULL, operands[0], operands[1],
11400 operands[2], NULL, false);
11404 (define_expand "sibcall"
11405 [(call (match_operand:QI 0)
11407 (use (match_operand 2))]
11410 ix86_expand_call (NULL, operands[0], operands[1],
11411 operands[2], NULL, true);
11415 (define_insn_and_split "*call_vzeroupper"
11416 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11418 (unspec [(match_operand 2 "const_int_operand")]
11419 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11420 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11422 "&& reload_completed"
11424 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11425 [(set_attr "type" "call")])
11427 (define_insn "*call"
11428 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11429 (match_operand 1))]
11430 "!SIBLING_CALL_P (insn)"
11431 "* return ix86_output_call_insn (insn, operands[0]);"
11432 [(set_attr "type" "call")])
11434 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11435 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11437 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11438 (clobber (reg:TI XMM6_REG))
11439 (clobber (reg:TI XMM7_REG))
11440 (clobber (reg:TI XMM8_REG))
11441 (clobber (reg:TI XMM9_REG))
11442 (clobber (reg:TI XMM10_REG))
11443 (clobber (reg:TI XMM11_REG))
11444 (clobber (reg:TI XMM12_REG))
11445 (clobber (reg:TI XMM13_REG))
11446 (clobber (reg:TI XMM14_REG))
11447 (clobber (reg:TI XMM15_REG))
11448 (clobber (reg:DI SI_REG))
11449 (clobber (reg:DI DI_REG))
11450 (unspec [(match_operand 2 "const_int_operand")]
11451 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11452 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11454 "&& reload_completed"
11456 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11457 [(set_attr "type" "call")])
11459 (define_insn "*call_rex64_ms_sysv"
11460 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11462 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11463 (clobber (reg:TI XMM6_REG))
11464 (clobber (reg:TI XMM7_REG))
11465 (clobber (reg:TI XMM8_REG))
11466 (clobber (reg:TI XMM9_REG))
11467 (clobber (reg:TI XMM10_REG))
11468 (clobber (reg:TI XMM11_REG))
11469 (clobber (reg:TI XMM12_REG))
11470 (clobber (reg:TI XMM13_REG))
11471 (clobber (reg:TI XMM14_REG))
11472 (clobber (reg:TI XMM15_REG))
11473 (clobber (reg:DI SI_REG))
11474 (clobber (reg:DI DI_REG))]
11475 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11476 "* return ix86_output_call_insn (insn, operands[0]);"
11477 [(set_attr "type" "call")])
11479 (define_insn_and_split "*sibcall_vzeroupper"
11480 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11482 (unspec [(match_operand 2 "const_int_operand")]
11483 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11484 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11486 "&& reload_completed"
11488 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11489 [(set_attr "type" "call")])
11491 (define_insn "*sibcall"
11492 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11493 (match_operand 1))]
11494 "SIBLING_CALL_P (insn)"
11495 "* return ix86_output_call_insn (insn, operands[0]);"
11496 [(set_attr "type" "call")])
11498 (define_expand "call_pop"
11499 [(parallel [(call (match_operand:QI 0)
11500 (match_operand:SI 1))
11501 (set (reg:SI SP_REG)
11502 (plus:SI (reg:SI SP_REG)
11503 (match_operand:SI 3)))])]
11506 ix86_expand_call (NULL, operands[0], operands[1],
11507 operands[2], operands[3], false);
11511 (define_insn_and_split "*call_pop_vzeroupper"
11512 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11514 (set (reg:SI SP_REG)
11515 (plus:SI (reg:SI SP_REG)
11516 (match_operand:SI 2 "immediate_operand" "i")))
11517 (unspec [(match_operand 3 "const_int_operand")]
11518 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11519 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11521 "&& reload_completed"
11523 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11524 [(set_attr "type" "call")])
11526 (define_insn "*call_pop"
11527 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11529 (set (reg:SI SP_REG)
11530 (plus:SI (reg:SI SP_REG)
11531 (match_operand:SI 2 "immediate_operand" "i")))]
11532 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11533 "* return ix86_output_call_insn (insn, operands[0]);"
11534 [(set_attr "type" "call")])
11536 (define_insn_and_split "*sibcall_pop_vzeroupper"
11537 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11539 (set (reg:SI SP_REG)
11540 (plus:SI (reg:SI SP_REG)
11541 (match_operand:SI 2 "immediate_operand" "i")))
11542 (unspec [(match_operand 3 "const_int_operand")]
11543 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11544 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11546 "&& reload_completed"
11548 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11549 [(set_attr "type" "call")])
11551 (define_insn "*sibcall_pop"
11552 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11554 (set (reg:SI SP_REG)
11555 (plus:SI (reg:SI SP_REG)
11556 (match_operand:SI 2 "immediate_operand" "i")))]
11557 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11558 "* return ix86_output_call_insn (insn, operands[0]);"
11559 [(set_attr "type" "call")])
11561 ;; Call subroutine, returning value in operand 0
11563 (define_expand "call_value"
11564 [(set (match_operand 0)
11565 (call (match_operand:QI 1)
11566 (match_operand 2)))
11567 (use (match_operand 3))]
11570 ix86_expand_call (operands[0], operands[1], operands[2],
11571 operands[3], NULL, false);
11575 (define_expand "sibcall_value"
11576 [(set (match_operand 0)
11577 (call (match_operand:QI 1)
11578 (match_operand 2)))
11579 (use (match_operand 3))]
11582 ix86_expand_call (operands[0], operands[1], operands[2],
11583 operands[3], NULL, true);
11587 (define_insn_and_split "*call_value_vzeroupper"
11588 [(set (match_operand 0)
11589 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11590 (match_operand 2)))
11591 (unspec [(match_operand 3 "const_int_operand")]
11592 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11593 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11595 "&& reload_completed"
11597 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11598 [(set_attr "type" "callv")])
11600 (define_insn "*call_value"
11601 [(set (match_operand 0)
11602 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11603 (match_operand 2)))]
11604 "!SIBLING_CALL_P (insn)"
11605 "* return ix86_output_call_insn (insn, operands[1]);"
11606 [(set_attr "type" "callv")])
11608 (define_insn_and_split "*sibcall_value_vzeroupper"
11609 [(set (match_operand 0)
11610 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11611 (match_operand 2)))
11612 (unspec [(match_operand 3 "const_int_operand")]
11613 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11614 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11616 "&& reload_completed"
11618 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11619 [(set_attr "type" "callv")])
11621 (define_insn "*sibcall_value"
11622 [(set (match_operand 0)
11623 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11624 (match_operand 2)))]
11625 "SIBLING_CALL_P (insn)"
11626 "* return ix86_output_call_insn (insn, operands[1]);"
11627 [(set_attr "type" "callv")])
11629 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11630 [(set (match_operand 0)
11631 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11632 (match_operand 2)))
11633 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11634 (clobber (reg:TI XMM6_REG))
11635 (clobber (reg:TI XMM7_REG))
11636 (clobber (reg:TI XMM8_REG))
11637 (clobber (reg:TI XMM9_REG))
11638 (clobber (reg:TI XMM10_REG))
11639 (clobber (reg:TI XMM11_REG))
11640 (clobber (reg:TI XMM12_REG))
11641 (clobber (reg:TI XMM13_REG))
11642 (clobber (reg:TI XMM14_REG))
11643 (clobber (reg:TI XMM15_REG))
11644 (clobber (reg:DI SI_REG))
11645 (clobber (reg:DI DI_REG))
11646 (unspec [(match_operand 3 "const_int_operand")]
11647 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11648 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11650 "&& reload_completed"
11652 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11653 [(set_attr "type" "callv")])
11655 (define_insn "*call_value_rex64_ms_sysv"
11656 [(set (match_operand 0)
11657 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11658 (match_operand 2)))
11659 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11660 (clobber (reg:TI XMM6_REG))
11661 (clobber (reg:TI XMM7_REG))
11662 (clobber (reg:TI XMM8_REG))
11663 (clobber (reg:TI XMM9_REG))
11664 (clobber (reg:TI XMM10_REG))
11665 (clobber (reg:TI XMM11_REG))
11666 (clobber (reg:TI XMM12_REG))
11667 (clobber (reg:TI XMM13_REG))
11668 (clobber (reg:TI XMM14_REG))
11669 (clobber (reg:TI XMM15_REG))
11670 (clobber (reg:DI SI_REG))
11671 (clobber (reg:DI DI_REG))]
11672 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11673 "* return ix86_output_call_insn (insn, operands[1]);"
11674 [(set_attr "type" "callv")])
11676 (define_expand "call_value_pop"
11677 [(parallel [(set (match_operand 0)
11678 (call (match_operand:QI 1)
11679 (match_operand:SI 2)))
11680 (set (reg:SI SP_REG)
11681 (plus:SI (reg:SI SP_REG)
11682 (match_operand:SI 4)))])]
11685 ix86_expand_call (operands[0], operands[1], operands[2],
11686 operands[3], operands[4], false);
11690 (define_insn_and_split "*call_value_pop_vzeroupper"
11691 [(set (match_operand 0)
11692 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11693 (match_operand 2)))
11694 (set (reg:SI SP_REG)
11695 (plus:SI (reg:SI SP_REG)
11696 (match_operand:SI 3 "immediate_operand" "i")))
11697 (unspec [(match_operand 4 "const_int_operand")]
11698 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11699 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11701 "&& reload_completed"
11703 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11704 [(set_attr "type" "callv")])
11706 (define_insn "*call_value_pop"
11707 [(set (match_operand 0)
11708 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11709 (match_operand 2)))
11710 (set (reg:SI SP_REG)
11711 (plus:SI (reg:SI SP_REG)
11712 (match_operand:SI 3 "immediate_operand" "i")))]
11713 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11714 "* return ix86_output_call_insn (insn, operands[1]);"
11715 [(set_attr "type" "callv")])
11717 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11718 [(set (match_operand 0)
11719 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11720 (match_operand 2)))
11721 (set (reg:SI SP_REG)
11722 (plus:SI (reg:SI SP_REG)
11723 (match_operand:SI 3 "immediate_operand" "i")))
11724 (unspec [(match_operand 4 "const_int_operand")]
11725 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11726 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11728 "&& reload_completed"
11730 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11731 [(set_attr "type" "callv")])
11733 (define_insn "*sibcall_value_pop"
11734 [(set (match_operand 0)
11735 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11736 (match_operand 2)))
11737 (set (reg:SI SP_REG)
11738 (plus:SI (reg:SI SP_REG)
11739 (match_operand:SI 3 "immediate_operand" "i")))]
11740 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11741 "* return ix86_output_call_insn (insn, operands[1]);"
11742 [(set_attr "type" "callv")])
11744 ;; Call subroutine returning any type.
11746 (define_expand "untyped_call"
11747 [(parallel [(call (match_operand 0)
11750 (match_operand 2)])]
11755 /* In order to give reg-stack an easier job in validating two
11756 coprocessor registers as containing a possible return value,
11757 simply pretend the untyped call returns a complex long double
11760 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11761 and should have the default ABI. */
11763 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11764 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11765 operands[0], const0_rtx,
11766 GEN_INT ((TARGET_64BIT
11767 ? (ix86_abi == SYSV_ABI
11768 ? X86_64_SSE_REGPARM_MAX
11769 : X86_64_MS_SSE_REGPARM_MAX)
11770 : X86_32_SSE_REGPARM_MAX)
11774 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11776 rtx set = XVECEXP (operands[2], 0, i);
11777 emit_move_insn (SET_DEST (set), SET_SRC (set));
11780 /* The optimizer does not know that the call sets the function value
11781 registers we stored in the result block. We avoid problems by
11782 claiming that all hard registers are used and clobbered at this
11784 emit_insn (gen_blockage ());
11789 ;; Prologue and epilogue instructions
11791 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11792 ;; all of memory. This blocks insns from being moved across this point.
11794 (define_insn "blockage"
11795 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11798 [(set_attr "length" "0")])
11800 ;; Do not schedule instructions accessing memory across this point.
11802 (define_expand "memory_blockage"
11803 [(set (match_dup 0)
11804 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11807 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11808 MEM_VOLATILE_P (operands[0]) = 1;
11811 (define_insn "*memory_blockage"
11812 [(set (match_operand:BLK 0)
11813 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11816 [(set_attr "length" "0")])
11818 ;; As USE insns aren't meaningful after reload, this is used instead
11819 ;; to prevent deleting instructions setting registers for PIC code
11820 (define_insn "prologue_use"
11821 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
11824 [(set_attr "length" "0")])
11826 ;; Insn emitted into the body of a function to return from a function.
11827 ;; This is only done if the function's epilogue is known to be simple.
11828 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11830 (define_expand "return"
11832 "ix86_can_use_return_insn_p ()"
11834 ix86_maybe_emit_epilogue_vzeroupper ();
11835 if (crtl->args.pops_args)
11837 rtx popc = GEN_INT (crtl->args.pops_args);
11838 emit_jump_insn (gen_simple_return_pop_internal (popc));
11843 ;; We need to disable this for TARGET_SEH, as otherwise
11844 ;; shrink-wrapped prologue gets enabled too. This might exceed
11845 ;; the maximum size of prologue in unwind information.
11847 (define_expand "simple_return"
11851 ix86_maybe_emit_epilogue_vzeroupper ();
11852 if (crtl->args.pops_args)
11854 rtx popc = GEN_INT (crtl->args.pops_args);
11855 emit_jump_insn (gen_simple_return_pop_internal (popc));
11860 (define_insn "simple_return_internal"
11864 [(set_attr "length" "1")
11865 (set_attr "atom_unit" "jeu")
11866 (set_attr "length_immediate" "0")
11867 (set_attr "modrm" "0")])
11869 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11870 ;; instruction Athlon and K8 have.
11872 (define_insn "simple_return_internal_long"
11874 (unspec [(const_int 0)] UNSPEC_REP)]
11877 [(set_attr "length" "2")
11878 (set_attr "atom_unit" "jeu")
11879 (set_attr "length_immediate" "0")
11880 (set_attr "prefix_rep" "1")
11881 (set_attr "modrm" "0")])
11883 (define_insn "simple_return_pop_internal"
11885 (use (match_operand:SI 0 "const_int_operand"))]
11888 [(set_attr "length" "3")
11889 (set_attr "atom_unit" "jeu")
11890 (set_attr "length_immediate" "2")
11891 (set_attr "modrm" "0")])
11893 (define_insn "simple_return_indirect_internal"
11895 (use (match_operand:SI 0 "register_operand" "r"))]
11898 [(set_attr "type" "ibr")
11899 (set_attr "length_immediate" "0")])
11905 [(set_attr "length" "1")
11906 (set_attr "length_immediate" "0")
11907 (set_attr "modrm" "0")])
11909 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11910 (define_insn "nops"
11911 [(unspec_volatile [(match_operand 0 "const_int_operand")]
11915 int num = INTVAL (operands[0]);
11917 gcc_assert (IN_RANGE (num, 1, 8));
11920 fputs ("\tnop\n", asm_out_file);
11924 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11925 (set_attr "length_immediate" "0")
11926 (set_attr "modrm" "0")])
11928 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11929 ;; branch prediction penalty for the third jump in a 16-byte
11933 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
11936 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11937 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11939 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11940 The align insn is used to avoid 3 jump instructions in the row to improve
11941 branch prediction and the benefits hardly outweigh the cost of extra 8
11942 nops on the average inserted by full alignment pseudo operation. */
11946 [(set_attr "length" "16")])
11948 (define_expand "prologue"
11951 "ix86_expand_prologue (); DONE;")
11953 (define_insn "set_got"
11954 [(set (match_operand:SI 0 "register_operand" "=r")
11955 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11956 (clobber (reg:CC FLAGS_REG))]
11958 "* return output_set_got (operands[0], NULL_RTX);"
11959 [(set_attr "type" "multi")
11960 (set_attr "length" "12")])
11962 (define_insn "set_got_labelled"
11963 [(set (match_operand:SI 0 "register_operand" "=r")
11964 (unspec:SI [(label_ref (match_operand 1))]
11966 (clobber (reg:CC FLAGS_REG))]
11968 "* return output_set_got (operands[0], operands[1]);"
11969 [(set_attr "type" "multi")
11970 (set_attr "length" "12")])
11972 (define_insn "set_got_rex64"
11973 [(set (match_operand:DI 0 "register_operand" "=r")
11974 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11976 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11977 [(set_attr "type" "lea")
11978 (set_attr "length_address" "4")
11979 (set_attr "mode" "DI")])
11981 (define_insn "set_rip_rex64"
11982 [(set (match_operand:DI 0 "register_operand" "=r")
11983 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
11985 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11986 [(set_attr "type" "lea")
11987 (set_attr "length_address" "4")
11988 (set_attr "mode" "DI")])
11990 (define_insn "set_got_offset_rex64"
11991 [(set (match_operand:DI 0 "register_operand" "=r")
11993 [(label_ref (match_operand 1))]
11994 UNSPEC_SET_GOT_OFFSET))]
11996 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11997 [(set_attr "type" "imov")
11998 (set_attr "length_immediate" "0")
11999 (set_attr "length_address" "8")
12000 (set_attr "mode" "DI")])
12002 (define_expand "epilogue"
12005 "ix86_expand_epilogue (1); DONE;")
12007 (define_expand "sibcall_epilogue"
12010 "ix86_expand_epilogue (0); DONE;")
12012 (define_expand "eh_return"
12013 [(use (match_operand 0 "register_operand"))]
12016 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12018 /* Tricky bit: we write the address of the handler to which we will
12019 be returning into someone else's stack frame, one word below the
12020 stack address we wish to restore. */
12021 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12022 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12023 tmp = gen_rtx_MEM (Pmode, tmp);
12024 emit_move_insn (tmp, ra);
12026 emit_jump_insn (gen_eh_return_internal ());
12031 (define_insn_and_split "eh_return_internal"
12035 "epilogue_completed"
12037 "ix86_expand_epilogue (2); DONE;")
12039 (define_insn "leave"
12040 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12041 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12042 (clobber (mem:BLK (scratch)))]
12045 [(set_attr "type" "leave")])
12047 (define_insn "leave_rex64"
12048 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12049 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12050 (clobber (mem:BLK (scratch)))]
12053 [(set_attr "type" "leave")])
12055 ;; Handle -fsplit-stack.
12057 (define_expand "split_stack_prologue"
12061 ix86_expand_split_stack_prologue ();
12065 ;; In order to support the call/return predictor, we use a return
12066 ;; instruction which the middle-end doesn't see.
12067 (define_insn "split_stack_return"
12068 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12069 UNSPECV_SPLIT_STACK_RETURN)]
12072 if (operands[0] == const0_rtx)
12077 [(set_attr "atom_unit" "jeu")
12078 (set_attr "modrm" "0")
12079 (set (attr "length")
12080 (if_then_else (match_operand:SI 0 "const0_operand")
12083 (set (attr "length_immediate")
12084 (if_then_else (match_operand:SI 0 "const0_operand")
12088 ;; If there are operand 0 bytes available on the stack, jump to
12091 (define_expand "split_stack_space_check"
12092 [(set (pc) (if_then_else
12093 (ltu (minus (reg SP_REG)
12094 (match_operand 0 "register_operand"))
12095 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12096 (label_ref (match_operand 1))
12100 rtx reg, size, limit;
12102 reg = gen_reg_rtx (Pmode);
12103 size = force_reg (Pmode, operands[0]);
12104 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12105 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12106 UNSPEC_STACK_CHECK);
12107 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12108 ix86_expand_branch (GEU, reg, limit, operands[1]);
12113 ;; Bit manipulation instructions.
12115 (define_expand "ffs<mode>2"
12116 [(set (match_dup 2) (const_int -1))
12117 (parallel [(set (match_dup 3) (match_dup 4))
12118 (set (match_operand:SWI48 0 "register_operand")
12120 (match_operand:SWI48 1 "nonimmediate_operand")))])
12121 (set (match_dup 0) (if_then_else:SWI48
12122 (eq (match_dup 3) (const_int 0))
12125 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12126 (clobber (reg:CC FLAGS_REG))])]
12129 enum machine_mode flags_mode;
12131 if (<MODE>mode == SImode && !TARGET_CMOVE)
12133 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12137 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12139 operands[2] = gen_reg_rtx (<MODE>mode);
12140 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12141 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12144 (define_insn_and_split "ffssi2_no_cmove"
12145 [(set (match_operand:SI 0 "register_operand" "=r")
12146 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12147 (clobber (match_scratch:SI 2 "=&q"))
12148 (clobber (reg:CC FLAGS_REG))]
12151 "&& reload_completed"
12152 [(parallel [(set (match_dup 4) (match_dup 5))
12153 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12154 (set (strict_low_part (match_dup 3))
12155 (eq:QI (match_dup 4) (const_int 0)))
12156 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12157 (clobber (reg:CC FLAGS_REG))])
12158 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12159 (clobber (reg:CC FLAGS_REG))])
12160 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12161 (clobber (reg:CC FLAGS_REG))])]
12163 enum machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12165 operands[3] = gen_lowpart (QImode, operands[2]);
12166 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12167 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12169 ix86_expand_clear (operands[2]);
12172 (define_insn "*tzcnt<mode>_1"
12173 [(set (reg:CCC FLAGS_REG)
12174 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12176 (set (match_operand:SWI48 0 "register_operand" "=r")
12177 (ctz:SWI48 (match_dup 1)))]
12179 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12180 [(set_attr "type" "alu1")
12181 (set_attr "prefix_0f" "1")
12182 (set_attr "prefix_rep" "1")
12183 (set_attr "mode" "<MODE>")])
12185 (define_insn "*bsf<mode>_1"
12186 [(set (reg:CCZ FLAGS_REG)
12187 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12189 (set (match_operand:SWI48 0 "register_operand" "=r")
12190 (ctz:SWI48 (match_dup 1)))]
12192 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12193 [(set_attr "type" "alu1")
12194 (set_attr "prefix_0f" "1")
12195 (set_attr "mode" "<MODE>")])
12197 (define_insn "ctz<mode>2"
12198 [(set (match_operand:SWI248 0 "register_operand" "=r")
12199 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12200 (clobber (reg:CC FLAGS_REG))]
12204 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12205 else if (optimize_function_for_size_p (cfun))
12207 else if (TARGET_GENERIC)
12208 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12209 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12211 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12213 [(set_attr "type" "alu1")
12214 (set_attr "prefix_0f" "1")
12215 (set (attr "prefix_rep")
12217 (ior (match_test "TARGET_BMI")
12218 (and (not (match_test "optimize_function_for_size_p (cfun)"))
12219 (match_test "TARGET_GENERIC")))
12221 (const_string "0")))
12222 (set_attr "mode" "<MODE>")])
12224 (define_expand "clz<mode>2"
12226 [(set (match_operand:SWI248 0 "register_operand")
12229 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12230 (clobber (reg:CC FLAGS_REG))])
12232 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12233 (clobber (reg:CC FLAGS_REG))])]
12238 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12241 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12244 (define_insn "clz<mode>2_lzcnt"
12245 [(set (match_operand:SWI248 0 "register_operand" "=r")
12246 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12247 (clobber (reg:CC FLAGS_REG))]
12249 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12250 [(set_attr "prefix_rep" "1")
12251 (set_attr "type" "bitmanip")
12252 (set_attr "mode" "<MODE>")])
12254 ;; BMI instructions.
12255 (define_insn "*bmi_andn_<mode>"
12256 [(set (match_operand:SWI48 0 "register_operand" "=r")
12259 (match_operand:SWI48 1 "register_operand" "r"))
12260 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12261 (clobber (reg:CC FLAGS_REG))]
12263 "andn\t{%2, %1, %0|%0, %1, %2}"
12264 [(set_attr "type" "bitmanip")
12265 (set_attr "mode" "<MODE>")])
12267 (define_insn "bmi_bextr_<mode>"
12268 [(set (match_operand:SWI48 0 "register_operand" "=r")
12269 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12270 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12272 (clobber (reg:CC FLAGS_REG))]
12274 "bextr\t{%2, %1, %0|%0, %1, %2}"
12275 [(set_attr "type" "bitmanip")
12276 (set_attr "mode" "<MODE>")])
12278 (define_insn "*bmi_blsi_<mode>"
12279 [(set (match_operand:SWI48 0 "register_operand" "=r")
12282 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12284 (clobber (reg:CC FLAGS_REG))]
12286 "blsi\t{%1, %0|%0, %1}"
12287 [(set_attr "type" "bitmanip")
12288 (set_attr "mode" "<MODE>")])
12290 (define_insn "*bmi_blsmsk_<mode>"
12291 [(set (match_operand:SWI48 0 "register_operand" "=r")
12294 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12297 (clobber (reg:CC FLAGS_REG))]
12299 "blsmsk\t{%1, %0|%0, %1}"
12300 [(set_attr "type" "bitmanip")
12301 (set_attr "mode" "<MODE>")])
12303 (define_insn "*bmi_blsr_<mode>"
12304 [(set (match_operand:SWI48 0 "register_operand" "=r")
12307 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12310 (clobber (reg:CC FLAGS_REG))]
12312 "blsr\t{%1, %0|%0, %1}"
12313 [(set_attr "type" "bitmanip")
12314 (set_attr "mode" "<MODE>")])
12316 ;; BMI2 instructions.
12317 (define_insn "bmi2_bzhi_<mode>3"
12318 [(set (match_operand:SWI48 0 "register_operand" "=r")
12319 (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
12320 (lshiftrt:SWI48 (const_int -1)
12321 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
12322 (clobber (reg:CC FLAGS_REG))]
12324 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12325 [(set_attr "type" "bitmanip")
12326 (set_attr "prefix" "vex")
12327 (set_attr "mode" "<MODE>")])
12329 (define_insn "bmi2_pdep_<mode>3"
12330 [(set (match_operand:SWI48 0 "register_operand" "=r")
12331 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12332 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12335 "pdep\t{%2, %1, %0|%0, %1, %2}"
12336 [(set_attr "type" "bitmanip")
12337 (set_attr "prefix" "vex")
12338 (set_attr "mode" "<MODE>")])
12340 (define_insn "bmi2_pext_<mode>3"
12341 [(set (match_operand:SWI48 0 "register_operand" "=r")
12342 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12343 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12346 "pext\t{%2, %1, %0|%0, %1, %2}"
12347 [(set_attr "type" "bitmanip")
12348 (set_attr "prefix" "vex")
12349 (set_attr "mode" "<MODE>")])
12351 ;; TBM instructions.
12352 (define_insn "tbm_bextri_<mode>"
12353 [(set (match_operand:SWI48 0 "register_operand" "=r")
12354 (zero_extract:SWI48
12355 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12356 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12357 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12358 (clobber (reg:CC FLAGS_REG))]
12361 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12362 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12364 [(set_attr "type" "bitmanip")
12365 (set_attr "mode" "<MODE>")])
12367 (define_insn "*tbm_blcfill_<mode>"
12368 [(set (match_operand:SWI48 0 "register_operand" "=r")
12371 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12374 (clobber (reg:CC FLAGS_REG))]
12376 "blcfill\t{%1, %0|%0, %1}"
12377 [(set_attr "type" "bitmanip")
12378 (set_attr "mode" "<MODE>")])
12380 (define_insn "*tbm_blci_<mode>"
12381 [(set (match_operand:SWI48 0 "register_operand" "=r")
12385 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12388 (clobber (reg:CC FLAGS_REG))]
12390 "blci\t{%1, %0|%0, %1}"
12391 [(set_attr "type" "bitmanip")
12392 (set_attr "mode" "<MODE>")])
12394 (define_insn "*tbm_blcic_<mode>"
12395 [(set (match_operand:SWI48 0 "register_operand" "=r")
12398 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12402 (clobber (reg:CC FLAGS_REG))]
12404 "blcic\t{%1, %0|%0, %1}"
12405 [(set_attr "type" "bitmanip")
12406 (set_attr "mode" "<MODE>")])
12408 (define_insn "*tbm_blcmsk_<mode>"
12409 [(set (match_operand:SWI48 0 "register_operand" "=r")
12412 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12415 (clobber (reg:CC FLAGS_REG))]
12417 "blcmsk\t{%1, %0|%0, %1}"
12418 [(set_attr "type" "bitmanip")
12419 (set_attr "mode" "<MODE>")])
12421 (define_insn "*tbm_blcs_<mode>"
12422 [(set (match_operand:SWI48 0 "register_operand" "=r")
12425 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12428 (clobber (reg:CC FLAGS_REG))]
12430 "blcs\t{%1, %0|%0, %1}"
12431 [(set_attr "type" "bitmanip")
12432 (set_attr "mode" "<MODE>")])
12434 (define_insn "*tbm_blsfill_<mode>"
12435 [(set (match_operand:SWI48 0 "register_operand" "=r")
12438 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12441 (clobber (reg:CC FLAGS_REG))]
12443 "blsfill\t{%1, %0|%0, %1}"
12444 [(set_attr "type" "bitmanip")
12445 (set_attr "mode" "<MODE>")])
12447 (define_insn "*tbm_blsic_<mode>"
12448 [(set (match_operand:SWI48 0 "register_operand" "=r")
12451 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12455 (clobber (reg:CC FLAGS_REG))]
12457 "blsic\t{%1, %0|%0, %1}"
12458 [(set_attr "type" "bitmanip")
12459 (set_attr "mode" "<MODE>")])
12461 (define_insn "*tbm_t1mskc_<mode>"
12462 [(set (match_operand:SWI48 0 "register_operand" "=r")
12465 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12469 (clobber (reg:CC FLAGS_REG))]
12471 "t1mskc\t{%1, %0|%0, %1}"
12472 [(set_attr "type" "bitmanip")
12473 (set_attr "mode" "<MODE>")])
12475 (define_insn "*tbm_tzmsk_<mode>"
12476 [(set (match_operand:SWI48 0 "register_operand" "=r")
12479 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12483 (clobber (reg:CC FLAGS_REG))]
12485 "tzmsk\t{%1, %0|%0, %1}"
12486 [(set_attr "type" "bitmanip")
12487 (set_attr "mode" "<MODE>")])
12489 (define_insn "bsr_rex64"
12490 [(set (match_operand:DI 0 "register_operand" "=r")
12491 (minus:DI (const_int 63)
12492 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12493 (clobber (reg:CC FLAGS_REG))]
12495 "bsr{q}\t{%1, %0|%0, %1}"
12496 [(set_attr "type" "alu1")
12497 (set_attr "prefix_0f" "1")
12498 (set_attr "mode" "DI")])
12501 [(set (match_operand:SI 0 "register_operand" "=r")
12502 (minus:SI (const_int 31)
12503 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12504 (clobber (reg:CC FLAGS_REG))]
12506 "bsr{l}\t{%1, %0|%0, %1}"
12507 [(set_attr "type" "alu1")
12508 (set_attr "prefix_0f" "1")
12509 (set_attr "mode" "SI")])
12511 (define_insn "*bsrhi"
12512 [(set (match_operand:HI 0 "register_operand" "=r")
12513 (minus:HI (const_int 15)
12514 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12515 (clobber (reg:CC FLAGS_REG))]
12517 "bsr{w}\t{%1, %0|%0, %1}"
12518 [(set_attr "type" "alu1")
12519 (set_attr "prefix_0f" "1")
12520 (set_attr "mode" "HI")])
12522 (define_insn "popcount<mode>2"
12523 [(set (match_operand:SWI248 0 "register_operand" "=r")
12525 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12526 (clobber (reg:CC FLAGS_REG))]
12530 return "popcnt\t{%1, %0|%0, %1}";
12532 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12535 [(set_attr "prefix_rep" "1")
12536 (set_attr "type" "bitmanip")
12537 (set_attr "mode" "<MODE>")])
12539 (define_insn "*popcount<mode>2_cmp"
12540 [(set (reg FLAGS_REG)
12543 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12545 (set (match_operand:SWI248 0 "register_operand" "=r")
12546 (popcount:SWI248 (match_dup 1)))]
12547 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12550 return "popcnt\t{%1, %0|%0, %1}";
12552 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12555 [(set_attr "prefix_rep" "1")
12556 (set_attr "type" "bitmanip")
12557 (set_attr "mode" "<MODE>")])
12559 (define_insn "*popcountsi2_cmp_zext"
12560 [(set (reg FLAGS_REG)
12562 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12564 (set (match_operand:DI 0 "register_operand" "=r")
12565 (zero_extend:DI(popcount:SI (match_dup 1))))]
12566 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12569 return "popcnt\t{%1, %0|%0, %1}";
12571 return "popcnt{l}\t{%1, %0|%0, %1}";
12574 [(set_attr "prefix_rep" "1")
12575 (set_attr "type" "bitmanip")
12576 (set_attr "mode" "SI")])
12578 (define_expand "bswapdi2"
12579 [(set (match_operand:DI 0 "register_operand")
12580 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
12583 if (TARGET_64BIT && !TARGET_MOVBE)
12584 operands[1] = force_reg (DImode, operands[1]);
12587 (define_insn_and_split "*bswapdi2_doubleword"
12588 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
12590 (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
12592 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12594 "&& reload_completed"
12595 [(set (match_dup 2)
12596 (bswap:SI (match_dup 1)))
12598 (bswap:SI (match_dup 3)))]
12600 split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);
12602 if (REG_P (operands[0]) && REG_P (operands[1]))
12604 emit_insn (gen_swapsi (operands[0], operands[2]));
12605 emit_insn (gen_bswapsi2 (operands[0], operands[0]));
12606 emit_insn (gen_bswapsi2 (operands[2], operands[2]));
12612 if (MEM_P (operands[0]))
12614 emit_insn (gen_bswapsi2 (operands[3], operands[3]));
12615 emit_insn (gen_bswapsi2 (operands[1], operands[1]));
12617 emit_move_insn (operands[0], operands[3]);
12618 emit_move_insn (operands[2], operands[1]);
12620 if (MEM_P (operands[1]))
12622 emit_move_insn (operands[2], operands[1]);
12623 emit_move_insn (operands[0], operands[3]);
12625 emit_insn (gen_bswapsi2 (operands[2], operands[2]));
12626 emit_insn (gen_bswapsi2 (operands[0], operands[0]));
12632 (define_expand "bswapsi2"
12633 [(set (match_operand:SI 0 "register_operand")
12634 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
12639 else if (TARGET_BSWAP)
12640 operands[1] = force_reg (SImode, operands[1]);
12643 rtx x = operands[0];
12645 emit_move_insn (x, operands[1]);
12646 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12647 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12648 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12653 (define_insn "*bswap<mode>2_movbe"
12654 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12655 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12657 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12660 movbe\t{%1, %0|%0, %1}
12661 movbe\t{%1, %0|%0, %1}"
12662 [(set_attr "type" "bitmanip,imov,imov")
12663 (set_attr "modrm" "0,1,1")
12664 (set_attr "prefix_0f" "*,1,1")
12665 (set_attr "prefix_extra" "*,1,1")
12666 (set_attr "mode" "<MODE>")])
12668 (define_insn "*bswap<mode>2"
12669 [(set (match_operand:SWI48 0 "register_operand" "=r")
12670 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12673 [(set_attr "type" "bitmanip")
12674 (set_attr "modrm" "0")
12675 (set_attr "mode" "<MODE>")])
12677 (define_insn "*bswaphi_lowpart_1"
12678 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12679 (bswap:HI (match_dup 0)))
12680 (clobber (reg:CC FLAGS_REG))]
12681 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12683 xchg{b}\t{%h0, %b0|%b0, %h0}
12684 rol{w}\t{$8, %0|%0, 8}"
12685 [(set_attr "length" "2,4")
12686 (set_attr "mode" "QI,HI")])
12688 (define_insn "bswaphi_lowpart"
12689 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12690 (bswap:HI (match_dup 0)))
12691 (clobber (reg:CC FLAGS_REG))]
12693 "rol{w}\t{$8, %0|%0, 8}"
12694 [(set_attr "length" "4")
12695 (set_attr "mode" "HI")])
12697 (define_expand "paritydi2"
12698 [(set (match_operand:DI 0 "register_operand")
12699 (parity:DI (match_operand:DI 1 "register_operand")))]
12702 rtx scratch = gen_reg_rtx (QImode);
12705 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12706 NULL_RTX, operands[1]));
12708 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12709 gen_rtx_REG (CCmode, FLAGS_REG),
12711 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12714 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12717 rtx tmp = gen_reg_rtx (SImode);
12719 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12720 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12725 (define_expand "paritysi2"
12726 [(set (match_operand:SI 0 "register_operand")
12727 (parity:SI (match_operand:SI 1 "register_operand")))]
12730 rtx scratch = gen_reg_rtx (QImode);
12733 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12735 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12736 gen_rtx_REG (CCmode, FLAGS_REG),
12738 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12740 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12744 (define_insn_and_split "paritydi2_cmp"
12745 [(set (reg:CC FLAGS_REG)
12746 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12748 (clobber (match_scratch:DI 0 "=r"))
12749 (clobber (match_scratch:SI 1 "=&r"))
12750 (clobber (match_scratch:HI 2 "=Q"))]
12753 "&& reload_completed"
12755 [(set (match_dup 1)
12756 (xor:SI (match_dup 1) (match_dup 4)))
12757 (clobber (reg:CC FLAGS_REG))])
12759 [(set (reg:CC FLAGS_REG)
12760 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12761 (clobber (match_dup 1))
12762 (clobber (match_dup 2))])]
12764 operands[4] = gen_lowpart (SImode, operands[3]);
12768 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12769 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12772 operands[1] = gen_highpart (SImode, operands[3]);
12775 (define_insn_and_split "paritysi2_cmp"
12776 [(set (reg:CC FLAGS_REG)
12777 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12779 (clobber (match_scratch:SI 0 "=r"))
12780 (clobber (match_scratch:HI 1 "=&Q"))]
12783 "&& reload_completed"
12785 [(set (match_dup 1)
12786 (xor:HI (match_dup 1) (match_dup 3)))
12787 (clobber (reg:CC FLAGS_REG))])
12789 [(set (reg:CC FLAGS_REG)
12790 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12791 (clobber (match_dup 1))])]
12793 operands[3] = gen_lowpart (HImode, operands[2]);
12795 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12796 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12799 (define_insn "*parityhi2_cmp"
12800 [(set (reg:CC FLAGS_REG)
12801 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12803 (clobber (match_scratch:HI 0 "=Q"))]
12805 "xor{b}\t{%h0, %b0|%b0, %h0}"
12806 [(set_attr "length" "2")
12807 (set_attr "mode" "HI")])
12810 ;; Thread-local storage patterns for ELF.
12812 ;; Note that these code sequences must appear exactly as shown
12813 ;; in order to allow linker relaxation.
12815 (define_insn "*tls_global_dynamic_32_gnu"
12816 [(set (match_operand:SI 0 "register_operand" "=a")
12818 [(match_operand:SI 1 "register_operand" "b")
12819 (match_operand 2 "tls_symbolic_operand")
12820 (match_operand 3 "constant_call_address_operand" "z")]
12822 (clobber (match_scratch:SI 4 "=d"))
12823 (clobber (match_scratch:SI 5 "=c"))
12824 (clobber (reg:CC FLAGS_REG))]
12825 "!TARGET_64BIT && TARGET_GNU_TLS"
12828 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12829 if (TARGET_SUN_TLS)
12830 #ifdef HAVE_AS_IX86_TLSGDPLT
12831 return "call\t%a2@tlsgdplt";
12833 return "call\t%p3@plt";
12835 return "call\t%P3";
12837 [(set_attr "type" "multi")
12838 (set_attr "length" "12")])
12840 (define_expand "tls_global_dynamic_32"
12842 [(set (match_operand:SI 0 "register_operand")
12843 (unspec:SI [(match_operand:SI 2 "register_operand")
12844 (match_operand 1 "tls_symbolic_operand")
12845 (match_operand 3 "constant_call_address_operand")]
12847 (clobber (match_scratch:SI 4))
12848 (clobber (match_scratch:SI 5))
12849 (clobber (reg:CC FLAGS_REG))])])
12851 (define_insn "*tls_global_dynamic_64_<mode>"
12852 [(set (match_operand:P 0 "register_operand" "=a")
12854 (mem:QI (match_operand 2 "constant_call_address_operand" "z"))
12855 (match_operand 3)))
12856 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12861 fputs (ASM_BYTE "0x66\n", asm_out_file);
12863 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12864 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12865 fputs ("\trex64\n", asm_out_file);
12866 if (TARGET_SUN_TLS)
12867 return "call\t%p2@plt";
12868 return "call\t%P2";
12870 [(set_attr "type" "multi")
12871 (set (attr "length")
12872 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12874 (define_expand "tls_global_dynamic_64_<mode>"
12876 [(set (match_operand:P 0 "register_operand")
12878 (mem:QI (match_operand 2 "constant_call_address_operand"))
12880 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12884 (define_insn "*tls_local_dynamic_base_32_gnu"
12885 [(set (match_operand:SI 0 "register_operand" "=a")
12887 [(match_operand:SI 1 "register_operand" "b")
12888 (match_operand 2 "constant_call_address_operand" "z")]
12889 UNSPEC_TLS_LD_BASE))
12890 (clobber (match_scratch:SI 3 "=d"))
12891 (clobber (match_scratch:SI 4 "=c"))
12892 (clobber (reg:CC FLAGS_REG))]
12893 "!TARGET_64BIT && TARGET_GNU_TLS"
12896 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12897 if (TARGET_SUN_TLS)
12898 #ifdef HAVE_AS_IX86_TLSLDMPLT
12899 return "call\t%&@tlsldmplt";
12901 return "call\t%p2@plt";
12903 return "call\t%P2";
12905 [(set_attr "type" "multi")
12906 (set_attr "length" "11")])
12908 (define_expand "tls_local_dynamic_base_32"
12910 [(set (match_operand:SI 0 "register_operand")
12912 [(match_operand:SI 1 "register_operand")
12913 (match_operand 2 "constant_call_address_operand")]
12914 UNSPEC_TLS_LD_BASE))
12915 (clobber (match_scratch:SI 3))
12916 (clobber (match_scratch:SI 4))
12917 (clobber (reg:CC FLAGS_REG))])])
12919 (define_insn "*tls_local_dynamic_base_64_<mode>"
12920 [(set (match_operand:P 0 "register_operand" "=a")
12922 (mem:QI (match_operand 1 "constant_call_address_operand" "z"))
12923 (match_operand 2)))
12924 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12928 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12929 if (TARGET_SUN_TLS)
12930 return "call\t%p1@plt";
12931 return "call\t%P1";
12933 [(set_attr "type" "multi")
12934 (set_attr "length" "12")])
12936 (define_expand "tls_local_dynamic_base_64_<mode>"
12938 [(set (match_operand:P 0 "register_operand")
12940 (mem:QI (match_operand 1 "constant_call_address_operand"))
12942 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12945 ;; Local dynamic of a single variable is a lose. Show combine how
12946 ;; to convert that back to global dynamic.
12948 (define_insn_and_split "*tls_local_dynamic_32_once"
12949 [(set (match_operand:SI 0 "register_operand" "=a")
12951 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12952 (match_operand 2 "constant_call_address_operand" "z")]
12953 UNSPEC_TLS_LD_BASE)
12954 (const:SI (unspec:SI
12955 [(match_operand 3 "tls_symbolic_operand")]
12957 (clobber (match_scratch:SI 4 "=d"))
12958 (clobber (match_scratch:SI 5 "=c"))
12959 (clobber (reg:CC FLAGS_REG))]
12964 [(set (match_dup 0)
12965 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12967 (clobber (match_dup 4))
12968 (clobber (match_dup 5))
12969 (clobber (reg:CC FLAGS_REG))])])
12971 ;; Segment register for the thread base ptr load
12972 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12974 ;; Load and add the thread base pointer from %<tp_seg>:0.
12975 (define_insn "*load_tp_x32"
12976 [(set (match_operand:SI 0 "register_operand" "=r")
12977 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12979 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12980 [(set_attr "type" "imov")
12981 (set_attr "modrm" "0")
12982 (set_attr "length" "7")
12983 (set_attr "memory" "load")
12984 (set_attr "imm_disp" "false")])
12986 (define_insn "*load_tp_x32_zext"
12987 [(set (match_operand:DI 0 "register_operand" "=r")
12988 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12990 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12991 [(set_attr "type" "imov")
12992 (set_attr "modrm" "0")
12993 (set_attr "length" "7")
12994 (set_attr "memory" "load")
12995 (set_attr "imm_disp" "false")])
12997 (define_insn "*load_tp_<mode>"
12998 [(set (match_operand:P 0 "register_operand" "=r")
12999 (unspec:P [(const_int 0)] UNSPEC_TP))]
13001 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13002 [(set_attr "type" "imov")
13003 (set_attr "modrm" "0")
13004 (set_attr "length" "7")
13005 (set_attr "memory" "load")
13006 (set_attr "imm_disp" "false")])
13008 (define_insn "*add_tp_x32"
13009 [(set (match_operand:SI 0 "register_operand" "=r")
13010 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13011 (match_operand:SI 1 "register_operand" "0")))
13012 (clobber (reg:CC FLAGS_REG))]
13014 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13015 [(set_attr "type" "alu")
13016 (set_attr "modrm" "0")
13017 (set_attr "length" "7")
13018 (set_attr "memory" "load")
13019 (set_attr "imm_disp" "false")])
13021 (define_insn "*add_tp_x32_zext"
13022 [(set (match_operand:DI 0 "register_operand" "=r")
13024 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13025 (match_operand:SI 1 "register_operand" "0"))))
13026 (clobber (reg:CC FLAGS_REG))]
13028 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13029 [(set_attr "type" "alu")
13030 (set_attr "modrm" "0")
13031 (set_attr "length" "7")
13032 (set_attr "memory" "load")
13033 (set_attr "imm_disp" "false")])
13035 (define_insn "*add_tp_<mode>"
13036 [(set (match_operand:P 0 "register_operand" "=r")
13037 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
13038 (match_operand:P 1 "register_operand" "0")))
13039 (clobber (reg:CC FLAGS_REG))]
13041 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13042 [(set_attr "type" "alu")
13043 (set_attr "modrm" "0")
13044 (set_attr "length" "7")
13045 (set_attr "memory" "load")
13046 (set_attr "imm_disp" "false")])
13048 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
13049 ;; %rax as destination of the initial executable code sequence.
13050 (define_insn "tls_initial_exec_64_sun"
13051 [(set (match_operand:DI 0 "register_operand" "=a")
13053 [(match_operand 1 "tls_symbolic_operand")]
13054 UNSPEC_TLS_IE_SUN))
13055 (clobber (reg:CC FLAGS_REG))]
13056 "TARGET_64BIT && TARGET_SUN_TLS"
13059 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
13060 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
13062 [(set_attr "type" "multi")])
13064 ;; GNU2 TLS patterns can be split.
13066 (define_expand "tls_dynamic_gnu2_32"
13067 [(set (match_dup 3)
13068 (plus:SI (match_operand:SI 2 "register_operand")
13070 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
13073 [(set (match_operand:SI 0 "register_operand")
13074 (unspec:SI [(match_dup 1) (match_dup 3)
13075 (match_dup 2) (reg:SI SP_REG)]
13077 (clobber (reg:CC FLAGS_REG))])]
13078 "!TARGET_64BIT && TARGET_GNU2_TLS"
13080 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13081 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13084 (define_insn "*tls_dynamic_gnu2_lea_32"
13085 [(set (match_operand:SI 0 "register_operand" "=r")
13086 (plus:SI (match_operand:SI 1 "register_operand" "b")
13088 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
13089 UNSPEC_TLSDESC))))]
13090 "!TARGET_64BIT && TARGET_GNU2_TLS"
13091 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
13092 [(set_attr "type" "lea")
13093 (set_attr "mode" "SI")
13094 (set_attr "length" "6")
13095 (set_attr "length_address" "4")])
13097 (define_insn "*tls_dynamic_gnu2_call_32"
13098 [(set (match_operand:SI 0 "register_operand" "=a")
13099 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
13100 (match_operand:SI 2 "register_operand" "0")
13101 ;; we have to make sure %ebx still points to the GOT
13102 (match_operand:SI 3 "register_operand" "b")
13105 (clobber (reg:CC FLAGS_REG))]
13106 "!TARGET_64BIT && TARGET_GNU2_TLS"
13107 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13108 [(set_attr "type" "call")
13109 (set_attr "length" "2")
13110 (set_attr "length_address" "0")])
13112 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13113 [(set (match_operand:SI 0 "register_operand" "=&a")
13115 (unspec:SI [(match_operand 3 "tls_modbase_operand")
13116 (match_operand:SI 4)
13117 (match_operand:SI 2 "register_operand" "b")
13120 (const:SI (unspec:SI
13121 [(match_operand 1 "tls_symbolic_operand")]
13123 (clobber (reg:CC FLAGS_REG))]
13124 "!TARGET_64BIT && TARGET_GNU2_TLS"
13127 [(set (match_dup 0) (match_dup 5))]
13129 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13130 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13133 (define_expand "tls_dynamic_gnu2_64"
13134 [(set (match_dup 2)
13135 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13138 [(set (match_operand:DI 0 "register_operand")
13139 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13141 (clobber (reg:CC FLAGS_REG))])]
13142 "TARGET_64BIT && TARGET_GNU2_TLS"
13144 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13145 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13148 (define_insn "*tls_dynamic_gnu2_lea_64"
13149 [(set (match_operand:DI 0 "register_operand" "=r")
13150 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13152 "TARGET_64BIT && TARGET_GNU2_TLS"
13153 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13154 [(set_attr "type" "lea")
13155 (set_attr "mode" "DI")
13156 (set_attr "length" "7")
13157 (set_attr "length_address" "4")])
13159 (define_insn "*tls_dynamic_gnu2_call_64"
13160 [(set (match_operand:DI 0 "register_operand" "=a")
13161 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13162 (match_operand:DI 2 "register_operand" "0")
13165 (clobber (reg:CC FLAGS_REG))]
13166 "TARGET_64BIT && TARGET_GNU2_TLS"
13167 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13168 [(set_attr "type" "call")
13169 (set_attr "length" "2")
13170 (set_attr "length_address" "0")])
13172 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13173 [(set (match_operand:DI 0 "register_operand" "=&a")
13175 (unspec:DI [(match_operand 2 "tls_modbase_operand")
13176 (match_operand:DI 3)
13179 (const:DI (unspec:DI
13180 [(match_operand 1 "tls_symbolic_operand")]
13182 (clobber (reg:CC FLAGS_REG))]
13183 "TARGET_64BIT && TARGET_GNU2_TLS"
13186 [(set (match_dup 0) (match_dup 4))]
13188 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13189 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13192 ;; These patterns match the binary 387 instructions for addM3, subM3,
13193 ;; mulM3 and divM3. There are three patterns for each of DFmode and
13194 ;; SFmode. The first is the normal insn, the second the same insn but
13195 ;; with one operand a conversion, and the third the same insn but with
13196 ;; the other operand a conversion. The conversion may be SFmode or
13197 ;; SImode if the target mode DFmode, but only SImode if the target mode
13200 ;; Gcc is slightly more smart about handling normal two address instructions
13201 ;; so use special patterns for add and mull.
13203 (define_insn "*fop_<mode>_comm_mixed"
13204 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
13205 (match_operator:MODEF 3 "binary_fp_operator"
13206 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
13207 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
13208 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13209 && COMMUTATIVE_ARITH_P (operands[3])
13210 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13211 "* return output_387_binary_op (insn, operands);"
13212 [(set (attr "type")
13213 (if_then_else (eq_attr "alternative" "1,2")
13214 (if_then_else (match_operand:MODEF 3 "mult_operator")
13215 (const_string "ssemul")
13216 (const_string "sseadd"))
13217 (if_then_else (match_operand:MODEF 3 "mult_operator")
13218 (const_string "fmul")
13219 (const_string "fop"))))
13220 (set_attr "isa" "*,noavx,avx")
13221 (set_attr "prefix" "orig,orig,vex")
13222 (set_attr "mode" "<MODE>")])
13224 (define_insn "*fop_<mode>_comm_sse"
13225 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13226 (match_operator:MODEF 3 "binary_fp_operator"
13227 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
13228 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13229 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13230 && COMMUTATIVE_ARITH_P (operands[3])
13231 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13232 "* return output_387_binary_op (insn, operands);"
13233 [(set (attr "type")
13234 (if_then_else (match_operand:MODEF 3 "mult_operator")
13235 (const_string "ssemul")
13236 (const_string "sseadd")))
13237 (set_attr "isa" "noavx,avx")
13238 (set_attr "prefix" "orig,vex")
13239 (set_attr "mode" "<MODE>")])
13241 (define_insn "*fop_<mode>_comm_i387"
13242 [(set (match_operand:MODEF 0 "register_operand" "=f")
13243 (match_operator:MODEF 3 "binary_fp_operator"
13244 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13245 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13246 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13247 && COMMUTATIVE_ARITH_P (operands[3])
13248 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13249 "* return output_387_binary_op (insn, operands);"
13250 [(set (attr "type")
13251 (if_then_else (match_operand:MODEF 3 "mult_operator")
13252 (const_string "fmul")
13253 (const_string "fop")))
13254 (set_attr "mode" "<MODE>")])
13256 (define_insn "*fop_<mode>_1_mixed"
13257 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13258 (match_operator:MODEF 3 "binary_fp_operator"
13259 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13260 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13261 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13262 && !COMMUTATIVE_ARITH_P (operands[3])
13263 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13264 "* return output_387_binary_op (insn, operands);"
13265 [(set (attr "type")
13266 (cond [(and (eq_attr "alternative" "2,3")
13267 (match_operand:MODEF 3 "mult_operator"))
13268 (const_string "ssemul")
13269 (and (eq_attr "alternative" "2,3")
13270 (match_operand:MODEF 3 "div_operator"))
13271 (const_string "ssediv")
13272 (eq_attr "alternative" "2,3")
13273 (const_string "sseadd")
13274 (match_operand:MODEF 3 "mult_operator")
13275 (const_string "fmul")
13276 (match_operand:MODEF 3 "div_operator")
13277 (const_string "fdiv")
13279 (const_string "fop")))
13280 (set_attr "isa" "*,*,noavx,avx")
13281 (set_attr "prefix" "orig,orig,orig,vex")
13282 (set_attr "mode" "<MODE>")])
13284 (define_insn "*rcpsf2_sse"
13285 [(set (match_operand:SF 0 "register_operand" "=x")
13286 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13289 "%vrcpss\t{%1, %d0|%d0, %1}"
13290 [(set_attr "type" "sse")
13291 (set_attr "atom_sse_attr" "rcp")
13292 (set_attr "prefix" "maybe_vex")
13293 (set_attr "mode" "SF")])
13295 (define_insn "*fop_<mode>_1_sse"
13296 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13297 (match_operator:MODEF 3 "binary_fp_operator"
13298 [(match_operand:MODEF 1 "register_operand" "0,x")
13299 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13300 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13301 && !COMMUTATIVE_ARITH_P (operands[3])"
13302 "* return output_387_binary_op (insn, operands);"
13303 [(set (attr "type")
13304 (cond [(match_operand:MODEF 3 "mult_operator")
13305 (const_string "ssemul")
13306 (match_operand:MODEF 3 "div_operator")
13307 (const_string "ssediv")
13309 (const_string "sseadd")))
13310 (set_attr "isa" "noavx,avx")
13311 (set_attr "prefix" "orig,vex")
13312 (set_attr "mode" "<MODE>")])
13314 ;; This pattern is not fully shadowed by the pattern above.
13315 (define_insn "*fop_<mode>_1_i387"
13316 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13317 (match_operator:MODEF 3 "binary_fp_operator"
13318 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13319 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13320 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13321 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13322 && !COMMUTATIVE_ARITH_P (operands[3])
13323 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13324 "* return output_387_binary_op (insn, operands);"
13325 [(set (attr "type")
13326 (cond [(match_operand:MODEF 3 "mult_operator")
13327 (const_string "fmul")
13328 (match_operand:MODEF 3 "div_operator")
13329 (const_string "fdiv")
13331 (const_string "fop")))
13332 (set_attr "mode" "<MODE>")])
13334 ;; ??? Add SSE splitters for these!
13335 (define_insn "*fop_<MODEF:mode>_2_i387"
13336 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13337 (match_operator:MODEF 3 "binary_fp_operator"
13339 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13340 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13341 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13342 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13343 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13344 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13345 [(set (attr "type")
13346 (cond [(match_operand:MODEF 3 "mult_operator")
13347 (const_string "fmul")
13348 (match_operand:MODEF 3 "div_operator")
13349 (const_string "fdiv")
13351 (const_string "fop")))
13352 (set_attr "fp_int_src" "true")
13353 (set_attr "mode" "<SWI24:MODE>")])
13355 (define_insn "*fop_<MODEF:mode>_3_i387"
13356 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13357 (match_operator:MODEF 3 "binary_fp_operator"
13358 [(match_operand:MODEF 1 "register_operand" "0,0")
13360 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13361 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13362 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13363 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13364 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13365 [(set (attr "type")
13366 (cond [(match_operand:MODEF 3 "mult_operator")
13367 (const_string "fmul")
13368 (match_operand:MODEF 3 "div_operator")
13369 (const_string "fdiv")
13371 (const_string "fop")))
13372 (set_attr "fp_int_src" "true")
13373 (set_attr "mode" "<MODE>")])
13375 (define_insn "*fop_df_4_i387"
13376 [(set (match_operand:DF 0 "register_operand" "=f,f")
13377 (match_operator:DF 3 "binary_fp_operator"
13379 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13380 (match_operand:DF 2 "register_operand" "0,f")]))]
13381 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13382 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13383 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13384 "* return output_387_binary_op (insn, operands);"
13385 [(set (attr "type")
13386 (cond [(match_operand:DF 3 "mult_operator")
13387 (const_string "fmul")
13388 (match_operand:DF 3 "div_operator")
13389 (const_string "fdiv")
13391 (const_string "fop")))
13392 (set_attr "mode" "SF")])
13394 (define_insn "*fop_df_5_i387"
13395 [(set (match_operand:DF 0 "register_operand" "=f,f")
13396 (match_operator:DF 3 "binary_fp_operator"
13397 [(match_operand:DF 1 "register_operand" "0,f")
13399 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13400 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13401 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13402 "* return output_387_binary_op (insn, operands);"
13403 [(set (attr "type")
13404 (cond [(match_operand:DF 3 "mult_operator")
13405 (const_string "fmul")
13406 (match_operand:DF 3 "div_operator")
13407 (const_string "fdiv")
13409 (const_string "fop")))
13410 (set_attr "mode" "SF")])
13412 (define_insn "*fop_df_6_i387"
13413 [(set (match_operand:DF 0 "register_operand" "=f,f")
13414 (match_operator:DF 3 "binary_fp_operator"
13416 (match_operand:SF 1 "register_operand" "0,f"))
13418 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13419 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13420 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13421 "* return output_387_binary_op (insn, operands);"
13422 [(set (attr "type")
13423 (cond [(match_operand:DF 3 "mult_operator")
13424 (const_string "fmul")
13425 (match_operand:DF 3 "div_operator")
13426 (const_string "fdiv")
13428 (const_string "fop")))
13429 (set_attr "mode" "SF")])
13431 (define_insn "*fop_xf_comm_i387"
13432 [(set (match_operand:XF 0 "register_operand" "=f")
13433 (match_operator:XF 3 "binary_fp_operator"
13434 [(match_operand:XF 1 "register_operand" "%0")
13435 (match_operand:XF 2 "register_operand" "f")]))]
13437 && COMMUTATIVE_ARITH_P (operands[3])"
13438 "* return output_387_binary_op (insn, operands);"
13439 [(set (attr "type")
13440 (if_then_else (match_operand:XF 3 "mult_operator")
13441 (const_string "fmul")
13442 (const_string "fop")))
13443 (set_attr "mode" "XF")])
13445 (define_insn "*fop_xf_1_i387"
13446 [(set (match_operand:XF 0 "register_operand" "=f,f")
13447 (match_operator:XF 3 "binary_fp_operator"
13448 [(match_operand:XF 1 "register_operand" "0,f")
13449 (match_operand:XF 2 "register_operand" "f,0")]))]
13451 && !COMMUTATIVE_ARITH_P (operands[3])"
13452 "* return output_387_binary_op (insn, operands);"
13453 [(set (attr "type")
13454 (cond [(match_operand:XF 3 "mult_operator")
13455 (const_string "fmul")
13456 (match_operand:XF 3 "div_operator")
13457 (const_string "fdiv")
13459 (const_string "fop")))
13460 (set_attr "mode" "XF")])
13462 (define_insn "*fop_xf_2_i387"
13463 [(set (match_operand:XF 0 "register_operand" "=f,f")
13464 (match_operator:XF 3 "binary_fp_operator"
13466 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13467 (match_operand:XF 2 "register_operand" "0,0")]))]
13468 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13469 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13470 [(set (attr "type")
13471 (cond [(match_operand:XF 3 "mult_operator")
13472 (const_string "fmul")
13473 (match_operand:XF 3 "div_operator")
13474 (const_string "fdiv")
13476 (const_string "fop")))
13477 (set_attr "fp_int_src" "true")
13478 (set_attr "mode" "<MODE>")])
13480 (define_insn "*fop_xf_3_i387"
13481 [(set (match_operand:XF 0 "register_operand" "=f,f")
13482 (match_operator:XF 3 "binary_fp_operator"
13483 [(match_operand:XF 1 "register_operand" "0,0")
13485 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13486 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13487 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13488 [(set (attr "type")
13489 (cond [(match_operand:XF 3 "mult_operator")
13490 (const_string "fmul")
13491 (match_operand:XF 3 "div_operator")
13492 (const_string "fdiv")
13494 (const_string "fop")))
13495 (set_attr "fp_int_src" "true")
13496 (set_attr "mode" "<MODE>")])
13498 (define_insn "*fop_xf_4_i387"
13499 [(set (match_operand:XF 0 "register_operand" "=f,f")
13500 (match_operator:XF 3 "binary_fp_operator"
13502 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13503 (match_operand:XF 2 "register_operand" "0,f")]))]
13505 "* return output_387_binary_op (insn, operands);"
13506 [(set (attr "type")
13507 (cond [(match_operand:XF 3 "mult_operator")
13508 (const_string "fmul")
13509 (match_operand:XF 3 "div_operator")
13510 (const_string "fdiv")
13512 (const_string "fop")))
13513 (set_attr "mode" "<MODE>")])
13515 (define_insn "*fop_xf_5_i387"
13516 [(set (match_operand:XF 0 "register_operand" "=f,f")
13517 (match_operator:XF 3 "binary_fp_operator"
13518 [(match_operand:XF 1 "register_operand" "0,f")
13520 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13522 "* return output_387_binary_op (insn, operands);"
13523 [(set (attr "type")
13524 (cond [(match_operand:XF 3 "mult_operator")
13525 (const_string "fmul")
13526 (match_operand:XF 3 "div_operator")
13527 (const_string "fdiv")
13529 (const_string "fop")))
13530 (set_attr "mode" "<MODE>")])
13532 (define_insn "*fop_xf_6_i387"
13533 [(set (match_operand:XF 0 "register_operand" "=f,f")
13534 (match_operator:XF 3 "binary_fp_operator"
13536 (match_operand:MODEF 1 "register_operand" "0,f"))
13538 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13540 "* return output_387_binary_op (insn, operands);"
13541 [(set (attr "type")
13542 (cond [(match_operand:XF 3 "mult_operator")
13543 (const_string "fmul")
13544 (match_operand:XF 3 "div_operator")
13545 (const_string "fdiv")
13547 (const_string "fop")))
13548 (set_attr "mode" "<MODE>")])
13551 [(set (match_operand 0 "register_operand")
13552 (match_operator 3 "binary_fp_operator"
13553 [(float (match_operand:SWI24 1 "register_operand"))
13554 (match_operand 2 "register_operand")]))]
13556 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13557 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13560 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13561 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13562 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13563 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13564 GET_MODE (operands[3]),
13567 ix86_free_from_memory (GET_MODE (operands[1]));
13572 [(set (match_operand 0 "register_operand")
13573 (match_operator 3 "binary_fp_operator"
13574 [(match_operand 1 "register_operand")
13575 (float (match_operand:SWI24 2 "register_operand"))]))]
13577 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13578 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13581 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13582 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13583 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13584 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13585 GET_MODE (operands[3]),
13588 ix86_free_from_memory (GET_MODE (operands[2]));
13592 ;; FPU special functions.
13594 ;; This pattern implements a no-op XFmode truncation for
13595 ;; all fancy i386 XFmode math functions.
13597 (define_insn "truncxf<mode>2_i387_noop_unspec"
13598 [(set (match_operand:MODEF 0 "register_operand" "=f")
13599 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13600 UNSPEC_TRUNC_NOOP))]
13601 "TARGET_USE_FANCY_MATH_387"
13602 "* return output_387_reg_move (insn, operands);"
13603 [(set_attr "type" "fmov")
13604 (set_attr "mode" "<MODE>")])
13606 (define_insn "sqrtxf2"
13607 [(set (match_operand:XF 0 "register_operand" "=f")
13608 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13609 "TARGET_USE_FANCY_MATH_387"
13611 [(set_attr "type" "fpspc")
13612 (set_attr "mode" "XF")
13613 (set_attr "athlon_decode" "direct")
13614 (set_attr "amdfam10_decode" "direct")
13615 (set_attr "bdver1_decode" "direct")])
13617 (define_insn "sqrt_extend<mode>xf2_i387"
13618 [(set (match_operand:XF 0 "register_operand" "=f")
13621 (match_operand:MODEF 1 "register_operand" "0"))))]
13622 "TARGET_USE_FANCY_MATH_387"
13624 [(set_attr "type" "fpspc")
13625 (set_attr "mode" "XF")
13626 (set_attr "athlon_decode" "direct")
13627 (set_attr "amdfam10_decode" "direct")
13628 (set_attr "bdver1_decode" "direct")])
13630 (define_insn "*rsqrtsf2_sse"
13631 [(set (match_operand:SF 0 "register_operand" "=x")
13632 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13635 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13636 [(set_attr "type" "sse")
13637 (set_attr "atom_sse_attr" "rcp")
13638 (set_attr "prefix" "maybe_vex")
13639 (set_attr "mode" "SF")])
13641 (define_expand "rsqrtsf2"
13642 [(set (match_operand:SF 0 "register_operand")
13643 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
13647 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13651 (define_insn "*sqrt<mode>2_sse"
13652 [(set (match_operand:MODEF 0 "register_operand" "=x")
13654 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13655 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13656 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13657 [(set_attr "type" "sse")
13658 (set_attr "atom_sse_attr" "sqrt")
13659 (set_attr "prefix" "maybe_vex")
13660 (set_attr "mode" "<MODE>")
13661 (set_attr "athlon_decode" "*")
13662 (set_attr "amdfam10_decode" "*")
13663 (set_attr "bdver1_decode" "*")])
13665 (define_expand "sqrt<mode>2"
13666 [(set (match_operand:MODEF 0 "register_operand")
13668 (match_operand:MODEF 1 "nonimmediate_operand")))]
13669 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13670 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13672 if (<MODE>mode == SFmode
13674 && TARGET_RECIP_SQRT
13675 && !optimize_function_for_size_p (cfun)
13676 && flag_finite_math_only && !flag_trapping_math
13677 && flag_unsafe_math_optimizations)
13679 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13683 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13685 rtx op0 = gen_reg_rtx (XFmode);
13686 rtx op1 = force_reg (<MODE>mode, operands[1]);
13688 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13689 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13694 (define_insn "fpremxf4_i387"
13695 [(set (match_operand:XF 0 "register_operand" "=f")
13696 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13697 (match_operand:XF 3 "register_operand" "1")]
13699 (set (match_operand:XF 1 "register_operand" "=u")
13700 (unspec:XF [(match_dup 2) (match_dup 3)]
13702 (set (reg:CCFP FPSR_REG)
13703 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13705 "TARGET_USE_FANCY_MATH_387"
13707 [(set_attr "type" "fpspc")
13708 (set_attr "mode" "XF")])
13710 (define_expand "fmodxf3"
13711 [(use (match_operand:XF 0 "register_operand"))
13712 (use (match_operand:XF 1 "general_operand"))
13713 (use (match_operand:XF 2 "general_operand"))]
13714 "TARGET_USE_FANCY_MATH_387"
13716 rtx label = gen_label_rtx ();
13718 rtx op1 = gen_reg_rtx (XFmode);
13719 rtx op2 = gen_reg_rtx (XFmode);
13721 emit_move_insn (op2, operands[2]);
13722 emit_move_insn (op1, operands[1]);
13724 emit_label (label);
13725 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13726 ix86_emit_fp_unordered_jump (label);
13727 LABEL_NUSES (label) = 1;
13729 emit_move_insn (operands[0], op1);
13733 (define_expand "fmod<mode>3"
13734 [(use (match_operand:MODEF 0 "register_operand"))
13735 (use (match_operand:MODEF 1 "general_operand"))
13736 (use (match_operand:MODEF 2 "general_operand"))]
13737 "TARGET_USE_FANCY_MATH_387"
13739 rtx (*gen_truncxf) (rtx, rtx);
13741 rtx label = gen_label_rtx ();
13743 rtx op1 = gen_reg_rtx (XFmode);
13744 rtx op2 = gen_reg_rtx (XFmode);
13746 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13747 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13749 emit_label (label);
13750 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13751 ix86_emit_fp_unordered_jump (label);
13752 LABEL_NUSES (label) = 1;
13754 /* Truncate the result properly for strict SSE math. */
13755 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13756 && !TARGET_MIX_SSE_I387)
13757 gen_truncxf = gen_truncxf<mode>2;
13759 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13761 emit_insn (gen_truncxf (operands[0], op1));
13765 (define_insn "fprem1xf4_i387"
13766 [(set (match_operand:XF 0 "register_operand" "=f")
13767 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13768 (match_operand:XF 3 "register_operand" "1")]
13770 (set (match_operand:XF 1 "register_operand" "=u")
13771 (unspec:XF [(match_dup 2) (match_dup 3)]
13773 (set (reg:CCFP FPSR_REG)
13774 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13776 "TARGET_USE_FANCY_MATH_387"
13778 [(set_attr "type" "fpspc")
13779 (set_attr "mode" "XF")])
13781 (define_expand "remainderxf3"
13782 [(use (match_operand:XF 0 "register_operand"))
13783 (use (match_operand:XF 1 "general_operand"))
13784 (use (match_operand:XF 2 "general_operand"))]
13785 "TARGET_USE_FANCY_MATH_387"
13787 rtx label = gen_label_rtx ();
13789 rtx op1 = gen_reg_rtx (XFmode);
13790 rtx op2 = gen_reg_rtx (XFmode);
13792 emit_move_insn (op2, operands[2]);
13793 emit_move_insn (op1, operands[1]);
13795 emit_label (label);
13796 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13797 ix86_emit_fp_unordered_jump (label);
13798 LABEL_NUSES (label) = 1;
13800 emit_move_insn (operands[0], op1);
13804 (define_expand "remainder<mode>3"
13805 [(use (match_operand:MODEF 0 "register_operand"))
13806 (use (match_operand:MODEF 1 "general_operand"))
13807 (use (match_operand:MODEF 2 "general_operand"))]
13808 "TARGET_USE_FANCY_MATH_387"
13810 rtx (*gen_truncxf) (rtx, rtx);
13812 rtx label = gen_label_rtx ();
13814 rtx op1 = gen_reg_rtx (XFmode);
13815 rtx op2 = gen_reg_rtx (XFmode);
13817 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13818 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13820 emit_label (label);
13822 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13823 ix86_emit_fp_unordered_jump (label);
13824 LABEL_NUSES (label) = 1;
13826 /* Truncate the result properly for strict SSE math. */
13827 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13828 && !TARGET_MIX_SSE_I387)
13829 gen_truncxf = gen_truncxf<mode>2;
13831 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13833 emit_insn (gen_truncxf (operands[0], op1));
13837 (define_int_iterator SINCOS
13841 (define_int_attr sincos
13842 [(UNSPEC_SIN "sin")
13843 (UNSPEC_COS "cos")])
13845 (define_insn "*<sincos>xf2_i387"
13846 [(set (match_operand:XF 0 "register_operand" "=f")
13847 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13849 "TARGET_USE_FANCY_MATH_387
13850 && flag_unsafe_math_optimizations"
13852 [(set_attr "type" "fpspc")
13853 (set_attr "mode" "XF")])
13855 (define_insn "*<sincos>_extend<mode>xf2_i387"
13856 [(set (match_operand:XF 0 "register_operand" "=f")
13857 (unspec:XF [(float_extend:XF
13858 (match_operand:MODEF 1 "register_operand" "0"))]
13860 "TARGET_USE_FANCY_MATH_387
13861 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13862 || TARGET_MIX_SSE_I387)
13863 && flag_unsafe_math_optimizations"
13865 [(set_attr "type" "fpspc")
13866 (set_attr "mode" "XF")])
13868 ;; When sincos pattern is defined, sin and cos builtin functions will be
13869 ;; expanded to sincos pattern with one of its outputs left unused.
13870 ;; CSE pass will figure out if two sincos patterns can be combined,
13871 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13872 ;; depending on the unused output.
13874 (define_insn "sincosxf3"
13875 [(set (match_operand:XF 0 "register_operand" "=f")
13876 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13877 UNSPEC_SINCOS_COS))
13878 (set (match_operand:XF 1 "register_operand" "=u")
13879 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13880 "TARGET_USE_FANCY_MATH_387
13881 && flag_unsafe_math_optimizations"
13883 [(set_attr "type" "fpspc")
13884 (set_attr "mode" "XF")])
13887 [(set (match_operand:XF 0 "register_operand")
13888 (unspec:XF [(match_operand:XF 2 "register_operand")]
13889 UNSPEC_SINCOS_COS))
13890 (set (match_operand:XF 1 "register_operand")
13891 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13892 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13893 && can_create_pseudo_p ()"
13894 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13897 [(set (match_operand:XF 0 "register_operand")
13898 (unspec:XF [(match_operand:XF 2 "register_operand")]
13899 UNSPEC_SINCOS_COS))
13900 (set (match_operand:XF 1 "register_operand")
13901 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13902 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13903 && can_create_pseudo_p ()"
13904 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13906 (define_insn "sincos_extend<mode>xf3_i387"
13907 [(set (match_operand:XF 0 "register_operand" "=f")
13908 (unspec:XF [(float_extend:XF
13909 (match_operand:MODEF 2 "register_operand" "0"))]
13910 UNSPEC_SINCOS_COS))
13911 (set (match_operand:XF 1 "register_operand" "=u")
13912 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
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")])
13922 [(set (match_operand:XF 0 "register_operand")
13923 (unspec:XF [(float_extend:XF
13924 (match_operand:MODEF 2 "register_operand"))]
13925 UNSPEC_SINCOS_COS))
13926 (set (match_operand:XF 1 "register_operand")
13927 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13928 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13929 && can_create_pseudo_p ()"
13930 [(set (match_dup 1)
13931 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13934 [(set (match_operand:XF 0 "register_operand")
13935 (unspec:XF [(float_extend:XF
13936 (match_operand:MODEF 2 "register_operand"))]
13937 UNSPEC_SINCOS_COS))
13938 (set (match_operand:XF 1 "register_operand")
13939 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13940 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13941 && can_create_pseudo_p ()"
13942 [(set (match_dup 0)
13943 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13945 (define_expand "sincos<mode>3"
13946 [(use (match_operand:MODEF 0 "register_operand"))
13947 (use (match_operand:MODEF 1 "register_operand"))
13948 (use (match_operand:MODEF 2 "register_operand"))]
13949 "TARGET_USE_FANCY_MATH_387
13950 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13951 || TARGET_MIX_SSE_I387)
13952 && flag_unsafe_math_optimizations"
13954 rtx op0 = gen_reg_rtx (XFmode);
13955 rtx op1 = gen_reg_rtx (XFmode);
13957 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13958 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13959 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13963 (define_insn "fptanxf4_i387"
13964 [(set (match_operand:XF 0 "register_operand" "=f")
13965 (match_operand:XF 3 "const_double_operand" "F"))
13966 (set (match_operand:XF 1 "register_operand" "=u")
13967 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13969 "TARGET_USE_FANCY_MATH_387
13970 && flag_unsafe_math_optimizations
13971 && standard_80387_constant_p (operands[3]) == 2"
13973 [(set_attr "type" "fpspc")
13974 (set_attr "mode" "XF")])
13976 (define_insn "fptan_extend<mode>xf4_i387"
13977 [(set (match_operand:MODEF 0 "register_operand" "=f")
13978 (match_operand:MODEF 3 "const_double_operand" "F"))
13979 (set (match_operand:XF 1 "register_operand" "=u")
13980 (unspec:XF [(float_extend:XF
13981 (match_operand:MODEF 2 "register_operand" "0"))]
13983 "TARGET_USE_FANCY_MATH_387
13984 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13985 || TARGET_MIX_SSE_I387)
13986 && flag_unsafe_math_optimizations
13987 && standard_80387_constant_p (operands[3]) == 2"
13989 [(set_attr "type" "fpspc")
13990 (set_attr "mode" "XF")])
13992 (define_expand "tanxf2"
13993 [(use (match_operand:XF 0 "register_operand"))
13994 (use (match_operand:XF 1 "register_operand"))]
13995 "TARGET_USE_FANCY_MATH_387
13996 && flag_unsafe_math_optimizations"
13998 rtx one = gen_reg_rtx (XFmode);
13999 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14001 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14005 (define_expand "tan<mode>2"
14006 [(use (match_operand:MODEF 0 "register_operand"))
14007 (use (match_operand:MODEF 1 "register_operand"))]
14008 "TARGET_USE_FANCY_MATH_387
14009 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14010 || TARGET_MIX_SSE_I387)
14011 && flag_unsafe_math_optimizations"
14013 rtx op0 = gen_reg_rtx (XFmode);
14015 rtx one = gen_reg_rtx (<MODE>mode);
14016 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14018 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14019 operands[1], op2));
14020 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14024 (define_insn "*fpatanxf3_i387"
14025 [(set (match_operand:XF 0 "register_operand" "=f")
14026 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14027 (match_operand:XF 2 "register_operand" "u")]
14029 (clobber (match_scratch:XF 3 "=2"))]
14030 "TARGET_USE_FANCY_MATH_387
14031 && flag_unsafe_math_optimizations"
14033 [(set_attr "type" "fpspc")
14034 (set_attr "mode" "XF")])
14036 (define_insn "fpatan_extend<mode>xf3_i387"
14037 [(set (match_operand:XF 0 "register_operand" "=f")
14038 (unspec:XF [(float_extend:XF
14039 (match_operand:MODEF 1 "register_operand" "0"))
14041 (match_operand:MODEF 2 "register_operand" "u"))]
14043 (clobber (match_scratch:XF 3 "=2"))]
14044 "TARGET_USE_FANCY_MATH_387
14045 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14046 || TARGET_MIX_SSE_I387)
14047 && flag_unsafe_math_optimizations"
14049 [(set_attr "type" "fpspc")
14050 (set_attr "mode" "XF")])
14052 (define_expand "atan2xf3"
14053 [(parallel [(set (match_operand:XF 0 "register_operand")
14054 (unspec:XF [(match_operand:XF 2 "register_operand")
14055 (match_operand:XF 1 "register_operand")]
14057 (clobber (match_scratch:XF 3))])]
14058 "TARGET_USE_FANCY_MATH_387
14059 && flag_unsafe_math_optimizations")
14061 (define_expand "atan2<mode>3"
14062 [(use (match_operand:MODEF 0 "register_operand"))
14063 (use (match_operand:MODEF 1 "register_operand"))
14064 (use (match_operand:MODEF 2 "register_operand"))]
14065 "TARGET_USE_FANCY_MATH_387
14066 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14067 || TARGET_MIX_SSE_I387)
14068 && flag_unsafe_math_optimizations"
14070 rtx op0 = gen_reg_rtx (XFmode);
14072 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14073 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14077 (define_expand "atanxf2"
14078 [(parallel [(set (match_operand:XF 0 "register_operand")
14079 (unspec:XF [(match_dup 2)
14080 (match_operand:XF 1 "register_operand")]
14082 (clobber (match_scratch:XF 3))])]
14083 "TARGET_USE_FANCY_MATH_387
14084 && flag_unsafe_math_optimizations"
14086 operands[2] = gen_reg_rtx (XFmode);
14087 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14090 (define_expand "atan<mode>2"
14091 [(use (match_operand:MODEF 0 "register_operand"))
14092 (use (match_operand:MODEF 1 "register_operand"))]
14093 "TARGET_USE_FANCY_MATH_387
14094 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14095 || TARGET_MIX_SSE_I387)
14096 && flag_unsafe_math_optimizations"
14098 rtx op0 = gen_reg_rtx (XFmode);
14100 rtx op2 = gen_reg_rtx (<MODE>mode);
14101 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
14103 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14104 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14108 (define_expand "asinxf2"
14109 [(set (match_dup 2)
14110 (mult:XF (match_operand:XF 1 "register_operand")
14112 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14113 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14114 (parallel [(set (match_operand:XF 0 "register_operand")
14115 (unspec:XF [(match_dup 5) (match_dup 1)]
14117 (clobber (match_scratch:XF 6))])]
14118 "TARGET_USE_FANCY_MATH_387
14119 && flag_unsafe_math_optimizations"
14123 if (optimize_insn_for_size_p ())
14126 for (i = 2; i < 6; i++)
14127 operands[i] = gen_reg_rtx (XFmode);
14129 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14132 (define_expand "asin<mode>2"
14133 [(use (match_operand:MODEF 0 "register_operand"))
14134 (use (match_operand:MODEF 1 "general_operand"))]
14135 "TARGET_USE_FANCY_MATH_387
14136 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14137 || TARGET_MIX_SSE_I387)
14138 && flag_unsafe_math_optimizations"
14140 rtx op0 = gen_reg_rtx (XFmode);
14141 rtx op1 = gen_reg_rtx (XFmode);
14143 if (optimize_insn_for_size_p ())
14146 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14147 emit_insn (gen_asinxf2 (op0, op1));
14148 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14152 (define_expand "acosxf2"
14153 [(set (match_dup 2)
14154 (mult:XF (match_operand:XF 1 "register_operand")
14156 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14157 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14158 (parallel [(set (match_operand:XF 0 "register_operand")
14159 (unspec:XF [(match_dup 1) (match_dup 5)]
14161 (clobber (match_scratch:XF 6))])]
14162 "TARGET_USE_FANCY_MATH_387
14163 && flag_unsafe_math_optimizations"
14167 if (optimize_insn_for_size_p ())
14170 for (i = 2; i < 6; i++)
14171 operands[i] = gen_reg_rtx (XFmode);
14173 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14176 (define_expand "acos<mode>2"
14177 [(use (match_operand:MODEF 0 "register_operand"))
14178 (use (match_operand:MODEF 1 "general_operand"))]
14179 "TARGET_USE_FANCY_MATH_387
14180 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14181 || TARGET_MIX_SSE_I387)
14182 && flag_unsafe_math_optimizations"
14184 rtx op0 = gen_reg_rtx (XFmode);
14185 rtx op1 = gen_reg_rtx (XFmode);
14187 if (optimize_insn_for_size_p ())
14190 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14191 emit_insn (gen_acosxf2 (op0, op1));
14192 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14196 (define_insn "fyl2xxf3_i387"
14197 [(set (match_operand:XF 0 "register_operand" "=f")
14198 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14199 (match_operand:XF 2 "register_operand" "u")]
14201 (clobber (match_scratch:XF 3 "=2"))]
14202 "TARGET_USE_FANCY_MATH_387
14203 && flag_unsafe_math_optimizations"
14205 [(set_attr "type" "fpspc")
14206 (set_attr "mode" "XF")])
14208 (define_insn "fyl2x_extend<mode>xf3_i387"
14209 [(set (match_operand:XF 0 "register_operand" "=f")
14210 (unspec:XF [(float_extend:XF
14211 (match_operand:MODEF 1 "register_operand" "0"))
14212 (match_operand:XF 2 "register_operand" "u")]
14214 (clobber (match_scratch:XF 3 "=2"))]
14215 "TARGET_USE_FANCY_MATH_387
14216 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14217 || TARGET_MIX_SSE_I387)
14218 && flag_unsafe_math_optimizations"
14220 [(set_attr "type" "fpspc")
14221 (set_attr "mode" "XF")])
14223 (define_expand "logxf2"
14224 [(parallel [(set (match_operand:XF 0 "register_operand")
14225 (unspec:XF [(match_operand:XF 1 "register_operand")
14226 (match_dup 2)] UNSPEC_FYL2X))
14227 (clobber (match_scratch:XF 3))])]
14228 "TARGET_USE_FANCY_MATH_387
14229 && flag_unsafe_math_optimizations"
14231 operands[2] = gen_reg_rtx (XFmode);
14232 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14235 (define_expand "log<mode>2"
14236 [(use (match_operand:MODEF 0 "register_operand"))
14237 (use (match_operand:MODEF 1 "register_operand"))]
14238 "TARGET_USE_FANCY_MATH_387
14239 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14240 || TARGET_MIX_SSE_I387)
14241 && flag_unsafe_math_optimizations"
14243 rtx op0 = gen_reg_rtx (XFmode);
14245 rtx op2 = gen_reg_rtx (XFmode);
14246 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14248 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14249 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14253 (define_expand "log10xf2"
14254 [(parallel [(set (match_operand:XF 0 "register_operand")
14255 (unspec:XF [(match_operand:XF 1 "register_operand")
14256 (match_dup 2)] UNSPEC_FYL2X))
14257 (clobber (match_scratch:XF 3))])]
14258 "TARGET_USE_FANCY_MATH_387
14259 && flag_unsafe_math_optimizations"
14261 operands[2] = gen_reg_rtx (XFmode);
14262 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14265 (define_expand "log10<mode>2"
14266 [(use (match_operand:MODEF 0 "register_operand"))
14267 (use (match_operand:MODEF 1 "register_operand"))]
14268 "TARGET_USE_FANCY_MATH_387
14269 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14270 || TARGET_MIX_SSE_I387)
14271 && flag_unsafe_math_optimizations"
14273 rtx op0 = gen_reg_rtx (XFmode);
14275 rtx op2 = gen_reg_rtx (XFmode);
14276 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14278 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14279 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14283 (define_expand "log2xf2"
14284 [(parallel [(set (match_operand:XF 0 "register_operand")
14285 (unspec:XF [(match_operand:XF 1 "register_operand")
14286 (match_dup 2)] UNSPEC_FYL2X))
14287 (clobber (match_scratch:XF 3))])]
14288 "TARGET_USE_FANCY_MATH_387
14289 && flag_unsafe_math_optimizations"
14291 operands[2] = gen_reg_rtx (XFmode);
14292 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14295 (define_expand "log2<mode>2"
14296 [(use (match_operand:MODEF 0 "register_operand"))
14297 (use (match_operand:MODEF 1 "register_operand"))]
14298 "TARGET_USE_FANCY_MATH_387
14299 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14300 || TARGET_MIX_SSE_I387)
14301 && flag_unsafe_math_optimizations"
14303 rtx op0 = gen_reg_rtx (XFmode);
14305 rtx op2 = gen_reg_rtx (XFmode);
14306 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14308 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14309 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14313 (define_insn "fyl2xp1xf3_i387"
14314 [(set (match_operand:XF 0 "register_operand" "=f")
14315 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14316 (match_operand:XF 2 "register_operand" "u")]
14318 (clobber (match_scratch:XF 3 "=2"))]
14319 "TARGET_USE_FANCY_MATH_387
14320 && flag_unsafe_math_optimizations"
14322 [(set_attr "type" "fpspc")
14323 (set_attr "mode" "XF")])
14325 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14326 [(set (match_operand:XF 0 "register_operand" "=f")
14327 (unspec:XF [(float_extend:XF
14328 (match_operand:MODEF 1 "register_operand" "0"))
14329 (match_operand:XF 2 "register_operand" "u")]
14331 (clobber (match_scratch:XF 3 "=2"))]
14332 "TARGET_USE_FANCY_MATH_387
14333 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14334 || TARGET_MIX_SSE_I387)
14335 && flag_unsafe_math_optimizations"
14337 [(set_attr "type" "fpspc")
14338 (set_attr "mode" "XF")])
14340 (define_expand "log1pxf2"
14341 [(use (match_operand:XF 0 "register_operand"))
14342 (use (match_operand:XF 1 "register_operand"))]
14343 "TARGET_USE_FANCY_MATH_387
14344 && flag_unsafe_math_optimizations"
14346 if (optimize_insn_for_size_p ())
14349 ix86_emit_i387_log1p (operands[0], operands[1]);
14353 (define_expand "log1p<mode>2"
14354 [(use (match_operand:MODEF 0 "register_operand"))
14355 (use (match_operand:MODEF 1 "register_operand"))]
14356 "TARGET_USE_FANCY_MATH_387
14357 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14358 || TARGET_MIX_SSE_I387)
14359 && flag_unsafe_math_optimizations"
14363 if (optimize_insn_for_size_p ())
14366 op0 = gen_reg_rtx (XFmode);
14368 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14370 ix86_emit_i387_log1p (op0, operands[1]);
14371 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14375 (define_insn "fxtractxf3_i387"
14376 [(set (match_operand:XF 0 "register_operand" "=f")
14377 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14378 UNSPEC_XTRACT_FRACT))
14379 (set (match_operand:XF 1 "register_operand" "=u")
14380 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14381 "TARGET_USE_FANCY_MATH_387
14382 && flag_unsafe_math_optimizations"
14384 [(set_attr "type" "fpspc")
14385 (set_attr "mode" "XF")])
14387 (define_insn "fxtract_extend<mode>xf3_i387"
14388 [(set (match_operand:XF 0 "register_operand" "=f")
14389 (unspec:XF [(float_extend:XF
14390 (match_operand:MODEF 2 "register_operand" "0"))]
14391 UNSPEC_XTRACT_FRACT))
14392 (set (match_operand:XF 1 "register_operand" "=u")
14393 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14394 "TARGET_USE_FANCY_MATH_387
14395 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14396 || TARGET_MIX_SSE_I387)
14397 && flag_unsafe_math_optimizations"
14399 [(set_attr "type" "fpspc")
14400 (set_attr "mode" "XF")])
14402 (define_expand "logbxf2"
14403 [(parallel [(set (match_dup 2)
14404 (unspec:XF [(match_operand:XF 1 "register_operand")]
14405 UNSPEC_XTRACT_FRACT))
14406 (set (match_operand:XF 0 "register_operand")
14407 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14408 "TARGET_USE_FANCY_MATH_387
14409 && flag_unsafe_math_optimizations"
14410 "operands[2] = gen_reg_rtx (XFmode);")
14412 (define_expand "logb<mode>2"
14413 [(use (match_operand:MODEF 0 "register_operand"))
14414 (use (match_operand:MODEF 1 "register_operand"))]
14415 "TARGET_USE_FANCY_MATH_387
14416 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14417 || TARGET_MIX_SSE_I387)
14418 && flag_unsafe_math_optimizations"
14420 rtx op0 = gen_reg_rtx (XFmode);
14421 rtx op1 = gen_reg_rtx (XFmode);
14423 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14424 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14428 (define_expand "ilogbxf2"
14429 [(use (match_operand:SI 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 op0 = gen_reg_rtx (XFmode);
14440 op1 = gen_reg_rtx (XFmode);
14442 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14443 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14447 (define_expand "ilogb<mode>2"
14448 [(use (match_operand:SI 0 "register_operand"))
14449 (use (match_operand:MODEF 1 "register_operand"))]
14450 "TARGET_USE_FANCY_MATH_387
14451 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14452 || TARGET_MIX_SSE_I387)
14453 && flag_unsafe_math_optimizations"
14457 if (optimize_insn_for_size_p ())
14460 op0 = gen_reg_rtx (XFmode);
14461 op1 = gen_reg_rtx (XFmode);
14463 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14464 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14468 (define_insn "*f2xm1xf2_i387"
14469 [(set (match_operand:XF 0 "register_operand" "=f")
14470 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14472 "TARGET_USE_FANCY_MATH_387
14473 && flag_unsafe_math_optimizations"
14475 [(set_attr "type" "fpspc")
14476 (set_attr "mode" "XF")])
14478 (define_insn "*fscalexf4_i387"
14479 [(set (match_operand:XF 0 "register_operand" "=f")
14480 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14481 (match_operand:XF 3 "register_operand" "1")]
14482 UNSPEC_FSCALE_FRACT))
14483 (set (match_operand:XF 1 "register_operand" "=u")
14484 (unspec:XF [(match_dup 2) (match_dup 3)]
14485 UNSPEC_FSCALE_EXP))]
14486 "TARGET_USE_FANCY_MATH_387
14487 && flag_unsafe_math_optimizations"
14489 [(set_attr "type" "fpspc")
14490 (set_attr "mode" "XF")])
14492 (define_expand "expNcorexf3"
14493 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14494 (match_operand:XF 2 "register_operand")))
14495 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14496 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14497 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14498 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14499 (parallel [(set (match_operand:XF 0 "register_operand")
14500 (unspec:XF [(match_dup 8) (match_dup 4)]
14501 UNSPEC_FSCALE_FRACT))
14503 (unspec:XF [(match_dup 8) (match_dup 4)]
14504 UNSPEC_FSCALE_EXP))])]
14505 "TARGET_USE_FANCY_MATH_387
14506 && flag_unsafe_math_optimizations"
14510 if (optimize_insn_for_size_p ())
14513 for (i = 3; i < 10; i++)
14514 operands[i] = gen_reg_rtx (XFmode);
14516 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14519 (define_expand "expxf2"
14520 [(use (match_operand:XF 0 "register_operand"))
14521 (use (match_operand:XF 1 "register_operand"))]
14522 "TARGET_USE_FANCY_MATH_387
14523 && flag_unsafe_math_optimizations"
14527 if (optimize_insn_for_size_p ())
14530 op2 = gen_reg_rtx (XFmode);
14531 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14533 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14537 (define_expand "exp<mode>2"
14538 [(use (match_operand:MODEF 0 "register_operand"))
14539 (use (match_operand:MODEF 1 "general_operand"))]
14540 "TARGET_USE_FANCY_MATH_387
14541 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14542 || TARGET_MIX_SSE_I387)
14543 && flag_unsafe_math_optimizations"
14547 if (optimize_insn_for_size_p ())
14550 op0 = gen_reg_rtx (XFmode);
14551 op1 = gen_reg_rtx (XFmode);
14553 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14554 emit_insn (gen_expxf2 (op0, op1));
14555 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14559 (define_expand "exp10xf2"
14560 [(use (match_operand:XF 0 "register_operand"))
14561 (use (match_operand:XF 1 "register_operand"))]
14562 "TARGET_USE_FANCY_MATH_387
14563 && flag_unsafe_math_optimizations"
14567 if (optimize_insn_for_size_p ())
14570 op2 = gen_reg_rtx (XFmode);
14571 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14573 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14577 (define_expand "exp10<mode>2"
14578 [(use (match_operand:MODEF 0 "register_operand"))
14579 (use (match_operand:MODEF 1 "general_operand"))]
14580 "TARGET_USE_FANCY_MATH_387
14581 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14582 || TARGET_MIX_SSE_I387)
14583 && flag_unsafe_math_optimizations"
14587 if (optimize_insn_for_size_p ())
14590 op0 = gen_reg_rtx (XFmode);
14591 op1 = gen_reg_rtx (XFmode);
14593 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14594 emit_insn (gen_exp10xf2 (op0, op1));
14595 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14599 (define_expand "exp2xf2"
14600 [(use (match_operand:XF 0 "register_operand"))
14601 (use (match_operand:XF 1 "register_operand"))]
14602 "TARGET_USE_FANCY_MATH_387
14603 && flag_unsafe_math_optimizations"
14607 if (optimize_insn_for_size_p ())
14610 op2 = gen_reg_rtx (XFmode);
14611 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14613 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14617 (define_expand "exp2<mode>2"
14618 [(use (match_operand:MODEF 0 "register_operand"))
14619 (use (match_operand:MODEF 1 "general_operand"))]
14620 "TARGET_USE_FANCY_MATH_387
14621 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14622 || TARGET_MIX_SSE_I387)
14623 && flag_unsafe_math_optimizations"
14627 if (optimize_insn_for_size_p ())
14630 op0 = gen_reg_rtx (XFmode);
14631 op1 = gen_reg_rtx (XFmode);
14633 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14634 emit_insn (gen_exp2xf2 (op0, op1));
14635 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14639 (define_expand "expm1xf2"
14640 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14642 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14643 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14644 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14645 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14646 (parallel [(set (match_dup 7)
14647 (unspec:XF [(match_dup 6) (match_dup 4)]
14648 UNSPEC_FSCALE_FRACT))
14650 (unspec:XF [(match_dup 6) (match_dup 4)]
14651 UNSPEC_FSCALE_EXP))])
14652 (parallel [(set (match_dup 10)
14653 (unspec:XF [(match_dup 9) (match_dup 8)]
14654 UNSPEC_FSCALE_FRACT))
14655 (set (match_dup 11)
14656 (unspec:XF [(match_dup 9) (match_dup 8)]
14657 UNSPEC_FSCALE_EXP))])
14658 (set (match_dup 12) (minus:XF (match_dup 10)
14659 (float_extend:XF (match_dup 13))))
14660 (set (match_operand:XF 0 "register_operand")
14661 (plus:XF (match_dup 12) (match_dup 7)))]
14662 "TARGET_USE_FANCY_MATH_387
14663 && flag_unsafe_math_optimizations"
14667 if (optimize_insn_for_size_p ())
14670 for (i = 2; i < 13; i++)
14671 operands[i] = gen_reg_rtx (XFmode);
14674 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14676 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14679 (define_expand "expm1<mode>2"
14680 [(use (match_operand:MODEF 0 "register_operand"))
14681 (use (match_operand:MODEF 1 "general_operand"))]
14682 "TARGET_USE_FANCY_MATH_387
14683 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14684 || TARGET_MIX_SSE_I387)
14685 && flag_unsafe_math_optimizations"
14689 if (optimize_insn_for_size_p ())
14692 op0 = gen_reg_rtx (XFmode);
14693 op1 = gen_reg_rtx (XFmode);
14695 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14696 emit_insn (gen_expm1xf2 (op0, op1));
14697 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14701 (define_expand "ldexpxf3"
14702 [(set (match_dup 3)
14703 (float:XF (match_operand:SI 2 "register_operand")))
14704 (parallel [(set (match_operand:XF 0 " register_operand")
14705 (unspec:XF [(match_operand:XF 1 "register_operand")
14707 UNSPEC_FSCALE_FRACT))
14709 (unspec:XF [(match_dup 1) (match_dup 3)]
14710 UNSPEC_FSCALE_EXP))])]
14711 "TARGET_USE_FANCY_MATH_387
14712 && flag_unsafe_math_optimizations"
14714 if (optimize_insn_for_size_p ())
14717 operands[3] = gen_reg_rtx (XFmode);
14718 operands[4] = gen_reg_rtx (XFmode);
14721 (define_expand "ldexp<mode>3"
14722 [(use (match_operand:MODEF 0 "register_operand"))
14723 (use (match_operand:MODEF 1 "general_operand"))
14724 (use (match_operand:SI 2 "register_operand"))]
14725 "TARGET_USE_FANCY_MATH_387
14726 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14727 || TARGET_MIX_SSE_I387)
14728 && flag_unsafe_math_optimizations"
14732 if (optimize_insn_for_size_p ())
14735 op0 = gen_reg_rtx (XFmode);
14736 op1 = gen_reg_rtx (XFmode);
14738 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14739 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14740 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14744 (define_expand "scalbxf3"
14745 [(parallel [(set (match_operand:XF 0 " register_operand")
14746 (unspec:XF [(match_operand:XF 1 "register_operand")
14747 (match_operand:XF 2 "register_operand")]
14748 UNSPEC_FSCALE_FRACT))
14750 (unspec:XF [(match_dup 1) (match_dup 2)]
14751 UNSPEC_FSCALE_EXP))])]
14752 "TARGET_USE_FANCY_MATH_387
14753 && flag_unsafe_math_optimizations"
14755 if (optimize_insn_for_size_p ())
14758 operands[3] = gen_reg_rtx (XFmode);
14761 (define_expand "scalb<mode>3"
14762 [(use (match_operand:MODEF 0 "register_operand"))
14763 (use (match_operand:MODEF 1 "general_operand"))
14764 (use (match_operand:MODEF 2 "general_operand"))]
14765 "TARGET_USE_FANCY_MATH_387
14766 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14767 || TARGET_MIX_SSE_I387)
14768 && flag_unsafe_math_optimizations"
14772 if (optimize_insn_for_size_p ())
14775 op0 = gen_reg_rtx (XFmode);
14776 op1 = gen_reg_rtx (XFmode);
14777 op2 = gen_reg_rtx (XFmode);
14779 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14780 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14781 emit_insn (gen_scalbxf3 (op0, op1, op2));
14782 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14786 (define_expand "significandxf2"
14787 [(parallel [(set (match_operand:XF 0 "register_operand")
14788 (unspec:XF [(match_operand:XF 1 "register_operand")]
14789 UNSPEC_XTRACT_FRACT))
14791 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14792 "TARGET_USE_FANCY_MATH_387
14793 && flag_unsafe_math_optimizations"
14794 "operands[2] = gen_reg_rtx (XFmode);")
14796 (define_expand "significand<mode>2"
14797 [(use (match_operand:MODEF 0 "register_operand"))
14798 (use (match_operand:MODEF 1 "register_operand"))]
14799 "TARGET_USE_FANCY_MATH_387
14800 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14801 || TARGET_MIX_SSE_I387)
14802 && flag_unsafe_math_optimizations"
14804 rtx op0 = gen_reg_rtx (XFmode);
14805 rtx op1 = gen_reg_rtx (XFmode);
14807 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14808 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14813 (define_insn "sse4_1_round<mode>2"
14814 [(set (match_operand:MODEF 0 "register_operand" "=x")
14815 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14816 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14819 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14820 [(set_attr "type" "ssecvt")
14821 (set_attr "prefix_extra" "1")
14822 (set_attr "prefix" "maybe_vex")
14823 (set_attr "mode" "<MODE>")])
14825 (define_insn "rintxf2"
14826 [(set (match_operand:XF 0 "register_operand" "=f")
14827 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14829 "TARGET_USE_FANCY_MATH_387
14830 && flag_unsafe_math_optimizations"
14832 [(set_attr "type" "fpspc")
14833 (set_attr "mode" "XF")])
14835 (define_expand "rint<mode>2"
14836 [(use (match_operand:MODEF 0 "register_operand"))
14837 (use (match_operand:MODEF 1 "register_operand"))]
14838 "(TARGET_USE_FANCY_MATH_387
14839 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14840 || TARGET_MIX_SSE_I387)
14841 && flag_unsafe_math_optimizations)
14842 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14843 && !flag_trapping_math)"
14845 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14846 && !flag_trapping_math)
14849 emit_insn (gen_sse4_1_round<mode>2
14850 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14851 else if (optimize_insn_for_size_p ())
14854 ix86_expand_rint (operands[0], operands[1]);
14858 rtx op0 = gen_reg_rtx (XFmode);
14859 rtx op1 = gen_reg_rtx (XFmode);
14861 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14862 emit_insn (gen_rintxf2 (op0, op1));
14864 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14869 (define_expand "round<mode>2"
14870 [(match_operand:X87MODEF 0 "register_operand")
14871 (match_operand:X87MODEF 1 "nonimmediate_operand")]
14872 "(TARGET_USE_FANCY_MATH_387
14873 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14874 || TARGET_MIX_SSE_I387)
14875 && flag_unsafe_math_optimizations)
14876 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14877 && !flag_trapping_math && !flag_rounding_math)"
14879 if (optimize_insn_for_size_p ())
14882 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14883 && !flag_trapping_math && !flag_rounding_math)
14887 operands[1] = force_reg (<MODE>mode, operands[1]);
14888 ix86_expand_round_sse4 (operands[0], operands[1]);
14890 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14891 ix86_expand_round (operands[0], operands[1]);
14893 ix86_expand_rounddf_32 (operands[0], operands[1]);
14897 operands[1] = force_reg (<MODE>mode, operands[1]);
14898 ix86_emit_i387_round (operands[0], operands[1]);
14903 (define_insn_and_split "*fistdi2_1"
14904 [(set (match_operand:DI 0 "nonimmediate_operand")
14905 (unspec:DI [(match_operand:XF 1 "register_operand")]
14907 "TARGET_USE_FANCY_MATH_387
14908 && can_create_pseudo_p ()"
14913 if (memory_operand (operands[0], VOIDmode))
14914 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14917 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14918 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14923 [(set_attr "type" "fpspc")
14924 (set_attr "mode" "DI")])
14926 (define_insn "fistdi2"
14927 [(set (match_operand:DI 0 "memory_operand" "=m")
14928 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14930 (clobber (match_scratch:XF 2 "=&1f"))]
14931 "TARGET_USE_FANCY_MATH_387"
14932 "* return output_fix_trunc (insn, operands, false);"
14933 [(set_attr "type" "fpspc")
14934 (set_attr "mode" "DI")])
14936 (define_insn "fistdi2_with_temp"
14937 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14938 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14940 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14941 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14942 "TARGET_USE_FANCY_MATH_387"
14944 [(set_attr "type" "fpspc")
14945 (set_attr "mode" "DI")])
14948 [(set (match_operand:DI 0 "register_operand")
14949 (unspec:DI [(match_operand:XF 1 "register_operand")]
14951 (clobber (match_operand:DI 2 "memory_operand"))
14952 (clobber (match_scratch 3))]
14954 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14955 (clobber (match_dup 3))])
14956 (set (match_dup 0) (match_dup 2))])
14959 [(set (match_operand:DI 0 "memory_operand")
14960 (unspec:DI [(match_operand:XF 1 "register_operand")]
14962 (clobber (match_operand:DI 2 "memory_operand"))
14963 (clobber (match_scratch 3))]
14965 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14966 (clobber (match_dup 3))])])
14968 (define_insn_and_split "*fist<mode>2_1"
14969 [(set (match_operand:SWI24 0 "register_operand")
14970 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14972 "TARGET_USE_FANCY_MATH_387
14973 && can_create_pseudo_p ()"
14978 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14979 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14983 [(set_attr "type" "fpspc")
14984 (set_attr "mode" "<MODE>")])
14986 (define_insn "fist<mode>2"
14987 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14988 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14990 "TARGET_USE_FANCY_MATH_387"
14991 "* return output_fix_trunc (insn, operands, false);"
14992 [(set_attr "type" "fpspc")
14993 (set_attr "mode" "<MODE>")])
14995 (define_insn "fist<mode>2_with_temp"
14996 [(set (match_operand:SWI24 0 "register_operand" "=r")
14997 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14999 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15000 "TARGET_USE_FANCY_MATH_387"
15002 [(set_attr "type" "fpspc")
15003 (set_attr "mode" "<MODE>")])
15006 [(set (match_operand:SWI24 0 "register_operand")
15007 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15009 (clobber (match_operand:SWI24 2 "memory_operand"))]
15011 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15012 (set (match_dup 0) (match_dup 2))])
15015 [(set (match_operand:SWI24 0 "memory_operand")
15016 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15018 (clobber (match_operand:SWI24 2 "memory_operand"))]
15020 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15022 (define_expand "lrintxf<mode>2"
15023 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15024 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15026 "TARGET_USE_FANCY_MATH_387")
15028 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
15029 [(set (match_operand:SWI48x 0 "nonimmediate_operand")
15030 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand")]
15031 UNSPEC_FIX_NOTRUNC))]
15032 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15033 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
15035 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15036 [(match_operand:SWI248x 0 "nonimmediate_operand")
15037 (match_operand:X87MODEF 1 "register_operand")]
15038 "(TARGET_USE_FANCY_MATH_387
15039 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15040 || TARGET_MIX_SSE_I387)
15041 && flag_unsafe_math_optimizations)
15042 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15043 && <SWI248x:MODE>mode != HImode
15044 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15045 && !flag_trapping_math && !flag_rounding_math)"
15047 if (optimize_insn_for_size_p ())
15050 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15051 && <SWI248x:MODE>mode != HImode
15052 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15053 && !flag_trapping_math && !flag_rounding_math)
15054 ix86_expand_lround (operands[0], operands[1]);
15056 ix86_emit_i387_round (operands[0], operands[1]);
15060 (define_int_iterator FRNDINT_ROUNDING
15061 [UNSPEC_FRNDINT_FLOOR
15062 UNSPEC_FRNDINT_CEIL
15063 UNSPEC_FRNDINT_TRUNC])
15065 (define_int_iterator FIST_ROUNDING
15069 ;; Base name for define_insn
15070 (define_int_attr rounding_insn
15071 [(UNSPEC_FRNDINT_FLOOR "floor")
15072 (UNSPEC_FRNDINT_CEIL "ceil")
15073 (UNSPEC_FRNDINT_TRUNC "btrunc")
15074 (UNSPEC_FIST_FLOOR "floor")
15075 (UNSPEC_FIST_CEIL "ceil")])
15077 (define_int_attr rounding
15078 [(UNSPEC_FRNDINT_FLOOR "floor")
15079 (UNSPEC_FRNDINT_CEIL "ceil")
15080 (UNSPEC_FRNDINT_TRUNC "trunc")
15081 (UNSPEC_FIST_FLOOR "floor")
15082 (UNSPEC_FIST_CEIL "ceil")])
15084 (define_int_attr ROUNDING
15085 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15086 (UNSPEC_FRNDINT_CEIL "CEIL")
15087 (UNSPEC_FRNDINT_TRUNC "TRUNC")
15088 (UNSPEC_FIST_FLOOR "FLOOR")
15089 (UNSPEC_FIST_CEIL "CEIL")])
15091 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15092 (define_insn_and_split "frndintxf2_<rounding>"
15093 [(set (match_operand:XF 0 "register_operand")
15094 (unspec:XF [(match_operand:XF 1 "register_operand")]
15096 (clobber (reg:CC FLAGS_REG))]
15097 "TARGET_USE_FANCY_MATH_387
15098 && flag_unsafe_math_optimizations
15099 && can_create_pseudo_p ()"
15104 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15106 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15107 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15109 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
15110 operands[2], operands[3]));
15113 [(set_attr "type" "frndint")
15114 (set_attr "i387_cw" "<rounding>")
15115 (set_attr "mode" "XF")])
15117 (define_insn "frndintxf2_<rounding>_i387"
15118 [(set (match_operand:XF 0 "register_operand" "=f")
15119 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15121 (use (match_operand:HI 2 "memory_operand" "m"))
15122 (use (match_operand:HI 3 "memory_operand" "m"))]
15123 "TARGET_USE_FANCY_MATH_387
15124 && flag_unsafe_math_optimizations"
15125 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15126 [(set_attr "type" "frndint")
15127 (set_attr "i387_cw" "<rounding>")
15128 (set_attr "mode" "XF")])
15130 (define_expand "<rounding_insn>xf2"
15131 [(parallel [(set (match_operand:XF 0 "register_operand")
15132 (unspec:XF [(match_operand:XF 1 "register_operand")]
15134 (clobber (reg:CC FLAGS_REG))])]
15135 "TARGET_USE_FANCY_MATH_387
15136 && flag_unsafe_math_optimizations
15137 && !optimize_insn_for_size_p ()")
15139 (define_expand "<rounding_insn><mode>2"
15140 [(parallel [(set (match_operand:MODEF 0 "register_operand")
15141 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15143 (clobber (reg:CC FLAGS_REG))])]
15144 "(TARGET_USE_FANCY_MATH_387
15145 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15146 || TARGET_MIX_SSE_I387)
15147 && flag_unsafe_math_optimizations)
15148 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15149 && !flag_trapping_math)"
15151 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15152 && !flag_trapping_math)
15155 emit_insn (gen_sse4_1_round<mode>2
15156 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
15157 else if (optimize_insn_for_size_p ())
15159 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15161 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15162 ix86_expand_floorceil (operands[0], operands[1], true);
15163 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15164 ix86_expand_floorceil (operands[0], operands[1], false);
15165 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15166 ix86_expand_trunc (operands[0], operands[1]);
15168 gcc_unreachable ();
15172 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15173 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15174 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15175 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15176 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15177 ix86_expand_truncdf_32 (operands[0], operands[1]);
15179 gcc_unreachable ();
15186 if (optimize_insn_for_size_p ())
15189 op0 = gen_reg_rtx (XFmode);
15190 op1 = gen_reg_rtx (XFmode);
15191 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15192 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
15194 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15199 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15200 (define_insn_and_split "frndintxf2_mask_pm"
15201 [(set (match_operand:XF 0 "register_operand")
15202 (unspec:XF [(match_operand:XF 1 "register_operand")]
15203 UNSPEC_FRNDINT_MASK_PM))
15204 (clobber (reg:CC FLAGS_REG))]
15205 "TARGET_USE_FANCY_MATH_387
15206 && flag_unsafe_math_optimizations
15207 && can_create_pseudo_p ()"
15212 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15214 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15215 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15217 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15218 operands[2], operands[3]));
15221 [(set_attr "type" "frndint")
15222 (set_attr "i387_cw" "mask_pm")
15223 (set_attr "mode" "XF")])
15225 (define_insn "frndintxf2_mask_pm_i387"
15226 [(set (match_operand:XF 0 "register_operand" "=f")
15227 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15228 UNSPEC_FRNDINT_MASK_PM))
15229 (use (match_operand:HI 2 "memory_operand" "m"))
15230 (use (match_operand:HI 3 "memory_operand" "m"))]
15231 "TARGET_USE_FANCY_MATH_387
15232 && flag_unsafe_math_optimizations"
15233 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15234 [(set_attr "type" "frndint")
15235 (set_attr "i387_cw" "mask_pm")
15236 (set_attr "mode" "XF")])
15238 (define_expand "nearbyintxf2"
15239 [(parallel [(set (match_operand:XF 0 "register_operand")
15240 (unspec:XF [(match_operand:XF 1 "register_operand")]
15241 UNSPEC_FRNDINT_MASK_PM))
15242 (clobber (reg:CC FLAGS_REG))])]
15243 "TARGET_USE_FANCY_MATH_387
15244 && flag_unsafe_math_optimizations")
15246 (define_expand "nearbyint<mode>2"
15247 [(use (match_operand:MODEF 0 "register_operand"))
15248 (use (match_operand:MODEF 1 "register_operand"))]
15249 "TARGET_USE_FANCY_MATH_387
15250 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15251 || TARGET_MIX_SSE_I387)
15252 && flag_unsafe_math_optimizations"
15254 rtx op0 = gen_reg_rtx (XFmode);
15255 rtx op1 = gen_reg_rtx (XFmode);
15257 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15258 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15260 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15264 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15265 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15266 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15267 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15269 (clobber (reg:CC FLAGS_REG))]
15270 "TARGET_USE_FANCY_MATH_387
15271 && flag_unsafe_math_optimizations
15272 && can_create_pseudo_p ()"
15277 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15279 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15280 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15281 if (memory_operand (operands[0], VOIDmode))
15282 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15283 operands[2], operands[3]));
15286 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15287 emit_insn (gen_fist<mode>2_<rounding>_with_temp
15288 (operands[0], operands[1], operands[2],
15289 operands[3], operands[4]));
15293 [(set_attr "type" "fistp")
15294 (set_attr "i387_cw" "<rounding>")
15295 (set_attr "mode" "<MODE>")])
15297 (define_insn "fistdi2_<rounding>"
15298 [(set (match_operand:DI 0 "memory_operand" "=m")
15299 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15301 (use (match_operand:HI 2 "memory_operand" "m"))
15302 (use (match_operand:HI 3 "memory_operand" "m"))
15303 (clobber (match_scratch:XF 4 "=&1f"))]
15304 "TARGET_USE_FANCY_MATH_387
15305 && flag_unsafe_math_optimizations"
15306 "* return output_fix_trunc (insn, operands, false);"
15307 [(set_attr "type" "fistp")
15308 (set_attr "i387_cw" "<rounding>")
15309 (set_attr "mode" "DI")])
15311 (define_insn "fistdi2_<rounding>_with_temp"
15312 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15313 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15315 (use (match_operand:HI 2 "memory_operand" "m,m"))
15316 (use (match_operand:HI 3 "memory_operand" "m,m"))
15317 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15318 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15319 "TARGET_USE_FANCY_MATH_387
15320 && flag_unsafe_math_optimizations"
15322 [(set_attr "type" "fistp")
15323 (set_attr "i387_cw" "<rounding>")
15324 (set_attr "mode" "DI")])
15327 [(set (match_operand:DI 0 "register_operand")
15328 (unspec:DI [(match_operand:XF 1 "register_operand")]
15330 (use (match_operand:HI 2 "memory_operand"))
15331 (use (match_operand:HI 3 "memory_operand"))
15332 (clobber (match_operand:DI 4 "memory_operand"))
15333 (clobber (match_scratch 5))]
15335 [(parallel [(set (match_dup 4)
15336 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15337 (use (match_dup 2))
15338 (use (match_dup 3))
15339 (clobber (match_dup 5))])
15340 (set (match_dup 0) (match_dup 4))])
15343 [(set (match_operand:DI 0 "memory_operand")
15344 (unspec:DI [(match_operand:XF 1 "register_operand")]
15346 (use (match_operand:HI 2 "memory_operand"))
15347 (use (match_operand:HI 3 "memory_operand"))
15348 (clobber (match_operand:DI 4 "memory_operand"))
15349 (clobber (match_scratch 5))]
15351 [(parallel [(set (match_dup 0)
15352 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15353 (use (match_dup 2))
15354 (use (match_dup 3))
15355 (clobber (match_dup 5))])])
15357 (define_insn "fist<mode>2_<rounding>"
15358 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15359 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15361 (use (match_operand:HI 2 "memory_operand" "m"))
15362 (use (match_operand:HI 3 "memory_operand" "m"))]
15363 "TARGET_USE_FANCY_MATH_387
15364 && flag_unsafe_math_optimizations"
15365 "* return output_fix_trunc (insn, operands, false);"
15366 [(set_attr "type" "fistp")
15367 (set_attr "i387_cw" "<rounding>")
15368 (set_attr "mode" "<MODE>")])
15370 (define_insn "fist<mode>2_<rounding>_with_temp"
15371 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15372 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15374 (use (match_operand:HI 2 "memory_operand" "m,m"))
15375 (use (match_operand:HI 3 "memory_operand" "m,m"))
15376 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15377 "TARGET_USE_FANCY_MATH_387
15378 && flag_unsafe_math_optimizations"
15380 [(set_attr "type" "fistp")
15381 (set_attr "i387_cw" "<rounding>")
15382 (set_attr "mode" "<MODE>")])
15385 [(set (match_operand:SWI24 0 "register_operand")
15386 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15388 (use (match_operand:HI 2 "memory_operand"))
15389 (use (match_operand:HI 3 "memory_operand"))
15390 (clobber (match_operand:SWI24 4 "memory_operand"))]
15392 [(parallel [(set (match_dup 4)
15393 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15394 (use (match_dup 2))
15395 (use (match_dup 3))])
15396 (set (match_dup 0) (match_dup 4))])
15399 [(set (match_operand:SWI24 0 "memory_operand")
15400 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15402 (use (match_operand:HI 2 "memory_operand"))
15403 (use (match_operand:HI 3 "memory_operand"))
15404 (clobber (match_operand:SWI24 4 "memory_operand"))]
15406 [(parallel [(set (match_dup 0)
15407 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15408 (use (match_dup 2))
15409 (use (match_dup 3))])])
15411 (define_expand "l<rounding_insn>xf<mode>2"
15412 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15413 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15415 (clobber (reg:CC FLAGS_REG))])]
15416 "TARGET_USE_FANCY_MATH_387
15417 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15418 && flag_unsafe_math_optimizations")
15420 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
15421 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
15422 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15424 (clobber (reg:CC FLAGS_REG))])]
15425 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15426 && !flag_trapping_math"
15428 if (TARGET_64BIT && optimize_insn_for_size_p ())
15431 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15432 ix86_expand_lfloorceil (operands[0], operands[1], true);
15433 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15434 ix86_expand_lfloorceil (operands[0], operands[1], false);
15436 gcc_unreachable ();
15441 (define_insn "fxam<mode>2_i387"
15442 [(set (match_operand:HI 0 "register_operand" "=a")
15444 [(match_operand:X87MODEF 1 "register_operand" "f")]
15446 "TARGET_USE_FANCY_MATH_387"
15447 "fxam\n\tfnstsw\t%0"
15448 [(set_attr "type" "multi")
15449 (set_attr "length" "4")
15450 (set_attr "unit" "i387")
15451 (set_attr "mode" "<MODE>")])
15453 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15454 [(set (match_operand:HI 0 "register_operand")
15456 [(match_operand:MODEF 1 "memory_operand")]
15458 "TARGET_USE_FANCY_MATH_387
15459 && can_create_pseudo_p ()"
15462 [(set (match_dup 2)(match_dup 1))
15464 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15466 operands[2] = gen_reg_rtx (<MODE>mode);
15468 MEM_VOLATILE_P (operands[1]) = 1;
15470 [(set_attr "type" "multi")
15471 (set_attr "unit" "i387")
15472 (set_attr "mode" "<MODE>")])
15474 (define_expand "isinfxf2"
15475 [(use (match_operand:SI 0 "register_operand"))
15476 (use (match_operand:XF 1 "register_operand"))]
15477 "TARGET_USE_FANCY_MATH_387
15478 && TARGET_C99_FUNCTIONS"
15480 rtx mask = GEN_INT (0x45);
15481 rtx val = GEN_INT (0x05);
15485 rtx scratch = gen_reg_rtx (HImode);
15486 rtx res = gen_reg_rtx (QImode);
15488 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15490 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15491 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15492 cond = gen_rtx_fmt_ee (EQ, QImode,
15493 gen_rtx_REG (CCmode, FLAGS_REG),
15495 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15496 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15500 (define_expand "isinf<mode>2"
15501 [(use (match_operand:SI 0 "register_operand"))
15502 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15503 "TARGET_USE_FANCY_MATH_387
15504 && TARGET_C99_FUNCTIONS
15505 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15507 rtx mask = GEN_INT (0x45);
15508 rtx val = GEN_INT (0x05);
15512 rtx scratch = gen_reg_rtx (HImode);
15513 rtx res = gen_reg_rtx (QImode);
15515 /* Remove excess precision by forcing value through memory. */
15516 if (memory_operand (operands[1], VOIDmode))
15517 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15520 enum ix86_stack_slot slot = (virtuals_instantiated
15523 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15525 emit_move_insn (temp, operands[1]);
15526 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15529 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15530 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15531 cond = gen_rtx_fmt_ee (EQ, QImode,
15532 gen_rtx_REG (CCmode, FLAGS_REG),
15534 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15535 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15539 (define_expand "signbitxf2"
15540 [(use (match_operand:SI 0 "register_operand"))
15541 (use (match_operand:XF 1 "register_operand"))]
15542 "TARGET_USE_FANCY_MATH_387"
15544 rtx scratch = gen_reg_rtx (HImode);
15546 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15547 emit_insn (gen_andsi3 (operands[0],
15548 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15552 (define_insn "movmsk_df"
15553 [(set (match_operand:SI 0 "register_operand" "=r")
15555 [(match_operand:DF 1 "register_operand" "x")]
15557 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15558 "%vmovmskpd\t{%1, %0|%0, %1}"
15559 [(set_attr "type" "ssemov")
15560 (set_attr "prefix" "maybe_vex")
15561 (set_attr "mode" "DF")])
15563 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15564 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15565 (define_expand "signbitdf2"
15566 [(use (match_operand:SI 0 "register_operand"))
15567 (use (match_operand:DF 1 "register_operand"))]
15568 "TARGET_USE_FANCY_MATH_387
15569 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15571 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15573 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15574 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15578 rtx scratch = gen_reg_rtx (HImode);
15580 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15581 emit_insn (gen_andsi3 (operands[0],
15582 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15587 (define_expand "signbitsf2"
15588 [(use (match_operand:SI 0 "register_operand"))
15589 (use (match_operand:SF 1 "register_operand"))]
15590 "TARGET_USE_FANCY_MATH_387
15591 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15593 rtx scratch = gen_reg_rtx (HImode);
15595 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15596 emit_insn (gen_andsi3 (operands[0],
15597 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15601 ;; Block operation instructions
15604 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15607 [(set_attr "length" "1")
15608 (set_attr "length_immediate" "0")
15609 (set_attr "modrm" "0")])
15611 (define_expand "movmem<mode>"
15612 [(use (match_operand:BLK 0 "memory_operand"))
15613 (use (match_operand:BLK 1 "memory_operand"))
15614 (use (match_operand:SWI48 2 "nonmemory_operand"))
15615 (use (match_operand:SWI48 3 "const_int_operand"))
15616 (use (match_operand:SI 4 "const_int_operand"))
15617 (use (match_operand:SI 5 "const_int_operand"))]
15620 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15621 operands[4], operands[5]))
15627 ;; Most CPUs don't like single string operations
15628 ;; Handle this case here to simplify previous expander.
15630 (define_expand "strmov"
15631 [(set (match_dup 4) (match_operand 3 "memory_operand"))
15632 (set (match_operand 1 "memory_operand") (match_dup 4))
15633 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
15634 (clobber (reg:CC FLAGS_REG))])
15635 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
15636 (clobber (reg:CC FLAGS_REG))])]
15639 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15641 /* If .md ever supports :P for Pmode, these can be directly
15642 in the pattern above. */
15643 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15644 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15646 /* Can't use this if the user has appropriated esi or edi. */
15647 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15648 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15650 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15651 operands[2], operands[3],
15652 operands[5], operands[6]));
15656 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15659 (define_expand "strmov_singleop"
15660 [(parallel [(set (match_operand 1 "memory_operand")
15661 (match_operand 3 "memory_operand"))
15662 (set (match_operand 0 "register_operand")
15664 (set (match_operand 2 "register_operand")
15665 (match_operand 5))])]
15667 "ix86_current_function_needs_cld = 1;")
15669 (define_insn "*strmovdi_rex_1"
15670 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15671 (mem:DI (match_operand:P 3 "register_operand" "1")))
15672 (set (match_operand:P 0 "register_operand" "=D")
15673 (plus:P (match_dup 2)
15675 (set (match_operand:P 1 "register_operand" "=S")
15676 (plus:P (match_dup 3)
15679 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15681 [(set_attr "type" "str")
15682 (set_attr "memory" "both")
15683 (set_attr "mode" "DI")])
15685 (define_insn "*strmovsi_1"
15686 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15687 (mem:SI (match_operand:P 3 "register_operand" "1")))
15688 (set (match_operand:P 0 "register_operand" "=D")
15689 (plus:P (match_dup 2)
15691 (set (match_operand:P 1 "register_operand" "=S")
15692 (plus:P (match_dup 3)
15694 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15696 [(set_attr "type" "str")
15697 (set_attr "memory" "both")
15698 (set_attr "mode" "SI")])
15700 (define_insn "*strmovhi_1"
15701 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15702 (mem:HI (match_operand:P 3 "register_operand" "1")))
15703 (set (match_operand:P 0 "register_operand" "=D")
15704 (plus:P (match_dup 2)
15706 (set (match_operand:P 1 "register_operand" "=S")
15707 (plus:P (match_dup 3)
15709 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15711 [(set_attr "type" "str")
15712 (set_attr "memory" "both")
15713 (set_attr "mode" "HI")])
15715 (define_insn "*strmovqi_1"
15716 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15717 (mem:QI (match_operand:P 3 "register_operand" "1")))
15718 (set (match_operand:P 0 "register_operand" "=D")
15719 (plus:P (match_dup 2)
15721 (set (match_operand:P 1 "register_operand" "=S")
15722 (plus:P (match_dup 3)
15724 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15726 [(set_attr "type" "str")
15727 (set_attr "memory" "both")
15728 (set (attr "prefix_rex")
15730 (match_test "<P:MODE>mode == DImode")
15732 (const_string "*")))
15733 (set_attr "mode" "QI")])
15735 (define_expand "rep_mov"
15736 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
15737 (set (match_operand 0 "register_operand")
15739 (set (match_operand 2 "register_operand")
15741 (set (match_operand 1 "memory_operand")
15742 (match_operand 3 "memory_operand"))
15743 (use (match_dup 4))])]
15745 "ix86_current_function_needs_cld = 1;")
15747 (define_insn "*rep_movdi_rex64"
15748 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15749 (set (match_operand:P 0 "register_operand" "=D")
15750 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15752 (match_operand:P 3 "register_operand" "0")))
15753 (set (match_operand:P 1 "register_operand" "=S")
15754 (plus:P (ashift:P (match_dup 5) (const_int 3))
15755 (match_operand:P 4 "register_operand" "1")))
15756 (set (mem:BLK (match_dup 3))
15757 (mem:BLK (match_dup 4)))
15758 (use (match_dup 5))]
15760 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15762 [(set_attr "type" "str")
15763 (set_attr "prefix_rep" "1")
15764 (set_attr "memory" "both")
15765 (set_attr "mode" "DI")])
15767 (define_insn "*rep_movsi"
15768 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15769 (set (match_operand:P 0 "register_operand" "=D")
15770 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15772 (match_operand:P 3 "register_operand" "0")))
15773 (set (match_operand:P 1 "register_operand" "=S")
15774 (plus:P (ashift:P (match_dup 5) (const_int 2))
15775 (match_operand:P 4 "register_operand" "1")))
15776 (set (mem:BLK (match_dup 3))
15777 (mem:BLK (match_dup 4)))
15778 (use (match_dup 5))]
15779 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15780 "%^rep{%;} movs{l|d}"
15781 [(set_attr "type" "str")
15782 (set_attr "prefix_rep" "1")
15783 (set_attr "memory" "both")
15784 (set_attr "mode" "SI")])
15786 (define_insn "*rep_movqi"
15787 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15788 (set (match_operand:P 0 "register_operand" "=D")
15789 (plus:P (match_operand:P 3 "register_operand" "0")
15790 (match_operand:P 5 "register_operand" "2")))
15791 (set (match_operand:P 1 "register_operand" "=S")
15792 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15793 (set (mem:BLK (match_dup 3))
15794 (mem:BLK (match_dup 4)))
15795 (use (match_dup 5))]
15796 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15798 [(set_attr "type" "str")
15799 (set_attr "prefix_rep" "1")
15800 (set_attr "memory" "both")
15801 (set_attr "mode" "QI")])
15803 (define_expand "setmem<mode>"
15804 [(use (match_operand:BLK 0 "memory_operand"))
15805 (use (match_operand:SWI48 1 "nonmemory_operand"))
15806 (use (match_operand:QI 2 "nonmemory_operand"))
15807 (use (match_operand 3 "const_int_operand"))
15808 (use (match_operand:SI 4 "const_int_operand"))
15809 (use (match_operand:SI 5 "const_int_operand"))]
15812 if (ix86_expand_setmem (operands[0], operands[1],
15813 operands[2], operands[3],
15814 operands[4], operands[5]))
15820 ;; Most CPUs don't like single string operations
15821 ;; Handle this case here to simplify previous expander.
15823 (define_expand "strset"
15824 [(set (match_operand 1 "memory_operand")
15825 (match_operand 2 "register_operand"))
15826 (parallel [(set (match_operand 0 "register_operand")
15828 (clobber (reg:CC FLAGS_REG))])]
15831 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15832 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15834 /* If .md ever supports :P for Pmode, this can be directly
15835 in the pattern above. */
15836 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15837 GEN_INT (GET_MODE_SIZE (GET_MODE
15839 /* Can't use this if the user has appropriated eax or edi. */
15840 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15841 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15843 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15849 (define_expand "strset_singleop"
15850 [(parallel [(set (match_operand 1 "memory_operand")
15851 (match_operand 2 "register_operand"))
15852 (set (match_operand 0 "register_operand")
15853 (match_operand 3))])]
15855 "ix86_current_function_needs_cld = 1;")
15857 (define_insn "*strsetdi_rex_1"
15858 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
15859 (match_operand:DI 2 "register_operand" "a"))
15860 (set (match_operand:P 0 "register_operand" "=D")
15861 (plus:P (match_dup 1)
15864 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15866 [(set_attr "type" "str")
15867 (set_attr "memory" "store")
15868 (set_attr "mode" "DI")])
15870 (define_insn "*strsetsi_1"
15871 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15872 (match_operand:SI 2 "register_operand" "a"))
15873 (set (match_operand:P 0 "register_operand" "=D")
15874 (plus:P (match_dup 1)
15876 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15878 [(set_attr "type" "str")
15879 (set_attr "memory" "store")
15880 (set_attr "mode" "SI")])
15882 (define_insn "*strsethi_1"
15883 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15884 (match_operand:HI 2 "register_operand" "a"))
15885 (set (match_operand:P 0 "register_operand" "=D")
15886 (plus:P (match_dup 1)
15888 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15890 [(set_attr "type" "str")
15891 (set_attr "memory" "store")
15892 (set_attr "mode" "HI")])
15894 (define_insn "*strsetqi_1"
15895 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15896 (match_operand:QI 2 "register_operand" "a"))
15897 (set (match_operand:P 0 "register_operand" "=D")
15898 (plus:P (match_dup 1)
15900 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15902 [(set_attr "type" "str")
15903 (set_attr "memory" "store")
15904 (set (attr "prefix_rex")
15906 (match_test "<P:MODE>mode == DImode")
15908 (const_string "*")))
15909 (set_attr "mode" "QI")])
15911 (define_expand "rep_stos"
15912 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
15913 (set (match_operand 0 "register_operand")
15915 (set (match_operand 2 "memory_operand") (const_int 0))
15916 (use (match_operand 3 "register_operand"))
15917 (use (match_dup 1))])]
15919 "ix86_current_function_needs_cld = 1;")
15921 (define_insn "*rep_stosdi_rex64"
15922 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15923 (set (match_operand:P 0 "register_operand" "=D")
15924 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15926 (match_operand:P 3 "register_operand" "0")))
15927 (set (mem:BLK (match_dup 3))
15929 (use (match_operand:DI 2 "register_operand" "a"))
15930 (use (match_dup 4))]
15932 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15934 [(set_attr "type" "str")
15935 (set_attr "prefix_rep" "1")
15936 (set_attr "memory" "store")
15937 (set_attr "mode" "DI")])
15939 (define_insn "*rep_stossi"
15940 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15941 (set (match_operand:P 0 "register_operand" "=D")
15942 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15944 (match_operand:P 3 "register_operand" "0")))
15945 (set (mem:BLK (match_dup 3))
15947 (use (match_operand:SI 2 "register_operand" "a"))
15948 (use (match_dup 4))]
15949 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15950 "%^rep{%;} stos{l|d}"
15951 [(set_attr "type" "str")
15952 (set_attr "prefix_rep" "1")
15953 (set_attr "memory" "store")
15954 (set_attr "mode" "SI")])
15956 (define_insn "*rep_stosqi"
15957 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15958 (set (match_operand:P 0 "register_operand" "=D")
15959 (plus:P (match_operand:P 3 "register_operand" "0")
15960 (match_operand:P 4 "register_operand" "1")))
15961 (set (mem:BLK (match_dup 3))
15963 (use (match_operand:QI 2 "register_operand" "a"))
15964 (use (match_dup 4))]
15965 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15967 [(set_attr "type" "str")
15968 (set_attr "prefix_rep" "1")
15969 (set_attr "memory" "store")
15970 (set (attr "prefix_rex")
15972 (match_test "<P:MODE>mode == DImode")
15974 (const_string "*")))
15975 (set_attr "mode" "QI")])
15977 (define_expand "cmpstrnsi"
15978 [(set (match_operand:SI 0 "register_operand")
15979 (compare:SI (match_operand:BLK 1 "general_operand")
15980 (match_operand:BLK 2 "general_operand")))
15981 (use (match_operand 3 "general_operand"))
15982 (use (match_operand 4 "immediate_operand"))]
15985 rtx addr1, addr2, out, outlow, count, countreg, align;
15987 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15990 /* Can't use this if the user has appropriated ecx, esi or edi. */
15991 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
15996 out = gen_reg_rtx (SImode);
15998 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
15999 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16000 if (addr1 != XEXP (operands[1], 0))
16001 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16002 if (addr2 != XEXP (operands[2], 0))
16003 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16005 count = operands[3];
16006 countreg = ix86_zero_extend_to_Pmode (count);
16008 /* %%% Iff we are testing strict equality, we can use known alignment
16009 to good advantage. This may be possible with combine, particularly
16010 once cc0 is dead. */
16011 align = operands[4];
16013 if (CONST_INT_P (count))
16015 if (INTVAL (count) == 0)
16017 emit_move_insn (operands[0], const0_rtx);
16020 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16021 operands[1], operands[2]));
16025 rtx (*gen_cmp) (rtx, rtx);
16027 gen_cmp = (TARGET_64BIT
16028 ? gen_cmpdi_1 : gen_cmpsi_1);
16030 emit_insn (gen_cmp (countreg, countreg));
16031 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16032 operands[1], operands[2]));
16035 outlow = gen_lowpart (QImode, out);
16036 emit_insn (gen_cmpintqi (outlow));
16037 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16039 if (operands[0] != out)
16040 emit_move_insn (operands[0], out);
16045 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16047 (define_expand "cmpintqi"
16048 [(set (match_dup 1)
16049 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16051 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16052 (parallel [(set (match_operand:QI 0 "register_operand")
16053 (minus:QI (match_dup 1)
16055 (clobber (reg:CC FLAGS_REG))])]
16058 operands[1] = gen_reg_rtx (QImode);
16059 operands[2] = gen_reg_rtx (QImode);
16062 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16063 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16065 (define_expand "cmpstrnqi_nz_1"
16066 [(parallel [(set (reg:CC FLAGS_REG)
16067 (compare:CC (match_operand 4 "memory_operand")
16068 (match_operand 5 "memory_operand")))
16069 (use (match_operand 2 "register_operand"))
16070 (use (match_operand:SI 3 "immediate_operand"))
16071 (clobber (match_operand 0 "register_operand"))
16072 (clobber (match_operand 1 "register_operand"))
16073 (clobber (match_dup 2))])]
16075 "ix86_current_function_needs_cld = 1;")
16077 (define_insn "*cmpstrnqi_nz_1"
16078 [(set (reg:CC FLAGS_REG)
16079 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16080 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16081 (use (match_operand:P 6 "register_operand" "2"))
16082 (use (match_operand:SI 3 "immediate_operand" "i"))
16083 (clobber (match_operand:P 0 "register_operand" "=S"))
16084 (clobber (match_operand:P 1 "register_operand" "=D"))
16085 (clobber (match_operand:P 2 "register_operand" "=c"))]
16086 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16088 [(set_attr "type" "str")
16089 (set_attr "mode" "QI")
16090 (set (attr "prefix_rex")
16092 (match_test "<P:MODE>mode == DImode")
16094 (const_string "*")))
16095 (set_attr "prefix_rep" "1")])
16097 ;; The same, but the count is not known to not be zero.
16099 (define_expand "cmpstrnqi_1"
16100 [(parallel [(set (reg:CC FLAGS_REG)
16101 (if_then_else:CC (ne (match_operand 2 "register_operand")
16103 (compare:CC (match_operand 4 "memory_operand")
16104 (match_operand 5 "memory_operand"))
16106 (use (match_operand:SI 3 "immediate_operand"))
16107 (use (reg:CC FLAGS_REG))
16108 (clobber (match_operand 0 "register_operand"))
16109 (clobber (match_operand 1 "register_operand"))
16110 (clobber (match_dup 2))])]
16112 "ix86_current_function_needs_cld = 1;")
16114 (define_insn "*cmpstrnqi_1"
16115 [(set (reg:CC FLAGS_REG)
16116 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16118 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16119 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16121 (use (match_operand:SI 3 "immediate_operand" "i"))
16122 (use (reg:CC FLAGS_REG))
16123 (clobber (match_operand:P 0 "register_operand" "=S"))
16124 (clobber (match_operand:P 1 "register_operand" "=D"))
16125 (clobber (match_operand:P 2 "register_operand" "=c"))]
16126 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16128 [(set_attr "type" "str")
16129 (set_attr "mode" "QI")
16130 (set (attr "prefix_rex")
16132 (match_test "<P:MODE>mode == DImode")
16134 (const_string "*")))
16135 (set_attr "prefix_rep" "1")])
16137 (define_expand "strlen<mode>"
16138 [(set (match_operand:P 0 "register_operand")
16139 (unspec:P [(match_operand:BLK 1 "general_operand")
16140 (match_operand:QI 2 "immediate_operand")
16141 (match_operand 3 "immediate_operand")]
16145 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16151 (define_expand "strlenqi_1"
16152 [(parallel [(set (match_operand 0 "register_operand")
16154 (clobber (match_operand 1 "register_operand"))
16155 (clobber (reg:CC FLAGS_REG))])]
16157 "ix86_current_function_needs_cld = 1;")
16159 (define_insn "*strlenqi_1"
16160 [(set (match_operand:P 0 "register_operand" "=&c")
16161 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16162 (match_operand:QI 2 "register_operand" "a")
16163 (match_operand:P 3 "immediate_operand" "i")
16164 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16165 (clobber (match_operand:P 1 "register_operand" "=D"))
16166 (clobber (reg:CC FLAGS_REG))]
16167 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16168 "%^repnz{%;} scasb"
16169 [(set_attr "type" "str")
16170 (set_attr "mode" "QI")
16171 (set (attr "prefix_rex")
16173 (match_test "<P:MODE>mode == DImode")
16175 (const_string "*")))
16176 (set_attr "prefix_rep" "1")])
16178 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16179 ;; handled in combine, but it is not currently up to the task.
16180 ;; When used for their truth value, the cmpstrn* expanders generate
16189 ;; The intermediate three instructions are unnecessary.
16191 ;; This one handles cmpstrn*_nz_1...
16194 (set (reg:CC FLAGS_REG)
16195 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16196 (mem:BLK (match_operand 5 "register_operand"))))
16197 (use (match_operand 6 "register_operand"))
16198 (use (match_operand:SI 3 "immediate_operand"))
16199 (clobber (match_operand 0 "register_operand"))
16200 (clobber (match_operand 1 "register_operand"))
16201 (clobber (match_operand 2 "register_operand"))])
16202 (set (match_operand:QI 7 "register_operand")
16203 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16204 (set (match_operand:QI 8 "register_operand")
16205 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16206 (set (reg FLAGS_REG)
16207 (compare (match_dup 7) (match_dup 8)))
16209 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16211 (set (reg:CC FLAGS_REG)
16212 (compare:CC (mem:BLK (match_dup 4))
16213 (mem:BLK (match_dup 5))))
16214 (use (match_dup 6))
16215 (use (match_dup 3))
16216 (clobber (match_dup 0))
16217 (clobber (match_dup 1))
16218 (clobber (match_dup 2))])])
16220 ;; ...and this one handles cmpstrn*_1.
16223 (set (reg:CC FLAGS_REG)
16224 (if_then_else:CC (ne (match_operand 6 "register_operand")
16226 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16227 (mem:BLK (match_operand 5 "register_operand")))
16229 (use (match_operand:SI 3 "immediate_operand"))
16230 (use (reg:CC FLAGS_REG))
16231 (clobber (match_operand 0 "register_operand"))
16232 (clobber (match_operand 1 "register_operand"))
16233 (clobber (match_operand 2 "register_operand"))])
16234 (set (match_operand:QI 7 "register_operand")
16235 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16236 (set (match_operand:QI 8 "register_operand")
16237 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16238 (set (reg FLAGS_REG)
16239 (compare (match_dup 7) (match_dup 8)))
16241 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16243 (set (reg:CC FLAGS_REG)
16244 (if_then_else:CC (ne (match_dup 6)
16246 (compare:CC (mem:BLK (match_dup 4))
16247 (mem:BLK (match_dup 5)))
16249 (use (match_dup 3))
16250 (use (reg:CC FLAGS_REG))
16251 (clobber (match_dup 0))
16252 (clobber (match_dup 1))
16253 (clobber (match_dup 2))])])
16255 ;; Conditional move instructions.
16257 (define_expand "mov<mode>cc"
16258 [(set (match_operand:SWIM 0 "register_operand")
16259 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator")
16260 (match_operand:SWIM 2 "<general_operand>")
16261 (match_operand:SWIM 3 "<general_operand>")))]
16263 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16265 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16266 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16267 ;; So just document what we're doing explicitly.
16269 (define_expand "x86_mov<mode>cc_0_m1"
16271 [(set (match_operand:SWI48 0 "register_operand")
16272 (if_then_else:SWI48
16273 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16274 [(match_operand 1 "flags_reg_operand")
16278 (clobber (reg:CC FLAGS_REG))])])
16280 (define_insn "*x86_mov<mode>cc_0_m1"
16281 [(set (match_operand:SWI48 0 "register_operand" "=r")
16282 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16283 [(reg FLAGS_REG) (const_int 0)])
16286 (clobber (reg:CC FLAGS_REG))]
16288 "sbb{<imodesuffix>}\t%0, %0"
16289 ; Since we don't have the proper number of operands for an alu insn,
16290 ; fill in all the blanks.
16291 [(set_attr "type" "alu")
16292 (set_attr "use_carry" "1")
16293 (set_attr "pent_pair" "pu")
16294 (set_attr "memory" "none")
16295 (set_attr "imm_disp" "false")
16296 (set_attr "mode" "<MODE>")
16297 (set_attr "length_immediate" "0")])
16299 (define_insn "*x86_mov<mode>cc_0_m1_se"
16300 [(set (match_operand:SWI48 0 "register_operand" "=r")
16301 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16302 [(reg FLAGS_REG) (const_int 0)])
16305 (clobber (reg:CC FLAGS_REG))]
16307 "sbb{<imodesuffix>}\t%0, %0"
16308 [(set_attr "type" "alu")
16309 (set_attr "use_carry" "1")
16310 (set_attr "pent_pair" "pu")
16311 (set_attr "memory" "none")
16312 (set_attr "imm_disp" "false")
16313 (set_attr "mode" "<MODE>")
16314 (set_attr "length_immediate" "0")])
16316 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16317 [(set (match_operand:SWI48 0 "register_operand" "=r")
16318 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16319 [(reg FLAGS_REG) (const_int 0)])))
16320 (clobber (reg:CC FLAGS_REG))]
16322 "sbb{<imodesuffix>}\t%0, %0"
16323 [(set_attr "type" "alu")
16324 (set_attr "use_carry" "1")
16325 (set_attr "pent_pair" "pu")
16326 (set_attr "memory" "none")
16327 (set_attr "imm_disp" "false")
16328 (set_attr "mode" "<MODE>")
16329 (set_attr "length_immediate" "0")])
16331 (define_insn "*mov<mode>cc_noc"
16332 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16333 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16334 [(reg FLAGS_REG) (const_int 0)])
16335 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16336 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16337 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16339 cmov%O2%C1\t{%2, %0|%0, %2}
16340 cmov%O2%c1\t{%3, %0|%0, %3}"
16341 [(set_attr "type" "icmov")
16342 (set_attr "mode" "<MODE>")])
16344 (define_insn "*movqicc_noc"
16345 [(set (match_operand:QI 0 "register_operand" "=r,r")
16346 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16347 [(reg FLAGS_REG) (const_int 0)])
16348 (match_operand:QI 2 "register_operand" "r,0")
16349 (match_operand:QI 3 "register_operand" "0,r")))]
16350 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16352 [(set_attr "type" "icmov")
16353 (set_attr "mode" "QI")])
16356 [(set (match_operand 0 "register_operand")
16357 (if_then_else (match_operator 1 "ix86_comparison_operator"
16358 [(reg FLAGS_REG) (const_int 0)])
16359 (match_operand 2 "register_operand")
16360 (match_operand 3 "register_operand")))]
16361 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16362 && (GET_MODE (operands[0]) == QImode
16363 || GET_MODE (operands[0]) == HImode)
16364 && reload_completed"
16365 [(set (match_dup 0)
16366 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16368 operands[0] = gen_lowpart (SImode, operands[0]);
16369 operands[2] = gen_lowpart (SImode, operands[2]);
16370 operands[3] = gen_lowpart (SImode, operands[3]);
16373 (define_expand "mov<mode>cc"
16374 [(set (match_operand:X87MODEF 0 "register_operand")
16375 (if_then_else:X87MODEF
16376 (match_operand 1 "ix86_fp_comparison_operator")
16377 (match_operand:X87MODEF 2 "register_operand")
16378 (match_operand:X87MODEF 3 "register_operand")))]
16379 "(TARGET_80387 && TARGET_CMOVE)
16380 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16381 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16383 (define_insn "*movxfcc_1"
16384 [(set (match_operand:XF 0 "register_operand" "=f,f")
16385 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16386 [(reg FLAGS_REG) (const_int 0)])
16387 (match_operand:XF 2 "register_operand" "f,0")
16388 (match_operand:XF 3 "register_operand" "0,f")))]
16389 "TARGET_80387 && TARGET_CMOVE"
16391 fcmov%F1\t{%2, %0|%0, %2}
16392 fcmov%f1\t{%3, %0|%0, %3}"
16393 [(set_attr "type" "fcmov")
16394 (set_attr "mode" "XF")])
16396 (define_insn "*movdfcc_1_rex64"
16397 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16398 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16399 [(reg FLAGS_REG) (const_int 0)])
16400 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16401 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16402 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16403 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16405 fcmov%F1\t{%2, %0|%0, %2}
16406 fcmov%f1\t{%3, %0|%0, %3}
16407 cmov%O2%C1\t{%2, %0|%0, %2}
16408 cmov%O2%c1\t{%3, %0|%0, %3}"
16409 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16410 (set_attr "mode" "DF,DF,DI,DI")])
16412 (define_insn "*movdfcc_1"
16413 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16414 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16415 [(reg FLAGS_REG) (const_int 0)])
16416 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16417 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16418 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16419 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16421 fcmov%F1\t{%2, %0|%0, %2}
16422 fcmov%f1\t{%3, %0|%0, %3}
16425 [(set_attr "type" "fcmov,fcmov,multi,multi")
16426 (set_attr "mode" "DF,DF,DI,DI")])
16429 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16430 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16431 [(reg FLAGS_REG) (const_int 0)])
16432 (match_operand:DF 2 "nonimmediate_operand")
16433 (match_operand:DF 3 "nonimmediate_operand")))]
16434 "!TARGET_64BIT && reload_completed"
16435 [(set (match_dup 2)
16436 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16438 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16440 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16441 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16444 (define_insn "*movsfcc_1_387"
16445 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16446 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16447 [(reg FLAGS_REG) (const_int 0)])
16448 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16449 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16450 "TARGET_80387 && TARGET_CMOVE
16451 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16453 fcmov%F1\t{%2, %0|%0, %2}
16454 fcmov%f1\t{%3, %0|%0, %3}
16455 cmov%O2%C1\t{%2, %0|%0, %2}
16456 cmov%O2%c1\t{%3, %0|%0, %3}"
16457 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16458 (set_attr "mode" "SF,SF,SI,SI")])
16460 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16461 ;; the scalar versions to have only XMM registers as operands.
16463 ;; XOP conditional move
16464 (define_insn "*xop_pcmov_<mode>"
16465 [(set (match_operand:MODEF 0 "register_operand" "=x")
16466 (if_then_else:MODEF
16467 (match_operand:MODEF 1 "register_operand" "x")
16468 (match_operand:MODEF 2 "register_operand" "x")
16469 (match_operand:MODEF 3 "register_operand" "x")))]
16471 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16472 [(set_attr "type" "sse4arg")])
16474 ;; These versions of the min/max patterns are intentionally ignorant of
16475 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16476 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16477 ;; are undefined in this condition, we're certain this is correct.
16479 (define_insn "<code><mode>3"
16480 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16482 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16483 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16484 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16486 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16487 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16488 [(set_attr "isa" "noavx,avx")
16489 (set_attr "prefix" "orig,vex")
16490 (set_attr "type" "sseadd")
16491 (set_attr "mode" "<MODE>")])
16493 ;; These versions of the min/max patterns implement exactly the operations
16494 ;; min = (op1 < op2 ? op1 : op2)
16495 ;; max = (!(op1 < op2) ? op1 : op2)
16496 ;; Their operands are not commutative, and thus they may be used in the
16497 ;; presence of -0.0 and NaN.
16499 (define_int_iterator IEEE_MAXMIN
16503 (define_int_attr ieee_maxmin
16504 [(UNSPEC_IEEE_MAX "max")
16505 (UNSPEC_IEEE_MIN "min")])
16507 (define_insn "*ieee_s<ieee_maxmin><mode>3"
16508 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16510 [(match_operand:MODEF 1 "register_operand" "0,x")
16511 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16513 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16515 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
16516 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16517 [(set_attr "isa" "noavx,avx")
16518 (set_attr "prefix" "orig,vex")
16519 (set_attr "type" "sseadd")
16520 (set_attr "mode" "<MODE>")])
16522 ;; Make two stack loads independent:
16524 ;; fld %st(0) -> fld bb
16525 ;; fmul bb fmul %st(1), %st
16527 ;; Actually we only match the last two instructions for simplicity.
16529 [(set (match_operand 0 "fp_register_operand")
16530 (match_operand 1 "fp_register_operand"))
16532 (match_operator 2 "binary_fp_operator"
16534 (match_operand 3 "memory_operand")]))]
16535 "REGNO (operands[0]) != REGNO (operands[1])"
16536 [(set (match_dup 0) (match_dup 3))
16537 (set (match_dup 0) (match_dup 4))]
16539 ;; The % modifier is not operational anymore in peephole2's, so we have to
16540 ;; swap the operands manually in the case of addition and multiplication.
16544 if (COMMUTATIVE_ARITH_P (operands[2]))
16545 op0 = operands[0], op1 = operands[1];
16547 op0 = operands[1], op1 = operands[0];
16549 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16550 GET_MODE (operands[2]),
16554 ;; Conditional addition patterns
16555 (define_expand "add<mode>cc"
16556 [(match_operand:SWI 0 "register_operand")
16557 (match_operand 1 "ordered_comparison_operator")
16558 (match_operand:SWI 2 "register_operand")
16559 (match_operand:SWI 3 "const_int_operand")]
16561 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16563 ;; Misc patterns (?)
16565 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16566 ;; Otherwise there will be nothing to keep
16568 ;; [(set (reg ebp) (reg esp))]
16569 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16570 ;; (clobber (eflags)]
16571 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16573 ;; in proper program order.
16575 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16576 [(set (match_operand:P 0 "register_operand" "=r,r")
16577 (plus:P (match_operand:P 1 "register_operand" "0,r")
16578 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16579 (clobber (reg:CC FLAGS_REG))
16580 (clobber (mem:BLK (scratch)))]
16583 switch (get_attr_type (insn))
16586 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16589 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16590 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16591 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16593 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16596 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16597 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16600 [(set (attr "type")
16601 (cond [(and (eq_attr "alternative" "0")
16602 (not (match_test "TARGET_OPT_AGU")))
16603 (const_string "alu")
16604 (match_operand:<MODE> 2 "const0_operand")
16605 (const_string "imov")
16607 (const_string "lea")))
16608 (set (attr "length_immediate")
16609 (cond [(eq_attr "type" "imov")
16611 (and (eq_attr "type" "alu")
16612 (match_operand 2 "const128_operand"))
16615 (const_string "*")))
16616 (set_attr "mode" "<MODE>")])
16618 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16619 [(set (match_operand:P 0 "register_operand" "=r")
16620 (minus:P (match_operand:P 1 "register_operand" "0")
16621 (match_operand:P 2 "register_operand" "r")))
16622 (clobber (reg:CC FLAGS_REG))
16623 (clobber (mem:BLK (scratch)))]
16625 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16626 [(set_attr "type" "alu")
16627 (set_attr "mode" "<MODE>")])
16629 (define_insn "allocate_stack_worker_probe_<mode>"
16630 [(set (match_operand:P 0 "register_operand" "=a")
16631 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16632 UNSPECV_STACK_PROBE))
16633 (clobber (reg:CC FLAGS_REG))]
16634 "ix86_target_stack_probe ()"
16635 "call\t___chkstk_ms"
16636 [(set_attr "type" "multi")
16637 (set_attr "length" "5")])
16639 (define_expand "allocate_stack"
16640 [(match_operand 0 "register_operand")
16641 (match_operand 1 "general_operand")]
16642 "ix86_target_stack_probe ()"
16646 #ifndef CHECK_STACK_LIMIT
16647 #define CHECK_STACK_LIMIT 0
16650 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16651 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16655 rtx (*insn) (rtx, rtx);
16657 x = copy_to_mode_reg (Pmode, operands[1]);
16659 insn = (TARGET_64BIT
16660 ? gen_allocate_stack_worker_probe_di
16661 : gen_allocate_stack_worker_probe_si);
16663 emit_insn (insn (x, x));
16666 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16667 stack_pointer_rtx, 0, OPTAB_DIRECT);
16669 if (x != stack_pointer_rtx)
16670 emit_move_insn (stack_pointer_rtx, x);
16672 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16676 ;; Use IOR for stack probes, this is shorter.
16677 (define_expand "probe_stack"
16678 [(match_operand 0 "memory_operand")]
16681 rtx (*gen_ior3) (rtx, rtx, rtx);
16683 gen_ior3 = (GET_MODE (operands[0]) == DImode
16684 ? gen_iordi3 : gen_iorsi3);
16686 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16690 (define_insn "adjust_stack_and_probe<mode>"
16691 [(set (match_operand:P 0 "register_operand" "=r")
16692 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16693 UNSPECV_PROBE_STACK_RANGE))
16694 (set (reg:P SP_REG)
16695 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16696 (clobber (reg:CC FLAGS_REG))
16697 (clobber (mem:BLK (scratch)))]
16699 "* return output_adjust_stack_and_probe (operands[0]);"
16700 [(set_attr "type" "multi")])
16702 (define_insn "probe_stack_range<mode>"
16703 [(set (match_operand:P 0 "register_operand" "=r")
16704 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16705 (match_operand:P 2 "const_int_operand" "n")]
16706 UNSPECV_PROBE_STACK_RANGE))
16707 (clobber (reg:CC FLAGS_REG))]
16709 "* return output_probe_stack_range (operands[0], operands[2]);"
16710 [(set_attr "type" "multi")])
16712 (define_expand "builtin_setjmp_receiver"
16713 [(label_ref (match_operand 0))]
16714 "!TARGET_64BIT && flag_pic"
16720 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16721 rtx label_rtx = gen_label_rtx ();
16722 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16723 xops[0] = xops[1] = picreg;
16724 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16725 ix86_expand_binary_operator (MINUS, SImode, xops);
16729 emit_insn (gen_set_got (pic_offset_table_rtx));
16733 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16736 [(set (match_operand 0 "register_operand")
16737 (match_operator 3 "promotable_binary_operator"
16738 [(match_operand 1 "register_operand")
16739 (match_operand 2 "aligned_operand")]))
16740 (clobber (reg:CC FLAGS_REG))]
16741 "! TARGET_PARTIAL_REG_STALL && reload_completed
16742 && ((GET_MODE (operands[0]) == HImode
16743 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16744 /* ??? next two lines just !satisfies_constraint_K (...) */
16745 || !CONST_INT_P (operands[2])
16746 || satisfies_constraint_K (operands[2])))
16747 || (GET_MODE (operands[0]) == QImode
16748 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16749 [(parallel [(set (match_dup 0)
16750 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16751 (clobber (reg:CC FLAGS_REG))])]
16753 operands[0] = gen_lowpart (SImode, operands[0]);
16754 operands[1] = gen_lowpart (SImode, operands[1]);
16755 if (GET_CODE (operands[3]) != ASHIFT)
16756 operands[2] = gen_lowpart (SImode, operands[2]);
16757 PUT_MODE (operands[3], SImode);
16760 ; Promote the QImode tests, as i386 has encoding of the AND
16761 ; instruction with 32-bit sign-extended immediate and thus the
16762 ; instruction size is unchanged, except in the %eax case for
16763 ; which it is increased by one byte, hence the ! optimize_size.
16765 [(set (match_operand 0 "flags_reg_operand")
16766 (match_operator 2 "compare_operator"
16767 [(and (match_operand 3 "aligned_operand")
16768 (match_operand 4 "const_int_operand"))
16770 (set (match_operand 1 "register_operand")
16771 (and (match_dup 3) (match_dup 4)))]
16772 "! TARGET_PARTIAL_REG_STALL && reload_completed
16773 && optimize_insn_for_speed_p ()
16774 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16775 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16776 /* Ensure that the operand will remain sign-extended immediate. */
16777 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16778 [(parallel [(set (match_dup 0)
16779 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16782 (and:SI (match_dup 3) (match_dup 4)))])]
16785 = gen_int_mode (INTVAL (operands[4])
16786 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16787 operands[1] = gen_lowpart (SImode, operands[1]);
16788 operands[3] = gen_lowpart (SImode, operands[3]);
16791 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16792 ; the TEST instruction with 32-bit sign-extended immediate and thus
16793 ; the instruction size would at least double, which is not what we
16794 ; want even with ! optimize_size.
16796 [(set (match_operand 0 "flags_reg_operand")
16797 (match_operator 1 "compare_operator"
16798 [(and (match_operand:HI 2 "aligned_operand")
16799 (match_operand:HI 3 "const_int_operand"))
16801 "! TARGET_PARTIAL_REG_STALL && reload_completed
16802 && ! TARGET_FAST_PREFIX
16803 && optimize_insn_for_speed_p ()
16804 /* Ensure that the operand will remain sign-extended immediate. */
16805 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16806 [(set (match_dup 0)
16807 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16811 = gen_int_mode (INTVAL (operands[3])
16812 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16813 operands[2] = gen_lowpart (SImode, operands[2]);
16817 [(set (match_operand 0 "register_operand")
16818 (neg (match_operand 1 "register_operand")))
16819 (clobber (reg:CC FLAGS_REG))]
16820 "! TARGET_PARTIAL_REG_STALL && reload_completed
16821 && (GET_MODE (operands[0]) == HImode
16822 || (GET_MODE (operands[0]) == QImode
16823 && (TARGET_PROMOTE_QImode
16824 || optimize_insn_for_size_p ())))"
16825 [(parallel [(set (match_dup 0)
16826 (neg:SI (match_dup 1)))
16827 (clobber (reg:CC FLAGS_REG))])]
16829 operands[0] = gen_lowpart (SImode, operands[0]);
16830 operands[1] = gen_lowpart (SImode, operands[1]);
16834 [(set (match_operand 0 "register_operand")
16835 (not (match_operand 1 "register_operand")))]
16836 "! TARGET_PARTIAL_REG_STALL && reload_completed
16837 && (GET_MODE (operands[0]) == HImode
16838 || (GET_MODE (operands[0]) == QImode
16839 && (TARGET_PROMOTE_QImode
16840 || optimize_insn_for_size_p ())))"
16841 [(set (match_dup 0)
16842 (not:SI (match_dup 1)))]
16844 operands[0] = gen_lowpart (SImode, operands[0]);
16845 operands[1] = gen_lowpart (SImode, operands[1]);
16848 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16849 ;; transform a complex memory operation into two memory to register operations.
16851 ;; Don't push memory operands
16853 [(set (match_operand:SWI 0 "push_operand")
16854 (match_operand:SWI 1 "memory_operand"))
16855 (match_scratch:SWI 2 "<r>")]
16856 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16857 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16858 [(set (match_dup 2) (match_dup 1))
16859 (set (match_dup 0) (match_dup 2))])
16861 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16864 [(set (match_operand:SF 0 "push_operand")
16865 (match_operand:SF 1 "memory_operand"))
16866 (match_scratch:SF 2 "r")]
16867 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16868 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16869 [(set (match_dup 2) (match_dup 1))
16870 (set (match_dup 0) (match_dup 2))])
16872 ;; Don't move an immediate directly to memory when the instruction
16873 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
16875 [(match_scratch:SWI124 1 "<r>")
16876 (set (match_operand:SWI124 0 "memory_operand")
16878 "optimize_insn_for_speed_p ()
16879 && ((<MODE>mode == HImode
16880 && TARGET_LCP_STALL)
16881 || (!TARGET_USE_MOV0
16882 && TARGET_SPLIT_LONG_MOVES
16883 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
16884 && peep2_regno_dead_p (0, FLAGS_REG)"
16885 [(parallel [(set (match_dup 2) (const_int 0))
16886 (clobber (reg:CC FLAGS_REG))])
16887 (set (match_dup 0) (match_dup 1))]
16888 "operands[2] = gen_lowpart (SImode, operands[1]);")
16891 [(match_scratch:SWI124 2 "<r>")
16892 (set (match_operand:SWI124 0 "memory_operand")
16893 (match_operand:SWI124 1 "immediate_operand"))]
16894 "optimize_insn_for_speed_p ()
16895 && ((<MODE>mode == HImode
16896 && TARGET_LCP_STALL)
16897 || (TARGET_SPLIT_LONG_MOVES
16898 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
16899 [(set (match_dup 2) (match_dup 1))
16900 (set (match_dup 0) (match_dup 2))])
16902 ;; Don't compare memory with zero, load and use a test instead.
16904 [(set (match_operand 0 "flags_reg_operand")
16905 (match_operator 1 "compare_operator"
16906 [(match_operand:SI 2 "memory_operand")
16908 (match_scratch:SI 3 "r")]
16909 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16910 [(set (match_dup 3) (match_dup 2))
16911 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16913 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16914 ;; Don't split NOTs with a displacement operand, because resulting XOR
16915 ;; will not be pairable anyway.
16917 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16918 ;; represented using a modRM byte. The XOR replacement is long decoded,
16919 ;; so this split helps here as well.
16921 ;; Note: Can't do this as a regular split because we can't get proper
16922 ;; lifetime information then.
16925 [(set (match_operand:SWI124 0 "nonimmediate_operand")
16926 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
16927 "optimize_insn_for_speed_p ()
16928 && ((TARGET_NOT_UNPAIRABLE
16929 && (!MEM_P (operands[0])
16930 || !memory_displacement_operand (operands[0], <MODE>mode)))
16931 || (TARGET_NOT_VECTORMODE
16932 && long_memory_operand (operands[0], <MODE>mode)))
16933 && peep2_regno_dead_p (0, FLAGS_REG)"
16934 [(parallel [(set (match_dup 0)
16935 (xor:SWI124 (match_dup 1) (const_int -1)))
16936 (clobber (reg:CC FLAGS_REG))])])
16938 ;; Non pairable "test imm, reg" instructions can be translated to
16939 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16940 ;; byte opcode instead of two, have a short form for byte operands),
16941 ;; so do it for other CPUs as well. Given that the value was dead,
16942 ;; this should not create any new dependencies. Pass on the sub-word
16943 ;; versions if we're concerned about partial register stalls.
16946 [(set (match_operand 0 "flags_reg_operand")
16947 (match_operator 1 "compare_operator"
16948 [(and:SI (match_operand:SI 2 "register_operand")
16949 (match_operand:SI 3 "immediate_operand"))
16951 "ix86_match_ccmode (insn, CCNOmode)
16952 && (true_regnum (operands[2]) != AX_REG
16953 || satisfies_constraint_K (operands[3]))
16954 && peep2_reg_dead_p (1, operands[2])"
16956 [(set (match_dup 0)
16957 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16960 (and:SI (match_dup 2) (match_dup 3)))])])
16962 ;; We don't need to handle HImode case, because it will be promoted to SImode
16963 ;; on ! TARGET_PARTIAL_REG_STALL
16966 [(set (match_operand 0 "flags_reg_operand")
16967 (match_operator 1 "compare_operator"
16968 [(and:QI (match_operand:QI 2 "register_operand")
16969 (match_operand:QI 3 "immediate_operand"))
16971 "! TARGET_PARTIAL_REG_STALL
16972 && ix86_match_ccmode (insn, CCNOmode)
16973 && true_regnum (operands[2]) != AX_REG
16974 && peep2_reg_dead_p (1, operands[2])"
16976 [(set (match_dup 0)
16977 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16980 (and:QI (match_dup 2) (match_dup 3)))])])
16983 [(set (match_operand 0 "flags_reg_operand")
16984 (match_operator 1 "compare_operator"
16987 (match_operand 2 "ext_register_operand")
16990 (match_operand 3 "const_int_operand"))
16992 "! TARGET_PARTIAL_REG_STALL
16993 && ix86_match_ccmode (insn, CCNOmode)
16994 && true_regnum (operands[2]) != AX_REG
16995 && peep2_reg_dead_p (1, operands[2])"
16996 [(parallel [(set (match_dup 0)
17005 (set (zero_extract:SI (match_dup 2)
17013 (match_dup 3)))])])
17015 ;; Don't do logical operations with memory inputs.
17017 [(match_scratch:SI 2 "r")
17018 (parallel [(set (match_operand:SI 0 "register_operand")
17019 (match_operator:SI 3 "arith_or_logical_operator"
17021 (match_operand:SI 1 "memory_operand")]))
17022 (clobber (reg:CC FLAGS_REG))])]
17023 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17024 [(set (match_dup 2) (match_dup 1))
17025 (parallel [(set (match_dup 0)
17026 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17027 (clobber (reg:CC FLAGS_REG))])])
17030 [(match_scratch:SI 2 "r")
17031 (parallel [(set (match_operand:SI 0 "register_operand")
17032 (match_operator:SI 3 "arith_or_logical_operator"
17033 [(match_operand:SI 1 "memory_operand")
17035 (clobber (reg:CC FLAGS_REG))])]
17036 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17037 [(set (match_dup 2) (match_dup 1))
17038 (parallel [(set (match_dup 0)
17039 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17040 (clobber (reg:CC FLAGS_REG))])])
17042 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17043 ;; refers to the destination of the load!
17046 [(set (match_operand:SI 0 "register_operand")
17047 (match_operand:SI 1 "register_operand"))
17048 (parallel [(set (match_dup 0)
17049 (match_operator:SI 3 "commutative_operator"
17051 (match_operand:SI 2 "memory_operand")]))
17052 (clobber (reg:CC FLAGS_REG))])]
17053 "REGNO (operands[0]) != REGNO (operands[1])
17054 && GENERAL_REGNO_P (REGNO (operands[0]))
17055 && GENERAL_REGNO_P (REGNO (operands[1]))"
17056 [(set (match_dup 0) (match_dup 4))
17057 (parallel [(set (match_dup 0)
17058 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17059 (clobber (reg:CC FLAGS_REG))])]
17060 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17063 [(set (match_operand 0 "register_operand")
17064 (match_operand 1 "register_operand"))
17066 (match_operator 3 "commutative_operator"
17068 (match_operand 2 "memory_operand")]))]
17069 "REGNO (operands[0]) != REGNO (operands[1])
17070 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17071 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17072 [(set (match_dup 0) (match_dup 2))
17074 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17076 ; Don't do logical operations with memory outputs
17078 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17079 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17080 ; the same decoder scheduling characteristics as the original.
17083 [(match_scratch:SI 2 "r")
17084 (parallel [(set (match_operand:SI 0 "memory_operand")
17085 (match_operator:SI 3 "arith_or_logical_operator"
17087 (match_operand:SI 1 "nonmemory_operand")]))
17088 (clobber (reg:CC FLAGS_REG))])]
17089 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17090 /* Do not split stack checking probes. */
17091 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17092 [(set (match_dup 2) (match_dup 0))
17093 (parallel [(set (match_dup 2)
17094 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17095 (clobber (reg:CC FLAGS_REG))])
17096 (set (match_dup 0) (match_dup 2))])
17099 [(match_scratch:SI 2 "r")
17100 (parallel [(set (match_operand:SI 0 "memory_operand")
17101 (match_operator:SI 3 "arith_or_logical_operator"
17102 [(match_operand:SI 1 "nonmemory_operand")
17104 (clobber (reg:CC FLAGS_REG))])]
17105 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17106 /* Do not split stack checking probes. */
17107 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17108 [(set (match_dup 2) (match_dup 0))
17109 (parallel [(set (match_dup 2)
17110 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17111 (clobber (reg:CC FLAGS_REG))])
17112 (set (match_dup 0) (match_dup 2))])
17114 ;; Attempt to use arith or logical operations with memory outputs with
17115 ;; setting of flags.
17117 [(set (match_operand:SWI 0 "register_operand")
17118 (match_operand:SWI 1 "memory_operand"))
17119 (parallel [(set (match_dup 0)
17120 (match_operator:SWI 3 "plusminuslogic_operator"
17122 (match_operand:SWI 2 "<nonmemory_operand>")]))
17123 (clobber (reg:CC FLAGS_REG))])
17124 (set (match_dup 1) (match_dup 0))
17125 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17126 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17127 && peep2_reg_dead_p (4, operands[0])
17128 && !reg_overlap_mentioned_p (operands[0], operands[1])
17129 && (<MODE>mode != QImode
17130 || immediate_operand (operands[2], QImode)
17131 || q_regs_operand (operands[2], QImode))
17132 && ix86_match_ccmode (peep2_next_insn (3),
17133 (GET_CODE (operands[3]) == PLUS
17134 || GET_CODE (operands[3]) == MINUS)
17135 ? CCGOCmode : CCNOmode)"
17136 [(parallel [(set (match_dup 4) (match_dup 5))
17137 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17138 (match_dup 2)]))])]
17140 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17141 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17142 copy_rtx (operands[1]),
17143 copy_rtx (operands[2]));
17144 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17145 operands[5], const0_rtx);
17149 [(parallel [(set (match_operand:SWI 0 "register_operand")
17150 (match_operator:SWI 2 "plusminuslogic_operator"
17152 (match_operand:SWI 1 "memory_operand")]))
17153 (clobber (reg:CC FLAGS_REG))])
17154 (set (match_dup 1) (match_dup 0))
17155 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17156 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17157 && GET_CODE (operands[2]) != MINUS
17158 && peep2_reg_dead_p (3, operands[0])
17159 && !reg_overlap_mentioned_p (operands[0], operands[1])
17160 && ix86_match_ccmode (peep2_next_insn (2),
17161 GET_CODE (operands[2]) == PLUS
17162 ? CCGOCmode : CCNOmode)"
17163 [(parallel [(set (match_dup 3) (match_dup 4))
17164 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17165 (match_dup 0)]))])]
17167 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17168 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17169 copy_rtx (operands[1]),
17170 copy_rtx (operands[0]));
17171 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17172 operands[4], const0_rtx);
17176 [(set (match_operand:SWI12 0 "register_operand")
17177 (match_operand:SWI12 1 "memory_operand"))
17178 (parallel [(set (match_operand:SI 4 "register_operand")
17179 (match_operator:SI 3 "plusminuslogic_operator"
17181 (match_operand:SI 2 "nonmemory_operand")]))
17182 (clobber (reg:CC FLAGS_REG))])
17183 (set (match_dup 1) (match_dup 0))
17184 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17185 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17186 && REG_P (operands[0]) && REG_P (operands[4])
17187 && REGNO (operands[0]) == REGNO (operands[4])
17188 && peep2_reg_dead_p (4, operands[0])
17189 && (<MODE>mode != QImode
17190 || immediate_operand (operands[2], SImode)
17191 || q_regs_operand (operands[2], SImode))
17192 && !reg_overlap_mentioned_p (operands[0], operands[1])
17193 && ix86_match_ccmode (peep2_next_insn (3),
17194 (GET_CODE (operands[3]) == PLUS
17195 || GET_CODE (operands[3]) == MINUS)
17196 ? CCGOCmode : CCNOmode)"
17197 [(parallel [(set (match_dup 4) (match_dup 5))
17198 (set (match_dup 1) (match_dup 6))])]
17200 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17201 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17202 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17203 copy_rtx (operands[1]), operands[2]);
17204 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17205 operands[5], const0_rtx);
17206 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17207 copy_rtx (operands[1]),
17208 copy_rtx (operands[2]));
17211 ;; Attempt to always use XOR for zeroing registers.
17213 [(set (match_operand 0 "register_operand")
17214 (match_operand 1 "const0_operand"))]
17215 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17216 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17217 && GENERAL_REG_P (operands[0])
17218 && peep2_regno_dead_p (0, FLAGS_REG)"
17219 [(parallel [(set (match_dup 0) (const_int 0))
17220 (clobber (reg:CC FLAGS_REG))])]
17221 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17224 [(set (strict_low_part (match_operand 0 "register_operand"))
17226 "(GET_MODE (operands[0]) == QImode
17227 || GET_MODE (operands[0]) == HImode)
17228 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17229 && peep2_regno_dead_p (0, FLAGS_REG)"
17230 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17231 (clobber (reg:CC FLAGS_REG))])])
17233 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17235 [(set (match_operand:SWI248 0 "register_operand")
17237 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17238 && peep2_regno_dead_p (0, FLAGS_REG)"
17239 [(parallel [(set (match_dup 0) (const_int -1))
17240 (clobber (reg:CC FLAGS_REG))])]
17242 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17243 operands[0] = gen_lowpart (SImode, operands[0]);
17246 ;; Attempt to convert simple lea to add/shift.
17247 ;; These can be created by move expanders.
17250 [(set (match_operand:SWI48 0 "register_operand")
17251 (plus:SWI48 (match_dup 0)
17252 (match_operand:SWI48 1 "<nonmemory_operand>")))]
17253 "peep2_regno_dead_p (0, FLAGS_REG)"
17254 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17255 (clobber (reg:CC FLAGS_REG))])])
17258 [(set (match_operand:SWI48 0 "register_operand")
17259 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
17261 "peep2_regno_dead_p (0, FLAGS_REG)"
17262 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17263 (clobber (reg:CC FLAGS_REG))])])
17266 [(set (match_operand:SI 0 "register_operand")
17267 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand")
17268 (match_operand:DI 2 "nonmemory_operand")) 0))]
17270 && peep2_regno_dead_p (0, FLAGS_REG)
17271 && REGNO (operands[0]) == REGNO (operands[1])"
17272 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17273 (clobber (reg:CC FLAGS_REG))])]
17274 "operands[2] = gen_lowpart (SImode, operands[2]);")
17277 [(set (match_operand:SI 0 "register_operand")
17278 (subreg:SI (plus:DI (match_operand:DI 1 "nonmemory_operand")
17279 (match_operand:DI 2 "register_operand")) 0))]
17281 && peep2_regno_dead_p (0, FLAGS_REG)
17282 && REGNO (operands[0]) == REGNO (operands[2])"
17283 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
17284 (clobber (reg:CC FLAGS_REG))])]
17285 "operands[1] = gen_lowpart (SImode, operands[1]);")
17288 [(set (match_operand:SWI48 0 "register_operand")
17289 (mult:SWI48 (match_dup 0)
17290 (match_operand:SWI48 1 "const_int_operand")))]
17291 "exact_log2 (INTVAL (operands[1])) >= 0
17292 && peep2_regno_dead_p (0, FLAGS_REG)"
17293 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17294 (clobber (reg:CC FLAGS_REG))])]
17295 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17298 [(set (match_operand:SI 0 "register_operand")
17299 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand")
17300 (match_operand:DI 2 "const_int_operand")) 0))]
17302 && exact_log2 (INTVAL (operands[2])) >= 0
17303 && REGNO (operands[0]) == REGNO (operands[1])
17304 && peep2_regno_dead_p (0, FLAGS_REG)"
17305 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17306 (clobber (reg:CC FLAGS_REG))])]
17307 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17309 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17310 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17311 ;; On many CPUs it is also faster, since special hardware to avoid esp
17312 ;; dependencies is present.
17314 ;; While some of these conversions may be done using splitters, we use
17315 ;; peepholes in order to allow combine_stack_adjustments pass to see
17316 ;; nonobfuscated RTL.
17318 ;; Convert prologue esp subtractions to push.
17319 ;; We need register to push. In order to keep verify_flow_info happy we have
17321 ;; - use scratch and clobber it in order to avoid dependencies
17322 ;; - use already live register
17323 ;; We can't use the second way right now, since there is no reliable way how to
17324 ;; verify that given register is live. First choice will also most likely in
17325 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17326 ;; call clobbered registers are dead. We may want to use base pointer as an
17327 ;; alternative when no register is available later.
17330 [(match_scratch:W 1 "r")
17331 (parallel [(set (reg:P SP_REG)
17332 (plus:P (reg:P SP_REG)
17333 (match_operand:P 0 "const_int_operand")))
17334 (clobber (reg:CC FLAGS_REG))
17335 (clobber (mem:BLK (scratch)))])]
17336 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17337 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17338 [(clobber (match_dup 1))
17339 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17340 (clobber (mem:BLK (scratch)))])])
17343 [(match_scratch:W 1 "r")
17344 (parallel [(set (reg:P SP_REG)
17345 (plus:P (reg:P SP_REG)
17346 (match_operand:P 0 "const_int_operand")))
17347 (clobber (reg:CC FLAGS_REG))
17348 (clobber (mem:BLK (scratch)))])]
17349 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17350 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17351 [(clobber (match_dup 1))
17352 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17353 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17354 (clobber (mem:BLK (scratch)))])])
17356 ;; Convert esp subtractions to push.
17358 [(match_scratch:W 1 "r")
17359 (parallel [(set (reg:P SP_REG)
17360 (plus:P (reg:P SP_REG)
17361 (match_operand:P 0 "const_int_operand")))
17362 (clobber (reg:CC FLAGS_REG))])]
17363 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17364 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17365 [(clobber (match_dup 1))
17366 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17369 [(match_scratch:W 1 "r")
17370 (parallel [(set (reg:P SP_REG)
17371 (plus:P (reg:P SP_REG)
17372 (match_operand:P 0 "const_int_operand")))
17373 (clobber (reg:CC FLAGS_REG))])]
17374 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17375 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17376 [(clobber (match_dup 1))
17377 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17378 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17380 ;; Convert epilogue deallocator to pop.
17382 [(match_scratch:W 1 "r")
17383 (parallel [(set (reg:P SP_REG)
17384 (plus:P (reg:P SP_REG)
17385 (match_operand:P 0 "const_int_operand")))
17386 (clobber (reg:CC FLAGS_REG))
17387 (clobber (mem:BLK (scratch)))])]
17388 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17389 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17390 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17391 (clobber (mem:BLK (scratch)))])])
17393 ;; Two pops case is tricky, since pop causes dependency
17394 ;; on destination register. We use two registers if available.
17396 [(match_scratch:W 1 "r")
17397 (match_scratch:W 2 "r")
17398 (parallel [(set (reg:P SP_REG)
17399 (plus:P (reg:P SP_REG)
17400 (match_operand:P 0 "const_int_operand")))
17401 (clobber (reg:CC FLAGS_REG))
17402 (clobber (mem:BLK (scratch)))])]
17403 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17404 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17405 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17406 (clobber (mem:BLK (scratch)))])
17407 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17410 [(match_scratch:W 1 "r")
17411 (parallel [(set (reg:P SP_REG)
17412 (plus:P (reg:P SP_REG)
17413 (match_operand:P 0 "const_int_operand")))
17414 (clobber (reg:CC FLAGS_REG))
17415 (clobber (mem:BLK (scratch)))])]
17416 "optimize_insn_for_size_p ()
17417 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17418 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17419 (clobber (mem:BLK (scratch)))])
17420 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17422 ;; Convert esp additions to pop.
17424 [(match_scratch:W 1 "r")
17425 (parallel [(set (reg:P SP_REG)
17426 (plus:P (reg:P SP_REG)
17427 (match_operand:P 0 "const_int_operand")))
17428 (clobber (reg:CC FLAGS_REG))])]
17429 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17430 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17432 ;; Two pops case is tricky, since pop causes dependency
17433 ;; on destination register. We use two registers if available.
17435 [(match_scratch:W 1 "r")
17436 (match_scratch:W 2 "r")
17437 (parallel [(set (reg:P SP_REG)
17438 (plus:P (reg:P SP_REG)
17439 (match_operand:P 0 "const_int_operand")))
17440 (clobber (reg:CC FLAGS_REG))])]
17441 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17442 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17443 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17446 [(match_scratch:W 1 "r")
17447 (parallel [(set (reg:P SP_REG)
17448 (plus:P (reg:P SP_REG)
17449 (match_operand:P 0 "const_int_operand")))
17450 (clobber (reg:CC FLAGS_REG))])]
17451 "optimize_insn_for_size_p ()
17452 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17453 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17454 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17456 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17457 ;; required and register dies. Similarly for 128 to -128.
17459 [(set (match_operand 0 "flags_reg_operand")
17460 (match_operator 1 "compare_operator"
17461 [(match_operand 2 "register_operand")
17462 (match_operand 3 "const_int_operand")]))]
17463 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17464 && incdec_operand (operands[3], GET_MODE (operands[3])))
17465 || (!TARGET_FUSE_CMP_AND_BRANCH
17466 && INTVAL (operands[3]) == 128))
17467 && ix86_match_ccmode (insn, CCGCmode)
17468 && peep2_reg_dead_p (1, operands[2])"
17469 [(parallel [(set (match_dup 0)
17470 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17471 (clobber (match_dup 2))])])
17473 ;; Convert imul by three, five and nine into lea
17476 [(set (match_operand:SWI48 0 "register_operand")
17477 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
17478 (match_operand:SWI48 2 "const359_operand")))
17479 (clobber (reg:CC FLAGS_REG))])]
17480 "!TARGET_PARTIAL_REG_STALL
17481 || <MODE>mode == SImode
17482 || optimize_function_for_size_p (cfun)"
17483 [(set (match_dup 0)
17484 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17486 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17490 [(set (match_operand:SWI48 0 "register_operand")
17491 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17492 (match_operand:SWI48 2 "const359_operand")))
17493 (clobber (reg:CC FLAGS_REG))])]
17494 "optimize_insn_for_speed_p ()
17495 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17496 [(set (match_dup 0) (match_dup 1))
17498 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17500 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17502 ;; imul $32bit_imm, mem, reg is vector decoded, while
17503 ;; imul $32bit_imm, reg, reg is direct decoded.
17505 [(match_scratch:SWI48 3 "r")
17506 (parallel [(set (match_operand:SWI48 0 "register_operand")
17507 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
17508 (match_operand:SWI48 2 "immediate_operand")))
17509 (clobber (reg:CC FLAGS_REG))])]
17510 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17511 && !satisfies_constraint_K (operands[2])"
17512 [(set (match_dup 3) (match_dup 1))
17513 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17514 (clobber (reg:CC FLAGS_REG))])])
17517 [(match_scratch:SI 3 "r")
17518 (parallel [(set (match_operand:DI 0 "register_operand")
17520 (mult:SI (match_operand:SI 1 "memory_operand")
17521 (match_operand:SI 2 "immediate_operand"))))
17522 (clobber (reg:CC FLAGS_REG))])]
17524 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17525 && !satisfies_constraint_K (operands[2])"
17526 [(set (match_dup 3) (match_dup 1))
17527 (parallel [(set (match_dup 0)
17528 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17529 (clobber (reg:CC FLAGS_REG))])])
17531 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17532 ;; Convert it into imul reg, reg
17533 ;; It would be better to force assembler to encode instruction using long
17534 ;; immediate, but there is apparently no way to do so.
17536 [(parallel [(set (match_operand:SWI248 0 "register_operand")
17538 (match_operand:SWI248 1 "nonimmediate_operand")
17539 (match_operand:SWI248 2 "const_int_operand")))
17540 (clobber (reg:CC FLAGS_REG))])
17541 (match_scratch:SWI248 3 "r")]
17542 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17543 && satisfies_constraint_K (operands[2])"
17544 [(set (match_dup 3) (match_dup 2))
17545 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17546 (clobber (reg:CC FLAGS_REG))])]
17548 if (!rtx_equal_p (operands[0], operands[1]))
17549 emit_move_insn (operands[0], operands[1]);
17552 ;; After splitting up read-modify operations, array accesses with memory
17553 ;; operands might end up in form:
17555 ;; movl 4(%esp), %edx
17557 ;; instead of pre-splitting:
17559 ;; addl 4(%esp), %eax
17561 ;; movl 4(%esp), %edx
17562 ;; leal (%edx,%eax,4), %eax
17565 [(match_scratch:W 5 "r")
17566 (parallel [(set (match_operand 0 "register_operand")
17567 (ashift (match_operand 1 "register_operand")
17568 (match_operand 2 "const_int_operand")))
17569 (clobber (reg:CC FLAGS_REG))])
17570 (parallel [(set (match_operand 3 "register_operand")
17571 (plus (match_dup 0)
17572 (match_operand 4 "x86_64_general_operand")))
17573 (clobber (reg:CC FLAGS_REG))])]
17574 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17575 /* Validate MODE for lea. */
17576 && ((!TARGET_PARTIAL_REG_STALL
17577 && (GET_MODE (operands[0]) == QImode
17578 || GET_MODE (operands[0]) == HImode))
17579 || GET_MODE (operands[0]) == SImode
17580 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17581 && (rtx_equal_p (operands[0], operands[3])
17582 || peep2_reg_dead_p (2, operands[0]))
17583 /* We reorder load and the shift. */
17584 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17585 [(set (match_dup 5) (match_dup 4))
17586 (set (match_dup 0) (match_dup 1))]
17588 enum machine_mode op1mode = GET_MODE (operands[1]);
17589 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17590 int scale = 1 << INTVAL (operands[2]);
17591 rtx index = gen_lowpart (word_mode, operands[1]);
17592 rtx base = gen_lowpart (word_mode, operands[5]);
17593 rtx dest = gen_lowpart (mode, operands[3]);
17595 operands[1] = gen_rtx_PLUS (word_mode, base,
17596 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
17597 operands[5] = base;
17598 if (mode != word_mode)
17599 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17600 if (op1mode != word_mode)
17601 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17602 operands[0] = dest;
17605 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17606 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17607 ;; caught for use by garbage collectors and the like. Using an insn that
17608 ;; maps to SIGILL makes it more likely the program will rightfully die.
17609 ;; Keeping with tradition, "6" is in honor of #UD.
17610 (define_insn "trap"
17611 [(trap_if (const_int 1) (const_int 6))]
17613 { return ASM_SHORT "0x0b0f"; }
17614 [(set_attr "length" "2")])
17616 (define_expand "prefetch"
17617 [(prefetch (match_operand 0 "address_operand")
17618 (match_operand:SI 1 "const_int_operand")
17619 (match_operand:SI 2 "const_int_operand"))]
17620 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17622 int rw = INTVAL (operands[1]);
17623 int locality = INTVAL (operands[2]);
17625 gcc_assert (rw == 0 || rw == 1);
17626 gcc_assert (locality >= 0 && locality <= 3);
17627 gcc_assert (GET_MODE (operands[0]) == Pmode
17628 || GET_MODE (operands[0]) == VOIDmode);
17629 if (TARGET_PRFCHW && rw)
17630 operands[2] = GEN_INT (3);
17632 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17633 supported by SSE counterpart or the SSE prefetch is not available
17634 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17636 else if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17637 operands[2] = GEN_INT (3);
17639 operands[1] = const0_rtx;
17642 (define_insn "*prefetch_sse_<mode>"
17643 [(prefetch (match_operand:P 0 "address_operand" "p")
17645 (match_operand:SI 1 "const_int_operand"))]
17646 "TARGET_PREFETCH_SSE"
17648 static const char * const patterns[4] = {
17649 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17652 int locality = INTVAL (operands[1]);
17653 gcc_assert (locality >= 0 && locality <= 3);
17655 return patterns[locality];
17657 [(set_attr "type" "sse")
17658 (set_attr "atom_sse_attr" "prefetch")
17659 (set (attr "length_address")
17660 (symbol_ref "memory_address_length (operands[0])"))
17661 (set_attr "memory" "none")])
17663 (define_insn "*prefetch_3dnow_<mode>"
17664 [(prefetch (match_operand:P 0 "address_operand" "p")
17665 (match_operand:SI 1 "const_int_operand" "n")
17667 "TARGET_3DNOW || TARGET_PRFCHW"
17669 if (INTVAL (operands[1]) == 0)
17670 return "prefetch\t%a0";
17672 return "prefetchw\t%a0";
17674 [(set_attr "type" "mmx")
17675 (set (attr "length_address")
17676 (symbol_ref "memory_address_length (operands[0])"))
17677 (set_attr "memory" "none")])
17679 (define_expand "stack_protect_set"
17680 [(match_operand 0 "memory_operand")
17681 (match_operand 1 "memory_operand")]
17682 "!TARGET_HAS_BIONIC"
17684 rtx (*insn)(rtx, rtx);
17686 #ifdef TARGET_THREAD_SSP_OFFSET
17687 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17688 insn = (TARGET_LP64
17689 ? gen_stack_tls_protect_set_di
17690 : gen_stack_tls_protect_set_si);
17692 insn = (TARGET_LP64
17693 ? gen_stack_protect_set_di
17694 : gen_stack_protect_set_si);
17697 emit_insn (insn (operands[0], operands[1]));
17701 (define_insn "stack_protect_set_<mode>"
17702 [(set (match_operand:PTR 0 "memory_operand" "=m")
17703 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17705 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17706 (clobber (reg:CC FLAGS_REG))]
17707 "!TARGET_HAS_BIONIC"
17708 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17709 [(set_attr "type" "multi")])
17711 (define_insn "stack_tls_protect_set_<mode>"
17712 [(set (match_operand:PTR 0 "memory_operand" "=m")
17713 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17714 UNSPEC_SP_TLS_SET))
17715 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17716 (clobber (reg:CC FLAGS_REG))]
17718 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17719 [(set_attr "type" "multi")])
17721 (define_expand "stack_protect_test"
17722 [(match_operand 0 "memory_operand")
17723 (match_operand 1 "memory_operand")
17725 "!TARGET_HAS_BIONIC"
17727 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17729 rtx (*insn)(rtx, rtx, rtx);
17731 #ifdef TARGET_THREAD_SSP_OFFSET
17732 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17733 insn = (TARGET_LP64
17734 ? gen_stack_tls_protect_test_di
17735 : gen_stack_tls_protect_test_si);
17737 insn = (TARGET_LP64
17738 ? gen_stack_protect_test_di
17739 : gen_stack_protect_test_si);
17742 emit_insn (insn (flags, operands[0], operands[1]));
17744 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17745 flags, const0_rtx, operands[2]));
17749 (define_insn "stack_protect_test_<mode>"
17750 [(set (match_operand:CCZ 0 "flags_reg_operand")
17751 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17752 (match_operand:PTR 2 "memory_operand" "m")]
17754 (clobber (match_scratch:PTR 3 "=&r"))]
17755 "!TARGET_HAS_BIONIC"
17756 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17757 [(set_attr "type" "multi")])
17759 (define_insn "stack_tls_protect_test_<mode>"
17760 [(set (match_operand:CCZ 0 "flags_reg_operand")
17761 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17762 (match_operand:PTR 2 "const_int_operand" "i")]
17763 UNSPEC_SP_TLS_TEST))
17764 (clobber (match_scratch:PTR 3 "=r"))]
17766 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17767 [(set_attr "type" "multi")])
17769 (define_insn "sse4_2_crc32<mode>"
17770 [(set (match_operand:SI 0 "register_operand" "=r")
17772 [(match_operand:SI 1 "register_operand" "0")
17773 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17775 "TARGET_SSE4_2 || TARGET_CRC32"
17776 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17777 [(set_attr "type" "sselog1")
17778 (set_attr "prefix_rep" "1")
17779 (set_attr "prefix_extra" "1")
17780 (set (attr "prefix_data16")
17781 (if_then_else (match_operand:HI 2)
17783 (const_string "*")))
17784 (set (attr "prefix_rex")
17785 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
17787 (const_string "*")))
17788 (set_attr "mode" "SI")])
17790 (define_insn "sse4_2_crc32di"
17791 [(set (match_operand:DI 0 "register_operand" "=r")
17793 [(match_operand:DI 1 "register_operand" "0")
17794 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17796 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17797 "crc32{q}\t{%2, %0|%0, %2}"
17798 [(set_attr "type" "sselog1")
17799 (set_attr "prefix_rep" "1")
17800 (set_attr "prefix_extra" "1")
17801 (set_attr "mode" "DI")])
17803 (define_expand "rdpmc"
17804 [(match_operand:DI 0 "register_operand")
17805 (match_operand:SI 1 "register_operand")]
17808 rtx reg = gen_reg_rtx (DImode);
17811 /* Force operand 1 into ECX. */
17812 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17813 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17814 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17819 rtvec vec = rtvec_alloc (2);
17820 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17821 rtx upper = gen_reg_rtx (DImode);
17822 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17823 gen_rtvec (1, const0_rtx),
17825 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17826 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17828 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17829 NULL, 1, OPTAB_DIRECT);
17830 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17834 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17835 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17839 (define_insn "*rdpmc"
17840 [(set (match_operand:DI 0 "register_operand" "=A")
17841 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17845 [(set_attr "type" "other")
17846 (set_attr "length" "2")])
17848 (define_insn "*rdpmc_rex64"
17849 [(set (match_operand:DI 0 "register_operand" "=a")
17850 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17852 (set (match_operand:DI 1 "register_operand" "=d")
17853 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17856 [(set_attr "type" "other")
17857 (set_attr "length" "2")])
17859 (define_expand "rdtsc"
17860 [(set (match_operand:DI 0 "register_operand")
17861 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17866 rtvec vec = rtvec_alloc (2);
17867 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17868 rtx upper = gen_reg_rtx (DImode);
17869 rtx lower = gen_reg_rtx (DImode);
17870 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17871 gen_rtvec (1, const0_rtx),
17873 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17874 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17876 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17877 NULL, 1, OPTAB_DIRECT);
17878 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17880 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17885 (define_insn "*rdtsc"
17886 [(set (match_operand:DI 0 "register_operand" "=A")
17887 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17890 [(set_attr "type" "other")
17891 (set_attr "length" "2")])
17893 (define_insn "*rdtsc_rex64"
17894 [(set (match_operand:DI 0 "register_operand" "=a")
17895 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17896 (set (match_operand:DI 1 "register_operand" "=d")
17897 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17900 [(set_attr "type" "other")
17901 (set_attr "length" "2")])
17903 (define_expand "rdtscp"
17904 [(match_operand:DI 0 "register_operand")
17905 (match_operand:SI 1 "memory_operand")]
17908 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17909 gen_rtvec (1, const0_rtx),
17911 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17912 gen_rtvec (1, const0_rtx),
17914 rtx reg = gen_reg_rtx (DImode);
17915 rtx tmp = gen_reg_rtx (SImode);
17919 rtvec vec = rtvec_alloc (3);
17920 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17921 rtx upper = gen_reg_rtx (DImode);
17922 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17923 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17924 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17926 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17927 NULL, 1, OPTAB_DIRECT);
17928 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17933 rtvec vec = rtvec_alloc (2);
17934 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17935 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17936 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17939 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17940 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17944 (define_insn "*rdtscp"
17945 [(set (match_operand:DI 0 "register_operand" "=A")
17946 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17947 (set (match_operand:SI 1 "register_operand" "=c")
17948 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17951 [(set_attr "type" "other")
17952 (set_attr "length" "3")])
17954 (define_insn "*rdtscp_rex64"
17955 [(set (match_operand:DI 0 "register_operand" "=a")
17956 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17957 (set (match_operand:DI 1 "register_operand" "=d")
17958 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17959 (set (match_operand:SI 2 "register_operand" "=c")
17960 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17963 [(set_attr "type" "other")
17964 (set_attr "length" "3")])
17966 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17968 ;; LWP instructions
17970 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17972 (define_expand "lwp_llwpcb"
17973 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17974 UNSPECV_LLWP_INTRINSIC)]
17977 (define_insn "*lwp_llwpcb<mode>1"
17978 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17979 UNSPECV_LLWP_INTRINSIC)]
17982 [(set_attr "type" "lwp")
17983 (set_attr "mode" "<MODE>")
17984 (set_attr "length" "5")])
17986 (define_expand "lwp_slwpcb"
17987 [(set (match_operand 0 "register_operand" "=r")
17988 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17993 insn = (Pmode == DImode
17995 : gen_lwp_slwpcbsi);
17997 emit_insn (insn (operands[0]));
18001 (define_insn "lwp_slwpcb<mode>"
18002 [(set (match_operand:P 0 "register_operand" "=r")
18003 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18006 [(set_attr "type" "lwp")
18007 (set_attr "mode" "<MODE>")
18008 (set_attr "length" "5")])
18010 (define_expand "lwp_lwpval<mode>3"
18011 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18012 (match_operand:SI 2 "nonimmediate_operand" "rm")
18013 (match_operand:SI 3 "const_int_operand" "i")]
18014 UNSPECV_LWPVAL_INTRINSIC)]
18016 ;; Avoid unused variable warning.
18017 "(void) operands[0];")
18019 (define_insn "*lwp_lwpval<mode>3_1"
18020 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18021 (match_operand:SI 1 "nonimmediate_operand" "rm")
18022 (match_operand:SI 2 "const_int_operand" "i")]
18023 UNSPECV_LWPVAL_INTRINSIC)]
18025 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18026 [(set_attr "type" "lwp")
18027 (set_attr "mode" "<MODE>")
18028 (set (attr "length")
18029 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18031 (define_expand "lwp_lwpins<mode>3"
18032 [(set (reg:CCC FLAGS_REG)
18033 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18034 (match_operand:SI 2 "nonimmediate_operand" "rm")
18035 (match_operand:SI 3 "const_int_operand" "i")]
18036 UNSPECV_LWPINS_INTRINSIC))
18037 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18038 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18041 (define_insn "*lwp_lwpins<mode>3_1"
18042 [(set (reg:CCC FLAGS_REG)
18043 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18044 (match_operand:SI 1 "nonimmediate_operand" "rm")
18045 (match_operand:SI 2 "const_int_operand" "i")]
18046 UNSPECV_LWPINS_INTRINSIC))]
18048 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18049 [(set_attr "type" "lwp")
18050 (set_attr "mode" "<MODE>")
18051 (set (attr "length")
18052 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18054 (define_int_iterator RDFSGSBASE
18058 (define_int_iterator WRFSGSBASE
18062 (define_int_attr fsgs
18063 [(UNSPECV_RDFSBASE "fs")
18064 (UNSPECV_RDGSBASE "gs")
18065 (UNSPECV_WRFSBASE "fs")
18066 (UNSPECV_WRGSBASE "gs")])
18068 (define_insn "rd<fsgs>base<mode>"
18069 [(set (match_operand:SWI48 0 "register_operand" "=r")
18070 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
18071 "TARGET_64BIT && TARGET_FSGSBASE"
18073 [(set_attr "type" "other")
18074 (set_attr "prefix_extra" "2")])
18076 (define_insn "wr<fsgs>base<mode>"
18077 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18079 "TARGET_64BIT && TARGET_FSGSBASE"
18081 [(set_attr "type" "other")
18082 (set_attr "prefix_extra" "2")])
18084 (define_insn "rdrand<mode>_1"
18085 [(set (match_operand:SWI248 0 "register_operand" "=r")
18086 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18087 (set (reg:CCC FLAGS_REG)
18088 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18091 [(set_attr "type" "other")
18092 (set_attr "prefix_extra" "1")])
18094 (define_expand "pause"
18095 [(set (match_dup 0)
18096 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18099 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18100 MEM_VOLATILE_P (operands[0]) = 1;
18103 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18104 ;; They have the same encoding.
18105 (define_insn "*pause"
18106 [(set (match_operand:BLK 0)
18107 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18110 [(set_attr "length" "2")
18111 (set_attr "memory" "unknown")])
18113 (define_expand "xbegin"
18114 [(set (match_operand:SI 0 "register_operand")
18115 (unspec_volatile:SI [(match_dup 1)] UNSPECV_XBEGIN))]
18118 rtx label = gen_label_rtx ();
18120 operands[1] = force_reg (SImode, constm1_rtx);
18122 emit_jump_insn (gen_xbegin_1 (operands[1], label));
18124 emit_label (label);
18125 LABEL_NUSES (label) = 1;
18127 emit_move_insn (operands[0], operands[1]);
18132 (define_insn "xbegin_1"
18134 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18136 (label_ref (match_operand 1))
18138 (set (match_operand:SI 0 "register_operand" "+a")
18139 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
18142 [(set_attr "type" "other")
18143 (set_attr "length" "6")])
18145 (define_insn "xend"
18146 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18149 [(set_attr "type" "other")
18150 (set_attr "length" "3")])
18152 (define_insn "xabort"
18153 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18157 [(set_attr "type" "other")
18158 (set_attr "length" "3")])
18160 (define_expand "xtest"
18161 [(set (match_operand:QI 0 "register_operand")
18162 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18165 emit_insn (gen_xtest_1 ());
18167 ix86_expand_setcc (operands[0], NE,
18168 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18172 (define_insn "xtest_1"
18173 [(set (reg:CCZ FLAGS_REG)
18174 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18177 [(set_attr "type" "other")
18178 (set_attr "length" "3")])
18182 (include "sync.md")