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"
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]);
5455 (define_expand "add<mode>3"
5456 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5457 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5458 (match_operand:SDWIM 2 "<general_operand>")))]
5460 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5462 (define_insn_and_split "*add<dwi>3_doubleword"
5463 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5465 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5466 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5467 (clobber (reg:CC FLAGS_REG))]
5468 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5471 [(parallel [(set (reg:CC FLAGS_REG)
5472 (unspec:CC [(match_dup 1) (match_dup 2)]
5475 (plus:DWIH (match_dup 1) (match_dup 2)))])
5476 (parallel [(set (match_dup 3)
5480 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5482 (clobber (reg:CC FLAGS_REG))])]
5483 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5485 (define_insn "*add<mode>3_cc"
5486 [(set (reg:CC FLAGS_REG)
5488 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5489 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5491 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5492 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5493 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5494 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5495 [(set_attr "type" "alu")
5496 (set_attr "mode" "<MODE>")])
5498 (define_insn "addqi3_cc"
5499 [(set (reg:CC FLAGS_REG)
5501 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5502 (match_operand:QI 2 "general_operand" "qn,qm")]
5504 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5505 (plus:QI (match_dup 1) (match_dup 2)))]
5506 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5507 "add{b}\t{%2, %0|%0, %2}"
5508 [(set_attr "type" "alu")
5509 (set_attr "mode" "QI")])
5511 (define_insn_and_split "*lea_1"
5512 [(set (match_operand:SI 0 "register_operand" "=r")
5513 (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0))]
5515 "lea{l}\t{%E1, %0|%0, %E1}"
5516 "&& reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5519 ix86_split_lea_for_addr (operands, SImode);
5522 [(set_attr "type" "lea")
5523 (set_attr "mode" "SI")])
5525 (define_insn_and_split "*lea<mode>_2"
5526 [(set (match_operand:SWI48 0 "register_operand" "=r")
5527 (match_operand:SWI48 1 "lea_address_operand" "p"))]
5529 "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}"
5530 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5533 ix86_split_lea_for_addr (operands, <MODE>mode);
5536 [(set_attr "type" "lea")
5537 (set_attr "mode" "<MODE>")])
5539 (define_insn "*lea_3_zext"
5540 [(set (match_operand:DI 0 "register_operand" "=r")
5542 (subreg:SI (match_operand:DI 1 "lea_address_operand" "j") 0)))]
5544 "lea{l}\t{%E1, %k0|%k0, %E1}"
5545 [(set_attr "type" "lea")
5546 (set_attr "mode" "SI")])
5548 (define_insn "*lea_4_zext"
5549 [(set (match_operand:DI 0 "register_operand" "=r")
5551 (match_operand:SI 1 "lea_address_operand" "j")))]
5553 "lea{l}\t{%E1, %k0|%k0, %E1}"
5554 [(set_attr "type" "lea")
5555 (set_attr "mode" "SI")])
5557 (define_insn "*lea_5_zext"
5558 [(set (match_operand:DI 0 "register_operand" "=r")
5560 (subreg:DI (match_operand:SI 1 "lea_address_operand" "p") 0)
5561 (match_operand:DI 2 "const_32bit_mask" "n")))]
5563 "lea{l}\t{%E1, %k0|%k0, %E1}"
5564 [(set_attr "type" "lea")
5565 (set_attr "mode" "SI")])
5567 (define_insn "*lea_6_zext"
5568 [(set (match_operand:DI 0 "register_operand" "=r")
5570 (match_operand:DI 1 "lea_address_operand" "p")
5571 (match_operand:DI 2 "const_32bit_mask" "n")))]
5573 "lea{l}\t{%E1, %k0|%k0, %E1}"
5574 [(set_attr "type" "lea")
5575 (set_attr "mode" "SI")])
5577 (define_insn "*add<mode>_1"
5578 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5580 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5581 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5582 (clobber (reg:CC FLAGS_REG))]
5583 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5585 switch (get_attr_type (insn))
5591 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5592 if (operands[2] == const1_rtx)
5593 return "inc{<imodesuffix>}\t%0";
5596 gcc_assert (operands[2] == constm1_rtx);
5597 return "dec{<imodesuffix>}\t%0";
5601 /* For most processors, ADD is faster than LEA. This alternative
5602 was added to use ADD as much as possible. */
5603 if (which_alternative == 2)
5606 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5609 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5610 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5611 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5613 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5617 (cond [(eq_attr "alternative" "3")
5618 (const_string "lea")
5619 (match_operand:SWI48 2 "incdec_operand")
5620 (const_string "incdec")
5622 (const_string "alu")))
5623 (set (attr "length_immediate")
5625 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5627 (const_string "*")))
5628 (set_attr "mode" "<MODE>")])
5630 ;; It may seem that nonimmediate operand is proper one for operand 1.
5631 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5632 ;; we take care in ix86_binary_operator_ok to not allow two memory
5633 ;; operands so proper swapping will be done in reload. This allow
5634 ;; patterns constructed from addsi_1 to match.
5636 (define_insn "addsi_1_zext"
5637 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5639 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5640 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5641 (clobber (reg:CC FLAGS_REG))]
5642 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5644 switch (get_attr_type (insn))
5650 if (operands[2] == const1_rtx)
5651 return "inc{l}\t%k0";
5654 gcc_assert (operands[2] == constm1_rtx);
5655 return "dec{l}\t%k0";
5659 /* For most processors, ADD is faster than LEA. This alternative
5660 was added to use ADD as much as possible. */
5661 if (which_alternative == 1)
5664 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5667 if (x86_maybe_negate_const_int (&operands[2], SImode))
5668 return "sub{l}\t{%2, %k0|%k0, %2}";
5670 return "add{l}\t{%2, %k0|%k0, %2}";
5674 (cond [(eq_attr "alternative" "2")
5675 (const_string "lea")
5676 (match_operand:SI 2 "incdec_operand")
5677 (const_string "incdec")
5679 (const_string "alu")))
5680 (set (attr "length_immediate")
5682 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5684 (const_string "*")))
5685 (set_attr "mode" "SI")])
5687 (define_insn "*addhi_1"
5688 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5689 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5690 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5691 (clobber (reg:CC FLAGS_REG))]
5692 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5694 switch (get_attr_type (insn))
5700 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5701 if (operands[2] == const1_rtx)
5702 return "inc{w}\t%0";
5705 gcc_assert (operands[2] == constm1_rtx);
5706 return "dec{w}\t%0";
5710 /* For most processors, ADD is faster than LEA. This alternative
5711 was added to use ADD as much as possible. */
5712 if (which_alternative == 2)
5715 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5718 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5719 if (x86_maybe_negate_const_int (&operands[2], HImode))
5720 return "sub{w}\t{%2, %0|%0, %2}";
5722 return "add{w}\t{%2, %0|%0, %2}";
5726 (cond [(eq_attr "alternative" "3")
5727 (const_string "lea")
5728 (match_operand:HI 2 "incdec_operand")
5729 (const_string "incdec")
5731 (const_string "alu")))
5732 (set (attr "length_immediate")
5734 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5736 (const_string "*")))
5737 (set_attr "mode" "HI,HI,HI,SI")])
5739 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5740 (define_insn "*addqi_1"
5741 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5742 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5743 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5744 (clobber (reg:CC FLAGS_REG))]
5745 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5747 bool widen = (which_alternative == 3 || which_alternative == 4);
5749 switch (get_attr_type (insn))
5755 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5756 if (operands[2] == const1_rtx)
5757 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5760 gcc_assert (operands[2] == constm1_rtx);
5761 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5765 /* For most processors, ADD is faster than LEA. These alternatives
5766 were added to use ADD as much as possible. */
5767 if (which_alternative == 2 || which_alternative == 4)
5770 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5773 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5774 if (x86_maybe_negate_const_int (&operands[2], QImode))
5777 return "sub{l}\t{%2, %k0|%k0, %2}";
5779 return "sub{b}\t{%2, %0|%0, %2}";
5782 return "add{l}\t{%k2, %k0|%k0, %k2}";
5784 return "add{b}\t{%2, %0|%0, %2}";
5788 (cond [(eq_attr "alternative" "5")
5789 (const_string "lea")
5790 (match_operand:QI 2 "incdec_operand")
5791 (const_string "incdec")
5793 (const_string "alu")))
5794 (set (attr "length_immediate")
5796 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5798 (const_string "*")))
5799 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5801 (define_insn "*addqi_1_slp"
5802 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5803 (plus:QI (match_dup 0)
5804 (match_operand:QI 1 "general_operand" "qn,qm")))
5805 (clobber (reg:CC FLAGS_REG))]
5806 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5807 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5809 switch (get_attr_type (insn))
5812 if (operands[1] == const1_rtx)
5813 return "inc{b}\t%0";
5816 gcc_assert (operands[1] == constm1_rtx);
5817 return "dec{b}\t%0";
5821 if (x86_maybe_negate_const_int (&operands[1], QImode))
5822 return "sub{b}\t{%1, %0|%0, %1}";
5824 return "add{b}\t{%1, %0|%0, %1}";
5828 (if_then_else (match_operand:QI 1 "incdec_operand")
5829 (const_string "incdec")
5830 (const_string "alu1")))
5831 (set (attr "memory")
5832 (if_then_else (match_operand 1 "memory_operand")
5833 (const_string "load")
5834 (const_string "none")))
5835 (set_attr "mode" "QI")])
5837 ;; Split non destructive adds if we cannot use lea.
5839 [(set (match_operand:SWI48 0 "register_operand")
5840 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5841 (match_operand:SWI48 2 "nonmemory_operand")))
5842 (clobber (reg:CC FLAGS_REG))]
5843 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5844 [(set (match_dup 0) (match_dup 1))
5845 (parallel [(set (match_dup 0) (plus:<MODE> (match_dup 0) (match_dup 2)))
5846 (clobber (reg:CC FLAGS_REG))])])
5848 ;; Convert add to the lea pattern to avoid flags dependency.
5850 [(set (match_operand:SWI 0 "register_operand")
5851 (plus:SWI (match_operand:SWI 1 "register_operand")
5852 (match_operand:SWI 2 "<nonmemory_operand>")))
5853 (clobber (reg:CC FLAGS_REG))]
5854 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5857 enum machine_mode mode = <MODE>mode;
5860 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5863 operands[0] = gen_lowpart (mode, operands[0]);
5864 operands[1] = gen_lowpart (mode, operands[1]);
5865 operands[2] = gen_lowpart (mode, operands[2]);
5868 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5870 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5874 ;; Convert add to the lea pattern to avoid flags dependency.
5876 [(set (match_operand:DI 0 "register_operand")
5878 (plus:SI (match_operand:SI 1 "register_operand")
5879 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5880 (clobber (reg:CC FLAGS_REG))]
5881 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5883 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5885 (define_insn "*add<mode>_2"
5886 [(set (reg FLAGS_REG)
5889 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5890 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5892 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5893 (plus:SWI (match_dup 1) (match_dup 2)))]
5894 "ix86_match_ccmode (insn, CCGOCmode)
5895 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5897 switch (get_attr_type (insn))
5900 if (operands[2] == const1_rtx)
5901 return "inc{<imodesuffix>}\t%0";
5904 gcc_assert (operands[2] == constm1_rtx);
5905 return "dec{<imodesuffix>}\t%0";
5909 if (which_alternative == 2)
5912 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5915 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5916 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5917 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5919 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5923 (if_then_else (match_operand:SWI 2 "incdec_operand")
5924 (const_string "incdec")
5925 (const_string "alu")))
5926 (set (attr "length_immediate")
5928 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5930 (const_string "*")))
5931 (set_attr "mode" "<MODE>")])
5933 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5934 (define_insn "*addsi_2_zext"
5935 [(set (reg FLAGS_REG)
5937 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5938 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5940 (set (match_operand:DI 0 "register_operand" "=r,r")
5941 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5942 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5943 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5945 switch (get_attr_type (insn))
5948 if (operands[2] == const1_rtx)
5949 return "inc{l}\t%k0";
5952 gcc_assert (operands[2] == constm1_rtx);
5953 return "dec{l}\t%k0";
5957 if (which_alternative == 1)
5960 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5963 if (x86_maybe_negate_const_int (&operands[2], SImode))
5964 return "sub{l}\t{%2, %k0|%k0, %2}";
5966 return "add{l}\t{%2, %k0|%k0, %2}";
5970 (if_then_else (match_operand:SI 2 "incdec_operand")
5971 (const_string "incdec")
5972 (const_string "alu")))
5973 (set (attr "length_immediate")
5975 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5977 (const_string "*")))
5978 (set_attr "mode" "SI")])
5980 (define_insn "*add<mode>_3"
5981 [(set (reg FLAGS_REG)
5983 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5984 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5985 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5986 "ix86_match_ccmode (insn, CCZmode)
5987 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5989 switch (get_attr_type (insn))
5992 if (operands[2] == const1_rtx)
5993 return "inc{<imodesuffix>}\t%0";
5996 gcc_assert (operands[2] == constm1_rtx);
5997 return "dec{<imodesuffix>}\t%0";
6001 if (which_alternative == 1)
6004 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6007 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6008 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6009 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6011 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6015 (if_then_else (match_operand:SWI 2 "incdec_operand")
6016 (const_string "incdec")
6017 (const_string "alu")))
6018 (set (attr "length_immediate")
6020 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6022 (const_string "*")))
6023 (set_attr "mode" "<MODE>")])
6025 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6026 (define_insn "*addsi_3_zext"
6027 [(set (reg FLAGS_REG)
6029 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
6030 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
6031 (set (match_operand:DI 0 "register_operand" "=r,r")
6032 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6033 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6034 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6036 switch (get_attr_type (insn))
6039 if (operands[2] == const1_rtx)
6040 return "inc{l}\t%k0";
6043 gcc_assert (operands[2] == constm1_rtx);
6044 return "dec{l}\t%k0";
6048 if (which_alternative == 1)
6051 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6054 if (x86_maybe_negate_const_int (&operands[2], SImode))
6055 return "sub{l}\t{%2, %k0|%k0, %2}";
6057 return "add{l}\t{%2, %k0|%k0, %2}";
6061 (if_then_else (match_operand:SI 2 "incdec_operand")
6062 (const_string "incdec")
6063 (const_string "alu")))
6064 (set (attr "length_immediate")
6066 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6068 (const_string "*")))
6069 (set_attr "mode" "SI")])
6071 ; For comparisons against 1, -1 and 128, we may generate better code
6072 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6073 ; is matched then. We can't accept general immediate, because for
6074 ; case of overflows, the result is messed up.
6075 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6076 ; only for comparisons not depending on it.
6078 (define_insn "*adddi_4"
6079 [(set (reg FLAGS_REG)
6081 (match_operand:DI 1 "nonimmediate_operand" "0")
6082 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6083 (clobber (match_scratch:DI 0 "=rm"))]
6085 && ix86_match_ccmode (insn, CCGCmode)"
6087 switch (get_attr_type (insn))
6090 if (operands[2] == constm1_rtx)
6091 return "inc{q}\t%0";
6094 gcc_assert (operands[2] == const1_rtx);
6095 return "dec{q}\t%0";
6099 if (x86_maybe_negate_const_int (&operands[2], DImode))
6100 return "add{q}\t{%2, %0|%0, %2}";
6102 return "sub{q}\t{%2, %0|%0, %2}";
6106 (if_then_else (match_operand:DI 2 "incdec_operand")
6107 (const_string "incdec")
6108 (const_string "alu")))
6109 (set (attr "length_immediate")
6111 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6113 (const_string "*")))
6114 (set_attr "mode" "DI")])
6116 ; For comparisons against 1, -1 and 128, we may generate better code
6117 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6118 ; is matched then. We can't accept general immediate, because for
6119 ; case of overflows, the result is messed up.
6120 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6121 ; only for comparisons not depending on it.
6123 (define_insn "*add<mode>_4"
6124 [(set (reg FLAGS_REG)
6126 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6127 (match_operand:SWI124 2 "const_int_operand" "n")))
6128 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6129 "ix86_match_ccmode (insn, CCGCmode)"
6131 switch (get_attr_type (insn))
6134 if (operands[2] == constm1_rtx)
6135 return "inc{<imodesuffix>}\t%0";
6138 gcc_assert (operands[2] == const1_rtx);
6139 return "dec{<imodesuffix>}\t%0";
6143 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6144 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6146 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6150 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6151 (const_string "incdec")
6152 (const_string "alu")))
6153 (set (attr "length_immediate")
6155 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6157 (const_string "*")))
6158 (set_attr "mode" "<MODE>")])
6160 (define_insn "*add<mode>_5"
6161 [(set (reg FLAGS_REG)
6164 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6165 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6167 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6168 "ix86_match_ccmode (insn, CCGOCmode)
6169 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6171 switch (get_attr_type (insn))
6174 if (operands[2] == const1_rtx)
6175 return "inc{<imodesuffix>}\t%0";
6178 gcc_assert (operands[2] == constm1_rtx);
6179 return "dec{<imodesuffix>}\t%0";
6183 if (which_alternative == 1)
6186 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6189 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6190 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6191 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6193 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6197 (if_then_else (match_operand:SWI 2 "incdec_operand")
6198 (const_string "incdec")
6199 (const_string "alu")))
6200 (set (attr "length_immediate")
6202 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6204 (const_string "*")))
6205 (set_attr "mode" "<MODE>")])
6207 (define_insn "*addqi_ext_1_rex64"
6208 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6213 (match_operand 1 "ext_register_operand" "0")
6216 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6217 (clobber (reg:CC FLAGS_REG))]
6220 switch (get_attr_type (insn))
6223 if (operands[2] == const1_rtx)
6224 return "inc{b}\t%h0";
6227 gcc_assert (operands[2] == constm1_rtx);
6228 return "dec{b}\t%h0";
6232 return "add{b}\t{%2, %h0|%h0, %2}";
6236 (if_then_else (match_operand:QI 2 "incdec_operand")
6237 (const_string "incdec")
6238 (const_string "alu")))
6239 (set_attr "modrm" "1")
6240 (set_attr "mode" "QI")])
6242 (define_insn "addqi_ext_1"
6243 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6248 (match_operand 1 "ext_register_operand" "0")
6251 (match_operand:QI 2 "general_operand" "Qmn")))
6252 (clobber (reg:CC FLAGS_REG))]
6255 switch (get_attr_type (insn))
6258 if (operands[2] == const1_rtx)
6259 return "inc{b}\t%h0";
6262 gcc_assert (operands[2] == constm1_rtx);
6263 return "dec{b}\t%h0";
6267 return "add{b}\t{%2, %h0|%h0, %2}";
6271 (if_then_else (match_operand:QI 2 "incdec_operand")
6272 (const_string "incdec")
6273 (const_string "alu")))
6274 (set_attr "modrm" "1")
6275 (set_attr "mode" "QI")])
6277 (define_insn "*addqi_ext_2"
6278 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6283 (match_operand 1 "ext_register_operand" "%0")
6287 (match_operand 2 "ext_register_operand" "Q")
6290 (clobber (reg:CC FLAGS_REG))]
6292 "add{b}\t{%h2, %h0|%h0, %h2}"
6293 [(set_attr "type" "alu")
6294 (set_attr "mode" "QI")])
6296 ;; The lea patterns for modes less than 32 bits need to be matched by
6297 ;; several insns converted to real lea by splitters.
6299 (define_insn_and_split "*lea_general_1"
6300 [(set (match_operand 0 "register_operand" "=r")
6301 (plus (plus (match_operand 1 "index_register_operand" "l")
6302 (match_operand 2 "register_operand" "r"))
6303 (match_operand 3 "immediate_operand" "i")))]
6304 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6305 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6306 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6307 && GET_MODE (operands[0]) == GET_MODE (operands[2])
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[2] = gen_lowpart (mode, operands[2]);
6320 operands[3] = gen_lowpart (mode, operands[3]);
6322 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6325 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6328 [(set_attr "type" "lea")
6329 (set_attr "mode" "SI")])
6331 (define_insn_and_split "*lea_general_2"
6332 [(set (match_operand 0 "register_operand" "=r")
6333 (plus (mult (match_operand 1 "index_register_operand" "l")
6334 (match_operand 2 "const248_operand" "n"))
6335 (match_operand 3 "nonmemory_operand" "ri")))]
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])
6340 || GET_MODE (operands[3]) == VOIDmode)"
6342 "&& reload_completed"
6345 enum machine_mode mode = SImode;
6348 operands[0] = gen_lowpart (mode, operands[0]);
6349 operands[1] = gen_lowpart (mode, operands[1]);
6350 operands[3] = gen_lowpart (mode, operands[3]);
6352 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6355 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6358 [(set_attr "type" "lea")
6359 (set_attr "mode" "SI")])
6361 (define_insn_and_split "*lea_general_3"
6362 [(set (match_operand 0 "register_operand" "=r")
6363 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6364 (match_operand 2 "const248_operand" "n"))
6365 (match_operand 3 "register_operand" "r"))
6366 (match_operand 4 "immediate_operand" "i")))]
6367 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6368 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6369 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6370 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6372 "&& reload_completed"
6375 enum machine_mode mode = SImode;
6378 operands[0] = gen_lowpart (mode, operands[0]);
6379 operands[1] = gen_lowpart (mode, operands[1]);
6380 operands[3] = gen_lowpart (mode, operands[3]);
6381 operands[4] = gen_lowpart (mode, operands[4]);
6383 pat = gen_rtx_PLUS (mode,
6385 gen_rtx_MULT (mode, operands[1],
6390 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6393 [(set_attr "type" "lea")
6394 (set_attr "mode" "SI")])
6396 (define_insn_and_split "*lea_general_4"
6397 [(set (match_operand 0 "register_operand" "=r")
6399 (match_operand 1 "index_register_operand" "l")
6400 (match_operand 2 "const_int_operand" "n"))
6401 (match_operand 3 "const_int_operand" "n")))]
6402 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6403 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6404 || GET_MODE (operands[0]) == SImode
6405 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6406 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6407 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6408 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6409 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6411 "&& reload_completed"
6414 enum machine_mode mode = GET_MODE (operands[0]);
6417 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6420 operands[0] = gen_lowpart (mode, operands[0]);
6421 operands[1] = gen_lowpart (mode, operands[1]);
6424 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6426 pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6427 INTVAL (operands[3]));
6429 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6432 [(set_attr "type" "lea")
6434 (if_then_else (match_operand:DI 0)
6436 (const_string "SI")))])
6438 ;; Subtract instructions
6440 (define_expand "sub<mode>3"
6441 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6442 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6443 (match_operand:SDWIM 2 "<general_operand>")))]
6445 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6447 (define_insn_and_split "*sub<dwi>3_doubleword"
6448 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6450 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6451 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6452 (clobber (reg:CC FLAGS_REG))]
6453 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6456 [(parallel [(set (reg:CC FLAGS_REG)
6457 (compare:CC (match_dup 1) (match_dup 2)))
6459 (minus:DWIH (match_dup 1) (match_dup 2)))])
6460 (parallel [(set (match_dup 3)
6464 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6466 (clobber (reg:CC FLAGS_REG))])]
6467 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6469 (define_insn "*sub<mode>_1"
6470 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6472 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6473 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6474 (clobber (reg:CC FLAGS_REG))]
6475 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6476 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6477 [(set_attr "type" "alu")
6478 (set_attr "mode" "<MODE>")])
6480 (define_insn "*subsi_1_zext"
6481 [(set (match_operand:DI 0 "register_operand" "=r")
6483 (minus:SI (match_operand:SI 1 "register_operand" "0")
6484 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6485 (clobber (reg:CC FLAGS_REG))]
6486 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6487 "sub{l}\t{%2, %k0|%k0, %2}"
6488 [(set_attr "type" "alu")
6489 (set_attr "mode" "SI")])
6491 (define_insn "*subqi_1_slp"
6492 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6493 (minus:QI (match_dup 0)
6494 (match_operand:QI 1 "general_operand" "qn,qm")))
6495 (clobber (reg:CC FLAGS_REG))]
6496 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6497 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6498 "sub{b}\t{%1, %0|%0, %1}"
6499 [(set_attr "type" "alu1")
6500 (set_attr "mode" "QI")])
6502 (define_insn "*sub<mode>_2"
6503 [(set (reg FLAGS_REG)
6506 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6507 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6509 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6510 (minus:SWI (match_dup 1) (match_dup 2)))]
6511 "ix86_match_ccmode (insn, CCGOCmode)
6512 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6513 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6514 [(set_attr "type" "alu")
6515 (set_attr "mode" "<MODE>")])
6517 (define_insn "*subsi_2_zext"
6518 [(set (reg FLAGS_REG)
6520 (minus:SI (match_operand:SI 1 "register_operand" "0")
6521 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6523 (set (match_operand:DI 0 "register_operand" "=r")
6525 (minus:SI (match_dup 1)
6527 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6528 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6529 "sub{l}\t{%2, %k0|%k0, %2}"
6530 [(set_attr "type" "alu")
6531 (set_attr "mode" "SI")])
6533 (define_insn "*sub<mode>_3"
6534 [(set (reg FLAGS_REG)
6535 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6536 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6537 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6538 (minus:SWI (match_dup 1) (match_dup 2)))]
6539 "ix86_match_ccmode (insn, CCmode)
6540 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6541 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6542 [(set_attr "type" "alu")
6543 (set_attr "mode" "<MODE>")])
6545 (define_insn "*subsi_3_zext"
6546 [(set (reg FLAGS_REG)
6547 (compare (match_operand:SI 1 "register_operand" "0")
6548 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6549 (set (match_operand:DI 0 "register_operand" "=r")
6551 (minus:SI (match_dup 1)
6553 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6554 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6555 "sub{l}\t{%2, %1|%1, %2}"
6556 [(set_attr "type" "alu")
6557 (set_attr "mode" "SI")])
6559 ;; Add with carry and subtract with borrow
6561 (define_expand "<plusminus_insn><mode>3_carry"
6563 [(set (match_operand:SWI 0 "nonimmediate_operand")
6565 (match_operand:SWI 1 "nonimmediate_operand")
6566 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6567 [(match_operand 3 "flags_reg_operand")
6569 (match_operand:SWI 2 "<general_operand>"))))
6570 (clobber (reg:CC FLAGS_REG))])]
6571 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6573 (define_insn "*<plusminus_insn><mode>3_carry"
6574 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6576 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6578 (match_operator 3 "ix86_carry_flag_operator"
6579 [(reg FLAGS_REG) (const_int 0)])
6580 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6581 (clobber (reg:CC FLAGS_REG))]
6582 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6583 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6584 [(set_attr "type" "alu")
6585 (set_attr "use_carry" "1")
6586 (set_attr "pent_pair" "pu")
6587 (set_attr "mode" "<MODE>")])
6589 (define_insn "*addsi3_carry_zext"
6590 [(set (match_operand:DI 0 "register_operand" "=r")
6592 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6593 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6594 [(reg FLAGS_REG) (const_int 0)])
6595 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6596 (clobber (reg:CC FLAGS_REG))]
6597 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6598 "adc{l}\t{%2, %k0|%k0, %2}"
6599 [(set_attr "type" "alu")
6600 (set_attr "use_carry" "1")
6601 (set_attr "pent_pair" "pu")
6602 (set_attr "mode" "SI")])
6604 (define_insn "*subsi3_carry_zext"
6605 [(set (match_operand:DI 0 "register_operand" "=r")
6607 (minus:SI (match_operand:SI 1 "register_operand" "0")
6608 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6609 [(reg FLAGS_REG) (const_int 0)])
6610 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6611 (clobber (reg:CC FLAGS_REG))]
6612 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6613 "sbb{l}\t{%2, %k0|%k0, %2}"
6614 [(set_attr "type" "alu")
6615 (set_attr "pent_pair" "pu")
6616 (set_attr "mode" "SI")])
6618 ;; Overflow setting add and subtract instructions
6620 (define_insn "*add<mode>3_cconly_overflow"
6621 [(set (reg:CCC FLAGS_REG)
6624 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6625 (match_operand:SWI 2 "<general_operand>" "<g>"))
6627 (clobber (match_scratch:SWI 0 "=<r>"))]
6628 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6629 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6630 [(set_attr "type" "alu")
6631 (set_attr "mode" "<MODE>")])
6633 (define_insn "*sub<mode>3_cconly_overflow"
6634 [(set (reg:CCC FLAGS_REG)
6637 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6638 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6641 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6642 [(set_attr "type" "icmp")
6643 (set_attr "mode" "<MODE>")])
6645 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6646 [(set (reg:CCC FLAGS_REG)
6649 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6650 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6652 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6653 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6654 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6655 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6656 [(set_attr "type" "alu")
6657 (set_attr "mode" "<MODE>")])
6659 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6660 [(set (reg:CCC FLAGS_REG)
6663 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6664 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6666 (set (match_operand:DI 0 "register_operand" "=r")
6667 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6668 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6669 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6670 [(set_attr "type" "alu")
6671 (set_attr "mode" "SI")])
6673 ;; The patterns that match these are at the end of this file.
6675 (define_expand "<plusminus_insn>xf3"
6676 [(set (match_operand:XF 0 "register_operand")
6678 (match_operand:XF 1 "register_operand")
6679 (match_operand:XF 2 "register_operand")))]
6682 (define_expand "<plusminus_insn><mode>3"
6683 [(set (match_operand:MODEF 0 "register_operand")
6685 (match_operand:MODEF 1 "register_operand")
6686 (match_operand:MODEF 2 "nonimmediate_operand")))]
6687 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6688 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6690 ;; Multiply instructions
6692 (define_expand "mul<mode>3"
6693 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6695 (match_operand:SWIM248 1 "register_operand")
6696 (match_operand:SWIM248 2 "<general_operand>")))
6697 (clobber (reg:CC FLAGS_REG))])])
6699 (define_expand "mulqi3"
6700 [(parallel [(set (match_operand:QI 0 "register_operand")
6702 (match_operand:QI 1 "register_operand")
6703 (match_operand:QI 2 "nonimmediate_operand")))
6704 (clobber (reg:CC FLAGS_REG))])]
6705 "TARGET_QIMODE_MATH")
6708 ;; IMUL reg32/64, reg32/64, imm8 Direct
6709 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6710 ;; IMUL reg32/64, reg32/64, imm32 Direct
6711 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6712 ;; IMUL reg32/64, reg32/64 Direct
6713 ;; IMUL reg32/64, mem32/64 Direct
6715 ;; On BDVER1, all above IMULs use DirectPath
6717 (define_insn "*mul<mode>3_1"
6718 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6720 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6721 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6722 (clobber (reg:CC FLAGS_REG))]
6723 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6725 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6726 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6727 imul{<imodesuffix>}\t{%2, %0|%0, %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" "<MODE>")])
6747 (define_insn "*mulsi3_1_zext"
6748 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6750 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6751 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6752 (clobber (reg:CC FLAGS_REG))]
6754 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6756 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6757 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6758 imul{l}\t{%2, %k0|%k0, %2}"
6759 [(set_attr "type" "imul")
6760 (set_attr "prefix_0f" "0,0,1")
6761 (set (attr "athlon_decode")
6762 (cond [(eq_attr "cpu" "athlon")
6763 (const_string "vector")
6764 (eq_attr "alternative" "1")
6765 (const_string "vector")
6766 (and (eq_attr "alternative" "2")
6767 (match_operand 1 "memory_operand"))
6768 (const_string "vector")]
6769 (const_string "direct")))
6770 (set (attr "amdfam10_decode")
6771 (cond [(and (eq_attr "alternative" "0,1")
6772 (match_operand 1 "memory_operand"))
6773 (const_string "vector")]
6774 (const_string "direct")))
6775 (set_attr "bdver1_decode" "direct")
6776 (set_attr "mode" "SI")])
6779 ;; IMUL reg16, reg16, imm8 VectorPath
6780 ;; IMUL reg16, mem16, imm8 VectorPath
6781 ;; IMUL reg16, reg16, imm16 VectorPath
6782 ;; IMUL reg16, mem16, imm16 VectorPath
6783 ;; IMUL reg16, reg16 Direct
6784 ;; IMUL reg16, mem16 Direct
6786 ;; On BDVER1, all HI MULs use DoublePath
6788 (define_insn "*mulhi3_1"
6789 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6790 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6791 (match_operand:HI 2 "general_operand" "K,n,mr")))
6792 (clobber (reg:CC FLAGS_REG))]
6794 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6796 imul{w}\t{%2, %1, %0|%0, %1, %2}
6797 imul{w}\t{%2, %1, %0|%0, %1, %2}
6798 imul{w}\t{%2, %0|%0, %2}"
6799 [(set_attr "type" "imul")
6800 (set_attr "prefix_0f" "0,0,1")
6801 (set (attr "athlon_decode")
6802 (cond [(eq_attr "cpu" "athlon")
6803 (const_string "vector")
6804 (eq_attr "alternative" "1,2")
6805 (const_string "vector")]
6806 (const_string "direct")))
6807 (set (attr "amdfam10_decode")
6808 (cond [(eq_attr "alternative" "0,1")
6809 (const_string "vector")]
6810 (const_string "direct")))
6811 (set_attr "bdver1_decode" "double")
6812 (set_attr "mode" "HI")])
6814 ;;On AMDFAM10 and BDVER1
6818 (define_insn "*mulqi3_1"
6819 [(set (match_operand:QI 0 "register_operand" "=a")
6820 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6821 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6822 (clobber (reg:CC FLAGS_REG))]
6824 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6826 [(set_attr "type" "imul")
6827 (set_attr "length_immediate" "0")
6828 (set (attr "athlon_decode")
6829 (if_then_else (eq_attr "cpu" "athlon")
6830 (const_string "vector")
6831 (const_string "direct")))
6832 (set_attr "amdfam10_decode" "direct")
6833 (set_attr "bdver1_decode" "direct")
6834 (set_attr "mode" "QI")])
6836 (define_expand "<u>mul<mode><dwi>3"
6837 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6840 (match_operand:DWIH 1 "nonimmediate_operand"))
6842 (match_operand:DWIH 2 "register_operand"))))
6843 (clobber (reg:CC FLAGS_REG))])])
6845 (define_expand "<u>mulqihi3"
6846 [(parallel [(set (match_operand:HI 0 "register_operand")
6849 (match_operand:QI 1 "nonimmediate_operand"))
6851 (match_operand:QI 2 "register_operand"))))
6852 (clobber (reg:CC FLAGS_REG))])]
6853 "TARGET_QIMODE_MATH")
6855 (define_insn "*bmi2_umulditi3_1"
6856 [(set (match_operand:DI 0 "register_operand" "=r")
6858 (match_operand:DI 2 "nonimmediate_operand" "%d")
6859 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6860 (set (match_operand:DI 1 "register_operand" "=r")
6863 (mult:TI (zero_extend:TI (match_dup 2))
6864 (zero_extend:TI (match_dup 3)))
6866 "TARGET_64BIT && TARGET_BMI2
6867 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6868 "mulx\t{%3, %0, %1|%1, %0, %3}"
6869 [(set_attr "type" "imulx")
6870 (set_attr "prefix" "vex")
6871 (set_attr "mode" "DI")])
6873 (define_insn "*bmi2_umulsidi3_1"
6874 [(set (match_operand:SI 0 "register_operand" "=r")
6876 (match_operand:SI 2 "nonimmediate_operand" "%d")
6877 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6878 (set (match_operand:SI 1 "register_operand" "=r")
6881 (mult:DI (zero_extend:DI (match_dup 2))
6882 (zero_extend:DI (match_dup 3)))
6884 "!TARGET_64BIT && TARGET_BMI2
6885 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6886 "mulx\t{%3, %0, %1|%1, %0, %3}"
6887 [(set_attr "type" "imulx")
6888 (set_attr "prefix" "vex")
6889 (set_attr "mode" "SI")])
6891 (define_insn "*umul<mode><dwi>3_1"
6892 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6895 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6897 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6898 (clobber (reg:CC FLAGS_REG))]
6899 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6902 mul{<imodesuffix>}\t%2"
6903 [(set_attr "isa" "bmi2,*")
6904 (set_attr "type" "imulx,imul")
6905 (set_attr "length_immediate" "*,0")
6906 (set (attr "athlon_decode")
6907 (cond [(eq_attr "alternative" "1")
6908 (if_then_else (eq_attr "cpu" "athlon")
6909 (const_string "vector")
6910 (const_string "double"))]
6911 (const_string "*")))
6912 (set_attr "amdfam10_decode" "*,double")
6913 (set_attr "bdver1_decode" "*,direct")
6914 (set_attr "prefix" "vex,orig")
6915 (set_attr "mode" "<MODE>")])
6917 ;; Convert mul to the mulx pattern to avoid flags dependency.
6919 [(set (match_operand:<DWI> 0 "register_operand")
6922 (match_operand:DWIH 1 "register_operand"))
6924 (match_operand:DWIH 2 "nonimmediate_operand"))))
6925 (clobber (reg:CC FLAGS_REG))]
6926 "TARGET_BMI2 && reload_completed
6927 && true_regnum (operands[1]) == DX_REG"
6928 [(parallel [(set (match_dup 3)
6929 (mult:DWIH (match_dup 1) (match_dup 2)))
6933 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6934 (zero_extend:<DWI> (match_dup 2)))
6937 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6939 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6942 (define_insn "*mul<mode><dwi>3_1"
6943 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6946 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6948 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6949 (clobber (reg:CC FLAGS_REG))]
6950 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6951 "imul{<imodesuffix>}\t%2"
6952 [(set_attr "type" "imul")
6953 (set_attr "length_immediate" "0")
6954 (set (attr "athlon_decode")
6955 (if_then_else (eq_attr "cpu" "athlon")
6956 (const_string "vector")
6957 (const_string "double")))
6958 (set_attr "amdfam10_decode" "double")
6959 (set_attr "bdver1_decode" "direct")
6960 (set_attr "mode" "<MODE>")])
6962 (define_insn "*<u>mulqihi3_1"
6963 [(set (match_operand:HI 0 "register_operand" "=a")
6966 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6968 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6969 (clobber (reg:CC FLAGS_REG))]
6971 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6972 "<sgnprefix>mul{b}\t%2"
6973 [(set_attr "type" "imul")
6974 (set_attr "length_immediate" "0")
6975 (set (attr "athlon_decode")
6976 (if_then_else (eq_attr "cpu" "athlon")
6977 (const_string "vector")
6978 (const_string "direct")))
6979 (set_attr "amdfam10_decode" "direct")
6980 (set_attr "bdver1_decode" "direct")
6981 (set_attr "mode" "QI")])
6983 (define_expand "<s>mul<mode>3_highpart"
6984 [(parallel [(set (match_operand:SWI48 0 "register_operand")
6989 (match_operand:SWI48 1 "nonimmediate_operand"))
6991 (match_operand:SWI48 2 "register_operand")))
6993 (clobber (match_scratch:SWI48 3))
6994 (clobber (reg:CC FLAGS_REG))])]
6996 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6998 (define_insn "*<s>muldi3_highpart_1"
6999 [(set (match_operand:DI 0 "register_operand" "=d")
7004 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7006 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7008 (clobber (match_scratch:DI 3 "=1"))
7009 (clobber (reg:CC FLAGS_REG))]
7011 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7012 "<sgnprefix>mul{q}\t%2"
7013 [(set_attr "type" "imul")
7014 (set_attr "length_immediate" "0")
7015 (set (attr "athlon_decode")
7016 (if_then_else (eq_attr "cpu" "athlon")
7017 (const_string "vector")
7018 (const_string "double")))
7019 (set_attr "amdfam10_decode" "double")
7020 (set_attr "bdver1_decode" "direct")
7021 (set_attr "mode" "DI")])
7023 (define_insn "*<s>mulsi3_highpart_1"
7024 [(set (match_operand:SI 0 "register_operand" "=d")
7029 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7031 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7033 (clobber (match_scratch:SI 3 "=1"))
7034 (clobber (reg:CC FLAGS_REG))]
7035 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7036 "<sgnprefix>mul{l}\t%2"
7037 [(set_attr "type" "imul")
7038 (set_attr "length_immediate" "0")
7039 (set (attr "athlon_decode")
7040 (if_then_else (eq_attr "cpu" "athlon")
7041 (const_string "vector")
7042 (const_string "double")))
7043 (set_attr "amdfam10_decode" "double")
7044 (set_attr "bdver1_decode" "direct")
7045 (set_attr "mode" "SI")])
7047 (define_insn "*<s>mulsi3_highpart_zext"
7048 [(set (match_operand:DI 0 "register_operand" "=d")
7049 (zero_extend:DI (truncate:SI
7051 (mult:DI (any_extend:DI
7052 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7054 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7056 (clobber (match_scratch:SI 3 "=1"))
7057 (clobber (reg:CC FLAGS_REG))]
7059 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7060 "<sgnprefix>mul{l}\t%2"
7061 [(set_attr "type" "imul")
7062 (set_attr "length_immediate" "0")
7063 (set (attr "athlon_decode")
7064 (if_then_else (eq_attr "cpu" "athlon")
7065 (const_string "vector")
7066 (const_string "double")))
7067 (set_attr "amdfam10_decode" "double")
7068 (set_attr "bdver1_decode" "direct")
7069 (set_attr "mode" "SI")])
7071 ;; The patterns that match these are at the end of this file.
7073 (define_expand "mulxf3"
7074 [(set (match_operand:XF 0 "register_operand")
7075 (mult:XF (match_operand:XF 1 "register_operand")
7076 (match_operand:XF 2 "register_operand")))]
7079 (define_expand "mul<mode>3"
7080 [(set (match_operand:MODEF 0 "register_operand")
7081 (mult:MODEF (match_operand:MODEF 1 "register_operand")
7082 (match_operand:MODEF 2 "nonimmediate_operand")))]
7083 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7084 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7086 ;; Divide instructions
7088 ;; The patterns that match these are at the end of this file.
7090 (define_expand "divxf3"
7091 [(set (match_operand:XF 0 "register_operand")
7092 (div:XF (match_operand:XF 1 "register_operand")
7093 (match_operand:XF 2 "register_operand")))]
7096 (define_expand "divdf3"
7097 [(set (match_operand:DF 0 "register_operand")
7098 (div:DF (match_operand:DF 1 "register_operand")
7099 (match_operand:DF 2 "nonimmediate_operand")))]
7100 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7101 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7103 (define_expand "divsf3"
7104 [(set (match_operand:SF 0 "register_operand")
7105 (div:SF (match_operand:SF 1 "register_operand")
7106 (match_operand:SF 2 "nonimmediate_operand")))]
7107 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7112 && optimize_insn_for_speed_p ()
7113 && flag_finite_math_only && !flag_trapping_math
7114 && flag_unsafe_math_optimizations)
7116 ix86_emit_swdivsf (operands[0], operands[1],
7117 operands[2], SFmode);
7122 ;; Divmod instructions.
7124 (define_expand "divmod<mode>4"
7125 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7127 (match_operand:SWIM248 1 "register_operand")
7128 (match_operand:SWIM248 2 "nonimmediate_operand")))
7129 (set (match_operand:SWIM248 3 "register_operand")
7130 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7131 (clobber (reg:CC FLAGS_REG))])])
7133 ;; Split with 8bit unsigned divide:
7134 ;; if (dividend an divisor are in [0-255])
7135 ;; use 8bit unsigned integer divide
7137 ;; use original integer divide
7139 [(set (match_operand:SWI48 0 "register_operand")
7140 (div:SWI48 (match_operand:SWI48 2 "register_operand")
7141 (match_operand:SWI48 3 "nonimmediate_operand")))
7142 (set (match_operand:SWI48 1 "register_operand")
7143 (mod:SWI48 (match_dup 2) (match_dup 3)))
7144 (clobber (reg:CC FLAGS_REG))]
7145 "TARGET_USE_8BIT_IDIV
7146 && TARGET_QIMODE_MATH
7147 && can_create_pseudo_p ()
7148 && !optimize_insn_for_size_p ()"
7150 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7152 (define_insn_and_split "divmod<mode>4_1"
7153 [(set (match_operand:SWI48 0 "register_operand" "=a")
7154 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7155 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7156 (set (match_operand:SWI48 1 "register_operand" "=&d")
7157 (mod:SWI48 (match_dup 2) (match_dup 3)))
7158 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7159 (clobber (reg:CC FLAGS_REG))]
7163 [(parallel [(set (match_dup 1)
7164 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7165 (clobber (reg:CC FLAGS_REG))])
7166 (parallel [(set (match_dup 0)
7167 (div:SWI48 (match_dup 2) (match_dup 3)))
7169 (mod:SWI48 (match_dup 2) (match_dup 3)))
7171 (clobber (reg:CC FLAGS_REG))])]
7173 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7175 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7176 operands[4] = operands[2];
7179 /* Avoid use of cltd in favor of a mov+shift. */
7180 emit_move_insn (operands[1], operands[2]);
7181 operands[4] = operands[1];
7184 [(set_attr "type" "multi")
7185 (set_attr "mode" "<MODE>")])
7187 (define_insn_and_split "*divmod<mode>4"
7188 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7189 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7190 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7191 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7192 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7193 (clobber (reg:CC FLAGS_REG))]
7197 [(parallel [(set (match_dup 1)
7198 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7199 (clobber (reg:CC FLAGS_REG))])
7200 (parallel [(set (match_dup 0)
7201 (div:SWIM248 (match_dup 2) (match_dup 3)))
7203 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7205 (clobber (reg:CC FLAGS_REG))])]
7207 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7209 if (<MODE>mode != HImode
7210 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7211 operands[4] = operands[2];
7214 /* Avoid use of cltd in favor of a mov+shift. */
7215 emit_move_insn (operands[1], operands[2]);
7216 operands[4] = operands[1];
7219 [(set_attr "type" "multi")
7220 (set_attr "mode" "<MODE>")])
7222 (define_insn "*divmod<mode>4_noext"
7223 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7224 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7225 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7226 (set (match_operand:SWIM248 1 "register_operand" "=d")
7227 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7228 (use (match_operand:SWIM248 4 "register_operand" "1"))
7229 (clobber (reg:CC FLAGS_REG))]
7231 "idiv{<imodesuffix>}\t%3"
7232 [(set_attr "type" "idiv")
7233 (set_attr "mode" "<MODE>")])
7235 (define_expand "divmodqi4"
7236 [(parallel [(set (match_operand:QI 0 "register_operand")
7238 (match_operand:QI 1 "register_operand")
7239 (match_operand:QI 2 "nonimmediate_operand")))
7240 (set (match_operand:QI 3 "register_operand")
7241 (mod:QI (match_dup 1) (match_dup 2)))
7242 (clobber (reg:CC FLAGS_REG))])]
7243 "TARGET_QIMODE_MATH"
7248 tmp0 = gen_reg_rtx (HImode);
7249 tmp1 = gen_reg_rtx (HImode);
7251 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7253 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7254 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7256 /* Extract remainder from AH. */
7257 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7258 insn = emit_move_insn (operands[3], tmp1);
7260 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7261 set_unique_reg_note (insn, REG_EQUAL, mod);
7263 /* Extract quotient from AL. */
7264 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7266 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7267 set_unique_reg_note (insn, REG_EQUAL, div);
7272 ;; Divide AX by r/m8, with result stored in
7275 ;; Change div/mod to HImode and extend the second argument to HImode
7276 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7277 ;; combine may fail.
7278 (define_insn "divmodhiqi3"
7279 [(set (match_operand:HI 0 "register_operand" "=a")
7284 (mod:HI (match_operand:HI 1 "register_operand" "0")
7286 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7290 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7291 (clobber (reg:CC FLAGS_REG))]
7292 "TARGET_QIMODE_MATH"
7294 [(set_attr "type" "idiv")
7295 (set_attr "mode" "QI")])
7297 (define_expand "udivmod<mode>4"
7298 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7300 (match_operand:SWIM248 1 "register_operand")
7301 (match_operand:SWIM248 2 "nonimmediate_operand")))
7302 (set (match_operand:SWIM248 3 "register_operand")
7303 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7304 (clobber (reg:CC FLAGS_REG))])])
7306 ;; Split with 8bit unsigned divide:
7307 ;; if (dividend an divisor are in [0-255])
7308 ;; use 8bit unsigned integer divide
7310 ;; use original integer divide
7312 [(set (match_operand:SWI48 0 "register_operand")
7313 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7314 (match_operand:SWI48 3 "nonimmediate_operand")))
7315 (set (match_operand:SWI48 1 "register_operand")
7316 (umod:SWI48 (match_dup 2) (match_dup 3)))
7317 (clobber (reg:CC FLAGS_REG))]
7318 "TARGET_USE_8BIT_IDIV
7319 && TARGET_QIMODE_MATH
7320 && can_create_pseudo_p ()
7321 && !optimize_insn_for_size_p ()"
7323 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7325 (define_insn_and_split "udivmod<mode>4_1"
7326 [(set (match_operand:SWI48 0 "register_operand" "=a")
7327 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7328 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7329 (set (match_operand:SWI48 1 "register_operand" "=&d")
7330 (umod:SWI48 (match_dup 2) (match_dup 3)))
7331 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7332 (clobber (reg:CC FLAGS_REG))]
7336 [(set (match_dup 1) (const_int 0))
7337 (parallel [(set (match_dup 0)
7338 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7340 (umod:SWI48 (match_dup 2) (match_dup 3)))
7342 (clobber (reg:CC FLAGS_REG))])]
7344 [(set_attr "type" "multi")
7345 (set_attr "mode" "<MODE>")])
7347 (define_insn_and_split "*udivmod<mode>4"
7348 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7349 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7350 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7351 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7352 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7353 (clobber (reg:CC FLAGS_REG))]
7357 [(set (match_dup 1) (const_int 0))
7358 (parallel [(set (match_dup 0)
7359 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7361 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7363 (clobber (reg:CC FLAGS_REG))])]
7365 [(set_attr "type" "multi")
7366 (set_attr "mode" "<MODE>")])
7368 (define_insn "*udivmod<mode>4_noext"
7369 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7370 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7371 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7372 (set (match_operand:SWIM248 1 "register_operand" "=d")
7373 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7374 (use (match_operand:SWIM248 4 "register_operand" "1"))
7375 (clobber (reg:CC FLAGS_REG))]
7377 "div{<imodesuffix>}\t%3"
7378 [(set_attr "type" "idiv")
7379 (set_attr "mode" "<MODE>")])
7381 (define_expand "udivmodqi4"
7382 [(parallel [(set (match_operand:QI 0 "register_operand")
7384 (match_operand:QI 1 "register_operand")
7385 (match_operand:QI 2 "nonimmediate_operand")))
7386 (set (match_operand:QI 3 "register_operand")
7387 (umod:QI (match_dup 1) (match_dup 2)))
7388 (clobber (reg:CC FLAGS_REG))])]
7389 "TARGET_QIMODE_MATH"
7394 tmp0 = gen_reg_rtx (HImode);
7395 tmp1 = gen_reg_rtx (HImode);
7397 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7399 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7400 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7402 /* Extract remainder from AH. */
7403 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7404 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7405 insn = emit_move_insn (operands[3], tmp1);
7407 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7408 set_unique_reg_note (insn, REG_EQUAL, mod);
7410 /* Extract quotient from AL. */
7411 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7413 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7414 set_unique_reg_note (insn, REG_EQUAL, div);
7419 (define_insn "udivmodhiqi3"
7420 [(set (match_operand:HI 0 "register_operand" "=a")
7425 (mod:HI (match_operand:HI 1 "register_operand" "0")
7427 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7431 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7432 (clobber (reg:CC FLAGS_REG))]
7433 "TARGET_QIMODE_MATH"
7435 [(set_attr "type" "idiv")
7436 (set_attr "mode" "QI")])
7438 ;; We cannot use div/idiv for double division, because it causes
7439 ;; "division by zero" on the overflow and that's not what we expect
7440 ;; from truncate. Because true (non truncating) double division is
7441 ;; never generated, we can't create this insn anyway.
7444 ; [(set (match_operand:SI 0 "register_operand" "=a")
7446 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7448 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7449 ; (set (match_operand:SI 3 "register_operand" "=d")
7451 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7452 ; (clobber (reg:CC FLAGS_REG))]
7454 ; "div{l}\t{%2, %0|%0, %2}"
7455 ; [(set_attr "type" "idiv")])
7457 ;;- Logical AND instructions
7459 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7460 ;; Note that this excludes ah.
7462 (define_expand "testsi_ccno_1"
7463 [(set (reg:CCNO FLAGS_REG)
7465 (and:SI (match_operand:SI 0 "nonimmediate_operand")
7466 (match_operand:SI 1 "x86_64_nonmemory_operand"))
7469 (define_expand "testqi_ccz_1"
7470 [(set (reg:CCZ FLAGS_REG)
7471 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7472 (match_operand:QI 1 "nonmemory_operand"))
7475 (define_expand "testdi_ccno_1"
7476 [(set (reg:CCNO FLAGS_REG)
7478 (and:DI (match_operand:DI 0 "nonimmediate_operand")
7479 (match_operand:DI 1 "x86_64_szext_general_operand"))
7481 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7483 (define_insn "*testdi_1"
7484 [(set (reg FLAGS_REG)
7487 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7488 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7490 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7491 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7493 test{l}\t{%k1, %k0|%k0, %k1}
7494 test{l}\t{%k1, %k0|%k0, %k1}
7495 test{q}\t{%1, %0|%0, %1}
7496 test{q}\t{%1, %0|%0, %1}
7497 test{q}\t{%1, %0|%0, %1}"
7498 [(set_attr "type" "test")
7499 (set_attr "modrm" "0,1,0,1,1")
7500 (set_attr "mode" "SI,SI,DI,DI,DI")])
7502 (define_insn "*testqi_1_maybe_si"
7503 [(set (reg FLAGS_REG)
7506 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7507 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7509 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7510 && ix86_match_ccmode (insn,
7511 CONST_INT_P (operands[1])
7512 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7514 if (which_alternative == 3)
7516 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7517 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7518 return "test{l}\t{%1, %k0|%k0, %1}";
7520 return "test{b}\t{%1, %0|%0, %1}";
7522 [(set_attr "type" "test")
7523 (set_attr "modrm" "0,1,1,1")
7524 (set_attr "mode" "QI,QI,QI,SI")
7525 (set_attr "pent_pair" "uv,np,uv,np")])
7527 (define_insn "*test<mode>_1"
7528 [(set (reg FLAGS_REG)
7531 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7532 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7534 "ix86_match_ccmode (insn, CCNOmode)
7535 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7536 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7537 [(set_attr "type" "test")
7538 (set_attr "modrm" "0,1,1")
7539 (set_attr "mode" "<MODE>")
7540 (set_attr "pent_pair" "uv,np,uv")])
7542 (define_expand "testqi_ext_ccno_0"
7543 [(set (reg:CCNO FLAGS_REG)
7547 (match_operand 0 "ext_register_operand")
7550 (match_operand 1 "const_int_operand"))
7553 (define_insn "*testqi_ext_0"
7554 [(set (reg FLAGS_REG)
7558 (match_operand 0 "ext_register_operand" "Q")
7561 (match_operand 1 "const_int_operand" "n"))
7563 "ix86_match_ccmode (insn, CCNOmode)"
7564 "test{b}\t{%1, %h0|%h0, %1}"
7565 [(set_attr "type" "test")
7566 (set_attr "mode" "QI")
7567 (set_attr "length_immediate" "1")
7568 (set_attr "modrm" "1")
7569 (set_attr "pent_pair" "np")])
7571 (define_insn "*testqi_ext_1_rex64"
7572 [(set (reg FLAGS_REG)
7576 (match_operand 0 "ext_register_operand" "Q")
7580 (match_operand:QI 1 "register_operand" "Q")))
7582 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7583 "test{b}\t{%1, %h0|%h0, %1}"
7584 [(set_attr "type" "test")
7585 (set_attr "mode" "QI")])
7587 (define_insn "*testqi_ext_1"
7588 [(set (reg FLAGS_REG)
7592 (match_operand 0 "ext_register_operand" "Q")
7596 (match_operand:QI 1 "general_operand" "Qm")))
7598 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7599 "test{b}\t{%1, %h0|%h0, %1}"
7600 [(set_attr "type" "test")
7601 (set_attr "mode" "QI")])
7603 (define_insn "*testqi_ext_2"
7604 [(set (reg FLAGS_REG)
7608 (match_operand 0 "ext_register_operand" "Q")
7612 (match_operand 1 "ext_register_operand" "Q")
7616 "ix86_match_ccmode (insn, CCNOmode)"
7617 "test{b}\t{%h1, %h0|%h0, %h1}"
7618 [(set_attr "type" "test")
7619 (set_attr "mode" "QI")])
7621 (define_insn "*testqi_ext_3_rex64"
7622 [(set (reg FLAGS_REG)
7623 (compare (zero_extract:DI
7624 (match_operand 0 "nonimmediate_operand" "rm")
7625 (match_operand:DI 1 "const_int_operand")
7626 (match_operand:DI 2 "const_int_operand"))
7629 && ix86_match_ccmode (insn, CCNOmode)
7630 && INTVAL (operands[1]) > 0
7631 && INTVAL (operands[2]) >= 0
7632 /* Ensure that resulting mask is zero or sign extended operand. */
7633 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7634 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7635 && INTVAL (operands[1]) > 32))
7636 && (GET_MODE (operands[0]) == SImode
7637 || GET_MODE (operands[0]) == DImode
7638 || GET_MODE (operands[0]) == HImode
7639 || GET_MODE (operands[0]) == QImode)"
7642 ;; Combine likes to form bit extractions for some tests. Humor it.
7643 (define_insn "*testqi_ext_3"
7644 [(set (reg FLAGS_REG)
7645 (compare (zero_extract:SI
7646 (match_operand 0 "nonimmediate_operand" "rm")
7647 (match_operand:SI 1 "const_int_operand")
7648 (match_operand:SI 2 "const_int_operand"))
7650 "ix86_match_ccmode (insn, CCNOmode)
7651 && INTVAL (operands[1]) > 0
7652 && INTVAL (operands[2]) >= 0
7653 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7654 && (GET_MODE (operands[0]) == SImode
7655 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7656 || GET_MODE (operands[0]) == HImode
7657 || GET_MODE (operands[0]) == QImode)"
7661 [(set (match_operand 0 "flags_reg_operand")
7662 (match_operator 1 "compare_operator"
7664 (match_operand 2 "nonimmediate_operand")
7665 (match_operand 3 "const_int_operand")
7666 (match_operand 4 "const_int_operand"))
7668 "ix86_match_ccmode (insn, CCNOmode)"
7669 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7671 rtx val = operands[2];
7672 HOST_WIDE_INT len = INTVAL (operands[3]);
7673 HOST_WIDE_INT pos = INTVAL (operands[4]);
7675 enum machine_mode mode, submode;
7677 mode = GET_MODE (val);
7680 /* ??? Combine likes to put non-volatile mem extractions in QImode
7681 no matter the size of the test. So find a mode that works. */
7682 if (! MEM_VOLATILE_P (val))
7684 mode = smallest_mode_for_size (pos + len, MODE_INT);
7685 val = adjust_address (val, mode, 0);
7688 else if (GET_CODE (val) == SUBREG
7689 && (submode = GET_MODE (SUBREG_REG (val)),
7690 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7691 && pos + len <= GET_MODE_BITSIZE (submode)
7692 && GET_MODE_CLASS (submode) == MODE_INT)
7694 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7696 val = SUBREG_REG (val);
7698 else if (mode == HImode && pos + len <= 8)
7700 /* Small HImode tests can be converted to QImode. */
7702 val = gen_lowpart (QImode, val);
7705 if (len == HOST_BITS_PER_WIDE_INT)
7708 mask = ((HOST_WIDE_INT)1 << len) - 1;
7711 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7714 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7715 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7716 ;; this is relatively important trick.
7717 ;; Do the conversion only post-reload to avoid limiting of the register class
7720 [(set (match_operand 0 "flags_reg_operand")
7721 (match_operator 1 "compare_operator"
7722 [(and (match_operand 2 "register_operand")
7723 (match_operand 3 "const_int_operand"))
7726 && QI_REG_P (operands[2])
7727 && GET_MODE (operands[2]) != QImode
7728 && ((ix86_match_ccmode (insn, CCZmode)
7729 && !(INTVAL (operands[3]) & ~(255 << 8)))
7730 || (ix86_match_ccmode (insn, CCNOmode)
7731 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7734 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7738 operands[2] = gen_lowpart (SImode, operands[2]);
7739 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7743 [(set (match_operand 0 "flags_reg_operand")
7744 (match_operator 1 "compare_operator"
7745 [(and (match_operand 2 "nonimmediate_operand")
7746 (match_operand 3 "const_int_operand"))
7749 && GET_MODE (operands[2]) != QImode
7750 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7751 && ((ix86_match_ccmode (insn, CCZmode)
7752 && !(INTVAL (operands[3]) & ~255))
7753 || (ix86_match_ccmode (insn, CCNOmode)
7754 && !(INTVAL (operands[3]) & ~127)))"
7756 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7759 operands[2] = gen_lowpart (QImode, operands[2]);
7760 operands[3] = gen_lowpart (QImode, operands[3]);
7763 ;; %%% This used to optimize known byte-wide and operations to memory,
7764 ;; and sometimes to QImode registers. If this is considered useful,
7765 ;; it should be done with splitters.
7767 (define_expand "and<mode>3"
7768 [(set (match_operand:SWIM 0 "nonimmediate_operand")
7769 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7770 (match_operand:SWIM 2 "<general_szext_operand>")))]
7773 enum machine_mode mode = <MODE>mode;
7774 rtx (*insn) (rtx, rtx);
7776 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7778 HOST_WIDE_INT ival = INTVAL (operands[2]);
7780 if (ival == (HOST_WIDE_INT) 0xffffffff)
7782 else if (ival == 0xffff)
7784 else if (ival == 0xff)
7788 if (mode == <MODE>mode)
7790 ix86_expand_binary_operator (AND, <MODE>mode, operands);
7794 if (<MODE>mode == DImode)
7795 insn = (mode == SImode)
7796 ? gen_zero_extendsidi2
7798 ? gen_zero_extendhidi2
7799 : gen_zero_extendqidi2;
7800 else if (<MODE>mode == SImode)
7801 insn = (mode == HImode)
7802 ? gen_zero_extendhisi2
7803 : gen_zero_extendqisi2;
7804 else if (<MODE>mode == HImode)
7805 insn = gen_zero_extendqihi2;
7809 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7813 (define_insn "*anddi_1"
7814 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7816 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7817 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7818 (clobber (reg:CC FLAGS_REG))]
7819 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7821 switch (get_attr_type (insn))
7827 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7828 if (get_attr_mode (insn) == MODE_SI)
7829 return "and{l}\t{%k2, %k0|%k0, %k2}";
7831 return "and{q}\t{%2, %0|%0, %2}";
7834 [(set_attr "type" "alu,alu,alu,imovx")
7835 (set_attr "length_immediate" "*,*,*,0")
7836 (set (attr "prefix_rex")
7838 (and (eq_attr "type" "imovx")
7839 (and (match_test "INTVAL (operands[2]) == 0xff")
7840 (match_operand 1 "ext_QIreg_operand")))
7842 (const_string "*")))
7843 (set_attr "mode" "SI,DI,DI,SI")])
7845 (define_insn "*andsi_1"
7846 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya")
7847 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7848 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7849 (clobber (reg:CC FLAGS_REG))]
7850 "ix86_binary_operator_ok (AND, SImode, operands)"
7852 switch (get_attr_type (insn))
7858 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7859 return "and{l}\t{%2, %0|%0, %2}";
7862 [(set_attr "type" "alu,alu,imovx")
7863 (set (attr "prefix_rex")
7865 (and (eq_attr "type" "imovx")
7866 (and (match_test "INTVAL (operands[2]) == 0xff")
7867 (match_operand 1 "ext_QIreg_operand")))
7869 (const_string "*")))
7870 (set_attr "length_immediate" "*,*,0")
7871 (set_attr "mode" "SI")])
7873 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7874 (define_insn "*andsi_1_zext"
7875 [(set (match_operand:DI 0 "register_operand" "=r")
7877 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7878 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7879 (clobber (reg:CC FLAGS_REG))]
7880 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7881 "and{l}\t{%2, %k0|%k0, %2}"
7882 [(set_attr "type" "alu")
7883 (set_attr "mode" "SI")])
7885 (define_insn "*andhi_1"
7886 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya")
7887 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7888 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7889 (clobber (reg:CC FLAGS_REG))]
7890 "ix86_binary_operator_ok (AND, HImode, operands)"
7892 switch (get_attr_type (insn))
7898 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7899 return "and{w}\t{%2, %0|%0, %2}";
7902 [(set_attr "type" "alu,alu,imovx")
7903 (set_attr "length_immediate" "*,*,0")
7904 (set (attr "prefix_rex")
7906 (and (eq_attr "type" "imovx")
7907 (match_operand 1 "ext_QIreg_operand"))
7909 (const_string "*")))
7910 (set_attr "mode" "HI,HI,SI")])
7912 ;; %%% Potential partial reg stall on alternative 2. What to do?
7913 (define_insn "*andqi_1"
7914 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7915 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7916 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7917 (clobber (reg:CC FLAGS_REG))]
7918 "ix86_binary_operator_ok (AND, QImode, operands)"
7920 and{b}\t{%2, %0|%0, %2}
7921 and{b}\t{%2, %0|%0, %2}
7922 and{l}\t{%k2, %k0|%k0, %k2}"
7923 [(set_attr "type" "alu")
7924 (set_attr "mode" "QI,QI,SI")])
7926 (define_insn "*andqi_1_slp"
7927 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7928 (and:QI (match_dup 0)
7929 (match_operand:QI 1 "general_operand" "qn,qmn")))
7930 (clobber (reg:CC FLAGS_REG))]
7931 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7932 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7933 "and{b}\t{%1, %0|%0, %1}"
7934 [(set_attr "type" "alu1")
7935 (set_attr "mode" "QI")])
7937 ;; Turn *anddi_1 into *andsi_1_zext if possible.
7939 [(set (match_operand:DI 0 "register_operand")
7940 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
7941 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
7942 (clobber (reg:CC FLAGS_REG))]
7944 [(parallel [(set (match_dup 0)
7945 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
7946 (clobber (reg:CC FLAGS_REG))])]
7947 "operands[2] = gen_lowpart (SImode, operands[2]);")
7950 [(set (match_operand:SWI248 0 "register_operand")
7951 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
7952 (match_operand:SWI248 2 "const_int_operand")))
7953 (clobber (reg:CC FLAGS_REG))]
7955 && true_regnum (operands[0]) != true_regnum (operands[1])"
7958 HOST_WIDE_INT ival = INTVAL (operands[2]);
7959 enum machine_mode mode;
7960 rtx (*insn) (rtx, rtx);
7962 if (ival == (HOST_WIDE_INT) 0xffffffff)
7964 else if (ival == 0xffff)
7968 gcc_assert (ival == 0xff);
7972 if (<MODE>mode == DImode)
7973 insn = (mode == SImode)
7974 ? gen_zero_extendsidi2
7976 ? gen_zero_extendhidi2
7977 : gen_zero_extendqidi2;
7980 if (<MODE>mode != SImode)
7981 /* Zero extend to SImode to avoid partial register stalls. */
7982 operands[0] = gen_lowpart (SImode, operands[0]);
7984 insn = (mode == HImode)
7985 ? gen_zero_extendhisi2
7986 : gen_zero_extendqisi2;
7988 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7993 [(set (match_operand 0 "register_operand")
7995 (const_int -65536)))
7996 (clobber (reg:CC FLAGS_REG))]
7997 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7998 || optimize_function_for_size_p (cfun)"
7999 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8000 "operands[1] = gen_lowpart (HImode, operands[0]);")
8003 [(set (match_operand 0 "ext_register_operand")
8006 (clobber (reg:CC FLAGS_REG))]
8007 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8008 && reload_completed"
8009 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8010 "operands[1] = gen_lowpart (QImode, operands[0]);")
8013 [(set (match_operand 0 "ext_register_operand")
8015 (const_int -65281)))
8016 (clobber (reg:CC FLAGS_REG))]
8017 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8018 && reload_completed"
8019 [(parallel [(set (zero_extract:SI (match_dup 0)
8023 (zero_extract:SI (match_dup 0)
8026 (zero_extract:SI (match_dup 0)
8029 (clobber (reg:CC FLAGS_REG))])]
8030 "operands[0] = gen_lowpart (SImode, operands[0]);")
8032 (define_insn "*anddi_2"
8033 [(set (reg FLAGS_REG)
8036 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8037 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8039 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8040 (and:DI (match_dup 1) (match_dup 2)))]
8041 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8042 && ix86_binary_operator_ok (AND, DImode, operands)"
8044 and{l}\t{%k2, %k0|%k0, %k2}
8045 and{q}\t{%2, %0|%0, %2}
8046 and{q}\t{%2, %0|%0, %2}"
8047 [(set_attr "type" "alu")
8048 (set_attr "mode" "SI,DI,DI")])
8050 (define_insn "*andqi_2_maybe_si"
8051 [(set (reg FLAGS_REG)
8053 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8054 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8056 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8057 (and:QI (match_dup 1) (match_dup 2)))]
8058 "ix86_binary_operator_ok (AND, QImode, operands)
8059 && ix86_match_ccmode (insn,
8060 CONST_INT_P (operands[2])
8061 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8063 if (which_alternative == 2)
8065 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8066 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8067 return "and{l}\t{%2, %k0|%k0, %2}";
8069 return "and{b}\t{%2, %0|%0, %2}";
8071 [(set_attr "type" "alu")
8072 (set_attr "mode" "QI,QI,SI")])
8074 (define_insn "*and<mode>_2"
8075 [(set (reg FLAGS_REG)
8076 (compare (and:SWI124
8077 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8078 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8080 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8081 (and:SWI124 (match_dup 1) (match_dup 2)))]
8082 "ix86_match_ccmode (insn, CCNOmode)
8083 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8084 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8085 [(set_attr "type" "alu")
8086 (set_attr "mode" "<MODE>")])
8088 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8089 (define_insn "*andsi_2_zext"
8090 [(set (reg FLAGS_REG)
8092 (match_operand:SI 1 "nonimmediate_operand" "%0")
8093 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8095 (set (match_operand:DI 0 "register_operand" "=r")
8096 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8097 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8098 && ix86_binary_operator_ok (AND, SImode, operands)"
8099 "and{l}\t{%2, %k0|%k0, %2}"
8100 [(set_attr "type" "alu")
8101 (set_attr "mode" "SI")])
8103 (define_insn "*andqi_2_slp"
8104 [(set (reg FLAGS_REG)
8106 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8107 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8109 (set (strict_low_part (match_dup 0))
8110 (and:QI (match_dup 0) (match_dup 1)))]
8111 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8112 && ix86_match_ccmode (insn, CCNOmode)
8113 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8114 "and{b}\t{%1, %0|%0, %1}"
8115 [(set_attr "type" "alu1")
8116 (set_attr "mode" "QI")])
8118 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8119 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8120 ;; for a QImode operand, which of course failed.
8121 (define_insn "andqi_ext_0"
8122 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8127 (match_operand 1 "ext_register_operand" "0")
8130 (match_operand 2 "const_int_operand" "n")))
8131 (clobber (reg:CC FLAGS_REG))]
8133 "and{b}\t{%2, %h0|%h0, %2}"
8134 [(set_attr "type" "alu")
8135 (set_attr "length_immediate" "1")
8136 (set_attr "modrm" "1")
8137 (set_attr "mode" "QI")])
8139 ;; Generated by peephole translating test to and. This shows up
8140 ;; often in fp comparisons.
8141 (define_insn "*andqi_ext_0_cc"
8142 [(set (reg FLAGS_REG)
8146 (match_operand 1 "ext_register_operand" "0")
8149 (match_operand 2 "const_int_operand" "n"))
8151 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8160 "ix86_match_ccmode (insn, CCNOmode)"
8161 "and{b}\t{%2, %h0|%h0, %2}"
8162 [(set_attr "type" "alu")
8163 (set_attr "length_immediate" "1")
8164 (set_attr "modrm" "1")
8165 (set_attr "mode" "QI")])
8167 (define_insn "*andqi_ext_1_rex64"
8168 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8173 (match_operand 1 "ext_register_operand" "0")
8177 (match_operand 2 "ext_register_operand" "Q"))))
8178 (clobber (reg:CC FLAGS_REG))]
8180 "and{b}\t{%2, %h0|%h0, %2}"
8181 [(set_attr "type" "alu")
8182 (set_attr "length_immediate" "0")
8183 (set_attr "mode" "QI")])
8185 (define_insn "*andqi_ext_1"
8186 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8191 (match_operand 1 "ext_register_operand" "0")
8195 (match_operand:QI 2 "general_operand" "Qm"))))
8196 (clobber (reg:CC FLAGS_REG))]
8198 "and{b}\t{%2, %h0|%h0, %2}"
8199 [(set_attr "type" "alu")
8200 (set_attr "length_immediate" "0")
8201 (set_attr "mode" "QI")])
8203 (define_insn "*andqi_ext_2"
8204 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8209 (match_operand 1 "ext_register_operand" "%0")
8213 (match_operand 2 "ext_register_operand" "Q")
8216 (clobber (reg:CC FLAGS_REG))]
8218 "and{b}\t{%h2, %h0|%h0, %h2}"
8219 [(set_attr "type" "alu")
8220 (set_attr "length_immediate" "0")
8221 (set_attr "mode" "QI")])
8223 ;; Convert wide AND instructions with immediate operand to shorter QImode
8224 ;; equivalents when possible.
8225 ;; Don't do the splitting with memory operands, since it introduces risk
8226 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8227 ;; for size, but that can (should?) be handled by generic code instead.
8229 [(set (match_operand 0 "register_operand")
8230 (and (match_operand 1 "register_operand")
8231 (match_operand 2 "const_int_operand")))
8232 (clobber (reg:CC FLAGS_REG))]
8234 && QI_REG_P (operands[0])
8235 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8236 && !(~INTVAL (operands[2]) & ~(255 << 8))
8237 && GET_MODE (operands[0]) != QImode"
8238 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8239 (and:SI (zero_extract:SI (match_dup 1)
8240 (const_int 8) (const_int 8))
8242 (clobber (reg:CC FLAGS_REG))])]
8244 operands[0] = gen_lowpart (SImode, operands[0]);
8245 operands[1] = gen_lowpart (SImode, operands[1]);
8246 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8249 ;; Since AND can be encoded with sign extended immediate, this is only
8250 ;; profitable when 7th bit is not set.
8252 [(set (match_operand 0 "register_operand")
8253 (and (match_operand 1 "general_operand")
8254 (match_operand 2 "const_int_operand")))
8255 (clobber (reg:CC FLAGS_REG))]
8257 && ANY_QI_REG_P (operands[0])
8258 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8259 && !(~INTVAL (operands[2]) & ~255)
8260 && !(INTVAL (operands[2]) & 128)
8261 && GET_MODE (operands[0]) != QImode"
8262 [(parallel [(set (strict_low_part (match_dup 0))
8263 (and:QI (match_dup 1)
8265 (clobber (reg:CC FLAGS_REG))])]
8267 operands[0] = gen_lowpart (QImode, operands[0]);
8268 operands[1] = gen_lowpart (QImode, operands[1]);
8269 operands[2] = gen_lowpart (QImode, operands[2]);
8272 ;; Logical inclusive and exclusive OR instructions
8274 ;; %%% This used to optimize known byte-wide and operations to memory.
8275 ;; If this is considered useful, it should be done with splitters.
8277 (define_expand "<code><mode>3"
8278 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8279 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
8280 (match_operand:SWIM 2 "<general_operand>")))]
8282 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8284 (define_insn "*<code><mode>_1"
8285 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8287 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8288 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8289 (clobber (reg:CC FLAGS_REG))]
8290 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8291 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8292 [(set_attr "type" "alu")
8293 (set_attr "mode" "<MODE>")])
8295 ;; %%% Potential partial reg stall on alternative 2. What to do?
8296 (define_insn "*<code>qi_1"
8297 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8298 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8299 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8300 (clobber (reg:CC FLAGS_REG))]
8301 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8303 <logic>{b}\t{%2, %0|%0, %2}
8304 <logic>{b}\t{%2, %0|%0, %2}
8305 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8306 [(set_attr "type" "alu")
8307 (set_attr "mode" "QI,QI,SI")])
8309 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8310 (define_insn "*<code>si_1_zext"
8311 [(set (match_operand:DI 0 "register_operand" "=r")
8313 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8314 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8315 (clobber (reg:CC FLAGS_REG))]
8316 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8317 "<logic>{l}\t{%2, %k0|%k0, %2}"
8318 [(set_attr "type" "alu")
8319 (set_attr "mode" "SI")])
8321 (define_insn "*<code>si_1_zext_imm"
8322 [(set (match_operand:DI 0 "register_operand" "=r")
8324 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8325 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8326 (clobber (reg:CC FLAGS_REG))]
8327 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8328 "<logic>{l}\t{%2, %k0|%k0, %2}"
8329 [(set_attr "type" "alu")
8330 (set_attr "mode" "SI")])
8332 (define_insn "*<code>qi_1_slp"
8333 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8334 (any_or:QI (match_dup 0)
8335 (match_operand:QI 1 "general_operand" "qmn,qn")))
8336 (clobber (reg:CC FLAGS_REG))]
8337 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8338 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8339 "<logic>{b}\t{%1, %0|%0, %1}"
8340 [(set_attr "type" "alu1")
8341 (set_attr "mode" "QI")])
8343 (define_insn "*<code><mode>_2"
8344 [(set (reg FLAGS_REG)
8345 (compare (any_or:SWI
8346 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8347 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8349 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8350 (any_or:SWI (match_dup 1) (match_dup 2)))]
8351 "ix86_match_ccmode (insn, CCNOmode)
8352 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8353 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8354 [(set_attr "type" "alu")
8355 (set_attr "mode" "<MODE>")])
8357 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8358 ;; ??? Special case for immediate operand is missing - it is tricky.
8359 (define_insn "*<code>si_2_zext"
8360 [(set (reg FLAGS_REG)
8361 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8362 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8364 (set (match_operand:DI 0 "register_operand" "=r")
8365 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8366 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8367 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8368 "<logic>{l}\t{%2, %k0|%k0, %2}"
8369 [(set_attr "type" "alu")
8370 (set_attr "mode" "SI")])
8372 (define_insn "*<code>si_2_zext_imm"
8373 [(set (reg FLAGS_REG)
8375 (match_operand:SI 1 "nonimmediate_operand" "%0")
8376 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8378 (set (match_operand:DI 0 "register_operand" "=r")
8379 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8380 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8381 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8382 "<logic>{l}\t{%2, %k0|%k0, %2}"
8383 [(set_attr "type" "alu")
8384 (set_attr "mode" "SI")])
8386 (define_insn "*<code>qi_2_slp"
8387 [(set (reg FLAGS_REG)
8388 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8389 (match_operand:QI 1 "general_operand" "qmn,qn"))
8391 (set (strict_low_part (match_dup 0))
8392 (any_or:QI (match_dup 0) (match_dup 1)))]
8393 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8394 && ix86_match_ccmode (insn, CCNOmode)
8395 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8396 "<logic>{b}\t{%1, %0|%0, %1}"
8397 [(set_attr "type" "alu1")
8398 (set_attr "mode" "QI")])
8400 (define_insn "*<code><mode>_3"
8401 [(set (reg FLAGS_REG)
8402 (compare (any_or:SWI
8403 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8404 (match_operand:SWI 2 "<general_operand>" "<g>"))
8406 (clobber (match_scratch:SWI 0 "=<r>"))]
8407 "ix86_match_ccmode (insn, CCNOmode)
8408 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8409 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8410 [(set_attr "type" "alu")
8411 (set_attr "mode" "<MODE>")])
8413 (define_insn "*<code>qi_ext_0"
8414 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8419 (match_operand 1 "ext_register_operand" "0")
8422 (match_operand 2 "const_int_operand" "n")))
8423 (clobber (reg:CC FLAGS_REG))]
8424 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8425 "<logic>{b}\t{%2, %h0|%h0, %2}"
8426 [(set_attr "type" "alu")
8427 (set_attr "length_immediate" "1")
8428 (set_attr "modrm" "1")
8429 (set_attr "mode" "QI")])
8431 (define_insn "*<code>qi_ext_1_rex64"
8432 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8437 (match_operand 1 "ext_register_operand" "0")
8441 (match_operand 2 "ext_register_operand" "Q"))))
8442 (clobber (reg:CC FLAGS_REG))]
8444 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8445 "<logic>{b}\t{%2, %h0|%h0, %2}"
8446 [(set_attr "type" "alu")
8447 (set_attr "length_immediate" "0")
8448 (set_attr "mode" "QI")])
8450 (define_insn "*<code>qi_ext_1"
8451 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8456 (match_operand 1 "ext_register_operand" "0")
8460 (match_operand:QI 2 "general_operand" "Qm"))))
8461 (clobber (reg:CC FLAGS_REG))]
8463 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8464 "<logic>{b}\t{%2, %h0|%h0, %2}"
8465 [(set_attr "type" "alu")
8466 (set_attr "length_immediate" "0")
8467 (set_attr "mode" "QI")])
8469 (define_insn "*<code>qi_ext_2"
8470 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8474 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8477 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8480 (clobber (reg:CC FLAGS_REG))]
8481 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8482 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8483 [(set_attr "type" "alu")
8484 (set_attr "length_immediate" "0")
8485 (set_attr "mode" "QI")])
8488 [(set (match_operand 0 "register_operand")
8489 (any_or (match_operand 1 "register_operand")
8490 (match_operand 2 "const_int_operand")))
8491 (clobber (reg:CC FLAGS_REG))]
8493 && QI_REG_P (operands[0])
8494 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8495 && !(INTVAL (operands[2]) & ~(255 << 8))
8496 && GET_MODE (operands[0]) != QImode"
8497 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8498 (any_or:SI (zero_extract:SI (match_dup 1)
8499 (const_int 8) (const_int 8))
8501 (clobber (reg:CC FLAGS_REG))])]
8503 operands[0] = gen_lowpart (SImode, operands[0]);
8504 operands[1] = gen_lowpart (SImode, operands[1]);
8505 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8508 ;; Since OR can be encoded with sign extended immediate, this is only
8509 ;; profitable when 7th bit is set.
8511 [(set (match_operand 0 "register_operand")
8512 (any_or (match_operand 1 "general_operand")
8513 (match_operand 2 "const_int_operand")))
8514 (clobber (reg:CC FLAGS_REG))]
8516 && ANY_QI_REG_P (operands[0])
8517 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8518 && !(INTVAL (operands[2]) & ~255)
8519 && (INTVAL (operands[2]) & 128)
8520 && GET_MODE (operands[0]) != QImode"
8521 [(parallel [(set (strict_low_part (match_dup 0))
8522 (any_or:QI (match_dup 1)
8524 (clobber (reg:CC FLAGS_REG))])]
8526 operands[0] = gen_lowpart (QImode, operands[0]);
8527 operands[1] = gen_lowpart (QImode, operands[1]);
8528 operands[2] = gen_lowpart (QImode, operands[2]);
8531 (define_expand "xorqi_cc_ext_1"
8533 (set (reg:CCNO FLAGS_REG)
8537 (match_operand 1 "ext_register_operand")
8540 (match_operand:QI 2 "general_operand"))
8542 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8552 (define_insn "*xorqi_cc_ext_1_rex64"
8553 [(set (reg FLAGS_REG)
8557 (match_operand 1 "ext_register_operand" "0")
8560 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8562 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8571 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8572 "xor{b}\t{%2, %h0|%h0, %2}"
8573 [(set_attr "type" "alu")
8574 (set_attr "modrm" "1")
8575 (set_attr "mode" "QI")])
8577 (define_insn "*xorqi_cc_ext_1"
8578 [(set (reg FLAGS_REG)
8582 (match_operand 1 "ext_register_operand" "0")
8585 (match_operand:QI 2 "general_operand" "qmn"))
8587 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8596 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8597 "xor{b}\t{%2, %h0|%h0, %2}"
8598 [(set_attr "type" "alu")
8599 (set_attr "modrm" "1")
8600 (set_attr "mode" "QI")])
8602 ;; Negation instructions
8604 (define_expand "neg<mode>2"
8605 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8606 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8608 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8610 (define_insn_and_split "*neg<dwi>2_doubleword"
8611 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8612 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8613 (clobber (reg:CC FLAGS_REG))]
8614 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8618 [(set (reg:CCZ FLAGS_REG)
8619 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8620 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8623 (plus:DWIH (match_dup 3)
8624 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8626 (clobber (reg:CC FLAGS_REG))])
8629 (neg:DWIH (match_dup 2)))
8630 (clobber (reg:CC FLAGS_REG))])]
8631 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8633 (define_insn "*neg<mode>2_1"
8634 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8635 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8636 (clobber (reg:CC FLAGS_REG))]
8637 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8638 "neg{<imodesuffix>}\t%0"
8639 [(set_attr "type" "negnot")
8640 (set_attr "mode" "<MODE>")])
8642 ;; Combine is quite creative about this pattern.
8643 (define_insn "*negsi2_1_zext"
8644 [(set (match_operand:DI 0 "register_operand" "=r")
8646 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8649 (clobber (reg:CC FLAGS_REG))]
8650 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8652 [(set_attr "type" "negnot")
8653 (set_attr "mode" "SI")])
8655 ;; The problem with neg is that it does not perform (compare x 0),
8656 ;; it really performs (compare 0 x), which leaves us with the zero
8657 ;; flag being the only useful item.
8659 (define_insn "*neg<mode>2_cmpz"
8660 [(set (reg:CCZ FLAGS_REG)
8662 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8664 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8665 (neg:SWI (match_dup 1)))]
8666 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8667 "neg{<imodesuffix>}\t%0"
8668 [(set_attr "type" "negnot")
8669 (set_attr "mode" "<MODE>")])
8671 (define_insn "*negsi2_cmpz_zext"
8672 [(set (reg:CCZ FLAGS_REG)
8676 (match_operand:DI 1 "register_operand" "0")
8680 (set (match_operand:DI 0 "register_operand" "=r")
8681 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8684 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8686 [(set_attr "type" "negnot")
8687 (set_attr "mode" "SI")])
8689 ;; Changing of sign for FP values is doable using integer unit too.
8691 (define_expand "<code><mode>2"
8692 [(set (match_operand:X87MODEF 0 "register_operand")
8693 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8694 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8695 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8697 (define_insn "*absneg<mode>2_mixed"
8698 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8699 (match_operator:MODEF 3 "absneg_operator"
8700 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8701 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8702 (clobber (reg:CC FLAGS_REG))]
8703 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8706 (define_insn "*absneg<mode>2_sse"
8707 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8708 (match_operator:MODEF 3 "absneg_operator"
8709 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8710 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8711 (clobber (reg:CC FLAGS_REG))]
8712 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8715 (define_insn "*absneg<mode>2_i387"
8716 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8717 (match_operator:X87MODEF 3 "absneg_operator"
8718 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8719 (use (match_operand 2))
8720 (clobber (reg:CC FLAGS_REG))]
8721 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8724 (define_expand "<code>tf2"
8725 [(set (match_operand:TF 0 "register_operand")
8726 (absneg:TF (match_operand:TF 1 "register_operand")))]
8728 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8730 (define_insn "*absnegtf2_sse"
8731 [(set (match_operand:TF 0 "register_operand" "=x,x")
8732 (match_operator:TF 3 "absneg_operator"
8733 [(match_operand:TF 1 "register_operand" "0,x")]))
8734 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8735 (clobber (reg:CC FLAGS_REG))]
8739 ;; Splitters for fp abs and neg.
8742 [(set (match_operand 0 "fp_register_operand")
8743 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8744 (use (match_operand 2))
8745 (clobber (reg:CC FLAGS_REG))]
8747 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8750 [(set (match_operand 0 "register_operand")
8751 (match_operator 3 "absneg_operator"
8752 [(match_operand 1 "register_operand")]))
8753 (use (match_operand 2 "nonimmediate_operand"))
8754 (clobber (reg:CC FLAGS_REG))]
8755 "reload_completed && SSE_REG_P (operands[0])"
8756 [(set (match_dup 0) (match_dup 3))]
8758 enum machine_mode mode = GET_MODE (operands[0]);
8759 enum machine_mode vmode = GET_MODE (operands[2]);
8762 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8763 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8764 if (operands_match_p (operands[0], operands[2]))
8767 operands[1] = operands[2];
8770 if (GET_CODE (operands[3]) == ABS)
8771 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8773 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8778 [(set (match_operand:SF 0 "register_operand")
8779 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8780 (use (match_operand:V4SF 2))
8781 (clobber (reg:CC FLAGS_REG))]
8783 [(parallel [(set (match_dup 0) (match_dup 1))
8784 (clobber (reg:CC FLAGS_REG))])]
8787 operands[0] = gen_lowpart (SImode, operands[0]);
8788 if (GET_CODE (operands[1]) == ABS)
8790 tmp = gen_int_mode (0x7fffffff, SImode);
8791 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8795 tmp = gen_int_mode (0x80000000, SImode);
8796 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8802 [(set (match_operand:DF 0 "register_operand")
8803 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8804 (use (match_operand 2))
8805 (clobber (reg:CC FLAGS_REG))]
8807 [(parallel [(set (match_dup 0) (match_dup 1))
8808 (clobber (reg:CC FLAGS_REG))])]
8813 tmp = gen_lowpart (DImode, operands[0]);
8814 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8817 if (GET_CODE (operands[1]) == ABS)
8820 tmp = gen_rtx_NOT (DImode, tmp);
8824 operands[0] = gen_highpart (SImode, operands[0]);
8825 if (GET_CODE (operands[1]) == ABS)
8827 tmp = gen_int_mode (0x7fffffff, SImode);
8828 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8832 tmp = gen_int_mode (0x80000000, SImode);
8833 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8840 [(set (match_operand:XF 0 "register_operand")
8841 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8842 (use (match_operand 2))
8843 (clobber (reg:CC FLAGS_REG))]
8845 [(parallel [(set (match_dup 0) (match_dup 1))
8846 (clobber (reg:CC FLAGS_REG))])]
8849 operands[0] = gen_rtx_REG (SImode,
8850 true_regnum (operands[0])
8851 + (TARGET_64BIT ? 1 : 2));
8852 if (GET_CODE (operands[1]) == ABS)
8854 tmp = GEN_INT (0x7fff);
8855 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8859 tmp = GEN_INT (0x8000);
8860 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8865 ;; Conditionalize these after reload. If they match before reload, we
8866 ;; lose the clobber and ability to use integer instructions.
8868 (define_insn "*<code><mode>2_1"
8869 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8870 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8872 && (reload_completed
8873 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8874 "f<absneg_mnemonic>"
8875 [(set_attr "type" "fsgn")
8876 (set_attr "mode" "<MODE>")])
8878 (define_insn "*<code>extendsfdf2"
8879 [(set (match_operand:DF 0 "register_operand" "=f")
8880 (absneg:DF (float_extend:DF
8881 (match_operand:SF 1 "register_operand" "0"))))]
8882 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8883 "f<absneg_mnemonic>"
8884 [(set_attr "type" "fsgn")
8885 (set_attr "mode" "DF")])
8887 (define_insn "*<code>extendsfxf2"
8888 [(set (match_operand:XF 0 "register_operand" "=f")
8889 (absneg:XF (float_extend:XF
8890 (match_operand:SF 1 "register_operand" "0"))))]
8892 "f<absneg_mnemonic>"
8893 [(set_attr "type" "fsgn")
8894 (set_attr "mode" "XF")])
8896 (define_insn "*<code>extenddfxf2"
8897 [(set (match_operand:XF 0 "register_operand" "=f")
8898 (absneg:XF (float_extend:XF
8899 (match_operand:DF 1 "register_operand" "0"))))]
8901 "f<absneg_mnemonic>"
8902 [(set_attr "type" "fsgn")
8903 (set_attr "mode" "XF")])
8905 ;; Copysign instructions
8907 (define_mode_iterator CSGNMODE [SF DF TF])
8908 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8910 (define_expand "copysign<mode>3"
8911 [(match_operand:CSGNMODE 0 "register_operand")
8912 (match_operand:CSGNMODE 1 "nonmemory_operand")
8913 (match_operand:CSGNMODE 2 "register_operand")]
8914 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8915 || (TARGET_SSE && (<MODE>mode == TFmode))"
8916 "ix86_expand_copysign (operands); DONE;")
8918 (define_insn_and_split "copysign<mode>3_const"
8919 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8921 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8922 (match_operand:CSGNMODE 2 "register_operand" "0")
8923 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8925 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8926 || (TARGET_SSE && (<MODE>mode == TFmode))"
8928 "&& reload_completed"
8930 "ix86_split_copysign_const (operands); DONE;")
8932 (define_insn "copysign<mode>3_var"
8933 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8935 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8936 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8937 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8938 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8940 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8941 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8942 || (TARGET_SSE && (<MODE>mode == TFmode))"
8946 [(set (match_operand:CSGNMODE 0 "register_operand")
8948 [(match_operand:CSGNMODE 2 "register_operand")
8949 (match_operand:CSGNMODE 3 "register_operand")
8950 (match_operand:<CSGNVMODE> 4)
8951 (match_operand:<CSGNVMODE> 5)]
8953 (clobber (match_scratch:<CSGNVMODE> 1))]
8954 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8955 || (TARGET_SSE && (<MODE>mode == TFmode)))
8956 && reload_completed"
8958 "ix86_split_copysign_var (operands); DONE;")
8960 ;; One complement instructions
8962 (define_expand "one_cmpl<mode>2"
8963 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8964 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
8966 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8968 (define_insn "*one_cmpl<mode>2_1"
8969 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8970 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8971 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8972 "not{<imodesuffix>}\t%0"
8973 [(set_attr "type" "negnot")
8974 (set_attr "mode" "<MODE>")])
8976 ;; %%% Potential partial reg stall on alternative 1. What to do?
8977 (define_insn "*one_cmplqi2_1"
8978 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8979 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8980 "ix86_unary_operator_ok (NOT, QImode, operands)"
8984 [(set_attr "type" "negnot")
8985 (set_attr "mode" "QI,SI")])
8987 ;; ??? Currently never generated - xor is used instead.
8988 (define_insn "*one_cmplsi2_1_zext"
8989 [(set (match_operand:DI 0 "register_operand" "=r")
8991 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8992 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8994 [(set_attr "type" "negnot")
8995 (set_attr "mode" "SI")])
8997 (define_insn "*one_cmpl<mode>2_2"
8998 [(set (reg FLAGS_REG)
8999 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9001 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9002 (not:SWI (match_dup 1)))]
9003 "ix86_match_ccmode (insn, CCNOmode)
9004 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9006 [(set_attr "type" "alu1")
9007 (set_attr "mode" "<MODE>")])
9010 [(set (match_operand 0 "flags_reg_operand")
9011 (match_operator 2 "compare_operator"
9012 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9014 (set (match_operand:SWI 1 "nonimmediate_operand")
9015 (not:SWI (match_dup 3)))]
9016 "ix86_match_ccmode (insn, CCNOmode)"
9017 [(parallel [(set (match_dup 0)
9018 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9021 (xor:SWI (match_dup 3) (const_int -1)))])])
9023 ;; ??? Currently never generated - xor is used instead.
9024 (define_insn "*one_cmplsi2_2_zext"
9025 [(set (reg FLAGS_REG)
9026 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9028 (set (match_operand:DI 0 "register_operand" "=r")
9029 (zero_extend:DI (not:SI (match_dup 1))))]
9030 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9031 && ix86_unary_operator_ok (NOT, SImode, operands)"
9033 [(set_attr "type" "alu1")
9034 (set_attr "mode" "SI")])
9037 [(set (match_operand 0 "flags_reg_operand")
9038 (match_operator 2 "compare_operator"
9039 [(not:SI (match_operand:SI 3 "register_operand"))
9041 (set (match_operand:DI 1 "register_operand")
9042 (zero_extend:DI (not:SI (match_dup 3))))]
9043 "ix86_match_ccmode (insn, CCNOmode)"
9044 [(parallel [(set (match_dup 0)
9045 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9048 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9050 ;; Shift instructions
9052 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9053 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9054 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9055 ;; from the assembler input.
9057 ;; This instruction shifts the target reg/mem as usual, but instead of
9058 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9059 ;; is a left shift double, bits are taken from the high order bits of
9060 ;; reg, else if the insn is a shift right double, bits are taken from the
9061 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9062 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9064 ;; Since sh[lr]d does not change the `reg' operand, that is done
9065 ;; separately, making all shifts emit pairs of shift double and normal
9066 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9067 ;; support a 63 bit shift, each shift where the count is in a reg expands
9068 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9070 ;; If the shift count is a constant, we need never emit more than one
9071 ;; shift pair, instead using moves and sign extension for counts greater
9074 (define_expand "ashl<mode>3"
9075 [(set (match_operand:SDWIM 0 "<shift_operand>")
9076 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9077 (match_operand:QI 2 "nonmemory_operand")))]
9079 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9081 (define_insn "*ashl<mode>3_doubleword"
9082 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9083 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9084 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9085 (clobber (reg:CC FLAGS_REG))]
9088 [(set_attr "type" "multi")])
9091 [(set (match_operand:DWI 0 "register_operand")
9092 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9093 (match_operand:QI 2 "nonmemory_operand")))
9094 (clobber (reg:CC FLAGS_REG))]
9095 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9097 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9099 ;; By default we don't ask for a scratch register, because when DWImode
9100 ;; values are manipulated, registers are already at a premium. But if
9101 ;; we have one handy, we won't turn it away.
9104 [(match_scratch:DWIH 3 "r")
9105 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9107 (match_operand:<DWI> 1 "nonmemory_operand")
9108 (match_operand:QI 2 "nonmemory_operand")))
9109 (clobber (reg:CC FLAGS_REG))])
9113 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9115 (define_insn "x86_64_shld"
9116 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9117 (ior:DI (ashift:DI (match_dup 0)
9118 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9119 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9120 (minus:QI (const_int 64) (match_dup 2)))))
9121 (clobber (reg:CC FLAGS_REG))]
9123 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9124 [(set_attr "type" "ishift")
9125 (set_attr "prefix_0f" "1")
9126 (set_attr "mode" "DI")
9127 (set_attr "athlon_decode" "vector")
9128 (set_attr "amdfam10_decode" "vector")
9129 (set_attr "bdver1_decode" "vector")])
9131 (define_insn "x86_shld"
9132 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9133 (ior:SI (ashift:SI (match_dup 0)
9134 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9135 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9136 (minus:QI (const_int 32) (match_dup 2)))))
9137 (clobber (reg:CC FLAGS_REG))]
9139 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9140 [(set_attr "type" "ishift")
9141 (set_attr "prefix_0f" "1")
9142 (set_attr "mode" "SI")
9143 (set_attr "pent_pair" "np")
9144 (set_attr "athlon_decode" "vector")
9145 (set_attr "amdfam10_decode" "vector")
9146 (set_attr "bdver1_decode" "vector")])
9148 (define_expand "x86_shift<mode>_adj_1"
9149 [(set (reg:CCZ FLAGS_REG)
9150 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9153 (set (match_operand:SWI48 0 "register_operand")
9154 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9155 (match_operand:SWI48 1 "register_operand")
9158 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9159 (match_operand:SWI48 3 "register_operand")
9162 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9164 (define_expand "x86_shift<mode>_adj_2"
9165 [(use (match_operand:SWI48 0 "register_operand"))
9166 (use (match_operand:SWI48 1 "register_operand"))
9167 (use (match_operand:QI 2 "register_operand"))]
9170 rtx label = gen_label_rtx ();
9173 emit_insn (gen_testqi_ccz_1 (operands[2],
9174 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9176 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9177 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9178 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9179 gen_rtx_LABEL_REF (VOIDmode, label),
9181 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9182 JUMP_LABEL (tmp) = label;
9184 emit_move_insn (operands[0], operands[1]);
9185 ix86_expand_clear (operands[1]);
9188 LABEL_NUSES (label) = 1;
9193 ;; Avoid useless masking of count operand.
9194 (define_insn_and_split "*ashl<mode>3_mask"
9195 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9197 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9200 (match_operand:SI 2 "nonimmediate_operand" "c")
9201 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9202 (clobber (reg:CC FLAGS_REG))]
9203 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9204 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9205 == GET_MODE_BITSIZE (<MODE>mode)-1"
9208 [(parallel [(set (match_dup 0)
9209 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9210 (clobber (reg:CC FLAGS_REG))])]
9212 if (can_create_pseudo_p ())
9213 operands [2] = force_reg (SImode, operands[2]);
9215 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9217 [(set_attr "type" "ishift")
9218 (set_attr "mode" "<MODE>")])
9220 (define_insn "*bmi2_ashl<mode>3_1"
9221 [(set (match_operand:SWI48 0 "register_operand" "=r")
9222 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9223 (match_operand:SWI48 2 "register_operand" "r")))]
9225 "shlx\t{%2, %1, %0|%0, %1, %2}"
9226 [(set_attr "type" "ishiftx")
9227 (set_attr "mode" "<MODE>")])
9229 (define_insn "*ashl<mode>3_1"
9230 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9231 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9232 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9233 (clobber (reg:CC FLAGS_REG))]
9234 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9236 switch (get_attr_type (insn))
9243 gcc_assert (operands[2] == const1_rtx);
9244 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9245 return "add{<imodesuffix>}\t%0, %0";
9248 if (operands[2] == const1_rtx
9249 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9250 return "sal{<imodesuffix>}\t%0";
9252 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9255 [(set_attr "isa" "*,*,bmi2")
9257 (cond [(eq_attr "alternative" "1")
9258 (const_string "lea")
9259 (eq_attr "alternative" "2")
9260 (const_string "ishiftx")
9261 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9262 (match_operand 0 "register_operand"))
9263 (match_operand 2 "const1_operand"))
9264 (const_string "alu")
9266 (const_string "ishift")))
9267 (set (attr "length_immediate")
9269 (ior (eq_attr "type" "alu")
9270 (and (eq_attr "type" "ishift")
9271 (and (match_operand 2 "const1_operand")
9272 (ior (match_test "TARGET_SHIFT1")
9273 (match_test "optimize_function_for_size_p (cfun)")))))
9275 (const_string "*")))
9276 (set_attr "mode" "<MODE>")])
9278 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9280 [(set (match_operand:SWI48 0 "register_operand")
9281 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9282 (match_operand:QI 2 "register_operand")))
9283 (clobber (reg:CC FLAGS_REG))]
9284 "TARGET_BMI2 && reload_completed"
9286 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9287 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9289 (define_insn "*bmi2_ashlsi3_1_zext"
9290 [(set (match_operand:DI 0 "register_operand" "=r")
9292 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9293 (match_operand:SI 2 "register_operand" "r"))))]
9294 "TARGET_64BIT && TARGET_BMI2"
9295 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9296 [(set_attr "type" "ishiftx")
9297 (set_attr "mode" "SI")])
9299 (define_insn "*ashlsi3_1_zext"
9300 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9302 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9303 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9304 (clobber (reg:CC FLAGS_REG))]
9305 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9307 switch (get_attr_type (insn))
9314 gcc_assert (operands[2] == const1_rtx);
9315 return "add{l}\t%k0, %k0";
9318 if (operands[2] == const1_rtx
9319 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9320 return "sal{l}\t%k0";
9322 return "sal{l}\t{%2, %k0|%k0, %2}";
9325 [(set_attr "isa" "*,*,bmi2")
9327 (cond [(eq_attr "alternative" "1")
9328 (const_string "lea")
9329 (eq_attr "alternative" "2")
9330 (const_string "ishiftx")
9331 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9332 (match_operand 2 "const1_operand"))
9333 (const_string "alu")
9335 (const_string "ishift")))
9336 (set (attr "length_immediate")
9338 (ior (eq_attr "type" "alu")
9339 (and (eq_attr "type" "ishift")
9340 (and (match_operand 2 "const1_operand")
9341 (ior (match_test "TARGET_SHIFT1")
9342 (match_test "optimize_function_for_size_p (cfun)")))))
9344 (const_string "*")))
9345 (set_attr "mode" "SI")])
9347 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9349 [(set (match_operand:DI 0 "register_operand")
9351 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9352 (match_operand:QI 2 "register_operand"))))
9353 (clobber (reg:CC FLAGS_REG))]
9354 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9356 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9357 "operands[2] = gen_lowpart (SImode, operands[2]);")
9359 (define_insn "*ashlhi3_1"
9360 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9361 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9362 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9363 (clobber (reg:CC FLAGS_REG))]
9364 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9366 switch (get_attr_type (insn))
9372 gcc_assert (operands[2] == const1_rtx);
9373 return "add{w}\t%0, %0";
9376 if (operands[2] == const1_rtx
9377 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9378 return "sal{w}\t%0";
9380 return "sal{w}\t{%2, %0|%0, %2}";
9384 (cond [(eq_attr "alternative" "1")
9385 (const_string "lea")
9386 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9387 (match_operand 0 "register_operand"))
9388 (match_operand 2 "const1_operand"))
9389 (const_string "alu")
9391 (const_string "ishift")))
9392 (set (attr "length_immediate")
9394 (ior (eq_attr "type" "alu")
9395 (and (eq_attr "type" "ishift")
9396 (and (match_operand 2 "const1_operand")
9397 (ior (match_test "TARGET_SHIFT1")
9398 (match_test "optimize_function_for_size_p (cfun)")))))
9400 (const_string "*")))
9401 (set_attr "mode" "HI,SI")])
9403 ;; %%% Potential partial reg stall on alternative 1. What to do?
9404 (define_insn "*ashlqi3_1"
9405 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9406 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9407 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9408 (clobber (reg:CC FLAGS_REG))]
9409 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9411 switch (get_attr_type (insn))
9417 gcc_assert (operands[2] == const1_rtx);
9418 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9419 return "add{l}\t%k0, %k0";
9421 return "add{b}\t%0, %0";
9424 if (operands[2] == const1_rtx
9425 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9427 if (get_attr_mode (insn) == MODE_SI)
9428 return "sal{l}\t%k0";
9430 return "sal{b}\t%0";
9434 if (get_attr_mode (insn) == MODE_SI)
9435 return "sal{l}\t{%2, %k0|%k0, %2}";
9437 return "sal{b}\t{%2, %0|%0, %2}";
9442 (cond [(eq_attr "alternative" "2")
9443 (const_string "lea")
9444 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9445 (match_operand 0 "register_operand"))
9446 (match_operand 2 "const1_operand"))
9447 (const_string "alu")
9449 (const_string "ishift")))
9450 (set (attr "length_immediate")
9452 (ior (eq_attr "type" "alu")
9453 (and (eq_attr "type" "ishift")
9454 (and (match_operand 2 "const1_operand")
9455 (ior (match_test "TARGET_SHIFT1")
9456 (match_test "optimize_function_for_size_p (cfun)")))))
9458 (const_string "*")))
9459 (set_attr "mode" "QI,SI,SI")])
9461 (define_insn "*ashlqi3_1_slp"
9462 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9463 (ashift:QI (match_dup 0)
9464 (match_operand:QI 1 "nonmemory_operand" "cI")))
9465 (clobber (reg:CC FLAGS_REG))]
9466 "(optimize_function_for_size_p (cfun)
9467 || !TARGET_PARTIAL_FLAG_REG_STALL
9468 || (operands[1] == const1_rtx
9470 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9472 switch (get_attr_type (insn))
9475 gcc_assert (operands[1] == const1_rtx);
9476 return "add{b}\t%0, %0";
9479 if (operands[1] == const1_rtx
9480 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9481 return "sal{b}\t%0";
9483 return "sal{b}\t{%1, %0|%0, %1}";
9487 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9488 (match_operand 0 "register_operand"))
9489 (match_operand 1 "const1_operand"))
9490 (const_string "alu")
9492 (const_string "ishift1")))
9493 (set (attr "length_immediate")
9495 (ior (eq_attr "type" "alu")
9496 (and (eq_attr "type" "ishift1")
9497 (and (match_operand 1 "const1_operand")
9498 (ior (match_test "TARGET_SHIFT1")
9499 (match_test "optimize_function_for_size_p (cfun)")))))
9501 (const_string "*")))
9502 (set_attr "mode" "QI")])
9504 ;; Convert ashift to the lea pattern to avoid flags dependency.
9506 [(set (match_operand 0 "register_operand")
9507 (ashift (match_operand 1 "index_register_operand")
9508 (match_operand:QI 2 "const_int_operand")))
9509 (clobber (reg:CC FLAGS_REG))]
9510 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9512 && true_regnum (operands[0]) != true_regnum (operands[1])"
9515 enum machine_mode mode = GET_MODE (operands[0]);
9518 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9521 operands[0] = gen_lowpart (mode, operands[0]);
9522 operands[1] = gen_lowpart (mode, operands[1]);
9525 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9527 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9529 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9533 ;; Convert ashift to the lea pattern to avoid flags dependency.
9535 [(set (match_operand:DI 0 "register_operand")
9537 (ashift:SI (match_operand:SI 1 "index_register_operand")
9538 (match_operand:QI 2 "const_int_operand"))))
9539 (clobber (reg:CC FLAGS_REG))]
9540 "TARGET_64BIT && reload_completed
9541 && true_regnum (operands[0]) != true_regnum (operands[1])"
9543 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9545 operands[1] = gen_lowpart (DImode, operands[1]);
9546 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9549 ;; This pattern can't accept a variable shift count, since shifts by
9550 ;; zero don't affect the flags. We assume that shifts by constant
9551 ;; zero are optimized away.
9552 (define_insn "*ashl<mode>3_cmp"
9553 [(set (reg FLAGS_REG)
9555 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9556 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9558 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9559 (ashift:SWI (match_dup 1) (match_dup 2)))]
9560 "(optimize_function_for_size_p (cfun)
9561 || !TARGET_PARTIAL_FLAG_REG_STALL
9562 || (operands[2] == const1_rtx
9564 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9565 && ix86_match_ccmode (insn, CCGOCmode)
9566 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9568 switch (get_attr_type (insn))
9571 gcc_assert (operands[2] == const1_rtx);
9572 return "add{<imodesuffix>}\t%0, %0";
9575 if (operands[2] == const1_rtx
9576 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9577 return "sal{<imodesuffix>}\t%0";
9579 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9583 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9584 (match_operand 0 "register_operand"))
9585 (match_operand 2 "const1_operand"))
9586 (const_string "alu")
9588 (const_string "ishift")))
9589 (set (attr "length_immediate")
9591 (ior (eq_attr "type" "alu")
9592 (and (eq_attr "type" "ishift")
9593 (and (match_operand 2 "const1_operand")
9594 (ior (match_test "TARGET_SHIFT1")
9595 (match_test "optimize_function_for_size_p (cfun)")))))
9597 (const_string "*")))
9598 (set_attr "mode" "<MODE>")])
9600 (define_insn "*ashlsi3_cmp_zext"
9601 [(set (reg FLAGS_REG)
9603 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9604 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9606 (set (match_operand:DI 0 "register_operand" "=r")
9607 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9609 && (optimize_function_for_size_p (cfun)
9610 || !TARGET_PARTIAL_FLAG_REG_STALL
9611 || (operands[2] == const1_rtx
9613 || TARGET_DOUBLE_WITH_ADD)))
9614 && ix86_match_ccmode (insn, CCGOCmode)
9615 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9617 switch (get_attr_type (insn))
9620 gcc_assert (operands[2] == const1_rtx);
9621 return "add{l}\t%k0, %k0";
9624 if (operands[2] == const1_rtx
9625 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9626 return "sal{l}\t%k0";
9628 return "sal{l}\t{%2, %k0|%k0, %2}";
9632 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9633 (match_operand 2 "const1_operand"))
9634 (const_string "alu")
9636 (const_string "ishift")))
9637 (set (attr "length_immediate")
9639 (ior (eq_attr "type" "alu")
9640 (and (eq_attr "type" "ishift")
9641 (and (match_operand 2 "const1_operand")
9642 (ior (match_test "TARGET_SHIFT1")
9643 (match_test "optimize_function_for_size_p (cfun)")))))
9645 (const_string "*")))
9646 (set_attr "mode" "SI")])
9648 (define_insn "*ashl<mode>3_cconly"
9649 [(set (reg FLAGS_REG)
9651 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9652 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9654 (clobber (match_scratch:SWI 0 "=<r>"))]
9655 "(optimize_function_for_size_p (cfun)
9656 || !TARGET_PARTIAL_FLAG_REG_STALL
9657 || (operands[2] == const1_rtx
9659 || TARGET_DOUBLE_WITH_ADD)))
9660 && ix86_match_ccmode (insn, CCGOCmode)"
9662 switch (get_attr_type (insn))
9665 gcc_assert (operands[2] == const1_rtx);
9666 return "add{<imodesuffix>}\t%0, %0";
9669 if (operands[2] == const1_rtx
9670 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9671 return "sal{<imodesuffix>}\t%0";
9673 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9677 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9678 (match_operand 0 "register_operand"))
9679 (match_operand 2 "const1_operand"))
9680 (const_string "alu")
9682 (const_string "ishift")))
9683 (set (attr "length_immediate")
9685 (ior (eq_attr "type" "alu")
9686 (and (eq_attr "type" "ishift")
9687 (and (match_operand 2 "const1_operand")
9688 (ior (match_test "TARGET_SHIFT1")
9689 (match_test "optimize_function_for_size_p (cfun)")))))
9691 (const_string "*")))
9692 (set_attr "mode" "<MODE>")])
9694 ;; See comment above `ashl<mode>3' about how this works.
9696 (define_expand "<shift_insn><mode>3"
9697 [(set (match_operand:SDWIM 0 "<shift_operand>")
9698 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9699 (match_operand:QI 2 "nonmemory_operand")))]
9701 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9703 ;; Avoid useless masking of count operand.
9704 (define_insn_and_split "*<shift_insn><mode>3_mask"
9705 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9707 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9710 (match_operand:SI 2 "nonimmediate_operand" "c")
9711 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9712 (clobber (reg:CC FLAGS_REG))]
9713 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9714 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9715 == GET_MODE_BITSIZE (<MODE>mode)-1"
9718 [(parallel [(set (match_dup 0)
9719 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9720 (clobber (reg:CC FLAGS_REG))])]
9722 if (can_create_pseudo_p ())
9723 operands [2] = force_reg (SImode, operands[2]);
9725 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9727 [(set_attr "type" "ishift")
9728 (set_attr "mode" "<MODE>")])
9730 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9731 [(set (match_operand:DWI 0 "register_operand" "=r")
9732 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9733 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9734 (clobber (reg:CC FLAGS_REG))]
9737 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9739 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9740 [(set_attr "type" "multi")])
9742 ;; By default we don't ask for a scratch register, because when DWImode
9743 ;; values are manipulated, registers are already at a premium. But if
9744 ;; we have one handy, we won't turn it away.
9747 [(match_scratch:DWIH 3 "r")
9748 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9750 (match_operand:<DWI> 1 "register_operand")
9751 (match_operand:QI 2 "nonmemory_operand")))
9752 (clobber (reg:CC FLAGS_REG))])
9756 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9758 (define_insn "x86_64_shrd"
9759 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9760 (ior:DI (ashiftrt:DI (match_dup 0)
9761 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9762 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9763 (minus:QI (const_int 64) (match_dup 2)))))
9764 (clobber (reg:CC FLAGS_REG))]
9766 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9767 [(set_attr "type" "ishift")
9768 (set_attr "prefix_0f" "1")
9769 (set_attr "mode" "DI")
9770 (set_attr "athlon_decode" "vector")
9771 (set_attr "amdfam10_decode" "vector")
9772 (set_attr "bdver1_decode" "vector")])
9774 (define_insn "x86_shrd"
9775 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9776 (ior:SI (ashiftrt:SI (match_dup 0)
9777 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9778 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9779 (minus:QI (const_int 32) (match_dup 2)))))
9780 (clobber (reg:CC FLAGS_REG))]
9782 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9783 [(set_attr "type" "ishift")
9784 (set_attr "prefix_0f" "1")
9785 (set_attr "mode" "SI")
9786 (set_attr "pent_pair" "np")
9787 (set_attr "athlon_decode" "vector")
9788 (set_attr "amdfam10_decode" "vector")
9789 (set_attr "bdver1_decode" "vector")])
9791 (define_insn "ashrdi3_cvt"
9792 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9793 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9794 (match_operand:QI 2 "const_int_operand")))
9795 (clobber (reg:CC FLAGS_REG))]
9796 "TARGET_64BIT && INTVAL (operands[2]) == 63
9797 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9798 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9801 sar{q}\t{%2, %0|%0, %2}"
9802 [(set_attr "type" "imovx,ishift")
9803 (set_attr "prefix_0f" "0,*")
9804 (set_attr "length_immediate" "0,*")
9805 (set_attr "modrm" "0,1")
9806 (set_attr "mode" "DI")])
9808 (define_insn "ashrsi3_cvt"
9809 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9810 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9811 (match_operand:QI 2 "const_int_operand")))
9812 (clobber (reg:CC FLAGS_REG))]
9813 "INTVAL (operands[2]) == 31
9814 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9815 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9818 sar{l}\t{%2, %0|%0, %2}"
9819 [(set_attr "type" "imovx,ishift")
9820 (set_attr "prefix_0f" "0,*")
9821 (set_attr "length_immediate" "0,*")
9822 (set_attr "modrm" "0,1")
9823 (set_attr "mode" "SI")])
9825 (define_insn "*ashrsi3_cvt_zext"
9826 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9828 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9829 (match_operand:QI 2 "const_int_operand"))))
9830 (clobber (reg:CC FLAGS_REG))]
9831 "TARGET_64BIT && INTVAL (operands[2]) == 31
9832 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9833 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9836 sar{l}\t{%2, %k0|%k0, %2}"
9837 [(set_attr "type" "imovx,ishift")
9838 (set_attr "prefix_0f" "0,*")
9839 (set_attr "length_immediate" "0,*")
9840 (set_attr "modrm" "0,1")
9841 (set_attr "mode" "SI")])
9843 (define_expand "x86_shift<mode>_adj_3"
9844 [(use (match_operand:SWI48 0 "register_operand"))
9845 (use (match_operand:SWI48 1 "register_operand"))
9846 (use (match_operand:QI 2 "register_operand"))]
9849 rtx label = gen_label_rtx ();
9852 emit_insn (gen_testqi_ccz_1 (operands[2],
9853 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9855 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9856 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9857 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9858 gen_rtx_LABEL_REF (VOIDmode, label),
9860 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9861 JUMP_LABEL (tmp) = label;
9863 emit_move_insn (operands[0], operands[1]);
9864 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9865 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9867 LABEL_NUSES (label) = 1;
9872 (define_insn "*bmi2_<shift_insn><mode>3_1"
9873 [(set (match_operand:SWI48 0 "register_operand" "=r")
9874 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9875 (match_operand:SWI48 2 "register_operand" "r")))]
9877 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9878 [(set_attr "type" "ishiftx")
9879 (set_attr "mode" "<MODE>")])
9881 (define_insn "*<shift_insn><mode>3_1"
9882 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9884 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9885 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9886 (clobber (reg:CC FLAGS_REG))]
9887 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9889 switch (get_attr_type (insn))
9895 if (operands[2] == const1_rtx
9896 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9897 return "<shift>{<imodesuffix>}\t%0";
9899 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9902 [(set_attr "isa" "*,bmi2")
9903 (set_attr "type" "ishift,ishiftx")
9904 (set (attr "length_immediate")
9906 (and (match_operand 2 "const1_operand")
9907 (ior (match_test "TARGET_SHIFT1")
9908 (match_test "optimize_function_for_size_p (cfun)")))
9910 (const_string "*")))
9911 (set_attr "mode" "<MODE>")])
9913 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9915 [(set (match_operand:SWI48 0 "register_operand")
9916 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9917 (match_operand:QI 2 "register_operand")))
9918 (clobber (reg:CC FLAGS_REG))]
9919 "TARGET_BMI2 && reload_completed"
9921 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9922 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9924 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9925 [(set (match_operand:DI 0 "register_operand" "=r")
9927 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9928 (match_operand:SI 2 "register_operand" "r"))))]
9929 "TARGET_64BIT && TARGET_BMI2"
9930 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9931 [(set_attr "type" "ishiftx")
9932 (set_attr "mode" "SI")])
9934 (define_insn "*<shift_insn>si3_1_zext"
9935 [(set (match_operand:DI 0 "register_operand" "=r,r")
9937 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9938 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9939 (clobber (reg:CC FLAGS_REG))]
9940 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9942 switch (get_attr_type (insn))
9948 if (operands[2] == const1_rtx
9949 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9950 return "<shift>{l}\t%k0";
9952 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9955 [(set_attr "isa" "*,bmi2")
9956 (set_attr "type" "ishift,ishiftx")
9957 (set (attr "length_immediate")
9959 (and (match_operand 2 "const1_operand")
9960 (ior (match_test "TARGET_SHIFT1")
9961 (match_test "optimize_function_for_size_p (cfun)")))
9963 (const_string "*")))
9964 (set_attr "mode" "SI")])
9966 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9968 [(set (match_operand:DI 0 "register_operand")
9970 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
9971 (match_operand:QI 2 "register_operand"))))
9972 (clobber (reg:CC FLAGS_REG))]
9973 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9975 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9976 "operands[2] = gen_lowpart (SImode, operands[2]);")
9978 (define_insn "*<shift_insn><mode>3_1"
9979 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9981 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9982 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9983 (clobber (reg:CC FLAGS_REG))]
9984 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9986 if (operands[2] == const1_rtx
9987 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9988 return "<shift>{<imodesuffix>}\t%0";
9990 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9992 [(set_attr "type" "ishift")
9993 (set (attr "length_immediate")
9995 (and (match_operand 2 "const1_operand")
9996 (ior (match_test "TARGET_SHIFT1")
9997 (match_test "optimize_function_for_size_p (cfun)")))
9999 (const_string "*")))
10000 (set_attr "mode" "<MODE>")])
10002 (define_insn "*<shift_insn>qi3_1_slp"
10003 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10004 (any_shiftrt:QI (match_dup 0)
10005 (match_operand:QI 1 "nonmemory_operand" "cI")))
10006 (clobber (reg:CC FLAGS_REG))]
10007 "(optimize_function_for_size_p (cfun)
10008 || !TARGET_PARTIAL_REG_STALL
10009 || (operands[1] == const1_rtx
10010 && TARGET_SHIFT1))"
10012 if (operands[1] == const1_rtx
10013 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10014 return "<shift>{b}\t%0";
10016 return "<shift>{b}\t{%1, %0|%0, %1}";
10018 [(set_attr "type" "ishift1")
10019 (set (attr "length_immediate")
10021 (and (match_operand 1 "const1_operand")
10022 (ior (match_test "TARGET_SHIFT1")
10023 (match_test "optimize_function_for_size_p (cfun)")))
10025 (const_string "*")))
10026 (set_attr "mode" "QI")])
10028 ;; This pattern can't accept a variable shift count, since shifts by
10029 ;; zero don't affect the flags. We assume that shifts by constant
10030 ;; zero are optimized away.
10031 (define_insn "*<shift_insn><mode>3_cmp"
10032 [(set (reg FLAGS_REG)
10035 (match_operand:SWI 1 "nonimmediate_operand" "0")
10036 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10038 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10039 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10040 "(optimize_function_for_size_p (cfun)
10041 || !TARGET_PARTIAL_FLAG_REG_STALL
10042 || (operands[2] == const1_rtx
10044 && ix86_match_ccmode (insn, CCGOCmode)
10045 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10047 if (operands[2] == const1_rtx
10048 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10049 return "<shift>{<imodesuffix>}\t%0";
10051 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10053 [(set_attr "type" "ishift")
10054 (set (attr "length_immediate")
10056 (and (match_operand 2 "const1_operand")
10057 (ior (match_test "TARGET_SHIFT1")
10058 (match_test "optimize_function_for_size_p (cfun)")))
10060 (const_string "*")))
10061 (set_attr "mode" "<MODE>")])
10063 (define_insn "*<shift_insn>si3_cmp_zext"
10064 [(set (reg FLAGS_REG)
10066 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10067 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10069 (set (match_operand:DI 0 "register_operand" "=r")
10070 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10072 && (optimize_function_for_size_p (cfun)
10073 || !TARGET_PARTIAL_FLAG_REG_STALL
10074 || (operands[2] == const1_rtx
10076 && ix86_match_ccmode (insn, CCGOCmode)
10077 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10079 if (operands[2] == const1_rtx
10080 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10081 return "<shift>{l}\t%k0";
10083 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10085 [(set_attr "type" "ishift")
10086 (set (attr "length_immediate")
10088 (and (match_operand 2 "const1_operand")
10089 (ior (match_test "TARGET_SHIFT1")
10090 (match_test "optimize_function_for_size_p (cfun)")))
10092 (const_string "*")))
10093 (set_attr "mode" "SI")])
10095 (define_insn "*<shift_insn><mode>3_cconly"
10096 [(set (reg FLAGS_REG)
10099 (match_operand:SWI 1 "register_operand" "0")
10100 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10102 (clobber (match_scratch:SWI 0 "=<r>"))]
10103 "(optimize_function_for_size_p (cfun)
10104 || !TARGET_PARTIAL_FLAG_REG_STALL
10105 || (operands[2] == const1_rtx
10107 && ix86_match_ccmode (insn, CCGOCmode)"
10109 if (operands[2] == const1_rtx
10110 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10111 return "<shift>{<imodesuffix>}\t%0";
10113 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10115 [(set_attr "type" "ishift")
10116 (set (attr "length_immediate")
10118 (and (match_operand 2 "const1_operand")
10119 (ior (match_test "TARGET_SHIFT1")
10120 (match_test "optimize_function_for_size_p (cfun)")))
10122 (const_string "*")))
10123 (set_attr "mode" "<MODE>")])
10125 ;; Rotate instructions
10127 (define_expand "<rotate_insn>ti3"
10128 [(set (match_operand:TI 0 "register_operand")
10129 (any_rotate:TI (match_operand:TI 1 "register_operand")
10130 (match_operand:QI 2 "nonmemory_operand")))]
10133 if (const_1_to_63_operand (operands[2], VOIDmode))
10134 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10135 (operands[0], operands[1], operands[2]));
10142 (define_expand "<rotate_insn>di3"
10143 [(set (match_operand:DI 0 "shiftdi_operand")
10144 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10145 (match_operand:QI 2 "nonmemory_operand")))]
10149 ix86_expand_binary_operator (<CODE>, DImode, operands);
10150 else if (const_1_to_31_operand (operands[2], VOIDmode))
10151 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10152 (operands[0], operands[1], operands[2]));
10159 (define_expand "<rotate_insn><mode>3"
10160 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10161 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10162 (match_operand:QI 2 "nonmemory_operand")))]
10164 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10166 ;; Avoid useless masking of count operand.
10167 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10168 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10170 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10173 (match_operand:SI 2 "nonimmediate_operand" "c")
10174 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10175 (clobber (reg:CC FLAGS_REG))]
10176 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10177 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10178 == GET_MODE_BITSIZE (<MODE>mode)-1"
10181 [(parallel [(set (match_dup 0)
10182 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10183 (clobber (reg:CC FLAGS_REG))])]
10185 if (can_create_pseudo_p ())
10186 operands [2] = force_reg (SImode, operands[2]);
10188 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10190 [(set_attr "type" "rotate")
10191 (set_attr "mode" "<MODE>")])
10193 ;; Implement rotation using two double-precision
10194 ;; shift instructions and a scratch register.
10196 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10197 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10198 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10199 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10200 (clobber (reg:CC FLAGS_REG))
10201 (clobber (match_scratch:DWIH 3 "=&r"))]
10205 [(set (match_dup 3) (match_dup 4))
10207 [(set (match_dup 4)
10208 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10209 (lshiftrt:DWIH (match_dup 5)
10210 (minus:QI (match_dup 6) (match_dup 2)))))
10211 (clobber (reg:CC FLAGS_REG))])
10213 [(set (match_dup 5)
10214 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10215 (lshiftrt:DWIH (match_dup 3)
10216 (minus:QI (match_dup 6) (match_dup 2)))))
10217 (clobber (reg:CC FLAGS_REG))])]
10219 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10221 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10224 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10225 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10226 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10227 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10228 (clobber (reg:CC FLAGS_REG))
10229 (clobber (match_scratch:DWIH 3 "=&r"))]
10233 [(set (match_dup 3) (match_dup 4))
10235 [(set (match_dup 4)
10236 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10237 (ashift:DWIH (match_dup 5)
10238 (minus:QI (match_dup 6) (match_dup 2)))))
10239 (clobber (reg:CC FLAGS_REG))])
10241 [(set (match_dup 5)
10242 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10243 (ashift:DWIH (match_dup 3)
10244 (minus:QI (match_dup 6) (match_dup 2)))))
10245 (clobber (reg:CC FLAGS_REG))])]
10247 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10249 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10252 (define_insn "*bmi2_rorx<mode>3_1"
10253 [(set (match_operand:SWI48 0 "register_operand" "=r")
10254 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10255 (match_operand:QI 2 "immediate_operand" "<S>")))]
10257 "rorx\t{%2, %1, %0|%0, %1, %2}"
10258 [(set_attr "type" "rotatex")
10259 (set_attr "mode" "<MODE>")])
10261 (define_insn "*<rotate_insn><mode>3_1"
10262 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10264 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10265 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10266 (clobber (reg:CC FLAGS_REG))]
10267 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10269 switch (get_attr_type (insn))
10275 if (operands[2] == const1_rtx
10276 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10277 return "<rotate>{<imodesuffix>}\t%0";
10279 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10282 [(set_attr "isa" "*,bmi2")
10283 (set_attr "type" "rotate,rotatex")
10284 (set (attr "length_immediate")
10286 (and (eq_attr "type" "rotate")
10287 (and (match_operand 2 "const1_operand")
10288 (ior (match_test "TARGET_SHIFT1")
10289 (match_test "optimize_function_for_size_p (cfun)"))))
10291 (const_string "*")))
10292 (set_attr "mode" "<MODE>")])
10294 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10296 [(set (match_operand:SWI48 0 "register_operand")
10297 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10298 (match_operand:QI 2 "immediate_operand")))
10299 (clobber (reg:CC FLAGS_REG))]
10300 "TARGET_BMI2 && reload_completed"
10301 [(set (match_dup 0)
10302 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10305 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10309 [(set (match_operand:SWI48 0 "register_operand")
10310 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10311 (match_operand:QI 2 "immediate_operand")))
10312 (clobber (reg:CC FLAGS_REG))]
10313 "TARGET_BMI2 && reload_completed"
10314 [(set (match_dup 0)
10315 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10317 (define_insn "*bmi2_rorxsi3_1_zext"
10318 [(set (match_operand:DI 0 "register_operand" "=r")
10320 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10321 (match_operand:QI 2 "immediate_operand" "I"))))]
10322 "TARGET_64BIT && TARGET_BMI2"
10323 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10324 [(set_attr "type" "rotatex")
10325 (set_attr "mode" "SI")])
10327 (define_insn "*<rotate_insn>si3_1_zext"
10328 [(set (match_operand:DI 0 "register_operand" "=r,r")
10330 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10331 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10332 (clobber (reg:CC FLAGS_REG))]
10333 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10335 switch (get_attr_type (insn))
10341 if (operands[2] == const1_rtx
10342 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10343 return "<rotate>{l}\t%k0";
10345 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10348 [(set_attr "isa" "*,bmi2")
10349 (set_attr "type" "rotate,rotatex")
10350 (set (attr "length_immediate")
10352 (and (eq_attr "type" "rotate")
10353 (and (match_operand 2 "const1_operand")
10354 (ior (match_test "TARGET_SHIFT1")
10355 (match_test "optimize_function_for_size_p (cfun)"))))
10357 (const_string "*")))
10358 (set_attr "mode" "SI")])
10360 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10362 [(set (match_operand:DI 0 "register_operand")
10364 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10365 (match_operand:QI 2 "immediate_operand"))))
10366 (clobber (reg:CC FLAGS_REG))]
10367 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10368 [(set (match_dup 0)
10369 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10372 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10376 [(set (match_operand:DI 0 "register_operand")
10378 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10379 (match_operand:QI 2 "immediate_operand"))))
10380 (clobber (reg:CC FLAGS_REG))]
10381 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10382 [(set (match_dup 0)
10383 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10385 (define_insn "*<rotate_insn><mode>3_1"
10386 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10387 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10388 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10389 (clobber (reg:CC FLAGS_REG))]
10390 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10392 if (operands[2] == const1_rtx
10393 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10394 return "<rotate>{<imodesuffix>}\t%0";
10396 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10398 [(set_attr "type" "rotate")
10399 (set (attr "length_immediate")
10401 (and (match_operand 2 "const1_operand")
10402 (ior (match_test "TARGET_SHIFT1")
10403 (match_test "optimize_function_for_size_p (cfun)")))
10405 (const_string "*")))
10406 (set_attr "mode" "<MODE>")])
10408 (define_insn "*<rotate_insn>qi3_1_slp"
10409 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10410 (any_rotate:QI (match_dup 0)
10411 (match_operand:QI 1 "nonmemory_operand" "cI")))
10412 (clobber (reg:CC FLAGS_REG))]
10413 "(optimize_function_for_size_p (cfun)
10414 || !TARGET_PARTIAL_REG_STALL
10415 || (operands[1] == const1_rtx
10416 && TARGET_SHIFT1))"
10418 if (operands[1] == const1_rtx
10419 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10420 return "<rotate>{b}\t%0";
10422 return "<rotate>{b}\t{%1, %0|%0, %1}";
10424 [(set_attr "type" "rotate1")
10425 (set (attr "length_immediate")
10427 (and (match_operand 1 "const1_operand")
10428 (ior (match_test "TARGET_SHIFT1")
10429 (match_test "optimize_function_for_size_p (cfun)")))
10431 (const_string "*")))
10432 (set_attr "mode" "QI")])
10435 [(set (match_operand:HI 0 "register_operand")
10436 (any_rotate:HI (match_dup 0) (const_int 8)))
10437 (clobber (reg:CC FLAGS_REG))]
10439 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10440 [(parallel [(set (strict_low_part (match_dup 0))
10441 (bswap:HI (match_dup 0)))
10442 (clobber (reg:CC FLAGS_REG))])])
10444 ;; Bit set / bit test instructions
10446 (define_expand "extv"
10447 [(set (match_operand:SI 0 "register_operand")
10448 (sign_extract:SI (match_operand:SI 1 "register_operand")
10449 (match_operand:SI 2 "const8_operand")
10450 (match_operand:SI 3 "const8_operand")))]
10453 /* Handle extractions from %ah et al. */
10454 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10457 /* From mips.md: extract_bit_field doesn't verify that our source
10458 matches the predicate, so check it again here. */
10459 if (! ext_register_operand (operands[1], VOIDmode))
10463 (define_expand "extzv"
10464 [(set (match_operand:SI 0 "register_operand")
10465 (zero_extract:SI (match_operand 1 "ext_register_operand")
10466 (match_operand:SI 2 "const8_operand")
10467 (match_operand:SI 3 "const8_operand")))]
10470 /* Handle extractions from %ah et al. */
10471 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10474 /* From mips.md: extract_bit_field doesn't verify that our source
10475 matches the predicate, so check it again here. */
10476 if (! ext_register_operand (operands[1], VOIDmode))
10480 (define_expand "insv"
10481 [(set (zero_extract (match_operand 0 "register_operand")
10482 (match_operand 1 "const_int_operand")
10483 (match_operand 2 "const_int_operand"))
10484 (match_operand 3 "register_operand"))]
10487 rtx (*gen_mov_insv_1) (rtx, rtx);
10489 if (ix86_expand_pinsr (operands))
10492 /* Handle insertions to %ah et al. */
10493 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10496 /* From mips.md: insert_bit_field doesn't verify that our source
10497 matches the predicate, so check it again here. */
10498 if (! ext_register_operand (operands[0], VOIDmode))
10501 gen_mov_insv_1 = (TARGET_64BIT
10502 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10504 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10508 ;; %%% bts, btr, btc, bt.
10509 ;; In general these instructions are *slow* when applied to memory,
10510 ;; since they enforce atomic operation. When applied to registers,
10511 ;; it depends on the cpu implementation. They're never faster than
10512 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10513 ;; no point. But in 64-bit, we can't hold the relevant immediates
10514 ;; within the instruction itself, so operating on bits in the high
10515 ;; 32-bits of a register becomes easier.
10517 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10518 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10519 ;; negdf respectively, so they can never be disabled entirely.
10521 (define_insn "*btsq"
10522 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10524 (match_operand:DI 1 "const_0_to_63_operand"))
10526 (clobber (reg:CC FLAGS_REG))]
10527 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10528 "bts{q}\t{%1, %0|%0, %1}"
10529 [(set_attr "type" "alu1")
10530 (set_attr "prefix_0f" "1")
10531 (set_attr "mode" "DI")])
10533 (define_insn "*btrq"
10534 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10536 (match_operand:DI 1 "const_0_to_63_operand"))
10538 (clobber (reg:CC FLAGS_REG))]
10539 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10540 "btr{q}\t{%1, %0|%0, %1}"
10541 [(set_attr "type" "alu1")
10542 (set_attr "prefix_0f" "1")
10543 (set_attr "mode" "DI")])
10545 (define_insn "*btcq"
10546 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10548 (match_operand:DI 1 "const_0_to_63_operand"))
10549 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10550 (clobber (reg:CC FLAGS_REG))]
10551 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10552 "btc{q}\t{%1, %0|%0, %1}"
10553 [(set_attr "type" "alu1")
10554 (set_attr "prefix_0f" "1")
10555 (set_attr "mode" "DI")])
10557 ;; Allow Nocona to avoid these instructions if a register is available.
10560 [(match_scratch:DI 2 "r")
10561 (parallel [(set (zero_extract:DI
10562 (match_operand:DI 0 "register_operand")
10564 (match_operand:DI 1 "const_0_to_63_operand"))
10566 (clobber (reg:CC FLAGS_REG))])]
10567 "TARGET_64BIT && !TARGET_USE_BT"
10570 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10573 if (HOST_BITS_PER_WIDE_INT >= 64)
10574 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10575 else if (i < HOST_BITS_PER_WIDE_INT)
10576 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10578 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10580 op1 = immed_double_const (lo, hi, DImode);
10583 emit_move_insn (operands[2], op1);
10587 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10592 [(match_scratch:DI 2 "r")
10593 (parallel [(set (zero_extract:DI
10594 (match_operand:DI 0 "register_operand")
10596 (match_operand:DI 1 "const_0_to_63_operand"))
10598 (clobber (reg:CC FLAGS_REG))])]
10599 "TARGET_64BIT && !TARGET_USE_BT"
10602 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10605 if (HOST_BITS_PER_WIDE_INT >= 64)
10606 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10607 else if (i < HOST_BITS_PER_WIDE_INT)
10608 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10610 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10612 op1 = immed_double_const (~lo, ~hi, DImode);
10615 emit_move_insn (operands[2], op1);
10619 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10624 [(match_scratch:DI 2 "r")
10625 (parallel [(set (zero_extract:DI
10626 (match_operand:DI 0 "register_operand")
10628 (match_operand:DI 1 "const_0_to_63_operand"))
10629 (not:DI (zero_extract:DI
10630 (match_dup 0) (const_int 1) (match_dup 1))))
10631 (clobber (reg:CC FLAGS_REG))])]
10632 "TARGET_64BIT && !TARGET_USE_BT"
10635 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10638 if (HOST_BITS_PER_WIDE_INT >= 64)
10639 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10640 else if (i < HOST_BITS_PER_WIDE_INT)
10641 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10643 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10645 op1 = immed_double_const (lo, hi, DImode);
10648 emit_move_insn (operands[2], op1);
10652 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10656 (define_insn "*bt<mode>"
10657 [(set (reg:CCC FLAGS_REG)
10659 (zero_extract:SWI48
10660 (match_operand:SWI48 0 "register_operand" "r")
10662 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10664 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10665 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10666 [(set_attr "type" "alu1")
10667 (set_attr "prefix_0f" "1")
10668 (set_attr "mode" "<MODE>")])
10670 ;; Store-flag instructions.
10672 ;; For all sCOND expanders, also expand the compare or test insn that
10673 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10675 (define_insn_and_split "*setcc_di_1"
10676 [(set (match_operand:DI 0 "register_operand" "=q")
10677 (match_operator:DI 1 "ix86_comparison_operator"
10678 [(reg FLAGS_REG) (const_int 0)]))]
10679 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10681 "&& reload_completed"
10682 [(set (match_dup 2) (match_dup 1))
10683 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10685 PUT_MODE (operands[1], QImode);
10686 operands[2] = gen_lowpart (QImode, operands[0]);
10689 (define_insn_and_split "*setcc_si_1_and"
10690 [(set (match_operand:SI 0 "register_operand" "=q")
10691 (match_operator:SI 1 "ix86_comparison_operator"
10692 [(reg FLAGS_REG) (const_int 0)]))
10693 (clobber (reg:CC FLAGS_REG))]
10694 "!TARGET_PARTIAL_REG_STALL
10695 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10697 "&& reload_completed"
10698 [(set (match_dup 2) (match_dup 1))
10699 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10700 (clobber (reg:CC FLAGS_REG))])]
10702 PUT_MODE (operands[1], QImode);
10703 operands[2] = gen_lowpart (QImode, operands[0]);
10706 (define_insn_and_split "*setcc_si_1_movzbl"
10707 [(set (match_operand:SI 0 "register_operand" "=q")
10708 (match_operator:SI 1 "ix86_comparison_operator"
10709 [(reg FLAGS_REG) (const_int 0)]))]
10710 "!TARGET_PARTIAL_REG_STALL
10711 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10713 "&& reload_completed"
10714 [(set (match_dup 2) (match_dup 1))
10715 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10717 PUT_MODE (operands[1], QImode);
10718 operands[2] = gen_lowpart (QImode, operands[0]);
10721 (define_insn "*setcc_qi"
10722 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10723 (match_operator:QI 1 "ix86_comparison_operator"
10724 [(reg FLAGS_REG) (const_int 0)]))]
10727 [(set_attr "type" "setcc")
10728 (set_attr "mode" "QI")])
10730 (define_insn "*setcc_qi_slp"
10731 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10732 (match_operator:QI 1 "ix86_comparison_operator"
10733 [(reg FLAGS_REG) (const_int 0)]))]
10736 [(set_attr "type" "setcc")
10737 (set_attr "mode" "QI")])
10739 ;; In general it is not safe to assume too much about CCmode registers,
10740 ;; so simplify-rtx stops when it sees a second one. Under certain
10741 ;; conditions this is safe on x86, so help combine not create
10748 [(set (match_operand:QI 0 "nonimmediate_operand")
10749 (ne:QI (match_operator 1 "ix86_comparison_operator"
10750 [(reg FLAGS_REG) (const_int 0)])
10753 [(set (match_dup 0) (match_dup 1))]
10754 "PUT_MODE (operands[1], QImode);")
10757 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10758 (ne:QI (match_operator 1 "ix86_comparison_operator"
10759 [(reg FLAGS_REG) (const_int 0)])
10762 [(set (match_dup 0) (match_dup 1))]
10763 "PUT_MODE (operands[1], QImode);")
10766 [(set (match_operand:QI 0 "nonimmediate_operand")
10767 (eq:QI (match_operator 1 "ix86_comparison_operator"
10768 [(reg FLAGS_REG) (const_int 0)])
10771 [(set (match_dup 0) (match_dup 1))]
10773 rtx new_op1 = copy_rtx (operands[1]);
10774 operands[1] = new_op1;
10775 PUT_MODE (new_op1, QImode);
10776 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10777 GET_MODE (XEXP (new_op1, 0))));
10779 /* Make sure that (a) the CCmode we have for the flags is strong
10780 enough for the reversed compare or (b) we have a valid FP compare. */
10781 if (! ix86_comparison_operator (new_op1, VOIDmode))
10786 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10787 (eq:QI (match_operator 1 "ix86_comparison_operator"
10788 [(reg FLAGS_REG) (const_int 0)])
10791 [(set (match_dup 0) (match_dup 1))]
10793 rtx new_op1 = copy_rtx (operands[1]);
10794 operands[1] = new_op1;
10795 PUT_MODE (new_op1, QImode);
10796 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10797 GET_MODE (XEXP (new_op1, 0))));
10799 /* Make sure that (a) the CCmode we have for the flags is strong
10800 enough for the reversed compare or (b) we have a valid FP compare. */
10801 if (! ix86_comparison_operator (new_op1, VOIDmode))
10805 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10806 ;; subsequent logical operations are used to imitate conditional moves.
10807 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10810 (define_insn "setcc_<mode>_sse"
10811 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10812 (match_operator:MODEF 3 "sse_comparison_operator"
10813 [(match_operand:MODEF 1 "register_operand" "0,x")
10814 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10815 "SSE_FLOAT_MODE_P (<MODE>mode)"
10817 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10818 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10819 [(set_attr "isa" "noavx,avx")
10820 (set_attr "type" "ssecmp")
10821 (set_attr "length_immediate" "1")
10822 (set_attr "prefix" "orig,vex")
10823 (set_attr "mode" "<MODE>")])
10825 ;; Basic conditional jump instructions.
10826 ;; We ignore the overflow flag for signed branch instructions.
10828 (define_insn "*jcc_1"
10830 (if_then_else (match_operator 1 "ix86_comparison_operator"
10831 [(reg FLAGS_REG) (const_int 0)])
10832 (label_ref (match_operand 0))
10836 [(set_attr "type" "ibr")
10837 (set_attr "modrm" "0")
10838 (set (attr "length")
10839 (if_then_else (and (ge (minus (match_dup 0) (pc))
10841 (lt (minus (match_dup 0) (pc))
10846 (define_insn "*jcc_2"
10848 (if_then_else (match_operator 1 "ix86_comparison_operator"
10849 [(reg FLAGS_REG) (const_int 0)])
10851 (label_ref (match_operand 0))))]
10854 [(set_attr "type" "ibr")
10855 (set_attr "modrm" "0")
10856 (set (attr "length")
10857 (if_then_else (and (ge (minus (match_dup 0) (pc))
10859 (lt (minus (match_dup 0) (pc))
10864 ;; In general it is not safe to assume too much about CCmode registers,
10865 ;; so simplify-rtx stops when it sees a second one. Under certain
10866 ;; conditions this is safe on x86, so help combine not create
10874 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10875 [(reg FLAGS_REG) (const_int 0)])
10877 (label_ref (match_operand 1))
10881 (if_then_else (match_dup 0)
10882 (label_ref (match_dup 1))
10884 "PUT_MODE (operands[0], VOIDmode);")
10888 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10889 [(reg FLAGS_REG) (const_int 0)])
10891 (label_ref (match_operand 1))
10895 (if_then_else (match_dup 0)
10896 (label_ref (match_dup 1))
10899 rtx new_op0 = copy_rtx (operands[0]);
10900 operands[0] = new_op0;
10901 PUT_MODE (new_op0, VOIDmode);
10902 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10903 GET_MODE (XEXP (new_op0, 0))));
10905 /* Make sure that (a) the CCmode we have for the flags is strong
10906 enough for the reversed compare or (b) we have a valid FP compare. */
10907 if (! ix86_comparison_operator (new_op0, VOIDmode))
10911 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10912 ;; pass generates from shift insn with QImode operand. Actually, the mode
10913 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10914 ;; appropriate modulo of the bit offset value.
10916 (define_insn_and_split "*jcc_bt<mode>"
10918 (if_then_else (match_operator 0 "bt_comparison_operator"
10919 [(zero_extract:SWI48
10920 (match_operand:SWI48 1 "register_operand" "r")
10923 (match_operand:QI 2 "register_operand" "r")))
10925 (label_ref (match_operand 3))
10927 (clobber (reg:CC FLAGS_REG))]
10928 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10931 [(set (reg:CCC FLAGS_REG)
10933 (zero_extract:SWI48
10939 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10940 (label_ref (match_dup 3))
10943 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10945 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10948 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10949 ;; also for DImode, this is what combine produces.
10950 (define_insn_and_split "*jcc_bt<mode>_mask"
10952 (if_then_else (match_operator 0 "bt_comparison_operator"
10953 [(zero_extract:SWI48
10954 (match_operand:SWI48 1 "register_operand" "r")
10957 (match_operand:SI 2 "register_operand" "r")
10958 (match_operand:SI 3 "const_int_operand" "n")))])
10959 (label_ref (match_operand 4))
10961 (clobber (reg:CC FLAGS_REG))]
10962 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10963 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10964 == GET_MODE_BITSIZE (<MODE>mode)-1"
10967 [(set (reg:CCC FLAGS_REG)
10969 (zero_extract:SWI48
10975 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10976 (label_ref (match_dup 4))
10979 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10981 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10984 (define_insn_and_split "*jcc_btsi_1"
10986 (if_then_else (match_operator 0 "bt_comparison_operator"
10989 (match_operand:SI 1 "register_operand" "r")
10990 (match_operand:QI 2 "register_operand" "r"))
10993 (label_ref (match_operand 3))
10995 (clobber (reg:CC FLAGS_REG))]
10996 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10999 [(set (reg:CCC FLAGS_REG)
11007 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11008 (label_ref (match_dup 3))
11011 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
11013 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
11016 ;; avoid useless masking of bit offset operand
11017 (define_insn_and_split "*jcc_btsi_mask_1"
11020 (match_operator 0 "bt_comparison_operator"
11023 (match_operand:SI 1 "register_operand" "r")
11026 (match_operand:SI 2 "register_operand" "r")
11027 (match_operand:SI 3 "const_int_operand" "n")) 0))
11030 (label_ref (match_operand 4))
11032 (clobber (reg:CC FLAGS_REG))]
11033 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11034 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11037 [(set (reg:CCC FLAGS_REG)
11045 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11046 (label_ref (match_dup 4))
11048 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11050 ;; Define combination compare-and-branch fp compare instructions to help
11053 (define_insn "*fp_jcc_1_387"
11055 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11056 [(match_operand 1 "register_operand" "f")
11057 (match_operand 2 "nonimmediate_operand" "fm")])
11058 (label_ref (match_operand 3))
11060 (clobber (reg:CCFP FPSR_REG))
11061 (clobber (reg:CCFP FLAGS_REG))
11062 (clobber (match_scratch:HI 4 "=a"))]
11064 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11065 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11066 && SELECT_CC_MODE (GET_CODE (operands[0]),
11067 operands[1], operands[2]) == CCFPmode
11071 (define_insn "*fp_jcc_1r_387"
11073 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11074 [(match_operand 1 "register_operand" "f")
11075 (match_operand 2 "nonimmediate_operand" "fm")])
11077 (label_ref (match_operand 3))))
11078 (clobber (reg:CCFP FPSR_REG))
11079 (clobber (reg:CCFP FLAGS_REG))
11080 (clobber (match_scratch:HI 4 "=a"))]
11082 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
11083 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11084 && SELECT_CC_MODE (GET_CODE (operands[0]),
11085 operands[1], operands[2]) == CCFPmode
11089 (define_insn "*fp_jcc_2_387"
11091 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11092 [(match_operand 1 "register_operand" "f")
11093 (match_operand 2 "register_operand" "f")])
11094 (label_ref (match_operand 3))
11096 (clobber (reg:CCFP FPSR_REG))
11097 (clobber (reg:CCFP FLAGS_REG))
11098 (clobber (match_scratch:HI 4 "=a"))]
11099 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11100 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11104 (define_insn "*fp_jcc_2r_387"
11106 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11107 [(match_operand 1 "register_operand" "f")
11108 (match_operand 2 "register_operand" "f")])
11110 (label_ref (match_operand 3))))
11111 (clobber (reg:CCFP FPSR_REG))
11112 (clobber (reg:CCFP FLAGS_REG))
11113 (clobber (match_scratch:HI 4 "=a"))]
11114 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11115 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11119 (define_insn "*fp_jcc_3_387"
11121 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11122 [(match_operand 1 "register_operand" "f")
11123 (match_operand 2 "const0_operand")])
11124 (label_ref (match_operand 3))
11126 (clobber (reg:CCFP FPSR_REG))
11127 (clobber (reg:CCFP FLAGS_REG))
11128 (clobber (match_scratch:HI 4 "=a"))]
11129 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11130 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11131 && SELECT_CC_MODE (GET_CODE (operands[0]),
11132 operands[1], operands[2]) == CCFPmode
11138 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11139 [(match_operand 1 "register_operand")
11140 (match_operand 2 "nonimmediate_operand")])
11142 (match_operand 4)))
11143 (clobber (reg:CCFP FPSR_REG))
11144 (clobber (reg:CCFP FLAGS_REG))]
11148 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11149 operands[3], operands[4], NULL_RTX, NULL_RTX);
11155 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11156 [(match_operand 1 "register_operand")
11157 (match_operand 2 "general_operand")])
11159 (match_operand 4)))
11160 (clobber (reg:CCFP FPSR_REG))
11161 (clobber (reg:CCFP FLAGS_REG))
11162 (clobber (match_scratch:HI 5 "=a"))]
11166 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11167 operands[3], operands[4], operands[5], NULL_RTX);
11171 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11172 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11173 ;; with a precedence over other operators and is always put in the first
11174 ;; place. Swap condition and operands to match ficom instruction.
11176 (define_insn "*fp_jcc_4_<mode>_387"
11179 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11180 [(match_operator 1 "float_operator"
11181 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11182 (match_operand 3 "register_operand" "f,f")])
11183 (label_ref (match_operand 4))
11185 (clobber (reg:CCFP FPSR_REG))
11186 (clobber (reg:CCFP FLAGS_REG))
11187 (clobber (match_scratch:HI 5 "=a,a"))]
11188 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11189 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11190 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11191 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11198 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11199 [(match_operator 1 "float_operator"
11200 [(match_operand:SWI24 2 "memory_operand")])
11201 (match_operand 3 "register_operand")])
11203 (match_operand 5)))
11204 (clobber (reg:CCFP FPSR_REG))
11205 (clobber (reg:CCFP FLAGS_REG))
11206 (clobber (match_scratch:HI 6 "=a"))]
11210 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11212 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11213 operands[3], operands[7],
11214 operands[4], operands[5], operands[6], NULL_RTX);
11218 ;; %%% Kill this when reload knows how to do it.
11222 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11223 [(match_operator 1 "float_operator"
11224 [(match_operand:SWI24 2 "register_operand")])
11225 (match_operand 3 "register_operand")])
11227 (match_operand 5)))
11228 (clobber (reg:CCFP FPSR_REG))
11229 (clobber (reg:CCFP FLAGS_REG))
11230 (clobber (match_scratch:HI 6 "=a"))]
11234 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11235 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11237 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11238 operands[3], operands[7],
11239 operands[4], operands[5], operands[6], operands[2]);
11243 ;; Unconditional and other jump instructions
11245 (define_insn "jump"
11247 (label_ref (match_operand 0)))]
11250 [(set_attr "type" "ibr")
11251 (set (attr "length")
11252 (if_then_else (and (ge (minus (match_dup 0) (pc))
11254 (lt (minus (match_dup 0) (pc))
11258 (set_attr "modrm" "0")])
11260 (define_expand "indirect_jump"
11261 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11265 operands[0] = convert_memory_address (word_mode, operands[0]);
11268 (define_insn "*indirect_jump"
11269 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))]
11272 [(set_attr "type" "ibr")
11273 (set_attr "length_immediate" "0")])
11275 (define_expand "tablejump"
11276 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11277 (use (label_ref (match_operand 1)))])]
11280 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11281 relative. Convert the relative address to an absolute address. */
11285 enum rtx_code code;
11287 /* We can't use @GOTOFF for text labels on VxWorks;
11288 see gotoff_operand. */
11289 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11293 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11295 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11299 op1 = pic_offset_table_rtx;
11304 op0 = pic_offset_table_rtx;
11308 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11313 operands[0] = convert_memory_address (word_mode, operands[0]);
11316 (define_insn "*tablejump_1"
11317 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))
11318 (use (label_ref (match_operand 1)))]
11321 [(set_attr "type" "ibr")
11322 (set_attr "length_immediate" "0")])
11324 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11327 [(set (reg FLAGS_REG) (match_operand 0))
11328 (set (match_operand:QI 1 "register_operand")
11329 (match_operator:QI 2 "ix86_comparison_operator"
11330 [(reg FLAGS_REG) (const_int 0)]))
11331 (set (match_operand 3 "q_regs_operand")
11332 (zero_extend (match_dup 1)))]
11333 "(peep2_reg_dead_p (3, operands[1])
11334 || operands_match_p (operands[1], operands[3]))
11335 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11336 [(set (match_dup 4) (match_dup 0))
11337 (set (strict_low_part (match_dup 5))
11340 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11341 operands[5] = gen_lowpart (QImode, operands[3]);
11342 ix86_expand_clear (operands[3]);
11346 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11347 (match_operand 4)])
11348 (set (match_operand:QI 1 "register_operand")
11349 (match_operator:QI 2 "ix86_comparison_operator"
11350 [(reg FLAGS_REG) (const_int 0)]))
11351 (set (match_operand 3 "q_regs_operand")
11352 (zero_extend (match_dup 1)))]
11353 "(peep2_reg_dead_p (3, operands[1])
11354 || operands_match_p (operands[1], operands[3]))
11355 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11356 [(parallel [(set (match_dup 5) (match_dup 0))
11358 (set (strict_low_part (match_dup 6))
11361 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11362 operands[6] = gen_lowpart (QImode, operands[3]);
11363 ix86_expand_clear (operands[3]);
11366 ;; Similar, but match zero extend with andsi3.
11369 [(set (reg FLAGS_REG) (match_operand 0))
11370 (set (match_operand:QI 1 "register_operand")
11371 (match_operator:QI 2 "ix86_comparison_operator"
11372 [(reg FLAGS_REG) (const_int 0)]))
11373 (parallel [(set (match_operand:SI 3 "q_regs_operand")
11374 (and:SI (match_dup 3) (const_int 255)))
11375 (clobber (reg:CC FLAGS_REG))])]
11376 "REGNO (operands[1]) == REGNO (operands[3])
11377 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11378 [(set (match_dup 4) (match_dup 0))
11379 (set (strict_low_part (match_dup 5))
11382 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11383 operands[5] = gen_lowpart (QImode, operands[3]);
11384 ix86_expand_clear (operands[3]);
11388 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11389 (match_operand 4)])
11390 (set (match_operand:QI 1 "register_operand")
11391 (match_operator:QI 2 "ix86_comparison_operator"
11392 [(reg FLAGS_REG) (const_int 0)]))
11393 (parallel [(set (match_operand 3 "q_regs_operand")
11394 (zero_extend (match_dup 1)))
11395 (clobber (reg:CC FLAGS_REG))])]
11396 "(peep2_reg_dead_p (3, operands[1])
11397 || operands_match_p (operands[1], operands[3]))
11398 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11399 [(parallel [(set (match_dup 5) (match_dup 0))
11401 (set (strict_low_part (match_dup 6))
11404 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11405 operands[6] = gen_lowpart (QImode, operands[3]);
11406 ix86_expand_clear (operands[3]);
11409 ;; Call instructions.
11411 ;; The predicates normally associated with named expanders are not properly
11412 ;; checked for calls. This is a bug in the generic code, but it isn't that
11413 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11415 ;; P6 processors will jump to the address after the decrement when %esp
11416 ;; is used as a call operand, so they will execute return address as a code.
11417 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11419 ;; Register constraint for call instruction.
11420 (define_mode_attr c [(SI "l") (DI "r")])
11422 ;; Call subroutine returning no value.
11424 (define_expand "call"
11425 [(call (match_operand:QI 0)
11427 (use (match_operand 2))]
11430 ix86_expand_call (NULL, operands[0], operands[1],
11431 operands[2], NULL, false);
11435 (define_expand "sibcall"
11436 [(call (match_operand:QI 0)
11438 (use (match_operand 2))]
11441 ix86_expand_call (NULL, operands[0], operands[1],
11442 operands[2], NULL, true);
11446 (define_insn_and_split "*call_vzeroupper"
11447 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11449 (unspec [(match_operand 2 "const_int_operand")]
11450 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11451 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11453 "&& reload_completed"
11455 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11456 [(set_attr "type" "call")])
11458 (define_insn "*call"
11459 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11460 (match_operand 1))]
11461 "!SIBLING_CALL_P (insn)"
11462 "* return ix86_output_call_insn (insn, operands[0]);"
11463 [(set_attr "type" "call")])
11465 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11466 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11468 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11469 (clobber (reg:TI XMM6_REG))
11470 (clobber (reg:TI XMM7_REG))
11471 (clobber (reg:TI XMM8_REG))
11472 (clobber (reg:TI XMM9_REG))
11473 (clobber (reg:TI XMM10_REG))
11474 (clobber (reg:TI XMM11_REG))
11475 (clobber (reg:TI XMM12_REG))
11476 (clobber (reg:TI XMM13_REG))
11477 (clobber (reg:TI XMM14_REG))
11478 (clobber (reg:TI XMM15_REG))
11479 (clobber (reg:DI SI_REG))
11480 (clobber (reg:DI DI_REG))
11481 (unspec [(match_operand 2 "const_int_operand")]
11482 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11483 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11485 "&& reload_completed"
11487 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11488 [(set_attr "type" "call")])
11490 (define_insn "*call_rex64_ms_sysv"
11491 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11493 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11494 (clobber (reg:TI XMM6_REG))
11495 (clobber (reg:TI XMM7_REG))
11496 (clobber (reg:TI XMM8_REG))
11497 (clobber (reg:TI XMM9_REG))
11498 (clobber (reg:TI XMM10_REG))
11499 (clobber (reg:TI XMM11_REG))
11500 (clobber (reg:TI XMM12_REG))
11501 (clobber (reg:TI XMM13_REG))
11502 (clobber (reg:TI XMM14_REG))
11503 (clobber (reg:TI XMM15_REG))
11504 (clobber (reg:DI SI_REG))
11505 (clobber (reg:DI DI_REG))]
11506 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11507 "* return ix86_output_call_insn (insn, operands[0]);"
11508 [(set_attr "type" "call")])
11510 (define_insn_and_split "*sibcall_vzeroupper"
11511 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11513 (unspec [(match_operand 2 "const_int_operand")]
11514 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11515 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11517 "&& reload_completed"
11519 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11520 [(set_attr "type" "call")])
11522 (define_insn "*sibcall"
11523 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11524 (match_operand 1))]
11525 "SIBLING_CALL_P (insn)"
11526 "* return ix86_output_call_insn (insn, operands[0]);"
11527 [(set_attr "type" "call")])
11529 (define_expand "call_pop"
11530 [(parallel [(call (match_operand:QI 0)
11531 (match_operand:SI 1))
11532 (set (reg:SI SP_REG)
11533 (plus:SI (reg:SI SP_REG)
11534 (match_operand:SI 3)))])]
11537 ix86_expand_call (NULL, operands[0], operands[1],
11538 operands[2], operands[3], false);
11542 (define_insn_and_split "*call_pop_vzeroupper"
11543 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11545 (set (reg:SI SP_REG)
11546 (plus:SI (reg:SI SP_REG)
11547 (match_operand:SI 2 "immediate_operand" "i")))
11548 (unspec [(match_operand 3 "const_int_operand")]
11549 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11550 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11552 "&& reload_completed"
11554 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11555 [(set_attr "type" "call")])
11557 (define_insn "*call_pop"
11558 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11560 (set (reg:SI SP_REG)
11561 (plus:SI (reg:SI SP_REG)
11562 (match_operand:SI 2 "immediate_operand" "i")))]
11563 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11564 "* return ix86_output_call_insn (insn, operands[0]);"
11565 [(set_attr "type" "call")])
11567 (define_insn_and_split "*sibcall_pop_vzeroupper"
11568 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11570 (set (reg:SI SP_REG)
11571 (plus:SI (reg:SI SP_REG)
11572 (match_operand:SI 2 "immediate_operand" "i")))
11573 (unspec [(match_operand 3 "const_int_operand")]
11574 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11575 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11577 "&& reload_completed"
11579 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11580 [(set_attr "type" "call")])
11582 (define_insn "*sibcall_pop"
11583 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11585 (set (reg:SI SP_REG)
11586 (plus:SI (reg:SI SP_REG)
11587 (match_operand:SI 2 "immediate_operand" "i")))]
11588 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11589 "* return ix86_output_call_insn (insn, operands[0]);"
11590 [(set_attr "type" "call")])
11592 ;; Call subroutine, returning value in operand 0
11594 (define_expand "call_value"
11595 [(set (match_operand 0)
11596 (call (match_operand:QI 1)
11597 (match_operand 2)))
11598 (use (match_operand 3))]
11601 ix86_expand_call (operands[0], operands[1], operands[2],
11602 operands[3], NULL, false);
11606 (define_expand "sibcall_value"
11607 [(set (match_operand 0)
11608 (call (match_operand:QI 1)
11609 (match_operand 2)))
11610 (use (match_operand 3))]
11613 ix86_expand_call (operands[0], operands[1], operands[2],
11614 operands[3], NULL, true);
11618 (define_insn_and_split "*call_value_vzeroupper"
11619 [(set (match_operand 0)
11620 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11621 (match_operand 2)))
11622 (unspec [(match_operand 3 "const_int_operand")]
11623 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11624 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11626 "&& reload_completed"
11628 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11629 [(set_attr "type" "callv")])
11631 (define_insn "*call_value"
11632 [(set (match_operand 0)
11633 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11634 (match_operand 2)))]
11635 "!SIBLING_CALL_P (insn)"
11636 "* return ix86_output_call_insn (insn, operands[1]);"
11637 [(set_attr "type" "callv")])
11639 (define_insn_and_split "*sibcall_value_vzeroupper"
11640 [(set (match_operand 0)
11641 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11642 (match_operand 2)))
11643 (unspec [(match_operand 3 "const_int_operand")]
11644 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11645 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11647 "&& reload_completed"
11649 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11650 [(set_attr "type" "callv")])
11652 (define_insn "*sibcall_value"
11653 [(set (match_operand 0)
11654 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11655 (match_operand 2)))]
11656 "SIBLING_CALL_P (insn)"
11657 "* return ix86_output_call_insn (insn, operands[1]);"
11658 [(set_attr "type" "callv")])
11660 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11661 [(set (match_operand 0)
11662 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11663 (match_operand 2)))
11664 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11665 (clobber (reg:TI XMM6_REG))
11666 (clobber (reg:TI XMM7_REG))
11667 (clobber (reg:TI XMM8_REG))
11668 (clobber (reg:TI XMM9_REG))
11669 (clobber (reg:TI XMM10_REG))
11670 (clobber (reg:TI XMM11_REG))
11671 (clobber (reg:TI XMM12_REG))
11672 (clobber (reg:TI XMM13_REG))
11673 (clobber (reg:TI XMM14_REG))
11674 (clobber (reg:TI XMM15_REG))
11675 (clobber (reg:DI SI_REG))
11676 (clobber (reg:DI DI_REG))
11677 (unspec [(match_operand 3 "const_int_operand")]
11678 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11679 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11681 "&& reload_completed"
11683 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11684 [(set_attr "type" "callv")])
11686 (define_insn "*call_value_rex64_ms_sysv"
11687 [(set (match_operand 0)
11688 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11689 (match_operand 2)))
11690 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11691 (clobber (reg:TI XMM6_REG))
11692 (clobber (reg:TI XMM7_REG))
11693 (clobber (reg:TI XMM8_REG))
11694 (clobber (reg:TI XMM9_REG))
11695 (clobber (reg:TI XMM10_REG))
11696 (clobber (reg:TI XMM11_REG))
11697 (clobber (reg:TI XMM12_REG))
11698 (clobber (reg:TI XMM13_REG))
11699 (clobber (reg:TI XMM14_REG))
11700 (clobber (reg:TI XMM15_REG))
11701 (clobber (reg:DI SI_REG))
11702 (clobber (reg:DI DI_REG))]
11703 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11704 "* return ix86_output_call_insn (insn, operands[1]);"
11705 [(set_attr "type" "callv")])
11707 (define_expand "call_value_pop"
11708 [(parallel [(set (match_operand 0)
11709 (call (match_operand:QI 1)
11710 (match_operand:SI 2)))
11711 (set (reg:SI SP_REG)
11712 (plus:SI (reg:SI SP_REG)
11713 (match_operand:SI 4)))])]
11716 ix86_expand_call (operands[0], operands[1], operands[2],
11717 operands[3], operands[4], false);
11721 (define_insn_and_split "*call_value_pop_vzeroupper"
11722 [(set (match_operand 0)
11723 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11724 (match_operand 2)))
11725 (set (reg:SI SP_REG)
11726 (plus:SI (reg:SI SP_REG)
11727 (match_operand:SI 3 "immediate_operand" "i")))
11728 (unspec [(match_operand 4 "const_int_operand")]
11729 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11730 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11732 "&& reload_completed"
11734 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11735 [(set_attr "type" "callv")])
11737 (define_insn "*call_value_pop"
11738 [(set (match_operand 0)
11739 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11740 (match_operand 2)))
11741 (set (reg:SI SP_REG)
11742 (plus:SI (reg:SI SP_REG)
11743 (match_operand:SI 3 "immediate_operand" "i")))]
11744 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11745 "* return ix86_output_call_insn (insn, operands[1]);"
11746 [(set_attr "type" "callv")])
11748 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11749 [(set (match_operand 0)
11750 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11751 (match_operand 2)))
11752 (set (reg:SI SP_REG)
11753 (plus:SI (reg:SI SP_REG)
11754 (match_operand:SI 3 "immediate_operand" "i")))
11755 (unspec [(match_operand 4 "const_int_operand")]
11756 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11757 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11759 "&& reload_completed"
11761 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11762 [(set_attr "type" "callv")])
11764 (define_insn "*sibcall_value_pop"
11765 [(set (match_operand 0)
11766 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11767 (match_operand 2)))
11768 (set (reg:SI SP_REG)
11769 (plus:SI (reg:SI SP_REG)
11770 (match_operand:SI 3 "immediate_operand" "i")))]
11771 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11772 "* return ix86_output_call_insn (insn, operands[1]);"
11773 [(set_attr "type" "callv")])
11775 ;; Call subroutine returning any type.
11777 (define_expand "untyped_call"
11778 [(parallel [(call (match_operand 0)
11781 (match_operand 2)])]
11786 /* In order to give reg-stack an easier job in validating two
11787 coprocessor registers as containing a possible return value,
11788 simply pretend the untyped call returns a complex long double
11791 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11792 and should have the default ABI. */
11794 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11795 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11796 operands[0], const0_rtx,
11797 GEN_INT ((TARGET_64BIT
11798 ? (ix86_abi == SYSV_ABI
11799 ? X86_64_SSE_REGPARM_MAX
11800 : X86_64_MS_SSE_REGPARM_MAX)
11801 : X86_32_SSE_REGPARM_MAX)
11805 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11807 rtx set = XVECEXP (operands[2], 0, i);
11808 emit_move_insn (SET_DEST (set), SET_SRC (set));
11811 /* The optimizer does not know that the call sets the function value
11812 registers we stored in the result block. We avoid problems by
11813 claiming that all hard registers are used and clobbered at this
11815 emit_insn (gen_blockage ());
11820 ;; Prologue and epilogue instructions
11822 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11823 ;; all of memory. This blocks insns from being moved across this point.
11825 (define_insn "blockage"
11826 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11829 [(set_attr "length" "0")])
11831 ;; Do not schedule instructions accessing memory across this point.
11833 (define_expand "memory_blockage"
11834 [(set (match_dup 0)
11835 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11838 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11839 MEM_VOLATILE_P (operands[0]) = 1;
11842 (define_insn "*memory_blockage"
11843 [(set (match_operand:BLK 0)
11844 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11847 [(set_attr "length" "0")])
11849 ;; As USE insns aren't meaningful after reload, this is used instead
11850 ;; to prevent deleting instructions setting registers for PIC code
11851 (define_insn "prologue_use"
11852 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
11855 [(set_attr "length" "0")])
11857 ;; Insn emitted into the body of a function to return from a function.
11858 ;; This is only done if the function's epilogue is known to be simple.
11859 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11861 (define_expand "return"
11863 "ix86_can_use_return_insn_p ()"
11865 ix86_maybe_emit_epilogue_vzeroupper ();
11866 if (crtl->args.pops_args)
11868 rtx popc = GEN_INT (crtl->args.pops_args);
11869 emit_jump_insn (gen_simple_return_pop_internal (popc));
11874 ;; We need to disable this for TARGET_SEH, as otherwise
11875 ;; shrink-wrapped prologue gets enabled too. This might exceed
11876 ;; the maximum size of prologue in unwind information.
11878 (define_expand "simple_return"
11882 ix86_maybe_emit_epilogue_vzeroupper ();
11883 if (crtl->args.pops_args)
11885 rtx popc = GEN_INT (crtl->args.pops_args);
11886 emit_jump_insn (gen_simple_return_pop_internal (popc));
11891 (define_insn "simple_return_internal"
11895 [(set_attr "length" "1")
11896 (set_attr "atom_unit" "jeu")
11897 (set_attr "length_immediate" "0")
11898 (set_attr "modrm" "0")])
11900 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11901 ;; instruction Athlon and K8 have.
11903 (define_insn "simple_return_internal_long"
11905 (unspec [(const_int 0)] UNSPEC_REP)]
11908 [(set_attr "length" "2")
11909 (set_attr "atom_unit" "jeu")
11910 (set_attr "length_immediate" "0")
11911 (set_attr "prefix_rep" "1")
11912 (set_attr "modrm" "0")])
11914 (define_insn "simple_return_pop_internal"
11916 (use (match_operand:SI 0 "const_int_operand"))]
11919 [(set_attr "length" "3")
11920 (set_attr "atom_unit" "jeu")
11921 (set_attr "length_immediate" "2")
11922 (set_attr "modrm" "0")])
11924 (define_insn "simple_return_indirect_internal"
11926 (use (match_operand:SI 0 "register_operand" "r"))]
11929 [(set_attr "type" "ibr")
11930 (set_attr "length_immediate" "0")])
11936 [(set_attr "length" "1")
11937 (set_attr "length_immediate" "0")
11938 (set_attr "modrm" "0")])
11940 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11941 (define_insn "nops"
11942 [(unspec_volatile [(match_operand 0 "const_int_operand")]
11946 int num = INTVAL (operands[0]);
11948 gcc_assert (IN_RANGE (num, 1, 8));
11951 fputs ("\tnop\n", asm_out_file);
11955 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11956 (set_attr "length_immediate" "0")
11957 (set_attr "modrm" "0")])
11959 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11960 ;; branch prediction penalty for the third jump in a 16-byte
11964 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
11967 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11968 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11970 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11971 The align insn is used to avoid 3 jump instructions in the row to improve
11972 branch prediction and the benefits hardly outweigh the cost of extra 8
11973 nops on the average inserted by full alignment pseudo operation. */
11977 [(set_attr "length" "16")])
11979 (define_expand "prologue"
11982 "ix86_expand_prologue (); DONE;")
11984 (define_insn "set_got"
11985 [(set (match_operand:SI 0 "register_operand" "=r")
11986 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11987 (clobber (reg:CC FLAGS_REG))]
11989 "* return output_set_got (operands[0], NULL_RTX);"
11990 [(set_attr "type" "multi")
11991 (set_attr "length" "12")])
11993 (define_insn "set_got_labelled"
11994 [(set (match_operand:SI 0 "register_operand" "=r")
11995 (unspec:SI [(label_ref (match_operand 1))]
11997 (clobber (reg:CC FLAGS_REG))]
11999 "* return output_set_got (operands[0], operands[1]);"
12000 [(set_attr "type" "multi")
12001 (set_attr "length" "12")])
12003 (define_insn "set_got_rex64"
12004 [(set (match_operand:DI 0 "register_operand" "=r")
12005 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
12007 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
12008 [(set_attr "type" "lea")
12009 (set_attr "length_address" "4")
12010 (set_attr "mode" "DI")])
12012 (define_insn "set_rip_rex64"
12013 [(set (match_operand:DI 0 "register_operand" "=r")
12014 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
12016 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
12017 [(set_attr "type" "lea")
12018 (set_attr "length_address" "4")
12019 (set_attr "mode" "DI")])
12021 (define_insn "set_got_offset_rex64"
12022 [(set (match_operand:DI 0 "register_operand" "=r")
12024 [(label_ref (match_operand 1))]
12025 UNSPEC_SET_GOT_OFFSET))]
12027 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
12028 [(set_attr "type" "imov")
12029 (set_attr "length_immediate" "0")
12030 (set_attr "length_address" "8")
12031 (set_attr "mode" "DI")])
12033 (define_expand "epilogue"
12036 "ix86_expand_epilogue (1); DONE;")
12038 (define_expand "sibcall_epilogue"
12041 "ix86_expand_epilogue (0); DONE;")
12043 (define_expand "eh_return"
12044 [(use (match_operand 0 "register_operand"))]
12047 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
12049 /* Tricky bit: we write the address of the handler to which we will
12050 be returning into someone else's stack frame, one word below the
12051 stack address we wish to restore. */
12052 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
12053 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
12054 tmp = gen_rtx_MEM (Pmode, tmp);
12055 emit_move_insn (tmp, ra);
12057 emit_jump_insn (gen_eh_return_internal ());
12062 (define_insn_and_split "eh_return_internal"
12066 "epilogue_completed"
12068 "ix86_expand_epilogue (2); DONE;")
12070 (define_insn "leave"
12071 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
12072 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
12073 (clobber (mem:BLK (scratch)))]
12076 [(set_attr "type" "leave")])
12078 (define_insn "leave_rex64"
12079 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
12080 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
12081 (clobber (mem:BLK (scratch)))]
12084 [(set_attr "type" "leave")])
12086 ;; Handle -fsplit-stack.
12088 (define_expand "split_stack_prologue"
12092 ix86_expand_split_stack_prologue ();
12096 ;; In order to support the call/return predictor, we use a return
12097 ;; instruction which the middle-end doesn't see.
12098 (define_insn "split_stack_return"
12099 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
12100 UNSPECV_SPLIT_STACK_RETURN)]
12103 if (operands[0] == const0_rtx)
12108 [(set_attr "atom_unit" "jeu")
12109 (set_attr "modrm" "0")
12110 (set (attr "length")
12111 (if_then_else (match_operand:SI 0 "const0_operand")
12114 (set (attr "length_immediate")
12115 (if_then_else (match_operand:SI 0 "const0_operand")
12119 ;; If there are operand 0 bytes available on the stack, jump to
12122 (define_expand "split_stack_space_check"
12123 [(set (pc) (if_then_else
12124 (ltu (minus (reg SP_REG)
12125 (match_operand 0 "register_operand"))
12126 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
12127 (label_ref (match_operand 1))
12131 rtx reg, size, limit;
12133 reg = gen_reg_rtx (Pmode);
12134 size = force_reg (Pmode, operands[0]);
12135 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
12136 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
12137 UNSPEC_STACK_CHECK);
12138 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
12139 ix86_expand_branch (GEU, reg, limit, operands[1]);
12144 ;; Bit manipulation instructions.
12146 (define_expand "ffs<mode>2"
12147 [(set (match_dup 2) (const_int -1))
12148 (parallel [(set (match_dup 3) (match_dup 4))
12149 (set (match_operand:SWI48 0 "register_operand")
12151 (match_operand:SWI48 1 "nonimmediate_operand")))])
12152 (set (match_dup 0) (if_then_else:SWI48
12153 (eq (match_dup 3) (const_int 0))
12156 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12157 (clobber (reg:CC FLAGS_REG))])]
12160 enum machine_mode flags_mode;
12162 if (<MODE>mode == SImode && !TARGET_CMOVE)
12164 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12168 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12170 operands[2] = gen_reg_rtx (<MODE>mode);
12171 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12172 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12175 (define_insn_and_split "ffssi2_no_cmove"
12176 [(set (match_operand:SI 0 "register_operand" "=r")
12177 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12178 (clobber (match_scratch:SI 2 "=&q"))
12179 (clobber (reg:CC FLAGS_REG))]
12182 "&& reload_completed"
12183 [(parallel [(set (match_dup 4) (match_dup 5))
12184 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12185 (set (strict_low_part (match_dup 3))
12186 (eq:QI (match_dup 4) (const_int 0)))
12187 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12188 (clobber (reg:CC FLAGS_REG))])
12189 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12190 (clobber (reg:CC FLAGS_REG))])
12191 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12192 (clobber (reg:CC FLAGS_REG))])]
12194 enum machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12196 operands[3] = gen_lowpart (QImode, operands[2]);
12197 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12198 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12200 ix86_expand_clear (operands[2]);
12203 (define_insn "*tzcnt<mode>_1"
12204 [(set (reg:CCC FLAGS_REG)
12205 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12207 (set (match_operand:SWI48 0 "register_operand" "=r")
12208 (ctz:SWI48 (match_dup 1)))]
12210 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12211 [(set_attr "type" "alu1")
12212 (set_attr "prefix_0f" "1")
12213 (set_attr "prefix_rep" "1")
12214 (set_attr "mode" "<MODE>")])
12216 (define_insn "*bsf<mode>_1"
12217 [(set (reg:CCZ FLAGS_REG)
12218 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12220 (set (match_operand:SWI48 0 "register_operand" "=r")
12221 (ctz:SWI48 (match_dup 1)))]
12223 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12224 [(set_attr "type" "alu1")
12225 (set_attr "prefix_0f" "1")
12226 (set_attr "mode" "<MODE>")])
12228 (define_insn "ctz<mode>2"
12229 [(set (match_operand:SWI248 0 "register_operand" "=r")
12230 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12231 (clobber (reg:CC FLAGS_REG))]
12235 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12236 else if (optimize_function_for_size_p (cfun))
12238 else if (TARGET_GENERIC)
12239 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12240 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12242 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12244 [(set_attr "type" "alu1")
12245 (set_attr "prefix_0f" "1")
12246 (set (attr "prefix_rep")
12248 (ior (match_test "TARGET_BMI")
12249 (and (not (match_test "optimize_function_for_size_p (cfun)"))
12250 (match_test "TARGET_GENERIC")))
12252 (const_string "0")))
12253 (set_attr "mode" "<MODE>")])
12255 (define_expand "clz<mode>2"
12257 [(set (match_operand:SWI248 0 "register_operand")
12260 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12261 (clobber (reg:CC FLAGS_REG))])
12263 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12264 (clobber (reg:CC FLAGS_REG))])]
12269 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12272 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12275 (define_insn "clz<mode>2_lzcnt"
12276 [(set (match_operand:SWI248 0 "register_operand" "=r")
12277 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12278 (clobber (reg:CC FLAGS_REG))]
12280 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12281 [(set_attr "prefix_rep" "1")
12282 (set_attr "type" "bitmanip")
12283 (set_attr "mode" "<MODE>")])
12285 ;; BMI instructions.
12286 (define_insn "*bmi_andn_<mode>"
12287 [(set (match_operand:SWI48 0 "register_operand" "=r")
12290 (match_operand:SWI48 1 "register_operand" "r"))
12291 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12292 (clobber (reg:CC FLAGS_REG))]
12294 "andn\t{%2, %1, %0|%0, %1, %2}"
12295 [(set_attr "type" "bitmanip")
12296 (set_attr "mode" "<MODE>")])
12298 (define_insn "bmi_bextr_<mode>"
12299 [(set (match_operand:SWI48 0 "register_operand" "=r")
12300 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12301 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12303 (clobber (reg:CC FLAGS_REG))]
12305 "bextr\t{%2, %1, %0|%0, %1, %2}"
12306 [(set_attr "type" "bitmanip")
12307 (set_attr "mode" "<MODE>")])
12309 (define_insn "*bmi_blsi_<mode>"
12310 [(set (match_operand:SWI48 0 "register_operand" "=r")
12313 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12315 (clobber (reg:CC FLAGS_REG))]
12317 "blsi\t{%1, %0|%0, %1}"
12318 [(set_attr "type" "bitmanip")
12319 (set_attr "mode" "<MODE>")])
12321 (define_insn "*bmi_blsmsk_<mode>"
12322 [(set (match_operand:SWI48 0 "register_operand" "=r")
12325 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12328 (clobber (reg:CC FLAGS_REG))]
12330 "blsmsk\t{%1, %0|%0, %1}"
12331 [(set_attr "type" "bitmanip")
12332 (set_attr "mode" "<MODE>")])
12334 (define_insn "*bmi_blsr_<mode>"
12335 [(set (match_operand:SWI48 0 "register_operand" "=r")
12338 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12341 (clobber (reg:CC FLAGS_REG))]
12343 "blsr\t{%1, %0|%0, %1}"
12344 [(set_attr "type" "bitmanip")
12345 (set_attr "mode" "<MODE>")])
12347 ;; BMI2 instructions.
12348 (define_insn "bmi2_bzhi_<mode>3"
12349 [(set (match_operand:SWI48 0 "register_operand" "=r")
12350 (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
12351 (lshiftrt:SWI48 (const_int -1)
12352 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
12353 (clobber (reg:CC FLAGS_REG))]
12355 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12356 [(set_attr "type" "bitmanip")
12357 (set_attr "prefix" "vex")
12358 (set_attr "mode" "<MODE>")])
12360 (define_insn "bmi2_pdep_<mode>3"
12361 [(set (match_operand:SWI48 0 "register_operand" "=r")
12362 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12363 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12366 "pdep\t{%2, %1, %0|%0, %1, %2}"
12367 [(set_attr "type" "bitmanip")
12368 (set_attr "prefix" "vex")
12369 (set_attr "mode" "<MODE>")])
12371 (define_insn "bmi2_pext_<mode>3"
12372 [(set (match_operand:SWI48 0 "register_operand" "=r")
12373 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12374 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12377 "pext\t{%2, %1, %0|%0, %1, %2}"
12378 [(set_attr "type" "bitmanip")
12379 (set_attr "prefix" "vex")
12380 (set_attr "mode" "<MODE>")])
12382 ;; TBM instructions.
12383 (define_insn "tbm_bextri_<mode>"
12384 [(set (match_operand:SWI48 0 "register_operand" "=r")
12385 (zero_extract:SWI48
12386 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12387 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12388 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12389 (clobber (reg:CC FLAGS_REG))]
12392 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12393 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12395 [(set_attr "type" "bitmanip")
12396 (set_attr "mode" "<MODE>")])
12398 (define_insn "*tbm_blcfill_<mode>"
12399 [(set (match_operand:SWI48 0 "register_operand" "=r")
12402 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12405 (clobber (reg:CC FLAGS_REG))]
12407 "blcfill\t{%1, %0|%0, %1}"
12408 [(set_attr "type" "bitmanip")
12409 (set_attr "mode" "<MODE>")])
12411 (define_insn "*tbm_blci_<mode>"
12412 [(set (match_operand:SWI48 0 "register_operand" "=r")
12416 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12419 (clobber (reg:CC FLAGS_REG))]
12421 "blci\t{%1, %0|%0, %1}"
12422 [(set_attr "type" "bitmanip")
12423 (set_attr "mode" "<MODE>")])
12425 (define_insn "*tbm_blcic_<mode>"
12426 [(set (match_operand:SWI48 0 "register_operand" "=r")
12429 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12433 (clobber (reg:CC FLAGS_REG))]
12435 "blcic\t{%1, %0|%0, %1}"
12436 [(set_attr "type" "bitmanip")
12437 (set_attr "mode" "<MODE>")])
12439 (define_insn "*tbm_blcmsk_<mode>"
12440 [(set (match_operand:SWI48 0 "register_operand" "=r")
12443 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12446 (clobber (reg:CC FLAGS_REG))]
12448 "blcmsk\t{%1, %0|%0, %1}"
12449 [(set_attr "type" "bitmanip")
12450 (set_attr "mode" "<MODE>")])
12452 (define_insn "*tbm_blcs_<mode>"
12453 [(set (match_operand:SWI48 0 "register_operand" "=r")
12456 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12459 (clobber (reg:CC FLAGS_REG))]
12461 "blcs\t{%1, %0|%0, %1}"
12462 [(set_attr "type" "bitmanip")
12463 (set_attr "mode" "<MODE>")])
12465 (define_insn "*tbm_blsfill_<mode>"
12466 [(set (match_operand:SWI48 0 "register_operand" "=r")
12469 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12472 (clobber (reg:CC FLAGS_REG))]
12474 "blsfill\t{%1, %0|%0, %1}"
12475 [(set_attr "type" "bitmanip")
12476 (set_attr "mode" "<MODE>")])
12478 (define_insn "*tbm_blsic_<mode>"
12479 [(set (match_operand:SWI48 0 "register_operand" "=r")
12482 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12486 (clobber (reg:CC FLAGS_REG))]
12488 "blsic\t{%1, %0|%0, %1}"
12489 [(set_attr "type" "bitmanip")
12490 (set_attr "mode" "<MODE>")])
12492 (define_insn "*tbm_t1mskc_<mode>"
12493 [(set (match_operand:SWI48 0 "register_operand" "=r")
12496 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12500 (clobber (reg:CC FLAGS_REG))]
12502 "t1mskc\t{%1, %0|%0, %1}"
12503 [(set_attr "type" "bitmanip")
12504 (set_attr "mode" "<MODE>")])
12506 (define_insn "*tbm_tzmsk_<mode>"
12507 [(set (match_operand:SWI48 0 "register_operand" "=r")
12510 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12514 (clobber (reg:CC FLAGS_REG))]
12516 "tzmsk\t{%1, %0|%0, %1}"
12517 [(set_attr "type" "bitmanip")
12518 (set_attr "mode" "<MODE>")])
12520 (define_insn "bsr_rex64"
12521 [(set (match_operand:DI 0 "register_operand" "=r")
12522 (minus:DI (const_int 63)
12523 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12524 (clobber (reg:CC FLAGS_REG))]
12526 "bsr{q}\t{%1, %0|%0, %1}"
12527 [(set_attr "type" "alu1")
12528 (set_attr "prefix_0f" "1")
12529 (set_attr "mode" "DI")])
12532 [(set (match_operand:SI 0 "register_operand" "=r")
12533 (minus:SI (const_int 31)
12534 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12535 (clobber (reg:CC FLAGS_REG))]
12537 "bsr{l}\t{%1, %0|%0, %1}"
12538 [(set_attr "type" "alu1")
12539 (set_attr "prefix_0f" "1")
12540 (set_attr "mode" "SI")])
12542 (define_insn "*bsrhi"
12543 [(set (match_operand:HI 0 "register_operand" "=r")
12544 (minus:HI (const_int 15)
12545 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12546 (clobber (reg:CC FLAGS_REG))]
12548 "bsr{w}\t{%1, %0|%0, %1}"
12549 [(set_attr "type" "alu1")
12550 (set_attr "prefix_0f" "1")
12551 (set_attr "mode" "HI")])
12553 (define_insn "popcount<mode>2"
12554 [(set (match_operand:SWI248 0 "register_operand" "=r")
12556 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12557 (clobber (reg:CC FLAGS_REG))]
12561 return "popcnt\t{%1, %0|%0, %1}";
12563 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12566 [(set_attr "prefix_rep" "1")
12567 (set_attr "type" "bitmanip")
12568 (set_attr "mode" "<MODE>")])
12570 (define_insn "*popcount<mode>2_cmp"
12571 [(set (reg FLAGS_REG)
12574 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12576 (set (match_operand:SWI248 0 "register_operand" "=r")
12577 (popcount:SWI248 (match_dup 1)))]
12578 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12581 return "popcnt\t{%1, %0|%0, %1}";
12583 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12586 [(set_attr "prefix_rep" "1")
12587 (set_attr "type" "bitmanip")
12588 (set_attr "mode" "<MODE>")])
12590 (define_insn "*popcountsi2_cmp_zext"
12591 [(set (reg FLAGS_REG)
12593 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12595 (set (match_operand:DI 0 "register_operand" "=r")
12596 (zero_extend:DI(popcount:SI (match_dup 1))))]
12597 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12600 return "popcnt\t{%1, %0|%0, %1}";
12602 return "popcnt{l}\t{%1, %0|%0, %1}";
12605 [(set_attr "prefix_rep" "1")
12606 (set_attr "type" "bitmanip")
12607 (set_attr "mode" "SI")])
12609 (define_expand "bswapdi2"
12610 [(set (match_operand:DI 0 "register_operand")
12611 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
12614 if (TARGET_64BIT && !TARGET_MOVBE)
12615 operands[1] = force_reg (DImode, operands[1]);
12618 (define_insn_and_split "*bswapdi2_doubleword"
12619 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
12621 (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
12623 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12625 "&& reload_completed"
12626 [(set (match_dup 2)
12627 (bswap:SI (match_dup 1)))
12629 (bswap:SI (match_dup 3)))]
12631 split_double_mode (DImode, &operands[0], 2, &operands[0], &operands[2]);
12633 if (REG_P (operands[0]) && REG_P (operands[1]))
12635 emit_insn (gen_swapsi (operands[0], operands[2]));
12636 emit_insn (gen_bswapsi2 (operands[0], operands[0]));
12637 emit_insn (gen_bswapsi2 (operands[2], operands[2]));
12643 if (MEM_P (operands[0]))
12645 emit_insn (gen_bswapsi2 (operands[3], operands[3]));
12646 emit_insn (gen_bswapsi2 (operands[1], operands[1]));
12648 emit_move_insn (operands[0], operands[3]);
12649 emit_move_insn (operands[2], operands[1]);
12651 if (MEM_P (operands[1]))
12653 emit_move_insn (operands[2], operands[1]);
12654 emit_move_insn (operands[0], operands[3]);
12656 emit_insn (gen_bswapsi2 (operands[2], operands[2]));
12657 emit_insn (gen_bswapsi2 (operands[0], operands[0]));
12663 (define_expand "bswapsi2"
12664 [(set (match_operand:SI 0 "register_operand")
12665 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
12670 else if (TARGET_BSWAP)
12671 operands[1] = force_reg (SImode, operands[1]);
12674 rtx x = operands[0];
12676 emit_move_insn (x, operands[1]);
12677 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12678 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12679 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12684 (define_insn "*bswap<mode>2_movbe"
12685 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12686 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12688 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12691 movbe\t{%1, %0|%0, %1}
12692 movbe\t{%1, %0|%0, %1}"
12693 [(set_attr "type" "bitmanip,imov,imov")
12694 (set_attr "modrm" "0,1,1")
12695 (set_attr "prefix_0f" "*,1,1")
12696 (set_attr "prefix_extra" "*,1,1")
12697 (set_attr "mode" "<MODE>")])
12699 (define_insn "*bswap<mode>2"
12700 [(set (match_operand:SWI48 0 "register_operand" "=r")
12701 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12704 [(set_attr "type" "bitmanip")
12705 (set_attr "modrm" "0")
12706 (set_attr "mode" "<MODE>")])
12708 (define_insn "*bswaphi_lowpart_1"
12709 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12710 (bswap:HI (match_dup 0)))
12711 (clobber (reg:CC FLAGS_REG))]
12712 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12714 xchg{b}\t{%h0, %b0|%b0, %h0}
12715 rol{w}\t{$8, %0|%0, 8}"
12716 [(set_attr "length" "2,4")
12717 (set_attr "mode" "QI,HI")])
12719 (define_insn "bswaphi_lowpart"
12720 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12721 (bswap:HI (match_dup 0)))
12722 (clobber (reg:CC FLAGS_REG))]
12724 "rol{w}\t{$8, %0|%0, 8}"
12725 [(set_attr "length" "4")
12726 (set_attr "mode" "HI")])
12728 (define_expand "paritydi2"
12729 [(set (match_operand:DI 0 "register_operand")
12730 (parity:DI (match_operand:DI 1 "register_operand")))]
12733 rtx scratch = gen_reg_rtx (QImode);
12736 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12737 NULL_RTX, operands[1]));
12739 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12740 gen_rtx_REG (CCmode, FLAGS_REG),
12742 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12745 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12748 rtx tmp = gen_reg_rtx (SImode);
12750 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12751 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12756 (define_expand "paritysi2"
12757 [(set (match_operand:SI 0 "register_operand")
12758 (parity:SI (match_operand:SI 1 "register_operand")))]
12761 rtx scratch = gen_reg_rtx (QImode);
12764 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12766 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12767 gen_rtx_REG (CCmode, FLAGS_REG),
12769 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12771 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12775 (define_insn_and_split "paritydi2_cmp"
12776 [(set (reg:CC FLAGS_REG)
12777 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12779 (clobber (match_scratch:DI 0 "=r"))
12780 (clobber (match_scratch:SI 1 "=&r"))
12781 (clobber (match_scratch:HI 2 "=Q"))]
12784 "&& reload_completed"
12786 [(set (match_dup 1)
12787 (xor:SI (match_dup 1) (match_dup 4)))
12788 (clobber (reg:CC FLAGS_REG))])
12790 [(set (reg:CC FLAGS_REG)
12791 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12792 (clobber (match_dup 1))
12793 (clobber (match_dup 2))])]
12795 operands[4] = gen_lowpart (SImode, operands[3]);
12799 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12800 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12803 operands[1] = gen_highpart (SImode, operands[3]);
12806 (define_insn_and_split "paritysi2_cmp"
12807 [(set (reg:CC FLAGS_REG)
12808 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12810 (clobber (match_scratch:SI 0 "=r"))
12811 (clobber (match_scratch:HI 1 "=&Q"))]
12814 "&& reload_completed"
12816 [(set (match_dup 1)
12817 (xor:HI (match_dup 1) (match_dup 3)))
12818 (clobber (reg:CC FLAGS_REG))])
12820 [(set (reg:CC FLAGS_REG)
12821 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12822 (clobber (match_dup 1))])]
12824 operands[3] = gen_lowpart (HImode, operands[2]);
12826 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12827 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12830 (define_insn "*parityhi2_cmp"
12831 [(set (reg:CC FLAGS_REG)
12832 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12834 (clobber (match_scratch:HI 0 "=Q"))]
12836 "xor{b}\t{%h0, %b0|%b0, %h0}"
12837 [(set_attr "length" "2")
12838 (set_attr "mode" "HI")])
12841 ;; Thread-local storage patterns for ELF.
12843 ;; Note that these code sequences must appear exactly as shown
12844 ;; in order to allow linker relaxation.
12846 (define_insn "*tls_global_dynamic_32_gnu"
12847 [(set (match_operand:SI 0 "register_operand" "=a")
12849 [(match_operand:SI 1 "register_operand" "b")
12850 (match_operand 2 "tls_symbolic_operand")
12851 (match_operand 3 "constant_call_address_operand" "z")]
12853 (clobber (match_scratch:SI 4 "=d"))
12854 (clobber (match_scratch:SI 5 "=c"))
12855 (clobber (reg:CC FLAGS_REG))]
12856 "!TARGET_64BIT && TARGET_GNU_TLS"
12859 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12860 if (TARGET_SUN_TLS)
12861 #ifdef HAVE_AS_IX86_TLSGDPLT
12862 return "call\t%a2@tlsgdplt";
12864 return "call\t%p3@plt";
12866 return "call\t%P3";
12868 [(set_attr "type" "multi")
12869 (set_attr "length" "12")])
12871 (define_expand "tls_global_dynamic_32"
12873 [(set (match_operand:SI 0 "register_operand")
12874 (unspec:SI [(match_operand:SI 2 "register_operand")
12875 (match_operand 1 "tls_symbolic_operand")
12876 (match_operand 3 "constant_call_address_operand")]
12878 (clobber (match_scratch:SI 4))
12879 (clobber (match_scratch:SI 5))
12880 (clobber (reg:CC FLAGS_REG))])])
12882 (define_insn "*tls_global_dynamic_64_<mode>"
12883 [(set (match_operand:P 0 "register_operand" "=a")
12885 (mem:QI (match_operand 2 "constant_call_address_operand" "z"))
12886 (match_operand 3)))
12887 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12892 fputs (ASM_BYTE "0x66\n", asm_out_file);
12894 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12895 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12896 fputs ("\trex64\n", asm_out_file);
12897 if (TARGET_SUN_TLS)
12898 return "call\t%p2@plt";
12899 return "call\t%P2";
12901 [(set_attr "type" "multi")
12902 (set (attr "length")
12903 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12905 (define_expand "tls_global_dynamic_64_<mode>"
12907 [(set (match_operand:P 0 "register_operand")
12909 (mem:QI (match_operand 2 "constant_call_address_operand"))
12911 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12915 (define_insn "*tls_local_dynamic_base_32_gnu"
12916 [(set (match_operand:SI 0 "register_operand" "=a")
12918 [(match_operand:SI 1 "register_operand" "b")
12919 (match_operand 2 "constant_call_address_operand" "z")]
12920 UNSPEC_TLS_LD_BASE))
12921 (clobber (match_scratch:SI 3 "=d"))
12922 (clobber (match_scratch:SI 4 "=c"))
12923 (clobber (reg:CC FLAGS_REG))]
12924 "!TARGET_64BIT && TARGET_GNU_TLS"
12927 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12928 if (TARGET_SUN_TLS)
12929 #ifdef HAVE_AS_IX86_TLSLDMPLT
12930 return "call\t%&@tlsldmplt";
12932 return "call\t%p2@plt";
12934 return "call\t%P2";
12936 [(set_attr "type" "multi")
12937 (set_attr "length" "11")])
12939 (define_expand "tls_local_dynamic_base_32"
12941 [(set (match_operand:SI 0 "register_operand")
12943 [(match_operand:SI 1 "register_operand")
12944 (match_operand 2 "constant_call_address_operand")]
12945 UNSPEC_TLS_LD_BASE))
12946 (clobber (match_scratch:SI 3))
12947 (clobber (match_scratch:SI 4))
12948 (clobber (reg:CC FLAGS_REG))])])
12950 (define_insn "*tls_local_dynamic_base_64_<mode>"
12951 [(set (match_operand:P 0 "register_operand" "=a")
12953 (mem:QI (match_operand 1 "constant_call_address_operand" "z"))
12954 (match_operand 2)))
12955 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12959 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12960 if (TARGET_SUN_TLS)
12961 return "call\t%p1@plt";
12962 return "call\t%P1";
12964 [(set_attr "type" "multi")
12965 (set_attr "length" "12")])
12967 (define_expand "tls_local_dynamic_base_64_<mode>"
12969 [(set (match_operand:P 0 "register_operand")
12971 (mem:QI (match_operand 1 "constant_call_address_operand"))
12973 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12976 ;; Local dynamic of a single variable is a lose. Show combine how
12977 ;; to convert that back to global dynamic.
12979 (define_insn_and_split "*tls_local_dynamic_32_once"
12980 [(set (match_operand:SI 0 "register_operand" "=a")
12982 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12983 (match_operand 2 "constant_call_address_operand" "z")]
12984 UNSPEC_TLS_LD_BASE)
12985 (const:SI (unspec:SI
12986 [(match_operand 3 "tls_symbolic_operand")]
12988 (clobber (match_scratch:SI 4 "=d"))
12989 (clobber (match_scratch:SI 5 "=c"))
12990 (clobber (reg:CC FLAGS_REG))]
12995 [(set (match_dup 0)
12996 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12998 (clobber (match_dup 4))
12999 (clobber (match_dup 5))
13000 (clobber (reg:CC FLAGS_REG))])])
13002 ;; Segment register for the thread base ptr load
13003 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
13005 ;; Load and add the thread base pointer from %<tp_seg>:0.
13006 (define_insn "*load_tp_x32"
13007 [(set (match_operand:SI 0 "register_operand" "=r")
13008 (unspec:SI [(const_int 0)] UNSPEC_TP))]
13010 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13011 [(set_attr "type" "imov")
13012 (set_attr "modrm" "0")
13013 (set_attr "length" "7")
13014 (set_attr "memory" "load")
13015 (set_attr "imm_disp" "false")])
13017 (define_insn "*load_tp_x32_zext"
13018 [(set (match_operand:DI 0 "register_operand" "=r")
13019 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
13021 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13022 [(set_attr "type" "imov")
13023 (set_attr "modrm" "0")
13024 (set_attr "length" "7")
13025 (set_attr "memory" "load")
13026 (set_attr "imm_disp" "false")])
13028 (define_insn "*load_tp_<mode>"
13029 [(set (match_operand:P 0 "register_operand" "=r")
13030 (unspec:P [(const_int 0)] UNSPEC_TP))]
13032 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13033 [(set_attr "type" "imov")
13034 (set_attr "modrm" "0")
13035 (set_attr "length" "7")
13036 (set_attr "memory" "load")
13037 (set_attr "imm_disp" "false")])
13039 (define_insn "*add_tp_x32"
13040 [(set (match_operand:SI 0 "register_operand" "=r")
13041 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13042 (match_operand:SI 1 "register_operand" "0")))
13043 (clobber (reg:CC FLAGS_REG))]
13045 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
13046 [(set_attr "type" "alu")
13047 (set_attr "modrm" "0")
13048 (set_attr "length" "7")
13049 (set_attr "memory" "load")
13050 (set_attr "imm_disp" "false")])
13052 (define_insn "*add_tp_x32_zext"
13053 [(set (match_operand:DI 0 "register_operand" "=r")
13055 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
13056 (match_operand:SI 1 "register_operand" "0"))))
13057 (clobber (reg:CC FLAGS_REG))]
13059 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
13060 [(set_attr "type" "alu")
13061 (set_attr "modrm" "0")
13062 (set_attr "length" "7")
13063 (set_attr "memory" "load")
13064 (set_attr "imm_disp" "false")])
13066 (define_insn "*add_tp_<mode>"
13067 [(set (match_operand:P 0 "register_operand" "=r")
13068 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
13069 (match_operand:P 1 "register_operand" "0")))
13070 (clobber (reg:CC FLAGS_REG))]
13072 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
13073 [(set_attr "type" "alu")
13074 (set_attr "modrm" "0")
13075 (set_attr "length" "7")
13076 (set_attr "memory" "load")
13077 (set_attr "imm_disp" "false")])
13079 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
13080 ;; %rax as destination of the initial executable code sequence.
13081 (define_insn "tls_initial_exec_64_sun"
13082 [(set (match_operand:DI 0 "register_operand" "=a")
13084 [(match_operand 1 "tls_symbolic_operand")]
13085 UNSPEC_TLS_IE_SUN))
13086 (clobber (reg:CC FLAGS_REG))]
13087 "TARGET_64BIT && TARGET_SUN_TLS"
13090 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
13091 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
13093 [(set_attr "type" "multi")])
13095 ;; GNU2 TLS patterns can be split.
13097 (define_expand "tls_dynamic_gnu2_32"
13098 [(set (match_dup 3)
13099 (plus:SI (match_operand:SI 2 "register_operand")
13101 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
13104 [(set (match_operand:SI 0 "register_operand")
13105 (unspec:SI [(match_dup 1) (match_dup 3)
13106 (match_dup 2) (reg:SI SP_REG)]
13108 (clobber (reg:CC FLAGS_REG))])]
13109 "!TARGET_64BIT && TARGET_GNU2_TLS"
13111 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13112 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13115 (define_insn "*tls_dynamic_gnu2_lea_32"
13116 [(set (match_operand:SI 0 "register_operand" "=r")
13117 (plus:SI (match_operand:SI 1 "register_operand" "b")
13119 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
13120 UNSPEC_TLSDESC))))]
13121 "!TARGET_64BIT && TARGET_GNU2_TLS"
13122 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
13123 [(set_attr "type" "lea")
13124 (set_attr "mode" "SI")
13125 (set_attr "length" "6")
13126 (set_attr "length_address" "4")])
13128 (define_insn "*tls_dynamic_gnu2_call_32"
13129 [(set (match_operand:SI 0 "register_operand" "=a")
13130 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
13131 (match_operand:SI 2 "register_operand" "0")
13132 ;; we have to make sure %ebx still points to the GOT
13133 (match_operand:SI 3 "register_operand" "b")
13136 (clobber (reg:CC FLAGS_REG))]
13137 "!TARGET_64BIT && TARGET_GNU2_TLS"
13138 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
13139 [(set_attr "type" "call")
13140 (set_attr "length" "2")
13141 (set_attr "length_address" "0")])
13143 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
13144 [(set (match_operand:SI 0 "register_operand" "=&a")
13146 (unspec:SI [(match_operand 3 "tls_modbase_operand")
13147 (match_operand:SI 4)
13148 (match_operand:SI 2 "register_operand" "b")
13151 (const:SI (unspec:SI
13152 [(match_operand 1 "tls_symbolic_operand")]
13154 (clobber (reg:CC FLAGS_REG))]
13155 "!TARGET_64BIT && TARGET_GNU2_TLS"
13158 [(set (match_dup 0) (match_dup 5))]
13160 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13161 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
13164 (define_expand "tls_dynamic_gnu2_64"
13165 [(set (match_dup 2)
13166 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13169 [(set (match_operand:DI 0 "register_operand")
13170 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
13172 (clobber (reg:CC FLAGS_REG))])]
13173 "TARGET_64BIT && TARGET_GNU2_TLS"
13175 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13176 ix86_tls_descriptor_calls_expanded_in_cfun = true;
13179 (define_insn "*tls_dynamic_gnu2_lea_64"
13180 [(set (match_operand:DI 0 "register_operand" "=r")
13181 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
13183 "TARGET_64BIT && TARGET_GNU2_TLS"
13184 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
13185 [(set_attr "type" "lea")
13186 (set_attr "mode" "DI")
13187 (set_attr "length" "7")
13188 (set_attr "length_address" "4")])
13190 (define_insn "*tls_dynamic_gnu2_call_64"
13191 [(set (match_operand:DI 0 "register_operand" "=a")
13192 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13193 (match_operand:DI 2 "register_operand" "0")
13196 (clobber (reg:CC FLAGS_REG))]
13197 "TARGET_64BIT && TARGET_GNU2_TLS"
13198 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13199 [(set_attr "type" "call")
13200 (set_attr "length" "2")
13201 (set_attr "length_address" "0")])
13203 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13204 [(set (match_operand:DI 0 "register_operand" "=&a")
13206 (unspec:DI [(match_operand 2 "tls_modbase_operand")
13207 (match_operand:DI 3)
13210 (const:DI (unspec:DI
13211 [(match_operand 1 "tls_symbolic_operand")]
13213 (clobber (reg:CC FLAGS_REG))]
13214 "TARGET_64BIT && TARGET_GNU2_TLS"
13217 [(set (match_dup 0) (match_dup 4))]
13219 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13220 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13223 ;; These patterns match the binary 387 instructions for addM3, subM3,
13224 ;; mulM3 and divM3. There are three patterns for each of DFmode and
13225 ;; SFmode. The first is the normal insn, the second the same insn but
13226 ;; with one operand a conversion, and the third the same insn but with
13227 ;; the other operand a conversion. The conversion may be SFmode or
13228 ;; SImode if the target mode DFmode, but only SImode if the target mode
13231 ;; Gcc is slightly more smart about handling normal two address instructions
13232 ;; so use special patterns for add and mull.
13234 (define_insn "*fop_<mode>_comm_mixed"
13235 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
13236 (match_operator:MODEF 3 "binary_fp_operator"
13237 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
13238 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
13239 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13240 && COMMUTATIVE_ARITH_P (operands[3])
13241 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13242 "* return output_387_binary_op (insn, operands);"
13243 [(set (attr "type")
13244 (if_then_else (eq_attr "alternative" "1,2")
13245 (if_then_else (match_operand:MODEF 3 "mult_operator")
13246 (const_string "ssemul")
13247 (const_string "sseadd"))
13248 (if_then_else (match_operand:MODEF 3 "mult_operator")
13249 (const_string "fmul")
13250 (const_string "fop"))))
13251 (set_attr "isa" "*,noavx,avx")
13252 (set_attr "prefix" "orig,orig,vex")
13253 (set_attr "mode" "<MODE>")])
13255 (define_insn "*fop_<mode>_comm_sse"
13256 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13257 (match_operator:MODEF 3 "binary_fp_operator"
13258 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
13259 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13260 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13261 && COMMUTATIVE_ARITH_P (operands[3])
13262 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13263 "* return output_387_binary_op (insn, operands);"
13264 [(set (attr "type")
13265 (if_then_else (match_operand:MODEF 3 "mult_operator")
13266 (const_string "ssemul")
13267 (const_string "sseadd")))
13268 (set_attr "isa" "noavx,avx")
13269 (set_attr "prefix" "orig,vex")
13270 (set_attr "mode" "<MODE>")])
13272 (define_insn "*fop_<mode>_comm_i387"
13273 [(set (match_operand:MODEF 0 "register_operand" "=f")
13274 (match_operator:MODEF 3 "binary_fp_operator"
13275 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13276 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13277 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13278 && COMMUTATIVE_ARITH_P (operands[3])
13279 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13280 "* return output_387_binary_op (insn, operands);"
13281 [(set (attr "type")
13282 (if_then_else (match_operand:MODEF 3 "mult_operator")
13283 (const_string "fmul")
13284 (const_string "fop")))
13285 (set_attr "mode" "<MODE>")])
13287 (define_insn "*fop_<mode>_1_mixed"
13288 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13289 (match_operator:MODEF 3 "binary_fp_operator"
13290 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13291 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13292 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13293 && !COMMUTATIVE_ARITH_P (operands[3])
13294 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13295 "* return output_387_binary_op (insn, operands);"
13296 [(set (attr "type")
13297 (cond [(and (eq_attr "alternative" "2,3")
13298 (match_operand:MODEF 3 "mult_operator"))
13299 (const_string "ssemul")
13300 (and (eq_attr "alternative" "2,3")
13301 (match_operand:MODEF 3 "div_operator"))
13302 (const_string "ssediv")
13303 (eq_attr "alternative" "2,3")
13304 (const_string "sseadd")
13305 (match_operand:MODEF 3 "mult_operator")
13306 (const_string "fmul")
13307 (match_operand:MODEF 3 "div_operator")
13308 (const_string "fdiv")
13310 (const_string "fop")))
13311 (set_attr "isa" "*,*,noavx,avx")
13312 (set_attr "prefix" "orig,orig,orig,vex")
13313 (set_attr "mode" "<MODE>")])
13315 (define_insn "*rcpsf2_sse"
13316 [(set (match_operand:SF 0 "register_operand" "=x")
13317 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13320 "%vrcpss\t{%1, %d0|%d0, %1}"
13321 [(set_attr "type" "sse")
13322 (set_attr "atom_sse_attr" "rcp")
13323 (set_attr "prefix" "maybe_vex")
13324 (set_attr "mode" "SF")])
13326 (define_insn "*fop_<mode>_1_sse"
13327 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13328 (match_operator:MODEF 3 "binary_fp_operator"
13329 [(match_operand:MODEF 1 "register_operand" "0,x")
13330 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13331 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13332 && !COMMUTATIVE_ARITH_P (operands[3])"
13333 "* return output_387_binary_op (insn, operands);"
13334 [(set (attr "type")
13335 (cond [(match_operand:MODEF 3 "mult_operator")
13336 (const_string "ssemul")
13337 (match_operand:MODEF 3 "div_operator")
13338 (const_string "ssediv")
13340 (const_string "sseadd")))
13341 (set_attr "isa" "noavx,avx")
13342 (set_attr "prefix" "orig,vex")
13343 (set_attr "mode" "<MODE>")])
13345 ;; This pattern is not fully shadowed by the pattern above.
13346 (define_insn "*fop_<mode>_1_i387"
13347 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13348 (match_operator:MODEF 3 "binary_fp_operator"
13349 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13350 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13351 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13352 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13353 && !COMMUTATIVE_ARITH_P (operands[3])
13354 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13355 "* return output_387_binary_op (insn, operands);"
13356 [(set (attr "type")
13357 (cond [(match_operand:MODEF 3 "mult_operator")
13358 (const_string "fmul")
13359 (match_operand:MODEF 3 "div_operator")
13360 (const_string "fdiv")
13362 (const_string "fop")))
13363 (set_attr "mode" "<MODE>")])
13365 ;; ??? Add SSE splitters for these!
13366 (define_insn "*fop_<MODEF:mode>_2_i387"
13367 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13368 (match_operator:MODEF 3 "binary_fp_operator"
13370 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13371 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13372 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13373 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13374 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13375 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13376 [(set (attr "type")
13377 (cond [(match_operand:MODEF 3 "mult_operator")
13378 (const_string "fmul")
13379 (match_operand:MODEF 3 "div_operator")
13380 (const_string "fdiv")
13382 (const_string "fop")))
13383 (set_attr "fp_int_src" "true")
13384 (set_attr "mode" "<SWI24:MODE>")])
13386 (define_insn "*fop_<MODEF:mode>_3_i387"
13387 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13388 (match_operator:MODEF 3 "binary_fp_operator"
13389 [(match_operand:MODEF 1 "register_operand" "0,0")
13391 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13392 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13393 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13394 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13395 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13396 [(set (attr "type")
13397 (cond [(match_operand:MODEF 3 "mult_operator")
13398 (const_string "fmul")
13399 (match_operand:MODEF 3 "div_operator")
13400 (const_string "fdiv")
13402 (const_string "fop")))
13403 (set_attr "fp_int_src" "true")
13404 (set_attr "mode" "<MODE>")])
13406 (define_insn "*fop_df_4_i387"
13407 [(set (match_operand:DF 0 "register_operand" "=f,f")
13408 (match_operator:DF 3 "binary_fp_operator"
13410 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13411 (match_operand:DF 2 "register_operand" "0,f")]))]
13412 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13413 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13414 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13415 "* return output_387_binary_op (insn, operands);"
13416 [(set (attr "type")
13417 (cond [(match_operand:DF 3 "mult_operator")
13418 (const_string "fmul")
13419 (match_operand:DF 3 "div_operator")
13420 (const_string "fdiv")
13422 (const_string "fop")))
13423 (set_attr "mode" "SF")])
13425 (define_insn "*fop_df_5_i387"
13426 [(set (match_operand:DF 0 "register_operand" "=f,f")
13427 (match_operator:DF 3 "binary_fp_operator"
13428 [(match_operand:DF 1 "register_operand" "0,f")
13430 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13431 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13432 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13433 "* return output_387_binary_op (insn, operands);"
13434 [(set (attr "type")
13435 (cond [(match_operand:DF 3 "mult_operator")
13436 (const_string "fmul")
13437 (match_operand:DF 3 "div_operator")
13438 (const_string "fdiv")
13440 (const_string "fop")))
13441 (set_attr "mode" "SF")])
13443 (define_insn "*fop_df_6_i387"
13444 [(set (match_operand:DF 0 "register_operand" "=f,f")
13445 (match_operator:DF 3 "binary_fp_operator"
13447 (match_operand:SF 1 "register_operand" "0,f"))
13449 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13450 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13451 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13452 "* return output_387_binary_op (insn, operands);"
13453 [(set (attr "type")
13454 (cond [(match_operand:DF 3 "mult_operator")
13455 (const_string "fmul")
13456 (match_operand:DF 3 "div_operator")
13457 (const_string "fdiv")
13459 (const_string "fop")))
13460 (set_attr "mode" "SF")])
13462 (define_insn "*fop_xf_comm_i387"
13463 [(set (match_operand:XF 0 "register_operand" "=f")
13464 (match_operator:XF 3 "binary_fp_operator"
13465 [(match_operand:XF 1 "register_operand" "%0")
13466 (match_operand:XF 2 "register_operand" "f")]))]
13468 && COMMUTATIVE_ARITH_P (operands[3])"
13469 "* return output_387_binary_op (insn, operands);"
13470 [(set (attr "type")
13471 (if_then_else (match_operand:XF 3 "mult_operator")
13472 (const_string "fmul")
13473 (const_string "fop")))
13474 (set_attr "mode" "XF")])
13476 (define_insn "*fop_xf_1_i387"
13477 [(set (match_operand:XF 0 "register_operand" "=f,f")
13478 (match_operator:XF 3 "binary_fp_operator"
13479 [(match_operand:XF 1 "register_operand" "0,f")
13480 (match_operand:XF 2 "register_operand" "f,0")]))]
13482 && !COMMUTATIVE_ARITH_P (operands[3])"
13483 "* return output_387_binary_op (insn, operands);"
13484 [(set (attr "type")
13485 (cond [(match_operand:XF 3 "mult_operator")
13486 (const_string "fmul")
13487 (match_operand:XF 3 "div_operator")
13488 (const_string "fdiv")
13490 (const_string "fop")))
13491 (set_attr "mode" "XF")])
13493 (define_insn "*fop_xf_2_i387"
13494 [(set (match_operand:XF 0 "register_operand" "=f,f")
13495 (match_operator:XF 3 "binary_fp_operator"
13497 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13498 (match_operand:XF 2 "register_operand" "0,0")]))]
13499 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13500 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13501 [(set (attr "type")
13502 (cond [(match_operand:XF 3 "mult_operator")
13503 (const_string "fmul")
13504 (match_operand:XF 3 "div_operator")
13505 (const_string "fdiv")
13507 (const_string "fop")))
13508 (set_attr "fp_int_src" "true")
13509 (set_attr "mode" "<MODE>")])
13511 (define_insn "*fop_xf_3_i387"
13512 [(set (match_operand:XF 0 "register_operand" "=f,f")
13513 (match_operator:XF 3 "binary_fp_operator"
13514 [(match_operand:XF 1 "register_operand" "0,0")
13516 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13517 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13518 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13519 [(set (attr "type")
13520 (cond [(match_operand:XF 3 "mult_operator")
13521 (const_string "fmul")
13522 (match_operand:XF 3 "div_operator")
13523 (const_string "fdiv")
13525 (const_string "fop")))
13526 (set_attr "fp_int_src" "true")
13527 (set_attr "mode" "<MODE>")])
13529 (define_insn "*fop_xf_4_i387"
13530 [(set (match_operand:XF 0 "register_operand" "=f,f")
13531 (match_operator:XF 3 "binary_fp_operator"
13533 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13534 (match_operand:XF 2 "register_operand" "0,f")]))]
13536 "* return output_387_binary_op (insn, operands);"
13537 [(set (attr "type")
13538 (cond [(match_operand:XF 3 "mult_operator")
13539 (const_string "fmul")
13540 (match_operand:XF 3 "div_operator")
13541 (const_string "fdiv")
13543 (const_string "fop")))
13544 (set_attr "mode" "<MODE>")])
13546 (define_insn "*fop_xf_5_i387"
13547 [(set (match_operand:XF 0 "register_operand" "=f,f")
13548 (match_operator:XF 3 "binary_fp_operator"
13549 [(match_operand:XF 1 "register_operand" "0,f")
13551 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13553 "* return output_387_binary_op (insn, operands);"
13554 [(set (attr "type")
13555 (cond [(match_operand:XF 3 "mult_operator")
13556 (const_string "fmul")
13557 (match_operand:XF 3 "div_operator")
13558 (const_string "fdiv")
13560 (const_string "fop")))
13561 (set_attr "mode" "<MODE>")])
13563 (define_insn "*fop_xf_6_i387"
13564 [(set (match_operand:XF 0 "register_operand" "=f,f")
13565 (match_operator:XF 3 "binary_fp_operator"
13567 (match_operand:MODEF 1 "register_operand" "0,f"))
13569 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13571 "* return output_387_binary_op (insn, operands);"
13572 [(set (attr "type")
13573 (cond [(match_operand:XF 3 "mult_operator")
13574 (const_string "fmul")
13575 (match_operand:XF 3 "div_operator")
13576 (const_string "fdiv")
13578 (const_string "fop")))
13579 (set_attr "mode" "<MODE>")])
13582 [(set (match_operand 0 "register_operand")
13583 (match_operator 3 "binary_fp_operator"
13584 [(float (match_operand:SWI24 1 "register_operand"))
13585 (match_operand 2 "register_operand")]))]
13587 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13588 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13591 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13592 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13593 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13594 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13595 GET_MODE (operands[3]),
13598 ix86_free_from_memory (GET_MODE (operands[1]));
13603 [(set (match_operand 0 "register_operand")
13604 (match_operator 3 "binary_fp_operator"
13605 [(match_operand 1 "register_operand")
13606 (float (match_operand:SWI24 2 "register_operand"))]))]
13608 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13609 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13612 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13613 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13614 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13615 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13616 GET_MODE (operands[3]),
13619 ix86_free_from_memory (GET_MODE (operands[2]));
13623 ;; FPU special functions.
13625 ;; This pattern implements a no-op XFmode truncation for
13626 ;; all fancy i386 XFmode math functions.
13628 (define_insn "truncxf<mode>2_i387_noop_unspec"
13629 [(set (match_operand:MODEF 0 "register_operand" "=f")
13630 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13631 UNSPEC_TRUNC_NOOP))]
13632 "TARGET_USE_FANCY_MATH_387"
13633 "* return output_387_reg_move (insn, operands);"
13634 [(set_attr "type" "fmov")
13635 (set_attr "mode" "<MODE>")])
13637 (define_insn "sqrtxf2"
13638 [(set (match_operand:XF 0 "register_operand" "=f")
13639 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13640 "TARGET_USE_FANCY_MATH_387"
13642 [(set_attr "type" "fpspc")
13643 (set_attr "mode" "XF")
13644 (set_attr "athlon_decode" "direct")
13645 (set_attr "amdfam10_decode" "direct")
13646 (set_attr "bdver1_decode" "direct")])
13648 (define_insn "sqrt_extend<mode>xf2_i387"
13649 [(set (match_operand:XF 0 "register_operand" "=f")
13652 (match_operand:MODEF 1 "register_operand" "0"))))]
13653 "TARGET_USE_FANCY_MATH_387"
13655 [(set_attr "type" "fpspc")
13656 (set_attr "mode" "XF")
13657 (set_attr "athlon_decode" "direct")
13658 (set_attr "amdfam10_decode" "direct")
13659 (set_attr "bdver1_decode" "direct")])
13661 (define_insn "*rsqrtsf2_sse"
13662 [(set (match_operand:SF 0 "register_operand" "=x")
13663 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13666 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13667 [(set_attr "type" "sse")
13668 (set_attr "atom_sse_attr" "rcp")
13669 (set_attr "prefix" "maybe_vex")
13670 (set_attr "mode" "SF")])
13672 (define_expand "rsqrtsf2"
13673 [(set (match_operand:SF 0 "register_operand")
13674 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
13678 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13682 (define_insn "*sqrt<mode>2_sse"
13683 [(set (match_operand:MODEF 0 "register_operand" "=x")
13685 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13686 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13687 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13688 [(set_attr "type" "sse")
13689 (set_attr "atom_sse_attr" "sqrt")
13690 (set_attr "prefix" "maybe_vex")
13691 (set_attr "mode" "<MODE>")
13692 (set_attr "athlon_decode" "*")
13693 (set_attr "amdfam10_decode" "*")
13694 (set_attr "bdver1_decode" "*")])
13696 (define_expand "sqrt<mode>2"
13697 [(set (match_operand:MODEF 0 "register_operand")
13699 (match_operand:MODEF 1 "nonimmediate_operand")))]
13700 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13701 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13703 if (<MODE>mode == SFmode
13705 && TARGET_RECIP_SQRT
13706 && !optimize_function_for_size_p (cfun)
13707 && flag_finite_math_only && !flag_trapping_math
13708 && flag_unsafe_math_optimizations)
13710 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13714 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13716 rtx op0 = gen_reg_rtx (XFmode);
13717 rtx op1 = force_reg (<MODE>mode, operands[1]);
13719 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13720 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13725 (define_insn "fpremxf4_i387"
13726 [(set (match_operand:XF 0 "register_operand" "=f")
13727 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13728 (match_operand:XF 3 "register_operand" "1")]
13730 (set (match_operand:XF 1 "register_operand" "=u")
13731 (unspec:XF [(match_dup 2) (match_dup 3)]
13733 (set (reg:CCFP FPSR_REG)
13734 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13736 "TARGET_USE_FANCY_MATH_387"
13738 [(set_attr "type" "fpspc")
13739 (set_attr "mode" "XF")])
13741 (define_expand "fmodxf3"
13742 [(use (match_operand:XF 0 "register_operand"))
13743 (use (match_operand:XF 1 "general_operand"))
13744 (use (match_operand:XF 2 "general_operand"))]
13745 "TARGET_USE_FANCY_MATH_387"
13747 rtx label = gen_label_rtx ();
13749 rtx op1 = gen_reg_rtx (XFmode);
13750 rtx op2 = gen_reg_rtx (XFmode);
13752 emit_move_insn (op2, operands[2]);
13753 emit_move_insn (op1, operands[1]);
13755 emit_label (label);
13756 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13757 ix86_emit_fp_unordered_jump (label);
13758 LABEL_NUSES (label) = 1;
13760 emit_move_insn (operands[0], op1);
13764 (define_expand "fmod<mode>3"
13765 [(use (match_operand:MODEF 0 "register_operand"))
13766 (use (match_operand:MODEF 1 "general_operand"))
13767 (use (match_operand:MODEF 2 "general_operand"))]
13768 "TARGET_USE_FANCY_MATH_387"
13770 rtx (*gen_truncxf) (rtx, rtx);
13772 rtx label = gen_label_rtx ();
13774 rtx op1 = gen_reg_rtx (XFmode);
13775 rtx op2 = gen_reg_rtx (XFmode);
13777 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13778 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13780 emit_label (label);
13781 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13782 ix86_emit_fp_unordered_jump (label);
13783 LABEL_NUSES (label) = 1;
13785 /* Truncate the result properly for strict SSE math. */
13786 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13787 && !TARGET_MIX_SSE_I387)
13788 gen_truncxf = gen_truncxf<mode>2;
13790 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13792 emit_insn (gen_truncxf (operands[0], op1));
13796 (define_insn "fprem1xf4_i387"
13797 [(set (match_operand:XF 0 "register_operand" "=f")
13798 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13799 (match_operand:XF 3 "register_operand" "1")]
13801 (set (match_operand:XF 1 "register_operand" "=u")
13802 (unspec:XF [(match_dup 2) (match_dup 3)]
13804 (set (reg:CCFP FPSR_REG)
13805 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13807 "TARGET_USE_FANCY_MATH_387"
13809 [(set_attr "type" "fpspc")
13810 (set_attr "mode" "XF")])
13812 (define_expand "remainderxf3"
13813 [(use (match_operand:XF 0 "register_operand"))
13814 (use (match_operand:XF 1 "general_operand"))
13815 (use (match_operand:XF 2 "general_operand"))]
13816 "TARGET_USE_FANCY_MATH_387"
13818 rtx label = gen_label_rtx ();
13820 rtx op1 = gen_reg_rtx (XFmode);
13821 rtx op2 = gen_reg_rtx (XFmode);
13823 emit_move_insn (op2, operands[2]);
13824 emit_move_insn (op1, operands[1]);
13826 emit_label (label);
13827 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13828 ix86_emit_fp_unordered_jump (label);
13829 LABEL_NUSES (label) = 1;
13831 emit_move_insn (operands[0], op1);
13835 (define_expand "remainder<mode>3"
13836 [(use (match_operand:MODEF 0 "register_operand"))
13837 (use (match_operand:MODEF 1 "general_operand"))
13838 (use (match_operand:MODEF 2 "general_operand"))]
13839 "TARGET_USE_FANCY_MATH_387"
13841 rtx (*gen_truncxf) (rtx, rtx);
13843 rtx label = gen_label_rtx ();
13845 rtx op1 = gen_reg_rtx (XFmode);
13846 rtx op2 = gen_reg_rtx (XFmode);
13848 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13849 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13851 emit_label (label);
13853 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13854 ix86_emit_fp_unordered_jump (label);
13855 LABEL_NUSES (label) = 1;
13857 /* Truncate the result properly for strict SSE math. */
13858 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13859 && !TARGET_MIX_SSE_I387)
13860 gen_truncxf = gen_truncxf<mode>2;
13862 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13864 emit_insn (gen_truncxf (operands[0], op1));
13868 (define_int_iterator SINCOS
13872 (define_int_attr sincos
13873 [(UNSPEC_SIN "sin")
13874 (UNSPEC_COS "cos")])
13876 (define_insn "*<sincos>xf2_i387"
13877 [(set (match_operand:XF 0 "register_operand" "=f")
13878 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13880 "TARGET_USE_FANCY_MATH_387
13881 && flag_unsafe_math_optimizations"
13883 [(set_attr "type" "fpspc")
13884 (set_attr "mode" "XF")])
13886 (define_insn "*<sincos>_extend<mode>xf2_i387"
13887 [(set (match_operand:XF 0 "register_operand" "=f")
13888 (unspec:XF [(float_extend:XF
13889 (match_operand:MODEF 1 "register_operand" "0"))]
13891 "TARGET_USE_FANCY_MATH_387
13892 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13893 || TARGET_MIX_SSE_I387)
13894 && flag_unsafe_math_optimizations"
13896 [(set_attr "type" "fpspc")
13897 (set_attr "mode" "XF")])
13899 ;; When sincos pattern is defined, sin and cos builtin functions will be
13900 ;; expanded to sincos pattern with one of its outputs left unused.
13901 ;; CSE pass will figure out if two sincos patterns can be combined,
13902 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13903 ;; depending on the unused output.
13905 (define_insn "sincosxf3"
13906 [(set (match_operand:XF 0 "register_operand" "=f")
13907 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13908 UNSPEC_SINCOS_COS))
13909 (set (match_operand:XF 1 "register_operand" "=u")
13910 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13911 "TARGET_USE_FANCY_MATH_387
13912 && flag_unsafe_math_optimizations"
13914 [(set_attr "type" "fpspc")
13915 (set_attr "mode" "XF")])
13918 [(set (match_operand:XF 0 "register_operand")
13919 (unspec:XF [(match_operand:XF 2 "register_operand")]
13920 UNSPEC_SINCOS_COS))
13921 (set (match_operand:XF 1 "register_operand")
13922 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13923 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13924 && can_create_pseudo_p ()"
13925 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13928 [(set (match_operand:XF 0 "register_operand")
13929 (unspec:XF [(match_operand:XF 2 "register_operand")]
13930 UNSPEC_SINCOS_COS))
13931 (set (match_operand:XF 1 "register_operand")
13932 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13933 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13934 && can_create_pseudo_p ()"
13935 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13937 (define_insn "sincos_extend<mode>xf3_i387"
13938 [(set (match_operand:XF 0 "register_operand" "=f")
13939 (unspec:XF [(float_extend:XF
13940 (match_operand:MODEF 2 "register_operand" "0"))]
13941 UNSPEC_SINCOS_COS))
13942 (set (match_operand:XF 1 "register_operand" "=u")
13943 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13944 "TARGET_USE_FANCY_MATH_387
13945 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13946 || TARGET_MIX_SSE_I387)
13947 && flag_unsafe_math_optimizations"
13949 [(set_attr "type" "fpspc")
13950 (set_attr "mode" "XF")])
13953 [(set (match_operand:XF 0 "register_operand")
13954 (unspec:XF [(float_extend:XF
13955 (match_operand:MODEF 2 "register_operand"))]
13956 UNSPEC_SINCOS_COS))
13957 (set (match_operand:XF 1 "register_operand")
13958 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13959 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13960 && can_create_pseudo_p ()"
13961 [(set (match_dup 1)
13962 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13965 [(set (match_operand:XF 0 "register_operand")
13966 (unspec:XF [(float_extend:XF
13967 (match_operand:MODEF 2 "register_operand"))]
13968 UNSPEC_SINCOS_COS))
13969 (set (match_operand:XF 1 "register_operand")
13970 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13971 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13972 && can_create_pseudo_p ()"
13973 [(set (match_dup 0)
13974 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13976 (define_expand "sincos<mode>3"
13977 [(use (match_operand:MODEF 0 "register_operand"))
13978 (use (match_operand:MODEF 1 "register_operand"))
13979 (use (match_operand:MODEF 2 "register_operand"))]
13980 "TARGET_USE_FANCY_MATH_387
13981 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13982 || TARGET_MIX_SSE_I387)
13983 && flag_unsafe_math_optimizations"
13985 rtx op0 = gen_reg_rtx (XFmode);
13986 rtx op1 = gen_reg_rtx (XFmode);
13988 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13989 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13990 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13994 (define_insn "fptanxf4_i387"
13995 [(set (match_operand:XF 0 "register_operand" "=f")
13996 (match_operand:XF 3 "const_double_operand" "F"))
13997 (set (match_operand:XF 1 "register_operand" "=u")
13998 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14000 "TARGET_USE_FANCY_MATH_387
14001 && flag_unsafe_math_optimizations
14002 && standard_80387_constant_p (operands[3]) == 2"
14004 [(set_attr "type" "fpspc")
14005 (set_attr "mode" "XF")])
14007 (define_insn "fptan_extend<mode>xf4_i387"
14008 [(set (match_operand:MODEF 0 "register_operand" "=f")
14009 (match_operand:MODEF 3 "const_double_operand" "F"))
14010 (set (match_operand:XF 1 "register_operand" "=u")
14011 (unspec:XF [(float_extend:XF
14012 (match_operand:MODEF 2 "register_operand" "0"))]
14014 "TARGET_USE_FANCY_MATH_387
14015 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14016 || TARGET_MIX_SSE_I387)
14017 && flag_unsafe_math_optimizations
14018 && standard_80387_constant_p (operands[3]) == 2"
14020 [(set_attr "type" "fpspc")
14021 (set_attr "mode" "XF")])
14023 (define_expand "tanxf2"
14024 [(use (match_operand:XF 0 "register_operand"))
14025 (use (match_operand:XF 1 "register_operand"))]
14026 "TARGET_USE_FANCY_MATH_387
14027 && flag_unsafe_math_optimizations"
14029 rtx one = gen_reg_rtx (XFmode);
14030 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
14032 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
14036 (define_expand "tan<mode>2"
14037 [(use (match_operand:MODEF 0 "register_operand"))
14038 (use (match_operand:MODEF 1 "register_operand"))]
14039 "TARGET_USE_FANCY_MATH_387
14040 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14041 || TARGET_MIX_SSE_I387)
14042 && flag_unsafe_math_optimizations"
14044 rtx op0 = gen_reg_rtx (XFmode);
14046 rtx one = gen_reg_rtx (<MODE>mode);
14047 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
14049 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
14050 operands[1], op2));
14051 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14055 (define_insn "*fpatanxf3_i387"
14056 [(set (match_operand:XF 0 "register_operand" "=f")
14057 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14058 (match_operand:XF 2 "register_operand" "u")]
14060 (clobber (match_scratch:XF 3 "=2"))]
14061 "TARGET_USE_FANCY_MATH_387
14062 && flag_unsafe_math_optimizations"
14064 [(set_attr "type" "fpspc")
14065 (set_attr "mode" "XF")])
14067 (define_insn "fpatan_extend<mode>xf3_i387"
14068 [(set (match_operand:XF 0 "register_operand" "=f")
14069 (unspec:XF [(float_extend:XF
14070 (match_operand:MODEF 1 "register_operand" "0"))
14072 (match_operand:MODEF 2 "register_operand" "u"))]
14074 (clobber (match_scratch:XF 3 "=2"))]
14075 "TARGET_USE_FANCY_MATH_387
14076 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14077 || TARGET_MIX_SSE_I387)
14078 && flag_unsafe_math_optimizations"
14080 [(set_attr "type" "fpspc")
14081 (set_attr "mode" "XF")])
14083 (define_expand "atan2xf3"
14084 [(parallel [(set (match_operand:XF 0 "register_operand")
14085 (unspec:XF [(match_operand:XF 2 "register_operand")
14086 (match_operand:XF 1 "register_operand")]
14088 (clobber (match_scratch:XF 3))])]
14089 "TARGET_USE_FANCY_MATH_387
14090 && flag_unsafe_math_optimizations")
14092 (define_expand "atan2<mode>3"
14093 [(use (match_operand:MODEF 0 "register_operand"))
14094 (use (match_operand:MODEF 1 "register_operand"))
14095 (use (match_operand:MODEF 2 "register_operand"))]
14096 "TARGET_USE_FANCY_MATH_387
14097 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14098 || TARGET_MIX_SSE_I387)
14099 && flag_unsafe_math_optimizations"
14101 rtx op0 = gen_reg_rtx (XFmode);
14103 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
14104 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14108 (define_expand "atanxf2"
14109 [(parallel [(set (match_operand:XF 0 "register_operand")
14110 (unspec:XF [(match_dup 2)
14111 (match_operand:XF 1 "register_operand")]
14113 (clobber (match_scratch:XF 3))])]
14114 "TARGET_USE_FANCY_MATH_387
14115 && flag_unsafe_math_optimizations"
14117 operands[2] = gen_reg_rtx (XFmode);
14118 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14121 (define_expand "atan<mode>2"
14122 [(use (match_operand:MODEF 0 "register_operand"))
14123 (use (match_operand:MODEF 1 "register_operand"))]
14124 "TARGET_USE_FANCY_MATH_387
14125 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14126 || TARGET_MIX_SSE_I387)
14127 && flag_unsafe_math_optimizations"
14129 rtx op0 = gen_reg_rtx (XFmode);
14131 rtx op2 = gen_reg_rtx (<MODE>mode);
14132 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
14134 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
14135 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14139 (define_expand "asinxf2"
14140 [(set (match_dup 2)
14141 (mult:XF (match_operand:XF 1 "register_operand")
14143 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14144 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14145 (parallel [(set (match_operand:XF 0 "register_operand")
14146 (unspec:XF [(match_dup 5) (match_dup 1)]
14148 (clobber (match_scratch:XF 6))])]
14149 "TARGET_USE_FANCY_MATH_387
14150 && flag_unsafe_math_optimizations"
14154 if (optimize_insn_for_size_p ())
14157 for (i = 2; i < 6; i++)
14158 operands[i] = gen_reg_rtx (XFmode);
14160 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14163 (define_expand "asin<mode>2"
14164 [(use (match_operand:MODEF 0 "register_operand"))
14165 (use (match_operand:MODEF 1 "general_operand"))]
14166 "TARGET_USE_FANCY_MATH_387
14167 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14168 || TARGET_MIX_SSE_I387)
14169 && flag_unsafe_math_optimizations"
14171 rtx op0 = gen_reg_rtx (XFmode);
14172 rtx op1 = gen_reg_rtx (XFmode);
14174 if (optimize_insn_for_size_p ())
14177 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14178 emit_insn (gen_asinxf2 (op0, op1));
14179 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14183 (define_expand "acosxf2"
14184 [(set (match_dup 2)
14185 (mult:XF (match_operand:XF 1 "register_operand")
14187 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14188 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14189 (parallel [(set (match_operand:XF 0 "register_operand")
14190 (unspec:XF [(match_dup 1) (match_dup 5)]
14192 (clobber (match_scratch:XF 6))])]
14193 "TARGET_USE_FANCY_MATH_387
14194 && flag_unsafe_math_optimizations"
14198 if (optimize_insn_for_size_p ())
14201 for (i = 2; i < 6; i++)
14202 operands[i] = gen_reg_rtx (XFmode);
14204 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14207 (define_expand "acos<mode>2"
14208 [(use (match_operand:MODEF 0 "register_operand"))
14209 (use (match_operand:MODEF 1 "general_operand"))]
14210 "TARGET_USE_FANCY_MATH_387
14211 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14212 || TARGET_MIX_SSE_I387)
14213 && flag_unsafe_math_optimizations"
14215 rtx op0 = gen_reg_rtx (XFmode);
14216 rtx op1 = gen_reg_rtx (XFmode);
14218 if (optimize_insn_for_size_p ())
14221 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14222 emit_insn (gen_acosxf2 (op0, op1));
14223 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14227 (define_insn "fyl2xxf3_i387"
14228 [(set (match_operand:XF 0 "register_operand" "=f")
14229 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14230 (match_operand:XF 2 "register_operand" "u")]
14232 (clobber (match_scratch:XF 3 "=2"))]
14233 "TARGET_USE_FANCY_MATH_387
14234 && flag_unsafe_math_optimizations"
14236 [(set_attr "type" "fpspc")
14237 (set_attr "mode" "XF")])
14239 (define_insn "fyl2x_extend<mode>xf3_i387"
14240 [(set (match_operand:XF 0 "register_operand" "=f")
14241 (unspec:XF [(float_extend:XF
14242 (match_operand:MODEF 1 "register_operand" "0"))
14243 (match_operand:XF 2 "register_operand" "u")]
14245 (clobber (match_scratch:XF 3 "=2"))]
14246 "TARGET_USE_FANCY_MATH_387
14247 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14248 || TARGET_MIX_SSE_I387)
14249 && flag_unsafe_math_optimizations"
14251 [(set_attr "type" "fpspc")
14252 (set_attr "mode" "XF")])
14254 (define_expand "logxf2"
14255 [(parallel [(set (match_operand:XF 0 "register_operand")
14256 (unspec:XF [(match_operand:XF 1 "register_operand")
14257 (match_dup 2)] UNSPEC_FYL2X))
14258 (clobber (match_scratch:XF 3))])]
14259 "TARGET_USE_FANCY_MATH_387
14260 && flag_unsafe_math_optimizations"
14262 operands[2] = gen_reg_rtx (XFmode);
14263 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14266 (define_expand "log<mode>2"
14267 [(use (match_operand:MODEF 0 "register_operand"))
14268 (use (match_operand:MODEF 1 "register_operand"))]
14269 "TARGET_USE_FANCY_MATH_387
14270 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14271 || TARGET_MIX_SSE_I387)
14272 && flag_unsafe_math_optimizations"
14274 rtx op0 = gen_reg_rtx (XFmode);
14276 rtx op2 = gen_reg_rtx (XFmode);
14277 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14279 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14280 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14284 (define_expand "log10xf2"
14285 [(parallel [(set (match_operand:XF 0 "register_operand")
14286 (unspec:XF [(match_operand:XF 1 "register_operand")
14287 (match_dup 2)] UNSPEC_FYL2X))
14288 (clobber (match_scratch:XF 3))])]
14289 "TARGET_USE_FANCY_MATH_387
14290 && flag_unsafe_math_optimizations"
14292 operands[2] = gen_reg_rtx (XFmode);
14293 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14296 (define_expand "log10<mode>2"
14297 [(use (match_operand:MODEF 0 "register_operand"))
14298 (use (match_operand:MODEF 1 "register_operand"))]
14299 "TARGET_USE_FANCY_MATH_387
14300 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14301 || TARGET_MIX_SSE_I387)
14302 && flag_unsafe_math_optimizations"
14304 rtx op0 = gen_reg_rtx (XFmode);
14306 rtx op2 = gen_reg_rtx (XFmode);
14307 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14309 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14310 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14314 (define_expand "log2xf2"
14315 [(parallel [(set (match_operand:XF 0 "register_operand")
14316 (unspec:XF [(match_operand:XF 1 "register_operand")
14317 (match_dup 2)] UNSPEC_FYL2X))
14318 (clobber (match_scratch:XF 3))])]
14319 "TARGET_USE_FANCY_MATH_387
14320 && flag_unsafe_math_optimizations"
14322 operands[2] = gen_reg_rtx (XFmode);
14323 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14326 (define_expand "log2<mode>2"
14327 [(use (match_operand:MODEF 0 "register_operand"))
14328 (use (match_operand:MODEF 1 "register_operand"))]
14329 "TARGET_USE_FANCY_MATH_387
14330 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14331 || TARGET_MIX_SSE_I387)
14332 && flag_unsafe_math_optimizations"
14334 rtx op0 = gen_reg_rtx (XFmode);
14336 rtx op2 = gen_reg_rtx (XFmode);
14337 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14339 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14340 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14344 (define_insn "fyl2xp1xf3_i387"
14345 [(set (match_operand:XF 0 "register_operand" "=f")
14346 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14347 (match_operand:XF 2 "register_operand" "u")]
14349 (clobber (match_scratch:XF 3 "=2"))]
14350 "TARGET_USE_FANCY_MATH_387
14351 && flag_unsafe_math_optimizations"
14353 [(set_attr "type" "fpspc")
14354 (set_attr "mode" "XF")])
14356 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14357 [(set (match_operand:XF 0 "register_operand" "=f")
14358 (unspec:XF [(float_extend:XF
14359 (match_operand:MODEF 1 "register_operand" "0"))
14360 (match_operand:XF 2 "register_operand" "u")]
14362 (clobber (match_scratch:XF 3 "=2"))]
14363 "TARGET_USE_FANCY_MATH_387
14364 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14365 || TARGET_MIX_SSE_I387)
14366 && flag_unsafe_math_optimizations"
14368 [(set_attr "type" "fpspc")
14369 (set_attr "mode" "XF")])
14371 (define_expand "log1pxf2"
14372 [(use (match_operand:XF 0 "register_operand"))
14373 (use (match_operand:XF 1 "register_operand"))]
14374 "TARGET_USE_FANCY_MATH_387
14375 && flag_unsafe_math_optimizations"
14377 if (optimize_insn_for_size_p ())
14380 ix86_emit_i387_log1p (operands[0], operands[1]);
14384 (define_expand "log1p<mode>2"
14385 [(use (match_operand:MODEF 0 "register_operand"))
14386 (use (match_operand:MODEF 1 "register_operand"))]
14387 "TARGET_USE_FANCY_MATH_387
14388 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14389 || TARGET_MIX_SSE_I387)
14390 && flag_unsafe_math_optimizations"
14394 if (optimize_insn_for_size_p ())
14397 op0 = gen_reg_rtx (XFmode);
14399 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14401 ix86_emit_i387_log1p (op0, operands[1]);
14402 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14406 (define_insn "fxtractxf3_i387"
14407 [(set (match_operand:XF 0 "register_operand" "=f")
14408 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14409 UNSPEC_XTRACT_FRACT))
14410 (set (match_operand:XF 1 "register_operand" "=u")
14411 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14412 "TARGET_USE_FANCY_MATH_387
14413 && flag_unsafe_math_optimizations"
14415 [(set_attr "type" "fpspc")
14416 (set_attr "mode" "XF")])
14418 (define_insn "fxtract_extend<mode>xf3_i387"
14419 [(set (match_operand:XF 0 "register_operand" "=f")
14420 (unspec:XF [(float_extend:XF
14421 (match_operand:MODEF 2 "register_operand" "0"))]
14422 UNSPEC_XTRACT_FRACT))
14423 (set (match_operand:XF 1 "register_operand" "=u")
14424 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14425 "TARGET_USE_FANCY_MATH_387
14426 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14427 || TARGET_MIX_SSE_I387)
14428 && flag_unsafe_math_optimizations"
14430 [(set_attr "type" "fpspc")
14431 (set_attr "mode" "XF")])
14433 (define_expand "logbxf2"
14434 [(parallel [(set (match_dup 2)
14435 (unspec:XF [(match_operand:XF 1 "register_operand")]
14436 UNSPEC_XTRACT_FRACT))
14437 (set (match_operand:XF 0 "register_operand")
14438 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14439 "TARGET_USE_FANCY_MATH_387
14440 && flag_unsafe_math_optimizations"
14441 "operands[2] = gen_reg_rtx (XFmode);")
14443 (define_expand "logb<mode>2"
14444 [(use (match_operand:MODEF 0 "register_operand"))
14445 (use (match_operand:MODEF 1 "register_operand"))]
14446 "TARGET_USE_FANCY_MATH_387
14447 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14448 || TARGET_MIX_SSE_I387)
14449 && flag_unsafe_math_optimizations"
14451 rtx op0 = gen_reg_rtx (XFmode);
14452 rtx op1 = gen_reg_rtx (XFmode);
14454 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14455 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14459 (define_expand "ilogbxf2"
14460 [(use (match_operand:SI 0 "register_operand"))
14461 (use (match_operand:XF 1 "register_operand"))]
14462 "TARGET_USE_FANCY_MATH_387
14463 && flag_unsafe_math_optimizations"
14467 if (optimize_insn_for_size_p ())
14470 op0 = gen_reg_rtx (XFmode);
14471 op1 = gen_reg_rtx (XFmode);
14473 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14474 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14478 (define_expand "ilogb<mode>2"
14479 [(use (match_operand:SI 0 "register_operand"))
14480 (use (match_operand:MODEF 1 "register_operand"))]
14481 "TARGET_USE_FANCY_MATH_387
14482 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14483 || TARGET_MIX_SSE_I387)
14484 && flag_unsafe_math_optimizations"
14488 if (optimize_insn_for_size_p ())
14491 op0 = gen_reg_rtx (XFmode);
14492 op1 = gen_reg_rtx (XFmode);
14494 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14495 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14499 (define_insn "*f2xm1xf2_i387"
14500 [(set (match_operand:XF 0 "register_operand" "=f")
14501 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14503 "TARGET_USE_FANCY_MATH_387
14504 && flag_unsafe_math_optimizations"
14506 [(set_attr "type" "fpspc")
14507 (set_attr "mode" "XF")])
14509 (define_insn "*fscalexf4_i387"
14510 [(set (match_operand:XF 0 "register_operand" "=f")
14511 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14512 (match_operand:XF 3 "register_operand" "1")]
14513 UNSPEC_FSCALE_FRACT))
14514 (set (match_operand:XF 1 "register_operand" "=u")
14515 (unspec:XF [(match_dup 2) (match_dup 3)]
14516 UNSPEC_FSCALE_EXP))]
14517 "TARGET_USE_FANCY_MATH_387
14518 && flag_unsafe_math_optimizations"
14520 [(set_attr "type" "fpspc")
14521 (set_attr "mode" "XF")])
14523 (define_expand "expNcorexf3"
14524 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14525 (match_operand:XF 2 "register_operand")))
14526 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14527 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14528 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14529 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14530 (parallel [(set (match_operand:XF 0 "register_operand")
14531 (unspec:XF [(match_dup 8) (match_dup 4)]
14532 UNSPEC_FSCALE_FRACT))
14534 (unspec:XF [(match_dup 8) (match_dup 4)]
14535 UNSPEC_FSCALE_EXP))])]
14536 "TARGET_USE_FANCY_MATH_387
14537 && flag_unsafe_math_optimizations"
14541 if (optimize_insn_for_size_p ())
14544 for (i = 3; i < 10; i++)
14545 operands[i] = gen_reg_rtx (XFmode);
14547 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14550 (define_expand "expxf2"
14551 [(use (match_operand:XF 0 "register_operand"))
14552 (use (match_operand:XF 1 "register_operand"))]
14553 "TARGET_USE_FANCY_MATH_387
14554 && flag_unsafe_math_optimizations"
14558 if (optimize_insn_for_size_p ())
14561 op2 = gen_reg_rtx (XFmode);
14562 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14564 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14568 (define_expand "exp<mode>2"
14569 [(use (match_operand:MODEF 0 "register_operand"))
14570 (use (match_operand:MODEF 1 "general_operand"))]
14571 "TARGET_USE_FANCY_MATH_387
14572 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14573 || TARGET_MIX_SSE_I387)
14574 && flag_unsafe_math_optimizations"
14578 if (optimize_insn_for_size_p ())
14581 op0 = gen_reg_rtx (XFmode);
14582 op1 = gen_reg_rtx (XFmode);
14584 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14585 emit_insn (gen_expxf2 (op0, op1));
14586 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14590 (define_expand "exp10xf2"
14591 [(use (match_operand:XF 0 "register_operand"))
14592 (use (match_operand:XF 1 "register_operand"))]
14593 "TARGET_USE_FANCY_MATH_387
14594 && flag_unsafe_math_optimizations"
14598 if (optimize_insn_for_size_p ())
14601 op2 = gen_reg_rtx (XFmode);
14602 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14604 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14608 (define_expand "exp10<mode>2"
14609 [(use (match_operand:MODEF 0 "register_operand"))
14610 (use (match_operand:MODEF 1 "general_operand"))]
14611 "TARGET_USE_FANCY_MATH_387
14612 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14613 || TARGET_MIX_SSE_I387)
14614 && flag_unsafe_math_optimizations"
14618 if (optimize_insn_for_size_p ())
14621 op0 = gen_reg_rtx (XFmode);
14622 op1 = gen_reg_rtx (XFmode);
14624 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14625 emit_insn (gen_exp10xf2 (op0, op1));
14626 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14630 (define_expand "exp2xf2"
14631 [(use (match_operand:XF 0 "register_operand"))
14632 (use (match_operand:XF 1 "register_operand"))]
14633 "TARGET_USE_FANCY_MATH_387
14634 && flag_unsafe_math_optimizations"
14638 if (optimize_insn_for_size_p ())
14641 op2 = gen_reg_rtx (XFmode);
14642 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14644 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14648 (define_expand "exp2<mode>2"
14649 [(use (match_operand:MODEF 0 "register_operand"))
14650 (use (match_operand:MODEF 1 "general_operand"))]
14651 "TARGET_USE_FANCY_MATH_387
14652 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14653 || TARGET_MIX_SSE_I387)
14654 && flag_unsafe_math_optimizations"
14658 if (optimize_insn_for_size_p ())
14661 op0 = gen_reg_rtx (XFmode);
14662 op1 = gen_reg_rtx (XFmode);
14664 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14665 emit_insn (gen_exp2xf2 (op0, op1));
14666 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14670 (define_expand "expm1xf2"
14671 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14673 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14674 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14675 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14676 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14677 (parallel [(set (match_dup 7)
14678 (unspec:XF [(match_dup 6) (match_dup 4)]
14679 UNSPEC_FSCALE_FRACT))
14681 (unspec:XF [(match_dup 6) (match_dup 4)]
14682 UNSPEC_FSCALE_EXP))])
14683 (parallel [(set (match_dup 10)
14684 (unspec:XF [(match_dup 9) (match_dup 8)]
14685 UNSPEC_FSCALE_FRACT))
14686 (set (match_dup 11)
14687 (unspec:XF [(match_dup 9) (match_dup 8)]
14688 UNSPEC_FSCALE_EXP))])
14689 (set (match_dup 12) (minus:XF (match_dup 10)
14690 (float_extend:XF (match_dup 13))))
14691 (set (match_operand:XF 0 "register_operand")
14692 (plus:XF (match_dup 12) (match_dup 7)))]
14693 "TARGET_USE_FANCY_MATH_387
14694 && flag_unsafe_math_optimizations"
14698 if (optimize_insn_for_size_p ())
14701 for (i = 2; i < 13; i++)
14702 operands[i] = gen_reg_rtx (XFmode);
14705 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14707 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14710 (define_expand "expm1<mode>2"
14711 [(use (match_operand:MODEF 0 "register_operand"))
14712 (use (match_operand:MODEF 1 "general_operand"))]
14713 "TARGET_USE_FANCY_MATH_387
14714 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14715 || TARGET_MIX_SSE_I387)
14716 && flag_unsafe_math_optimizations"
14720 if (optimize_insn_for_size_p ())
14723 op0 = gen_reg_rtx (XFmode);
14724 op1 = gen_reg_rtx (XFmode);
14726 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14727 emit_insn (gen_expm1xf2 (op0, op1));
14728 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14732 (define_expand "ldexpxf3"
14733 [(set (match_dup 3)
14734 (float:XF (match_operand:SI 2 "register_operand")))
14735 (parallel [(set (match_operand:XF 0 " register_operand")
14736 (unspec:XF [(match_operand:XF 1 "register_operand")
14738 UNSPEC_FSCALE_FRACT))
14740 (unspec:XF [(match_dup 1) (match_dup 3)]
14741 UNSPEC_FSCALE_EXP))])]
14742 "TARGET_USE_FANCY_MATH_387
14743 && flag_unsafe_math_optimizations"
14745 if (optimize_insn_for_size_p ())
14748 operands[3] = gen_reg_rtx (XFmode);
14749 operands[4] = gen_reg_rtx (XFmode);
14752 (define_expand "ldexp<mode>3"
14753 [(use (match_operand:MODEF 0 "register_operand"))
14754 (use (match_operand:MODEF 1 "general_operand"))
14755 (use (match_operand:SI 2 "register_operand"))]
14756 "TARGET_USE_FANCY_MATH_387
14757 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14758 || TARGET_MIX_SSE_I387)
14759 && flag_unsafe_math_optimizations"
14763 if (optimize_insn_for_size_p ())
14766 op0 = gen_reg_rtx (XFmode);
14767 op1 = gen_reg_rtx (XFmode);
14769 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14770 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14771 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14775 (define_expand "scalbxf3"
14776 [(parallel [(set (match_operand:XF 0 " register_operand")
14777 (unspec:XF [(match_operand:XF 1 "register_operand")
14778 (match_operand:XF 2 "register_operand")]
14779 UNSPEC_FSCALE_FRACT))
14781 (unspec:XF [(match_dup 1) (match_dup 2)]
14782 UNSPEC_FSCALE_EXP))])]
14783 "TARGET_USE_FANCY_MATH_387
14784 && flag_unsafe_math_optimizations"
14786 if (optimize_insn_for_size_p ())
14789 operands[3] = gen_reg_rtx (XFmode);
14792 (define_expand "scalb<mode>3"
14793 [(use (match_operand:MODEF 0 "register_operand"))
14794 (use (match_operand:MODEF 1 "general_operand"))
14795 (use (match_operand:MODEF 2 "general_operand"))]
14796 "TARGET_USE_FANCY_MATH_387
14797 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14798 || TARGET_MIX_SSE_I387)
14799 && flag_unsafe_math_optimizations"
14803 if (optimize_insn_for_size_p ())
14806 op0 = gen_reg_rtx (XFmode);
14807 op1 = gen_reg_rtx (XFmode);
14808 op2 = gen_reg_rtx (XFmode);
14810 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14811 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14812 emit_insn (gen_scalbxf3 (op0, op1, op2));
14813 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14817 (define_expand "significandxf2"
14818 [(parallel [(set (match_operand:XF 0 "register_operand")
14819 (unspec:XF [(match_operand:XF 1 "register_operand")]
14820 UNSPEC_XTRACT_FRACT))
14822 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14823 "TARGET_USE_FANCY_MATH_387
14824 && flag_unsafe_math_optimizations"
14825 "operands[2] = gen_reg_rtx (XFmode);")
14827 (define_expand "significand<mode>2"
14828 [(use (match_operand:MODEF 0 "register_operand"))
14829 (use (match_operand:MODEF 1 "register_operand"))]
14830 "TARGET_USE_FANCY_MATH_387
14831 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14832 || TARGET_MIX_SSE_I387)
14833 && flag_unsafe_math_optimizations"
14835 rtx op0 = gen_reg_rtx (XFmode);
14836 rtx op1 = gen_reg_rtx (XFmode);
14838 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14839 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14844 (define_insn "sse4_1_round<mode>2"
14845 [(set (match_operand:MODEF 0 "register_operand" "=x")
14846 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14847 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14850 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14851 [(set_attr "type" "ssecvt")
14852 (set_attr "prefix_extra" "1")
14853 (set_attr "prefix" "maybe_vex")
14854 (set_attr "mode" "<MODE>")])
14856 (define_insn "rintxf2"
14857 [(set (match_operand:XF 0 "register_operand" "=f")
14858 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14860 "TARGET_USE_FANCY_MATH_387
14861 && flag_unsafe_math_optimizations"
14863 [(set_attr "type" "fpspc")
14864 (set_attr "mode" "XF")])
14866 (define_expand "rint<mode>2"
14867 [(use (match_operand:MODEF 0 "register_operand"))
14868 (use (match_operand:MODEF 1 "register_operand"))]
14869 "(TARGET_USE_FANCY_MATH_387
14870 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14871 || TARGET_MIX_SSE_I387)
14872 && flag_unsafe_math_optimizations)
14873 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14874 && !flag_trapping_math)"
14876 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14877 && !flag_trapping_math)
14880 emit_insn (gen_sse4_1_round<mode>2
14881 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14882 else if (optimize_insn_for_size_p ())
14885 ix86_expand_rint (operands[0], operands[1]);
14889 rtx op0 = gen_reg_rtx (XFmode);
14890 rtx op1 = gen_reg_rtx (XFmode);
14892 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14893 emit_insn (gen_rintxf2 (op0, op1));
14895 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14900 (define_expand "round<mode>2"
14901 [(match_operand:X87MODEF 0 "register_operand")
14902 (match_operand:X87MODEF 1 "nonimmediate_operand")]
14903 "(TARGET_USE_FANCY_MATH_387
14904 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14905 || TARGET_MIX_SSE_I387)
14906 && flag_unsafe_math_optimizations)
14907 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14908 && !flag_trapping_math && !flag_rounding_math)"
14910 if (optimize_insn_for_size_p ())
14913 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14914 && !flag_trapping_math && !flag_rounding_math)
14918 operands[1] = force_reg (<MODE>mode, operands[1]);
14919 ix86_expand_round_sse4 (operands[0], operands[1]);
14921 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14922 ix86_expand_round (operands[0], operands[1]);
14924 ix86_expand_rounddf_32 (operands[0], operands[1]);
14928 operands[1] = force_reg (<MODE>mode, operands[1]);
14929 ix86_emit_i387_round (operands[0], operands[1]);
14934 (define_insn_and_split "*fistdi2_1"
14935 [(set (match_operand:DI 0 "nonimmediate_operand")
14936 (unspec:DI [(match_operand:XF 1 "register_operand")]
14938 "TARGET_USE_FANCY_MATH_387
14939 && can_create_pseudo_p ()"
14944 if (memory_operand (operands[0], VOIDmode))
14945 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14948 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14949 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14954 [(set_attr "type" "fpspc")
14955 (set_attr "mode" "DI")])
14957 (define_insn "fistdi2"
14958 [(set (match_operand:DI 0 "memory_operand" "=m")
14959 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14961 (clobber (match_scratch:XF 2 "=&1f"))]
14962 "TARGET_USE_FANCY_MATH_387"
14963 "* return output_fix_trunc (insn, operands, false);"
14964 [(set_attr "type" "fpspc")
14965 (set_attr "mode" "DI")])
14967 (define_insn "fistdi2_with_temp"
14968 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14969 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14971 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14972 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14973 "TARGET_USE_FANCY_MATH_387"
14975 [(set_attr "type" "fpspc")
14976 (set_attr "mode" "DI")])
14979 [(set (match_operand:DI 0 "register_operand")
14980 (unspec:DI [(match_operand:XF 1 "register_operand")]
14982 (clobber (match_operand:DI 2 "memory_operand"))
14983 (clobber (match_scratch 3))]
14985 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14986 (clobber (match_dup 3))])
14987 (set (match_dup 0) (match_dup 2))])
14990 [(set (match_operand:DI 0 "memory_operand")
14991 (unspec:DI [(match_operand:XF 1 "register_operand")]
14993 (clobber (match_operand:DI 2 "memory_operand"))
14994 (clobber (match_scratch 3))]
14996 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14997 (clobber (match_dup 3))])])
14999 (define_insn_and_split "*fist<mode>2_1"
15000 [(set (match_operand:SWI24 0 "register_operand")
15001 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15003 "TARGET_USE_FANCY_MATH_387
15004 && can_create_pseudo_p ()"
15009 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15010 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
15014 [(set_attr "type" "fpspc")
15015 (set_attr "mode" "<MODE>")])
15017 (define_insn "fist<mode>2"
15018 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15019 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15021 "TARGET_USE_FANCY_MATH_387"
15022 "* return output_fix_trunc (insn, operands, false);"
15023 [(set_attr "type" "fpspc")
15024 (set_attr "mode" "<MODE>")])
15026 (define_insn "fist<mode>2_with_temp"
15027 [(set (match_operand:SWI24 0 "register_operand" "=r")
15028 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15030 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
15031 "TARGET_USE_FANCY_MATH_387"
15033 [(set_attr "type" "fpspc")
15034 (set_attr "mode" "<MODE>")])
15037 [(set (match_operand:SWI24 0 "register_operand")
15038 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15040 (clobber (match_operand:SWI24 2 "memory_operand"))]
15042 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
15043 (set (match_dup 0) (match_dup 2))])
15046 [(set (match_operand:SWI24 0 "memory_operand")
15047 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15049 (clobber (match_operand:SWI24 2 "memory_operand"))]
15051 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
15053 (define_expand "lrintxf<mode>2"
15054 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15055 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15057 "TARGET_USE_FANCY_MATH_387")
15059 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
15060 [(set (match_operand:SWI48x 0 "nonimmediate_operand")
15061 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand")]
15062 UNSPEC_FIX_NOTRUNC))]
15063 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15064 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
15066 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
15067 [(match_operand:SWI248x 0 "nonimmediate_operand")
15068 (match_operand:X87MODEF 1 "register_operand")]
15069 "(TARGET_USE_FANCY_MATH_387
15070 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
15071 || TARGET_MIX_SSE_I387)
15072 && flag_unsafe_math_optimizations)
15073 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15074 && <SWI248x:MODE>mode != HImode
15075 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15076 && !flag_trapping_math && !flag_rounding_math)"
15078 if (optimize_insn_for_size_p ())
15081 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
15082 && <SWI248x:MODE>mode != HImode
15083 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
15084 && !flag_trapping_math && !flag_rounding_math)
15085 ix86_expand_lround (operands[0], operands[1]);
15087 ix86_emit_i387_round (operands[0], operands[1]);
15091 (define_int_iterator FRNDINT_ROUNDING
15092 [UNSPEC_FRNDINT_FLOOR
15093 UNSPEC_FRNDINT_CEIL
15094 UNSPEC_FRNDINT_TRUNC])
15096 (define_int_iterator FIST_ROUNDING
15100 ;; Base name for define_insn
15101 (define_int_attr rounding_insn
15102 [(UNSPEC_FRNDINT_FLOOR "floor")
15103 (UNSPEC_FRNDINT_CEIL "ceil")
15104 (UNSPEC_FRNDINT_TRUNC "btrunc")
15105 (UNSPEC_FIST_FLOOR "floor")
15106 (UNSPEC_FIST_CEIL "ceil")])
15108 (define_int_attr rounding
15109 [(UNSPEC_FRNDINT_FLOOR "floor")
15110 (UNSPEC_FRNDINT_CEIL "ceil")
15111 (UNSPEC_FRNDINT_TRUNC "trunc")
15112 (UNSPEC_FIST_FLOOR "floor")
15113 (UNSPEC_FIST_CEIL "ceil")])
15115 (define_int_attr ROUNDING
15116 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
15117 (UNSPEC_FRNDINT_CEIL "CEIL")
15118 (UNSPEC_FRNDINT_TRUNC "TRUNC")
15119 (UNSPEC_FIST_FLOOR "FLOOR")
15120 (UNSPEC_FIST_CEIL "CEIL")])
15122 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15123 (define_insn_and_split "frndintxf2_<rounding>"
15124 [(set (match_operand:XF 0 "register_operand")
15125 (unspec:XF [(match_operand:XF 1 "register_operand")]
15127 (clobber (reg:CC FLAGS_REG))]
15128 "TARGET_USE_FANCY_MATH_387
15129 && flag_unsafe_math_optimizations
15130 && can_create_pseudo_p ()"
15135 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15137 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15138 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15140 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
15141 operands[2], operands[3]));
15144 [(set_attr "type" "frndint")
15145 (set_attr "i387_cw" "<rounding>")
15146 (set_attr "mode" "XF")])
15148 (define_insn "frndintxf2_<rounding>_i387"
15149 [(set (match_operand:XF 0 "register_operand" "=f")
15150 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15152 (use (match_operand:HI 2 "memory_operand" "m"))
15153 (use (match_operand:HI 3 "memory_operand" "m"))]
15154 "TARGET_USE_FANCY_MATH_387
15155 && flag_unsafe_math_optimizations"
15156 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15157 [(set_attr "type" "frndint")
15158 (set_attr "i387_cw" "<rounding>")
15159 (set_attr "mode" "XF")])
15161 (define_expand "<rounding_insn>xf2"
15162 [(parallel [(set (match_operand:XF 0 "register_operand")
15163 (unspec:XF [(match_operand:XF 1 "register_operand")]
15165 (clobber (reg:CC FLAGS_REG))])]
15166 "TARGET_USE_FANCY_MATH_387
15167 && flag_unsafe_math_optimizations
15168 && !optimize_insn_for_size_p ()")
15170 (define_expand "<rounding_insn><mode>2"
15171 [(parallel [(set (match_operand:MODEF 0 "register_operand")
15172 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
15174 (clobber (reg:CC FLAGS_REG))])]
15175 "(TARGET_USE_FANCY_MATH_387
15176 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15177 || TARGET_MIX_SSE_I387)
15178 && flag_unsafe_math_optimizations)
15179 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15180 && !flag_trapping_math)"
15182 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15183 && !flag_trapping_math)
15186 emit_insn (gen_sse4_1_round<mode>2
15187 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
15188 else if (optimize_insn_for_size_p ())
15190 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15192 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15193 ix86_expand_floorceil (operands[0], operands[1], true);
15194 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15195 ix86_expand_floorceil (operands[0], operands[1], false);
15196 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15197 ix86_expand_trunc (operands[0], operands[1]);
15199 gcc_unreachable ();
15203 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15204 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15205 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15206 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15207 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15208 ix86_expand_truncdf_32 (operands[0], operands[1]);
15210 gcc_unreachable ();
15217 if (optimize_insn_for_size_p ())
15220 op0 = gen_reg_rtx (XFmode);
15221 op1 = gen_reg_rtx (XFmode);
15222 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15223 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
15225 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15230 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15231 (define_insn_and_split "frndintxf2_mask_pm"
15232 [(set (match_operand:XF 0 "register_operand")
15233 (unspec:XF [(match_operand:XF 1 "register_operand")]
15234 UNSPEC_FRNDINT_MASK_PM))
15235 (clobber (reg:CC FLAGS_REG))]
15236 "TARGET_USE_FANCY_MATH_387
15237 && flag_unsafe_math_optimizations
15238 && can_create_pseudo_p ()"
15243 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15245 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15246 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15248 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15249 operands[2], operands[3]));
15252 [(set_attr "type" "frndint")
15253 (set_attr "i387_cw" "mask_pm")
15254 (set_attr "mode" "XF")])
15256 (define_insn "frndintxf2_mask_pm_i387"
15257 [(set (match_operand:XF 0 "register_operand" "=f")
15258 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15259 UNSPEC_FRNDINT_MASK_PM))
15260 (use (match_operand:HI 2 "memory_operand" "m"))
15261 (use (match_operand:HI 3 "memory_operand" "m"))]
15262 "TARGET_USE_FANCY_MATH_387
15263 && flag_unsafe_math_optimizations"
15264 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15265 [(set_attr "type" "frndint")
15266 (set_attr "i387_cw" "mask_pm")
15267 (set_attr "mode" "XF")])
15269 (define_expand "nearbyintxf2"
15270 [(parallel [(set (match_operand:XF 0 "register_operand")
15271 (unspec:XF [(match_operand:XF 1 "register_operand")]
15272 UNSPEC_FRNDINT_MASK_PM))
15273 (clobber (reg:CC FLAGS_REG))])]
15274 "TARGET_USE_FANCY_MATH_387
15275 && flag_unsafe_math_optimizations")
15277 (define_expand "nearbyint<mode>2"
15278 [(use (match_operand:MODEF 0 "register_operand"))
15279 (use (match_operand:MODEF 1 "register_operand"))]
15280 "TARGET_USE_FANCY_MATH_387
15281 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15282 || TARGET_MIX_SSE_I387)
15283 && flag_unsafe_math_optimizations"
15285 rtx op0 = gen_reg_rtx (XFmode);
15286 rtx op1 = gen_reg_rtx (XFmode);
15288 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15289 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15291 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15295 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15296 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15297 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15298 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15300 (clobber (reg:CC FLAGS_REG))]
15301 "TARGET_USE_FANCY_MATH_387
15302 && flag_unsafe_math_optimizations
15303 && can_create_pseudo_p ()"
15308 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15310 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15311 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15312 if (memory_operand (operands[0], VOIDmode))
15313 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15314 operands[2], operands[3]));
15317 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15318 emit_insn (gen_fist<mode>2_<rounding>_with_temp
15319 (operands[0], operands[1], operands[2],
15320 operands[3], operands[4]));
15324 [(set_attr "type" "fistp")
15325 (set_attr "i387_cw" "<rounding>")
15326 (set_attr "mode" "<MODE>")])
15328 (define_insn "fistdi2_<rounding>"
15329 [(set (match_operand:DI 0 "memory_operand" "=m")
15330 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15332 (use (match_operand:HI 2 "memory_operand" "m"))
15333 (use (match_operand:HI 3 "memory_operand" "m"))
15334 (clobber (match_scratch:XF 4 "=&1f"))]
15335 "TARGET_USE_FANCY_MATH_387
15336 && flag_unsafe_math_optimizations"
15337 "* return output_fix_trunc (insn, operands, false);"
15338 [(set_attr "type" "fistp")
15339 (set_attr "i387_cw" "<rounding>")
15340 (set_attr "mode" "DI")])
15342 (define_insn "fistdi2_<rounding>_with_temp"
15343 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15344 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15346 (use (match_operand:HI 2 "memory_operand" "m,m"))
15347 (use (match_operand:HI 3 "memory_operand" "m,m"))
15348 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15349 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15350 "TARGET_USE_FANCY_MATH_387
15351 && flag_unsafe_math_optimizations"
15353 [(set_attr "type" "fistp")
15354 (set_attr "i387_cw" "<rounding>")
15355 (set_attr "mode" "DI")])
15358 [(set (match_operand:DI 0 "register_operand")
15359 (unspec:DI [(match_operand:XF 1 "register_operand")]
15361 (use (match_operand:HI 2 "memory_operand"))
15362 (use (match_operand:HI 3 "memory_operand"))
15363 (clobber (match_operand:DI 4 "memory_operand"))
15364 (clobber (match_scratch 5))]
15366 [(parallel [(set (match_dup 4)
15367 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15368 (use (match_dup 2))
15369 (use (match_dup 3))
15370 (clobber (match_dup 5))])
15371 (set (match_dup 0) (match_dup 4))])
15374 [(set (match_operand:DI 0 "memory_operand")
15375 (unspec:DI [(match_operand:XF 1 "register_operand")]
15377 (use (match_operand:HI 2 "memory_operand"))
15378 (use (match_operand:HI 3 "memory_operand"))
15379 (clobber (match_operand:DI 4 "memory_operand"))
15380 (clobber (match_scratch 5))]
15382 [(parallel [(set (match_dup 0)
15383 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15384 (use (match_dup 2))
15385 (use (match_dup 3))
15386 (clobber (match_dup 5))])])
15388 (define_insn "fist<mode>2_<rounding>"
15389 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15390 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15392 (use (match_operand:HI 2 "memory_operand" "m"))
15393 (use (match_operand:HI 3 "memory_operand" "m"))]
15394 "TARGET_USE_FANCY_MATH_387
15395 && flag_unsafe_math_optimizations"
15396 "* return output_fix_trunc (insn, operands, false);"
15397 [(set_attr "type" "fistp")
15398 (set_attr "i387_cw" "<rounding>")
15399 (set_attr "mode" "<MODE>")])
15401 (define_insn "fist<mode>2_<rounding>_with_temp"
15402 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15403 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15405 (use (match_operand:HI 2 "memory_operand" "m,m"))
15406 (use (match_operand:HI 3 "memory_operand" "m,m"))
15407 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15408 "TARGET_USE_FANCY_MATH_387
15409 && flag_unsafe_math_optimizations"
15411 [(set_attr "type" "fistp")
15412 (set_attr "i387_cw" "<rounding>")
15413 (set_attr "mode" "<MODE>")])
15416 [(set (match_operand:SWI24 0 "register_operand")
15417 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15419 (use (match_operand:HI 2 "memory_operand"))
15420 (use (match_operand:HI 3 "memory_operand"))
15421 (clobber (match_operand:SWI24 4 "memory_operand"))]
15423 [(parallel [(set (match_dup 4)
15424 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15425 (use (match_dup 2))
15426 (use (match_dup 3))])
15427 (set (match_dup 0) (match_dup 4))])
15430 [(set (match_operand:SWI24 0 "memory_operand")
15431 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15433 (use (match_operand:HI 2 "memory_operand"))
15434 (use (match_operand:HI 3 "memory_operand"))
15435 (clobber (match_operand:SWI24 4 "memory_operand"))]
15437 [(parallel [(set (match_dup 0)
15438 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15439 (use (match_dup 2))
15440 (use (match_dup 3))])])
15442 (define_expand "l<rounding_insn>xf<mode>2"
15443 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15444 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15446 (clobber (reg:CC FLAGS_REG))])]
15447 "TARGET_USE_FANCY_MATH_387
15448 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15449 && flag_unsafe_math_optimizations")
15451 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
15452 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
15453 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15455 (clobber (reg:CC FLAGS_REG))])]
15456 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15457 && !flag_trapping_math"
15459 if (TARGET_64BIT && optimize_insn_for_size_p ())
15462 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15463 ix86_expand_lfloorceil (operands[0], operands[1], true);
15464 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15465 ix86_expand_lfloorceil (operands[0], operands[1], false);
15467 gcc_unreachable ();
15472 (define_insn "fxam<mode>2_i387"
15473 [(set (match_operand:HI 0 "register_operand" "=a")
15475 [(match_operand:X87MODEF 1 "register_operand" "f")]
15477 "TARGET_USE_FANCY_MATH_387"
15478 "fxam\n\tfnstsw\t%0"
15479 [(set_attr "type" "multi")
15480 (set_attr "length" "4")
15481 (set_attr "unit" "i387")
15482 (set_attr "mode" "<MODE>")])
15484 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15485 [(set (match_operand:HI 0 "register_operand")
15487 [(match_operand:MODEF 1 "memory_operand")]
15489 "TARGET_USE_FANCY_MATH_387
15490 && can_create_pseudo_p ()"
15493 [(set (match_dup 2)(match_dup 1))
15495 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15497 operands[2] = gen_reg_rtx (<MODE>mode);
15499 MEM_VOLATILE_P (operands[1]) = 1;
15501 [(set_attr "type" "multi")
15502 (set_attr "unit" "i387")
15503 (set_attr "mode" "<MODE>")])
15505 (define_expand "isinfxf2"
15506 [(use (match_operand:SI 0 "register_operand"))
15507 (use (match_operand:XF 1 "register_operand"))]
15508 "TARGET_USE_FANCY_MATH_387
15509 && TARGET_C99_FUNCTIONS"
15511 rtx mask = GEN_INT (0x45);
15512 rtx val = GEN_INT (0x05);
15516 rtx scratch = gen_reg_rtx (HImode);
15517 rtx res = gen_reg_rtx (QImode);
15519 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15521 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15522 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15523 cond = gen_rtx_fmt_ee (EQ, QImode,
15524 gen_rtx_REG (CCmode, FLAGS_REG),
15526 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15527 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15531 (define_expand "isinf<mode>2"
15532 [(use (match_operand:SI 0 "register_operand"))
15533 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15534 "TARGET_USE_FANCY_MATH_387
15535 && TARGET_C99_FUNCTIONS
15536 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15538 rtx mask = GEN_INT (0x45);
15539 rtx val = GEN_INT (0x05);
15543 rtx scratch = gen_reg_rtx (HImode);
15544 rtx res = gen_reg_rtx (QImode);
15546 /* Remove excess precision by forcing value through memory. */
15547 if (memory_operand (operands[1], VOIDmode))
15548 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15551 enum ix86_stack_slot slot = (virtuals_instantiated
15554 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15556 emit_move_insn (temp, operands[1]);
15557 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15560 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15561 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15562 cond = gen_rtx_fmt_ee (EQ, QImode,
15563 gen_rtx_REG (CCmode, FLAGS_REG),
15565 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15566 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15570 (define_expand "signbitxf2"
15571 [(use (match_operand:SI 0 "register_operand"))
15572 (use (match_operand:XF 1 "register_operand"))]
15573 "TARGET_USE_FANCY_MATH_387"
15575 rtx scratch = gen_reg_rtx (HImode);
15577 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15578 emit_insn (gen_andsi3 (operands[0],
15579 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15583 (define_insn "movmsk_df"
15584 [(set (match_operand:SI 0 "register_operand" "=r")
15586 [(match_operand:DF 1 "register_operand" "x")]
15588 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15589 "%vmovmskpd\t{%1, %0|%0, %1}"
15590 [(set_attr "type" "ssemov")
15591 (set_attr "prefix" "maybe_vex")
15592 (set_attr "mode" "DF")])
15594 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15595 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15596 (define_expand "signbitdf2"
15597 [(use (match_operand:SI 0 "register_operand"))
15598 (use (match_operand:DF 1 "register_operand"))]
15599 "TARGET_USE_FANCY_MATH_387
15600 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15602 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15604 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15605 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15609 rtx scratch = gen_reg_rtx (HImode);
15611 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15612 emit_insn (gen_andsi3 (operands[0],
15613 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15618 (define_expand "signbitsf2"
15619 [(use (match_operand:SI 0 "register_operand"))
15620 (use (match_operand:SF 1 "register_operand"))]
15621 "TARGET_USE_FANCY_MATH_387
15622 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15624 rtx scratch = gen_reg_rtx (HImode);
15626 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15627 emit_insn (gen_andsi3 (operands[0],
15628 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15632 ;; Block operation instructions
15635 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15638 [(set_attr "length" "1")
15639 (set_attr "length_immediate" "0")
15640 (set_attr "modrm" "0")])
15642 (define_expand "movmem<mode>"
15643 [(use (match_operand:BLK 0 "memory_operand"))
15644 (use (match_operand:BLK 1 "memory_operand"))
15645 (use (match_operand:SWI48 2 "nonmemory_operand"))
15646 (use (match_operand:SWI48 3 "const_int_operand"))
15647 (use (match_operand:SI 4 "const_int_operand"))
15648 (use (match_operand:SI 5 "const_int_operand"))]
15651 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15652 operands[4], operands[5]))
15658 ;; Most CPUs don't like single string operations
15659 ;; Handle this case here to simplify previous expander.
15661 (define_expand "strmov"
15662 [(set (match_dup 4) (match_operand 3 "memory_operand"))
15663 (set (match_operand 1 "memory_operand") (match_dup 4))
15664 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
15665 (clobber (reg:CC FLAGS_REG))])
15666 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
15667 (clobber (reg:CC FLAGS_REG))])]
15670 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15672 /* If .md ever supports :P for Pmode, these can be directly
15673 in the pattern above. */
15674 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15675 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15677 /* Can't use this if the user has appropriated esi or edi. */
15678 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15679 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15681 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15682 operands[2], operands[3],
15683 operands[5], operands[6]));
15687 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15690 (define_expand "strmov_singleop"
15691 [(parallel [(set (match_operand 1 "memory_operand")
15692 (match_operand 3 "memory_operand"))
15693 (set (match_operand 0 "register_operand")
15695 (set (match_operand 2 "register_operand")
15696 (match_operand 5))])]
15698 "ix86_current_function_needs_cld = 1;")
15700 (define_insn "*strmovdi_rex_1"
15701 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15702 (mem:DI (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)
15710 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15712 [(set_attr "type" "str")
15713 (set_attr "memory" "both")
15714 (set_attr "mode" "DI")])
15716 (define_insn "*strmovsi_1"
15717 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15718 (mem:SI (match_operand:P 3 "register_operand" "1")))
15719 (set (match_operand:P 0 "register_operand" "=D")
15720 (plus:P (match_dup 2)
15722 (set (match_operand:P 1 "register_operand" "=S")
15723 (plus:P (match_dup 3)
15725 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15727 [(set_attr "type" "str")
15728 (set_attr "memory" "both")
15729 (set_attr "mode" "SI")])
15731 (define_insn "*strmovhi_1"
15732 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15733 (mem:HI (match_operand:P 3 "register_operand" "1")))
15734 (set (match_operand:P 0 "register_operand" "=D")
15735 (plus:P (match_dup 2)
15737 (set (match_operand:P 1 "register_operand" "=S")
15738 (plus:P (match_dup 3)
15740 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15742 [(set_attr "type" "str")
15743 (set_attr "memory" "both")
15744 (set_attr "mode" "HI")])
15746 (define_insn "*strmovqi_1"
15747 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15748 (mem:QI (match_operand:P 3 "register_operand" "1")))
15749 (set (match_operand:P 0 "register_operand" "=D")
15750 (plus:P (match_dup 2)
15752 (set (match_operand:P 1 "register_operand" "=S")
15753 (plus:P (match_dup 3)
15755 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15757 [(set_attr "type" "str")
15758 (set_attr "memory" "both")
15759 (set (attr "prefix_rex")
15761 (match_test "<P:MODE>mode == DImode")
15763 (const_string "*")))
15764 (set_attr "mode" "QI")])
15766 (define_expand "rep_mov"
15767 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
15768 (set (match_operand 0 "register_operand")
15770 (set (match_operand 2 "register_operand")
15772 (set (match_operand 1 "memory_operand")
15773 (match_operand 3 "memory_operand"))
15774 (use (match_dup 4))])]
15776 "ix86_current_function_needs_cld = 1;")
15778 (define_insn "*rep_movdi_rex64"
15779 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15780 (set (match_operand:P 0 "register_operand" "=D")
15781 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15783 (match_operand:P 3 "register_operand" "0")))
15784 (set (match_operand:P 1 "register_operand" "=S")
15785 (plus:P (ashift:P (match_dup 5) (const_int 3))
15786 (match_operand:P 4 "register_operand" "1")))
15787 (set (mem:BLK (match_dup 3))
15788 (mem:BLK (match_dup 4)))
15789 (use (match_dup 5))]
15791 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15793 [(set_attr "type" "str")
15794 (set_attr "prefix_rep" "1")
15795 (set_attr "memory" "both")
15796 (set_attr "mode" "DI")])
15798 (define_insn "*rep_movsi"
15799 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15800 (set (match_operand:P 0 "register_operand" "=D")
15801 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15803 (match_operand:P 3 "register_operand" "0")))
15804 (set (match_operand:P 1 "register_operand" "=S")
15805 (plus:P (ashift:P (match_dup 5) (const_int 2))
15806 (match_operand:P 4 "register_operand" "1")))
15807 (set (mem:BLK (match_dup 3))
15808 (mem:BLK (match_dup 4)))
15809 (use (match_dup 5))]
15810 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15811 "%^rep{%;} movs{l|d}"
15812 [(set_attr "type" "str")
15813 (set_attr "prefix_rep" "1")
15814 (set_attr "memory" "both")
15815 (set_attr "mode" "SI")])
15817 (define_insn "*rep_movqi"
15818 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15819 (set (match_operand:P 0 "register_operand" "=D")
15820 (plus:P (match_operand:P 3 "register_operand" "0")
15821 (match_operand:P 5 "register_operand" "2")))
15822 (set (match_operand:P 1 "register_operand" "=S")
15823 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15824 (set (mem:BLK (match_dup 3))
15825 (mem:BLK (match_dup 4)))
15826 (use (match_dup 5))]
15827 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15829 [(set_attr "type" "str")
15830 (set_attr "prefix_rep" "1")
15831 (set_attr "memory" "both")
15832 (set_attr "mode" "QI")])
15834 (define_expand "setmem<mode>"
15835 [(use (match_operand:BLK 0 "memory_operand"))
15836 (use (match_operand:SWI48 1 "nonmemory_operand"))
15837 (use (match_operand:QI 2 "nonmemory_operand"))
15838 (use (match_operand 3 "const_int_operand"))
15839 (use (match_operand:SI 4 "const_int_operand"))
15840 (use (match_operand:SI 5 "const_int_operand"))]
15843 if (ix86_expand_setmem (operands[0], operands[1],
15844 operands[2], operands[3],
15845 operands[4], operands[5]))
15851 ;; Most CPUs don't like single string operations
15852 ;; Handle this case here to simplify previous expander.
15854 (define_expand "strset"
15855 [(set (match_operand 1 "memory_operand")
15856 (match_operand 2 "register_operand"))
15857 (parallel [(set (match_operand 0 "register_operand")
15859 (clobber (reg:CC FLAGS_REG))])]
15862 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15863 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15865 /* If .md ever supports :P for Pmode, this can be directly
15866 in the pattern above. */
15867 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15868 GEN_INT (GET_MODE_SIZE (GET_MODE
15870 /* Can't use this if the user has appropriated eax or edi. */
15871 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15872 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15874 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15880 (define_expand "strset_singleop"
15881 [(parallel [(set (match_operand 1 "memory_operand")
15882 (match_operand 2 "register_operand"))
15883 (set (match_operand 0 "register_operand")
15884 (match_operand 3))])]
15886 "ix86_current_function_needs_cld = 1;")
15888 (define_insn "*strsetdi_rex_1"
15889 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
15890 (match_operand:DI 2 "register_operand" "a"))
15891 (set (match_operand:P 0 "register_operand" "=D")
15892 (plus:P (match_dup 1)
15895 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15897 [(set_attr "type" "str")
15898 (set_attr "memory" "store")
15899 (set_attr "mode" "DI")])
15901 (define_insn "*strsetsi_1"
15902 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15903 (match_operand:SI 2 "register_operand" "a"))
15904 (set (match_operand:P 0 "register_operand" "=D")
15905 (plus:P (match_dup 1)
15907 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15909 [(set_attr "type" "str")
15910 (set_attr "memory" "store")
15911 (set_attr "mode" "SI")])
15913 (define_insn "*strsethi_1"
15914 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15915 (match_operand:HI 2 "register_operand" "a"))
15916 (set (match_operand:P 0 "register_operand" "=D")
15917 (plus:P (match_dup 1)
15919 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15921 [(set_attr "type" "str")
15922 (set_attr "memory" "store")
15923 (set_attr "mode" "HI")])
15925 (define_insn "*strsetqi_1"
15926 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15927 (match_operand:QI 2 "register_operand" "a"))
15928 (set (match_operand:P 0 "register_operand" "=D")
15929 (plus:P (match_dup 1)
15931 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15933 [(set_attr "type" "str")
15934 (set_attr "memory" "store")
15935 (set (attr "prefix_rex")
15937 (match_test "<P:MODE>mode == DImode")
15939 (const_string "*")))
15940 (set_attr "mode" "QI")])
15942 (define_expand "rep_stos"
15943 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
15944 (set (match_operand 0 "register_operand")
15946 (set (match_operand 2 "memory_operand") (const_int 0))
15947 (use (match_operand 3 "register_operand"))
15948 (use (match_dup 1))])]
15950 "ix86_current_function_needs_cld = 1;")
15952 (define_insn "*rep_stosdi_rex64"
15953 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15954 (set (match_operand:P 0 "register_operand" "=D")
15955 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15957 (match_operand:P 3 "register_operand" "0")))
15958 (set (mem:BLK (match_dup 3))
15960 (use (match_operand:DI 2 "register_operand" "a"))
15961 (use (match_dup 4))]
15963 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15965 [(set_attr "type" "str")
15966 (set_attr "prefix_rep" "1")
15967 (set_attr "memory" "store")
15968 (set_attr "mode" "DI")])
15970 (define_insn "*rep_stossi"
15971 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15972 (set (match_operand:P 0 "register_operand" "=D")
15973 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15975 (match_operand:P 3 "register_operand" "0")))
15976 (set (mem:BLK (match_dup 3))
15978 (use (match_operand:SI 2 "register_operand" "a"))
15979 (use (match_dup 4))]
15980 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15981 "%^rep{%;} stos{l|d}"
15982 [(set_attr "type" "str")
15983 (set_attr "prefix_rep" "1")
15984 (set_attr "memory" "store")
15985 (set_attr "mode" "SI")])
15987 (define_insn "*rep_stosqi"
15988 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15989 (set (match_operand:P 0 "register_operand" "=D")
15990 (plus:P (match_operand:P 3 "register_operand" "0")
15991 (match_operand:P 4 "register_operand" "1")))
15992 (set (mem:BLK (match_dup 3))
15994 (use (match_operand:QI 2 "register_operand" "a"))
15995 (use (match_dup 4))]
15996 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15998 [(set_attr "type" "str")
15999 (set_attr "prefix_rep" "1")
16000 (set_attr "memory" "store")
16001 (set (attr "prefix_rex")
16003 (match_test "<P:MODE>mode == DImode")
16005 (const_string "*")))
16006 (set_attr "mode" "QI")])
16008 (define_expand "cmpstrnsi"
16009 [(set (match_operand:SI 0 "register_operand")
16010 (compare:SI (match_operand:BLK 1 "general_operand")
16011 (match_operand:BLK 2 "general_operand")))
16012 (use (match_operand 3 "general_operand"))
16013 (use (match_operand 4 "immediate_operand"))]
16016 rtx addr1, addr2, out, outlow, count, countreg, align;
16018 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16021 /* Can't use this if the user has appropriated ecx, esi or edi. */
16022 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16027 out = gen_reg_rtx (SImode);
16029 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
16030 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
16031 if (addr1 != XEXP (operands[1], 0))
16032 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16033 if (addr2 != XEXP (operands[2], 0))
16034 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16036 count = operands[3];
16037 countreg = ix86_zero_extend_to_Pmode (count);
16039 /* %%% Iff we are testing strict equality, we can use known alignment
16040 to good advantage. This may be possible with combine, particularly
16041 once cc0 is dead. */
16042 align = operands[4];
16044 if (CONST_INT_P (count))
16046 if (INTVAL (count) == 0)
16048 emit_move_insn (operands[0], const0_rtx);
16051 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16052 operands[1], operands[2]));
16056 rtx (*gen_cmp) (rtx, rtx);
16058 gen_cmp = (TARGET_64BIT
16059 ? gen_cmpdi_1 : gen_cmpsi_1);
16061 emit_insn (gen_cmp (countreg, countreg));
16062 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16063 operands[1], operands[2]));
16066 outlow = gen_lowpart (QImode, out);
16067 emit_insn (gen_cmpintqi (outlow));
16068 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16070 if (operands[0] != out)
16071 emit_move_insn (operands[0], out);
16076 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16078 (define_expand "cmpintqi"
16079 [(set (match_dup 1)
16080 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16082 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16083 (parallel [(set (match_operand:QI 0 "register_operand")
16084 (minus:QI (match_dup 1)
16086 (clobber (reg:CC FLAGS_REG))])]
16089 operands[1] = gen_reg_rtx (QImode);
16090 operands[2] = gen_reg_rtx (QImode);
16093 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16094 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16096 (define_expand "cmpstrnqi_nz_1"
16097 [(parallel [(set (reg:CC FLAGS_REG)
16098 (compare:CC (match_operand 4 "memory_operand")
16099 (match_operand 5 "memory_operand")))
16100 (use (match_operand 2 "register_operand"))
16101 (use (match_operand:SI 3 "immediate_operand"))
16102 (clobber (match_operand 0 "register_operand"))
16103 (clobber (match_operand 1 "register_operand"))
16104 (clobber (match_dup 2))])]
16106 "ix86_current_function_needs_cld = 1;")
16108 (define_insn "*cmpstrnqi_nz_1"
16109 [(set (reg:CC FLAGS_REG)
16110 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16111 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16112 (use (match_operand:P 6 "register_operand" "2"))
16113 (use (match_operand:SI 3 "immediate_operand" "i"))
16114 (clobber (match_operand:P 0 "register_operand" "=S"))
16115 (clobber (match_operand:P 1 "register_operand" "=D"))
16116 (clobber (match_operand:P 2 "register_operand" "=c"))]
16117 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16119 [(set_attr "type" "str")
16120 (set_attr "mode" "QI")
16121 (set (attr "prefix_rex")
16123 (match_test "<P:MODE>mode == DImode")
16125 (const_string "*")))
16126 (set_attr "prefix_rep" "1")])
16128 ;; The same, but the count is not known to not be zero.
16130 (define_expand "cmpstrnqi_1"
16131 [(parallel [(set (reg:CC FLAGS_REG)
16132 (if_then_else:CC (ne (match_operand 2 "register_operand")
16134 (compare:CC (match_operand 4 "memory_operand")
16135 (match_operand 5 "memory_operand"))
16137 (use (match_operand:SI 3 "immediate_operand"))
16138 (use (reg:CC FLAGS_REG))
16139 (clobber (match_operand 0 "register_operand"))
16140 (clobber (match_operand 1 "register_operand"))
16141 (clobber (match_dup 2))])]
16143 "ix86_current_function_needs_cld = 1;")
16145 (define_insn "*cmpstrnqi_1"
16146 [(set (reg:CC FLAGS_REG)
16147 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16149 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16150 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16152 (use (match_operand:SI 3 "immediate_operand" "i"))
16153 (use (reg:CC FLAGS_REG))
16154 (clobber (match_operand:P 0 "register_operand" "=S"))
16155 (clobber (match_operand:P 1 "register_operand" "=D"))
16156 (clobber (match_operand:P 2 "register_operand" "=c"))]
16157 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16159 [(set_attr "type" "str")
16160 (set_attr "mode" "QI")
16161 (set (attr "prefix_rex")
16163 (match_test "<P:MODE>mode == DImode")
16165 (const_string "*")))
16166 (set_attr "prefix_rep" "1")])
16168 (define_expand "strlen<mode>"
16169 [(set (match_operand:P 0 "register_operand")
16170 (unspec:P [(match_operand:BLK 1 "general_operand")
16171 (match_operand:QI 2 "immediate_operand")
16172 (match_operand 3 "immediate_operand")]
16176 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16182 (define_expand "strlenqi_1"
16183 [(parallel [(set (match_operand 0 "register_operand")
16185 (clobber (match_operand 1 "register_operand"))
16186 (clobber (reg:CC FLAGS_REG))])]
16188 "ix86_current_function_needs_cld = 1;")
16190 (define_insn "*strlenqi_1"
16191 [(set (match_operand:P 0 "register_operand" "=&c")
16192 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16193 (match_operand:QI 2 "register_operand" "a")
16194 (match_operand:P 3 "immediate_operand" "i")
16195 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16196 (clobber (match_operand:P 1 "register_operand" "=D"))
16197 (clobber (reg:CC FLAGS_REG))]
16198 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16199 "%^repnz{%;} scasb"
16200 [(set_attr "type" "str")
16201 (set_attr "mode" "QI")
16202 (set (attr "prefix_rex")
16204 (match_test "<P:MODE>mode == DImode")
16206 (const_string "*")))
16207 (set_attr "prefix_rep" "1")])
16209 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16210 ;; handled in combine, but it is not currently up to the task.
16211 ;; When used for their truth value, the cmpstrn* expanders generate
16220 ;; The intermediate three instructions are unnecessary.
16222 ;; This one handles cmpstrn*_nz_1...
16225 (set (reg:CC FLAGS_REG)
16226 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16227 (mem:BLK (match_operand 5 "register_operand"))))
16228 (use (match_operand 6 "register_operand"))
16229 (use (match_operand:SI 3 "immediate_operand"))
16230 (clobber (match_operand 0 "register_operand"))
16231 (clobber (match_operand 1 "register_operand"))
16232 (clobber (match_operand 2 "register_operand"))])
16233 (set (match_operand:QI 7 "register_operand")
16234 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16235 (set (match_operand:QI 8 "register_operand")
16236 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16237 (set (reg FLAGS_REG)
16238 (compare (match_dup 7) (match_dup 8)))
16240 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16242 (set (reg:CC FLAGS_REG)
16243 (compare:CC (mem:BLK (match_dup 4))
16244 (mem:BLK (match_dup 5))))
16245 (use (match_dup 6))
16246 (use (match_dup 3))
16247 (clobber (match_dup 0))
16248 (clobber (match_dup 1))
16249 (clobber (match_dup 2))])])
16251 ;; ...and this one handles cmpstrn*_1.
16254 (set (reg:CC FLAGS_REG)
16255 (if_then_else:CC (ne (match_operand 6 "register_operand")
16257 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16258 (mem:BLK (match_operand 5 "register_operand")))
16260 (use (match_operand:SI 3 "immediate_operand"))
16261 (use (reg:CC FLAGS_REG))
16262 (clobber (match_operand 0 "register_operand"))
16263 (clobber (match_operand 1 "register_operand"))
16264 (clobber (match_operand 2 "register_operand"))])
16265 (set (match_operand:QI 7 "register_operand")
16266 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16267 (set (match_operand:QI 8 "register_operand")
16268 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16269 (set (reg FLAGS_REG)
16270 (compare (match_dup 7) (match_dup 8)))
16272 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16274 (set (reg:CC FLAGS_REG)
16275 (if_then_else:CC (ne (match_dup 6)
16277 (compare:CC (mem:BLK (match_dup 4))
16278 (mem:BLK (match_dup 5)))
16280 (use (match_dup 3))
16281 (use (reg:CC FLAGS_REG))
16282 (clobber (match_dup 0))
16283 (clobber (match_dup 1))
16284 (clobber (match_dup 2))])])
16286 ;; Conditional move instructions.
16288 (define_expand "mov<mode>cc"
16289 [(set (match_operand:SWIM 0 "register_operand")
16290 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator")
16291 (match_operand:SWIM 2 "<general_operand>")
16292 (match_operand:SWIM 3 "<general_operand>")))]
16294 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16296 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16297 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16298 ;; So just document what we're doing explicitly.
16300 (define_expand "x86_mov<mode>cc_0_m1"
16302 [(set (match_operand:SWI48 0 "register_operand")
16303 (if_then_else:SWI48
16304 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16305 [(match_operand 1 "flags_reg_operand")
16309 (clobber (reg:CC FLAGS_REG))])])
16311 (define_insn "*x86_mov<mode>cc_0_m1"
16312 [(set (match_operand:SWI48 0 "register_operand" "=r")
16313 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16314 [(reg FLAGS_REG) (const_int 0)])
16317 (clobber (reg:CC FLAGS_REG))]
16319 "sbb{<imodesuffix>}\t%0, %0"
16320 ; Since we don't have the proper number of operands for an alu insn,
16321 ; fill in all the blanks.
16322 [(set_attr "type" "alu")
16323 (set_attr "use_carry" "1")
16324 (set_attr "pent_pair" "pu")
16325 (set_attr "memory" "none")
16326 (set_attr "imm_disp" "false")
16327 (set_attr "mode" "<MODE>")
16328 (set_attr "length_immediate" "0")])
16330 (define_insn "*x86_mov<mode>cc_0_m1_se"
16331 [(set (match_operand:SWI48 0 "register_operand" "=r")
16332 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16333 [(reg FLAGS_REG) (const_int 0)])
16336 (clobber (reg:CC FLAGS_REG))]
16338 "sbb{<imodesuffix>}\t%0, %0"
16339 [(set_attr "type" "alu")
16340 (set_attr "use_carry" "1")
16341 (set_attr "pent_pair" "pu")
16342 (set_attr "memory" "none")
16343 (set_attr "imm_disp" "false")
16344 (set_attr "mode" "<MODE>")
16345 (set_attr "length_immediate" "0")])
16347 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16348 [(set (match_operand:SWI48 0 "register_operand" "=r")
16349 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16350 [(reg FLAGS_REG) (const_int 0)])))
16351 (clobber (reg:CC FLAGS_REG))]
16353 "sbb{<imodesuffix>}\t%0, %0"
16354 [(set_attr "type" "alu")
16355 (set_attr "use_carry" "1")
16356 (set_attr "pent_pair" "pu")
16357 (set_attr "memory" "none")
16358 (set_attr "imm_disp" "false")
16359 (set_attr "mode" "<MODE>")
16360 (set_attr "length_immediate" "0")])
16362 (define_insn "*mov<mode>cc_noc"
16363 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16364 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16365 [(reg FLAGS_REG) (const_int 0)])
16366 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16367 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16368 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16370 cmov%O2%C1\t{%2, %0|%0, %2}
16371 cmov%O2%c1\t{%3, %0|%0, %3}"
16372 [(set_attr "type" "icmov")
16373 (set_attr "mode" "<MODE>")])
16375 (define_insn "*movqicc_noc"
16376 [(set (match_operand:QI 0 "register_operand" "=r,r")
16377 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16378 [(reg FLAGS_REG) (const_int 0)])
16379 (match_operand:QI 2 "register_operand" "r,0")
16380 (match_operand:QI 3 "register_operand" "0,r")))]
16381 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16383 [(set_attr "type" "icmov")
16384 (set_attr "mode" "QI")])
16387 [(set (match_operand 0 "register_operand")
16388 (if_then_else (match_operator 1 "ix86_comparison_operator"
16389 [(reg FLAGS_REG) (const_int 0)])
16390 (match_operand 2 "register_operand")
16391 (match_operand 3 "register_operand")))]
16392 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16393 && (GET_MODE (operands[0]) == QImode
16394 || GET_MODE (operands[0]) == HImode)
16395 && reload_completed"
16396 [(set (match_dup 0)
16397 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16399 operands[0] = gen_lowpart (SImode, operands[0]);
16400 operands[2] = gen_lowpart (SImode, operands[2]);
16401 operands[3] = gen_lowpart (SImode, operands[3]);
16404 (define_expand "mov<mode>cc"
16405 [(set (match_operand:X87MODEF 0 "register_operand")
16406 (if_then_else:X87MODEF
16407 (match_operand 1 "ix86_fp_comparison_operator")
16408 (match_operand:X87MODEF 2 "register_operand")
16409 (match_operand:X87MODEF 3 "register_operand")))]
16410 "(TARGET_80387 && TARGET_CMOVE)
16411 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16412 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16414 (define_insn "*movxfcc_1"
16415 [(set (match_operand:XF 0 "register_operand" "=f,f")
16416 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16417 [(reg FLAGS_REG) (const_int 0)])
16418 (match_operand:XF 2 "register_operand" "f,0")
16419 (match_operand:XF 3 "register_operand" "0,f")))]
16420 "TARGET_80387 && TARGET_CMOVE"
16422 fcmov%F1\t{%2, %0|%0, %2}
16423 fcmov%f1\t{%3, %0|%0, %3}"
16424 [(set_attr "type" "fcmov")
16425 (set_attr "mode" "XF")])
16427 (define_insn "*movdfcc_1_rex64"
16428 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16429 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16430 [(reg FLAGS_REG) (const_int 0)])
16431 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16432 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16433 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16434 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16436 fcmov%F1\t{%2, %0|%0, %2}
16437 fcmov%f1\t{%3, %0|%0, %3}
16438 cmov%O2%C1\t{%2, %0|%0, %2}
16439 cmov%O2%c1\t{%3, %0|%0, %3}"
16440 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16441 (set_attr "mode" "DF,DF,DI,DI")])
16443 (define_insn "*movdfcc_1"
16444 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16445 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16446 [(reg FLAGS_REG) (const_int 0)])
16447 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16448 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16449 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16450 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16452 fcmov%F1\t{%2, %0|%0, %2}
16453 fcmov%f1\t{%3, %0|%0, %3}
16456 [(set_attr "type" "fcmov,fcmov,multi,multi")
16457 (set_attr "mode" "DF,DF,DI,DI")])
16460 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16461 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16462 [(reg FLAGS_REG) (const_int 0)])
16463 (match_operand:DF 2 "nonimmediate_operand")
16464 (match_operand:DF 3 "nonimmediate_operand")))]
16465 "!TARGET_64BIT && reload_completed"
16466 [(set (match_dup 2)
16467 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16469 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16471 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16472 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16475 (define_insn "*movsfcc_1_387"
16476 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16477 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16478 [(reg FLAGS_REG) (const_int 0)])
16479 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16480 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16481 "TARGET_80387 && TARGET_CMOVE
16482 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16484 fcmov%F1\t{%2, %0|%0, %2}
16485 fcmov%f1\t{%3, %0|%0, %3}
16486 cmov%O2%C1\t{%2, %0|%0, %2}
16487 cmov%O2%c1\t{%3, %0|%0, %3}"
16488 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16489 (set_attr "mode" "SF,SF,SI,SI")])
16491 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16492 ;; the scalar versions to have only XMM registers as operands.
16494 ;; XOP conditional move
16495 (define_insn "*xop_pcmov_<mode>"
16496 [(set (match_operand:MODEF 0 "register_operand" "=x")
16497 (if_then_else:MODEF
16498 (match_operand:MODEF 1 "register_operand" "x")
16499 (match_operand:MODEF 2 "register_operand" "x")
16500 (match_operand:MODEF 3 "register_operand" "x")))]
16502 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16503 [(set_attr "type" "sse4arg")])
16505 ;; These versions of the min/max patterns are intentionally ignorant of
16506 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16507 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16508 ;; are undefined in this condition, we're certain this is correct.
16510 (define_insn "<code><mode>3"
16511 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16513 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16514 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16515 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16517 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16518 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16519 [(set_attr "isa" "noavx,avx")
16520 (set_attr "prefix" "orig,vex")
16521 (set_attr "type" "sseadd")
16522 (set_attr "mode" "<MODE>")])
16524 ;; These versions of the min/max patterns implement exactly the operations
16525 ;; min = (op1 < op2 ? op1 : op2)
16526 ;; max = (!(op1 < op2) ? op1 : op2)
16527 ;; Their operands are not commutative, and thus they may be used in the
16528 ;; presence of -0.0 and NaN.
16530 (define_int_iterator IEEE_MAXMIN
16534 (define_int_attr ieee_maxmin
16535 [(UNSPEC_IEEE_MAX "max")
16536 (UNSPEC_IEEE_MIN "min")])
16538 (define_insn "*ieee_s<ieee_maxmin><mode>3"
16539 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16541 [(match_operand:MODEF 1 "register_operand" "0,x")
16542 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16544 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16546 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
16547 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16548 [(set_attr "isa" "noavx,avx")
16549 (set_attr "prefix" "orig,vex")
16550 (set_attr "type" "sseadd")
16551 (set_attr "mode" "<MODE>")])
16553 ;; Make two stack loads independent:
16555 ;; fld %st(0) -> fld bb
16556 ;; fmul bb fmul %st(1), %st
16558 ;; Actually we only match the last two instructions for simplicity.
16560 [(set (match_operand 0 "fp_register_operand")
16561 (match_operand 1 "fp_register_operand"))
16563 (match_operator 2 "binary_fp_operator"
16565 (match_operand 3 "memory_operand")]))]
16566 "REGNO (operands[0]) != REGNO (operands[1])"
16567 [(set (match_dup 0) (match_dup 3))
16568 (set (match_dup 0) (match_dup 4))]
16570 ;; The % modifier is not operational anymore in peephole2's, so we have to
16571 ;; swap the operands manually in the case of addition and multiplication.
16575 if (COMMUTATIVE_ARITH_P (operands[2]))
16576 op0 = operands[0], op1 = operands[1];
16578 op0 = operands[1], op1 = operands[0];
16580 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16581 GET_MODE (operands[2]),
16585 ;; Conditional addition patterns
16586 (define_expand "add<mode>cc"
16587 [(match_operand:SWI 0 "register_operand")
16588 (match_operand 1 "ordered_comparison_operator")
16589 (match_operand:SWI 2 "register_operand")
16590 (match_operand:SWI 3 "const_int_operand")]
16592 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16594 ;; Misc patterns (?)
16596 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16597 ;; Otherwise there will be nothing to keep
16599 ;; [(set (reg ebp) (reg esp))]
16600 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16601 ;; (clobber (eflags)]
16602 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16604 ;; in proper program order.
16606 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16607 [(set (match_operand:P 0 "register_operand" "=r,r")
16608 (plus:P (match_operand:P 1 "register_operand" "0,r")
16609 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16610 (clobber (reg:CC FLAGS_REG))
16611 (clobber (mem:BLK (scratch)))]
16614 switch (get_attr_type (insn))
16617 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16620 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16621 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16622 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16624 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16627 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16628 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16631 [(set (attr "type")
16632 (cond [(and (eq_attr "alternative" "0")
16633 (not (match_test "TARGET_OPT_AGU")))
16634 (const_string "alu")
16635 (match_operand:<MODE> 2 "const0_operand")
16636 (const_string "imov")
16638 (const_string "lea")))
16639 (set (attr "length_immediate")
16640 (cond [(eq_attr "type" "imov")
16642 (and (eq_attr "type" "alu")
16643 (match_operand 2 "const128_operand"))
16646 (const_string "*")))
16647 (set_attr "mode" "<MODE>")])
16649 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16650 [(set (match_operand:P 0 "register_operand" "=r")
16651 (minus:P (match_operand:P 1 "register_operand" "0")
16652 (match_operand:P 2 "register_operand" "r")))
16653 (clobber (reg:CC FLAGS_REG))
16654 (clobber (mem:BLK (scratch)))]
16656 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16657 [(set_attr "type" "alu")
16658 (set_attr "mode" "<MODE>")])
16660 (define_insn "allocate_stack_worker_probe_<mode>"
16661 [(set (match_operand:P 0 "register_operand" "=a")
16662 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16663 UNSPECV_STACK_PROBE))
16664 (clobber (reg:CC FLAGS_REG))]
16665 "ix86_target_stack_probe ()"
16666 "call\t___chkstk_ms"
16667 [(set_attr "type" "multi")
16668 (set_attr "length" "5")])
16670 (define_expand "allocate_stack"
16671 [(match_operand 0 "register_operand")
16672 (match_operand 1 "general_operand")]
16673 "ix86_target_stack_probe ()"
16677 #ifndef CHECK_STACK_LIMIT
16678 #define CHECK_STACK_LIMIT 0
16681 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16682 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16686 rtx (*insn) (rtx, rtx);
16688 x = copy_to_mode_reg (Pmode, operands[1]);
16690 insn = (TARGET_64BIT
16691 ? gen_allocate_stack_worker_probe_di
16692 : gen_allocate_stack_worker_probe_si);
16694 emit_insn (insn (x, x));
16697 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16698 stack_pointer_rtx, 0, OPTAB_DIRECT);
16700 if (x != stack_pointer_rtx)
16701 emit_move_insn (stack_pointer_rtx, x);
16703 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16707 ;; Use IOR for stack probes, this is shorter.
16708 (define_expand "probe_stack"
16709 [(match_operand 0 "memory_operand")]
16712 rtx (*gen_ior3) (rtx, rtx, rtx);
16714 gen_ior3 = (GET_MODE (operands[0]) == DImode
16715 ? gen_iordi3 : gen_iorsi3);
16717 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16721 (define_insn "adjust_stack_and_probe<mode>"
16722 [(set (match_operand:P 0 "register_operand" "=r")
16723 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16724 UNSPECV_PROBE_STACK_RANGE))
16725 (set (reg:P SP_REG)
16726 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16727 (clobber (reg:CC FLAGS_REG))
16728 (clobber (mem:BLK (scratch)))]
16730 "* return output_adjust_stack_and_probe (operands[0]);"
16731 [(set_attr "type" "multi")])
16733 (define_insn "probe_stack_range<mode>"
16734 [(set (match_operand:P 0 "register_operand" "=r")
16735 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16736 (match_operand:P 2 "const_int_operand" "n")]
16737 UNSPECV_PROBE_STACK_RANGE))
16738 (clobber (reg:CC FLAGS_REG))]
16740 "* return output_probe_stack_range (operands[0], operands[2]);"
16741 [(set_attr "type" "multi")])
16743 (define_expand "builtin_setjmp_receiver"
16744 [(label_ref (match_operand 0))]
16745 "!TARGET_64BIT && flag_pic"
16751 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16752 rtx label_rtx = gen_label_rtx ();
16753 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16754 xops[0] = xops[1] = picreg;
16755 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16756 ix86_expand_binary_operator (MINUS, SImode, xops);
16760 emit_insn (gen_set_got (pic_offset_table_rtx));
16764 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16767 [(set (match_operand 0 "register_operand")
16768 (match_operator 3 "promotable_binary_operator"
16769 [(match_operand 1 "register_operand")
16770 (match_operand 2 "aligned_operand")]))
16771 (clobber (reg:CC FLAGS_REG))]
16772 "! TARGET_PARTIAL_REG_STALL && reload_completed
16773 && ((GET_MODE (operands[0]) == HImode
16774 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16775 /* ??? next two lines just !satisfies_constraint_K (...) */
16776 || !CONST_INT_P (operands[2])
16777 || satisfies_constraint_K (operands[2])))
16778 || (GET_MODE (operands[0]) == QImode
16779 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16780 [(parallel [(set (match_dup 0)
16781 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16782 (clobber (reg:CC FLAGS_REG))])]
16784 operands[0] = gen_lowpart (SImode, operands[0]);
16785 operands[1] = gen_lowpart (SImode, operands[1]);
16786 if (GET_CODE (operands[3]) != ASHIFT)
16787 operands[2] = gen_lowpart (SImode, operands[2]);
16788 PUT_MODE (operands[3], SImode);
16791 ; Promote the QImode tests, as i386 has encoding of the AND
16792 ; instruction with 32-bit sign-extended immediate and thus the
16793 ; instruction size is unchanged, except in the %eax case for
16794 ; which it is increased by one byte, hence the ! optimize_size.
16796 [(set (match_operand 0 "flags_reg_operand")
16797 (match_operator 2 "compare_operator"
16798 [(and (match_operand 3 "aligned_operand")
16799 (match_operand 4 "const_int_operand"))
16801 (set (match_operand 1 "register_operand")
16802 (and (match_dup 3) (match_dup 4)))]
16803 "! TARGET_PARTIAL_REG_STALL && reload_completed
16804 && optimize_insn_for_speed_p ()
16805 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16806 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16807 /* Ensure that the operand will remain sign-extended immediate. */
16808 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16809 [(parallel [(set (match_dup 0)
16810 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16813 (and:SI (match_dup 3) (match_dup 4)))])]
16816 = gen_int_mode (INTVAL (operands[4])
16817 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16818 operands[1] = gen_lowpart (SImode, operands[1]);
16819 operands[3] = gen_lowpart (SImode, operands[3]);
16822 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16823 ; the TEST instruction with 32-bit sign-extended immediate and thus
16824 ; the instruction size would at least double, which is not what we
16825 ; want even with ! optimize_size.
16827 [(set (match_operand 0 "flags_reg_operand")
16828 (match_operator 1 "compare_operator"
16829 [(and (match_operand:HI 2 "aligned_operand")
16830 (match_operand:HI 3 "const_int_operand"))
16832 "! TARGET_PARTIAL_REG_STALL && reload_completed
16833 && ! TARGET_FAST_PREFIX
16834 && optimize_insn_for_speed_p ()
16835 /* Ensure that the operand will remain sign-extended immediate. */
16836 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16837 [(set (match_dup 0)
16838 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16842 = gen_int_mode (INTVAL (operands[3])
16843 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16844 operands[2] = gen_lowpart (SImode, operands[2]);
16848 [(set (match_operand 0 "register_operand")
16849 (neg (match_operand 1 "register_operand")))
16850 (clobber (reg:CC FLAGS_REG))]
16851 "! TARGET_PARTIAL_REG_STALL && reload_completed
16852 && (GET_MODE (operands[0]) == HImode
16853 || (GET_MODE (operands[0]) == QImode
16854 && (TARGET_PROMOTE_QImode
16855 || optimize_insn_for_size_p ())))"
16856 [(parallel [(set (match_dup 0)
16857 (neg:SI (match_dup 1)))
16858 (clobber (reg:CC FLAGS_REG))])]
16860 operands[0] = gen_lowpart (SImode, operands[0]);
16861 operands[1] = gen_lowpart (SImode, operands[1]);
16865 [(set (match_operand 0 "register_operand")
16866 (not (match_operand 1 "register_operand")))]
16867 "! TARGET_PARTIAL_REG_STALL && reload_completed
16868 && (GET_MODE (operands[0]) == HImode
16869 || (GET_MODE (operands[0]) == QImode
16870 && (TARGET_PROMOTE_QImode
16871 || optimize_insn_for_size_p ())))"
16872 [(set (match_dup 0)
16873 (not:SI (match_dup 1)))]
16875 operands[0] = gen_lowpart (SImode, operands[0]);
16876 operands[1] = gen_lowpart (SImode, operands[1]);
16879 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16880 ;; transform a complex memory operation into two memory to register operations.
16882 ;; Don't push memory operands
16884 [(set (match_operand:SWI 0 "push_operand")
16885 (match_operand:SWI 1 "memory_operand"))
16886 (match_scratch:SWI 2 "<r>")]
16887 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16888 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16889 [(set (match_dup 2) (match_dup 1))
16890 (set (match_dup 0) (match_dup 2))])
16892 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16895 [(set (match_operand:SF 0 "push_operand")
16896 (match_operand:SF 1 "memory_operand"))
16897 (match_scratch:SF 2 "r")]
16898 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16899 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16900 [(set (match_dup 2) (match_dup 1))
16901 (set (match_dup 0) (match_dup 2))])
16903 ;; Don't move an immediate directly to memory when the instruction
16904 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
16906 [(match_scratch:SWI124 1 "<r>")
16907 (set (match_operand:SWI124 0 "memory_operand")
16909 "optimize_insn_for_speed_p ()
16910 && ((<MODE>mode == HImode
16911 && TARGET_LCP_STALL)
16912 || (!TARGET_USE_MOV0
16913 && TARGET_SPLIT_LONG_MOVES
16914 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
16915 && peep2_regno_dead_p (0, FLAGS_REG)"
16916 [(parallel [(set (match_dup 2) (const_int 0))
16917 (clobber (reg:CC FLAGS_REG))])
16918 (set (match_dup 0) (match_dup 1))]
16919 "operands[2] = gen_lowpart (SImode, operands[1]);")
16922 [(match_scratch:SWI124 2 "<r>")
16923 (set (match_operand:SWI124 0 "memory_operand")
16924 (match_operand:SWI124 1 "immediate_operand"))]
16925 "optimize_insn_for_speed_p ()
16926 && ((<MODE>mode == HImode
16927 && TARGET_LCP_STALL)
16928 || (TARGET_SPLIT_LONG_MOVES
16929 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
16930 [(set (match_dup 2) (match_dup 1))
16931 (set (match_dup 0) (match_dup 2))])
16933 ;; Don't compare memory with zero, load and use a test instead.
16935 [(set (match_operand 0 "flags_reg_operand")
16936 (match_operator 1 "compare_operator"
16937 [(match_operand:SI 2 "memory_operand")
16939 (match_scratch:SI 3 "r")]
16940 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16941 [(set (match_dup 3) (match_dup 2))
16942 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16944 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16945 ;; Don't split NOTs with a displacement operand, because resulting XOR
16946 ;; will not be pairable anyway.
16948 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16949 ;; represented using a modRM byte. The XOR replacement is long decoded,
16950 ;; so this split helps here as well.
16952 ;; Note: Can't do this as a regular split because we can't get proper
16953 ;; lifetime information then.
16956 [(set (match_operand:SWI124 0 "nonimmediate_operand")
16957 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
16958 "optimize_insn_for_speed_p ()
16959 && ((TARGET_NOT_UNPAIRABLE
16960 && (!MEM_P (operands[0])
16961 || !memory_displacement_operand (operands[0], <MODE>mode)))
16962 || (TARGET_NOT_VECTORMODE
16963 && long_memory_operand (operands[0], <MODE>mode)))
16964 && peep2_regno_dead_p (0, FLAGS_REG)"
16965 [(parallel [(set (match_dup 0)
16966 (xor:SWI124 (match_dup 1) (const_int -1)))
16967 (clobber (reg:CC FLAGS_REG))])])
16969 ;; Non pairable "test imm, reg" instructions can be translated to
16970 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16971 ;; byte opcode instead of two, have a short form for byte operands),
16972 ;; so do it for other CPUs as well. Given that the value was dead,
16973 ;; this should not create any new dependencies. Pass on the sub-word
16974 ;; versions if we're concerned about partial register stalls.
16977 [(set (match_operand 0 "flags_reg_operand")
16978 (match_operator 1 "compare_operator"
16979 [(and:SI (match_operand:SI 2 "register_operand")
16980 (match_operand:SI 3 "immediate_operand"))
16982 "ix86_match_ccmode (insn, CCNOmode)
16983 && (true_regnum (operands[2]) != AX_REG
16984 || satisfies_constraint_K (operands[3]))
16985 && peep2_reg_dead_p (1, operands[2])"
16987 [(set (match_dup 0)
16988 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16991 (and:SI (match_dup 2) (match_dup 3)))])])
16993 ;; We don't need to handle HImode case, because it will be promoted to SImode
16994 ;; on ! TARGET_PARTIAL_REG_STALL
16997 [(set (match_operand 0 "flags_reg_operand")
16998 (match_operator 1 "compare_operator"
16999 [(and:QI (match_operand:QI 2 "register_operand")
17000 (match_operand:QI 3 "immediate_operand"))
17002 "! TARGET_PARTIAL_REG_STALL
17003 && ix86_match_ccmode (insn, CCNOmode)
17004 && true_regnum (operands[2]) != AX_REG
17005 && peep2_reg_dead_p (1, operands[2])"
17007 [(set (match_dup 0)
17008 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17011 (and:QI (match_dup 2) (match_dup 3)))])])
17014 [(set (match_operand 0 "flags_reg_operand")
17015 (match_operator 1 "compare_operator"
17018 (match_operand 2 "ext_register_operand")
17021 (match_operand 3 "const_int_operand"))
17023 "! TARGET_PARTIAL_REG_STALL
17024 && ix86_match_ccmode (insn, CCNOmode)
17025 && true_regnum (operands[2]) != AX_REG
17026 && peep2_reg_dead_p (1, operands[2])"
17027 [(parallel [(set (match_dup 0)
17036 (set (zero_extract:SI (match_dup 2)
17044 (match_dup 3)))])])
17046 ;; Don't do logical operations with memory inputs.
17048 [(match_scratch:SI 2 "r")
17049 (parallel [(set (match_operand:SI 0 "register_operand")
17050 (match_operator:SI 3 "arith_or_logical_operator"
17052 (match_operand:SI 1 "memory_operand")]))
17053 (clobber (reg:CC FLAGS_REG))])]
17054 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17055 [(set (match_dup 2) (match_dup 1))
17056 (parallel [(set (match_dup 0)
17057 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17058 (clobber (reg:CC FLAGS_REG))])])
17061 [(match_scratch:SI 2 "r")
17062 (parallel [(set (match_operand:SI 0 "register_operand")
17063 (match_operator:SI 3 "arith_or_logical_operator"
17064 [(match_operand:SI 1 "memory_operand")
17066 (clobber (reg:CC FLAGS_REG))])]
17067 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17068 [(set (match_dup 2) (match_dup 1))
17069 (parallel [(set (match_dup 0)
17070 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17071 (clobber (reg:CC FLAGS_REG))])])
17073 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17074 ;; refers to the destination of the load!
17077 [(set (match_operand:SI 0 "register_operand")
17078 (match_operand:SI 1 "register_operand"))
17079 (parallel [(set (match_dup 0)
17080 (match_operator:SI 3 "commutative_operator"
17082 (match_operand:SI 2 "memory_operand")]))
17083 (clobber (reg:CC FLAGS_REG))])]
17084 "REGNO (operands[0]) != REGNO (operands[1])
17085 && GENERAL_REGNO_P (REGNO (operands[0]))
17086 && GENERAL_REGNO_P (REGNO (operands[1]))"
17087 [(set (match_dup 0) (match_dup 4))
17088 (parallel [(set (match_dup 0)
17089 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17090 (clobber (reg:CC FLAGS_REG))])]
17091 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17094 [(set (match_operand 0 "register_operand")
17095 (match_operand 1 "register_operand"))
17097 (match_operator 3 "commutative_operator"
17099 (match_operand 2 "memory_operand")]))]
17100 "REGNO (operands[0]) != REGNO (operands[1])
17101 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17102 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17103 [(set (match_dup 0) (match_dup 2))
17105 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17107 ; Don't do logical operations with memory outputs
17109 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17110 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17111 ; the same decoder scheduling characteristics as the original.
17114 [(match_scratch:SI 2 "r")
17115 (parallel [(set (match_operand:SI 0 "memory_operand")
17116 (match_operator:SI 3 "arith_or_logical_operator"
17118 (match_operand:SI 1 "nonmemory_operand")]))
17119 (clobber (reg:CC FLAGS_REG))])]
17120 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17121 /* Do not split stack checking probes. */
17122 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17123 [(set (match_dup 2) (match_dup 0))
17124 (parallel [(set (match_dup 2)
17125 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17126 (clobber (reg:CC FLAGS_REG))])
17127 (set (match_dup 0) (match_dup 2))])
17130 [(match_scratch:SI 2 "r")
17131 (parallel [(set (match_operand:SI 0 "memory_operand")
17132 (match_operator:SI 3 "arith_or_logical_operator"
17133 [(match_operand:SI 1 "nonmemory_operand")
17135 (clobber (reg:CC FLAGS_REG))])]
17136 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17137 /* Do not split stack checking probes. */
17138 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17139 [(set (match_dup 2) (match_dup 0))
17140 (parallel [(set (match_dup 2)
17141 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17142 (clobber (reg:CC FLAGS_REG))])
17143 (set (match_dup 0) (match_dup 2))])
17145 ;; Attempt to use arith or logical operations with memory outputs with
17146 ;; setting of flags.
17148 [(set (match_operand:SWI 0 "register_operand")
17149 (match_operand:SWI 1 "memory_operand"))
17150 (parallel [(set (match_dup 0)
17151 (match_operator:SWI 3 "plusminuslogic_operator"
17153 (match_operand:SWI 2 "<nonmemory_operand>")]))
17154 (clobber (reg:CC FLAGS_REG))])
17155 (set (match_dup 1) (match_dup 0))
17156 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17157 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17158 && peep2_reg_dead_p (4, operands[0])
17159 && !reg_overlap_mentioned_p (operands[0], operands[1])
17160 && (<MODE>mode != QImode
17161 || immediate_operand (operands[2], QImode)
17162 || q_regs_operand (operands[2], QImode))
17163 && ix86_match_ccmode (peep2_next_insn (3),
17164 (GET_CODE (operands[3]) == PLUS
17165 || GET_CODE (operands[3]) == MINUS)
17166 ? CCGOCmode : CCNOmode)"
17167 [(parallel [(set (match_dup 4) (match_dup 5))
17168 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17169 (match_dup 2)]))])]
17171 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17172 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17173 copy_rtx (operands[1]),
17174 copy_rtx (operands[2]));
17175 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17176 operands[5], const0_rtx);
17180 [(parallel [(set (match_operand:SWI 0 "register_operand")
17181 (match_operator:SWI 2 "plusminuslogic_operator"
17183 (match_operand:SWI 1 "memory_operand")]))
17184 (clobber (reg:CC FLAGS_REG))])
17185 (set (match_dup 1) (match_dup 0))
17186 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17187 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17188 && GET_CODE (operands[2]) != MINUS
17189 && peep2_reg_dead_p (3, operands[0])
17190 && !reg_overlap_mentioned_p (operands[0], operands[1])
17191 && ix86_match_ccmode (peep2_next_insn (2),
17192 GET_CODE (operands[2]) == PLUS
17193 ? CCGOCmode : CCNOmode)"
17194 [(parallel [(set (match_dup 3) (match_dup 4))
17195 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17196 (match_dup 0)]))])]
17198 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17199 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17200 copy_rtx (operands[1]),
17201 copy_rtx (operands[0]));
17202 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17203 operands[4], const0_rtx);
17207 [(set (match_operand:SWI12 0 "register_operand")
17208 (match_operand:SWI12 1 "memory_operand"))
17209 (parallel [(set (match_operand:SI 4 "register_operand")
17210 (match_operator:SI 3 "plusminuslogic_operator"
17212 (match_operand:SI 2 "nonmemory_operand")]))
17213 (clobber (reg:CC FLAGS_REG))])
17214 (set (match_dup 1) (match_dup 0))
17215 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17216 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17217 && REG_P (operands[0]) && REG_P (operands[4])
17218 && REGNO (operands[0]) == REGNO (operands[4])
17219 && peep2_reg_dead_p (4, operands[0])
17220 && (<MODE>mode != QImode
17221 || immediate_operand (operands[2], SImode)
17222 || q_regs_operand (operands[2], SImode))
17223 && !reg_overlap_mentioned_p (operands[0], operands[1])
17224 && ix86_match_ccmode (peep2_next_insn (3),
17225 (GET_CODE (operands[3]) == PLUS
17226 || GET_CODE (operands[3]) == MINUS)
17227 ? CCGOCmode : CCNOmode)"
17228 [(parallel [(set (match_dup 4) (match_dup 5))
17229 (set (match_dup 1) (match_dup 6))])]
17231 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17232 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17233 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17234 copy_rtx (operands[1]), operands[2]);
17235 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17236 operands[5], const0_rtx);
17237 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17238 copy_rtx (operands[1]),
17239 copy_rtx (operands[2]));
17242 ;; Attempt to always use XOR for zeroing registers.
17244 [(set (match_operand 0 "register_operand")
17245 (match_operand 1 "const0_operand"))]
17246 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17247 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17248 && GENERAL_REG_P (operands[0])
17249 && peep2_regno_dead_p (0, FLAGS_REG)"
17250 [(parallel [(set (match_dup 0) (const_int 0))
17251 (clobber (reg:CC FLAGS_REG))])]
17252 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17255 [(set (strict_low_part (match_operand 0 "register_operand"))
17257 "(GET_MODE (operands[0]) == QImode
17258 || GET_MODE (operands[0]) == HImode)
17259 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17260 && peep2_regno_dead_p (0, FLAGS_REG)"
17261 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17262 (clobber (reg:CC FLAGS_REG))])])
17264 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17266 [(set (match_operand:SWI248 0 "register_operand")
17268 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17269 && peep2_regno_dead_p (0, FLAGS_REG)"
17270 [(parallel [(set (match_dup 0) (const_int -1))
17271 (clobber (reg:CC FLAGS_REG))])]
17273 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17274 operands[0] = gen_lowpart (SImode, operands[0]);
17277 ;; Attempt to convert simple lea to add/shift.
17278 ;; These can be created by move expanders.
17281 [(set (match_operand:SWI48 0 "register_operand")
17282 (plus:SWI48 (match_dup 0)
17283 (match_operand:SWI48 1 "<nonmemory_operand>")))]
17284 "peep2_regno_dead_p (0, FLAGS_REG)"
17285 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17286 (clobber (reg:CC FLAGS_REG))])])
17289 [(set (match_operand:SWI48 0 "register_operand")
17290 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
17292 "peep2_regno_dead_p (0, FLAGS_REG)"
17293 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17294 (clobber (reg:CC FLAGS_REG))])])
17297 [(set (match_operand:SI 0 "register_operand")
17298 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand")
17299 (match_operand:DI 2 "nonmemory_operand")) 0))]
17301 && peep2_regno_dead_p (0, FLAGS_REG)
17302 && REGNO (operands[0]) == REGNO (operands[1])"
17303 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17304 (clobber (reg:CC FLAGS_REG))])]
17305 "operands[2] = gen_lowpart (SImode, operands[2]);")
17308 [(set (match_operand:SI 0 "register_operand")
17309 (subreg:SI (plus:DI (match_operand:DI 1 "nonmemory_operand")
17310 (match_operand:DI 2 "register_operand")) 0))]
17312 && peep2_regno_dead_p (0, FLAGS_REG)
17313 && REGNO (operands[0]) == REGNO (operands[2])"
17314 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
17315 (clobber (reg:CC FLAGS_REG))])]
17316 "operands[1] = gen_lowpart (SImode, operands[1]);")
17319 [(set (match_operand:SWI48 0 "register_operand")
17320 (mult:SWI48 (match_dup 0)
17321 (match_operand:SWI48 1 "const_int_operand")))]
17322 "exact_log2 (INTVAL (operands[1])) >= 0
17323 && peep2_regno_dead_p (0, FLAGS_REG)"
17324 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17325 (clobber (reg:CC FLAGS_REG))])]
17326 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17329 [(set (match_operand:SI 0 "register_operand")
17330 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand")
17331 (match_operand:DI 2 "const_int_operand")) 0))]
17333 && exact_log2 (INTVAL (operands[2])) >= 0
17334 && REGNO (operands[0]) == REGNO (operands[1])
17335 && peep2_regno_dead_p (0, FLAGS_REG)"
17336 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17337 (clobber (reg:CC FLAGS_REG))])]
17338 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17340 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17341 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17342 ;; On many CPUs it is also faster, since special hardware to avoid esp
17343 ;; dependencies is present.
17345 ;; While some of these conversions may be done using splitters, we use
17346 ;; peepholes in order to allow combine_stack_adjustments pass to see
17347 ;; nonobfuscated RTL.
17349 ;; Convert prologue esp subtractions to push.
17350 ;; We need register to push. In order to keep verify_flow_info happy we have
17352 ;; - use scratch and clobber it in order to avoid dependencies
17353 ;; - use already live register
17354 ;; We can't use the second way right now, since there is no reliable way how to
17355 ;; verify that given register is live. First choice will also most likely in
17356 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17357 ;; call clobbered registers are dead. We may want to use base pointer as an
17358 ;; alternative when no register is available later.
17361 [(match_scratch:W 1 "r")
17362 (parallel [(set (reg:P SP_REG)
17363 (plus:P (reg:P SP_REG)
17364 (match_operand:P 0 "const_int_operand")))
17365 (clobber (reg:CC FLAGS_REG))
17366 (clobber (mem:BLK (scratch)))])]
17367 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17368 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17369 [(clobber (match_dup 1))
17370 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17371 (clobber (mem:BLK (scratch)))])])
17374 [(match_scratch:W 1 "r")
17375 (parallel [(set (reg:P SP_REG)
17376 (plus:P (reg:P SP_REG)
17377 (match_operand:P 0 "const_int_operand")))
17378 (clobber (reg:CC FLAGS_REG))
17379 (clobber (mem:BLK (scratch)))])]
17380 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17381 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17382 [(clobber (match_dup 1))
17383 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17384 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17385 (clobber (mem:BLK (scratch)))])])
17387 ;; Convert esp subtractions to push.
17389 [(match_scratch:W 1 "r")
17390 (parallel [(set (reg:P SP_REG)
17391 (plus:P (reg:P SP_REG)
17392 (match_operand:P 0 "const_int_operand")))
17393 (clobber (reg:CC FLAGS_REG))])]
17394 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17395 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17396 [(clobber (match_dup 1))
17397 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17400 [(match_scratch:W 1 "r")
17401 (parallel [(set (reg:P SP_REG)
17402 (plus:P (reg:P SP_REG)
17403 (match_operand:P 0 "const_int_operand")))
17404 (clobber (reg:CC FLAGS_REG))])]
17405 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17406 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17407 [(clobber (match_dup 1))
17408 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17409 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17411 ;; Convert epilogue deallocator to pop.
17413 [(match_scratch:W 1 "r")
17414 (parallel [(set (reg:P SP_REG)
17415 (plus:P (reg:P SP_REG)
17416 (match_operand:P 0 "const_int_operand")))
17417 (clobber (reg:CC FLAGS_REG))
17418 (clobber (mem:BLK (scratch)))])]
17419 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17420 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17421 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17422 (clobber (mem:BLK (scratch)))])])
17424 ;; Two pops case is tricky, since pop causes dependency
17425 ;; on destination register. We use two registers if available.
17427 [(match_scratch:W 1 "r")
17428 (match_scratch:W 2 "r")
17429 (parallel [(set (reg:P SP_REG)
17430 (plus:P (reg:P SP_REG)
17431 (match_operand:P 0 "const_int_operand")))
17432 (clobber (reg:CC FLAGS_REG))
17433 (clobber (mem:BLK (scratch)))])]
17434 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17435 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17436 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17437 (clobber (mem:BLK (scratch)))])
17438 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17441 [(match_scratch:W 1 "r")
17442 (parallel [(set (reg:P SP_REG)
17443 (plus:P (reg:P SP_REG)
17444 (match_operand:P 0 "const_int_operand")))
17445 (clobber (reg:CC FLAGS_REG))
17446 (clobber (mem:BLK (scratch)))])]
17447 "optimize_insn_for_size_p ()
17448 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17449 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17450 (clobber (mem:BLK (scratch)))])
17451 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17453 ;; Convert esp additions to pop.
17455 [(match_scratch:W 1 "r")
17456 (parallel [(set (reg:P SP_REG)
17457 (plus:P (reg:P SP_REG)
17458 (match_operand:P 0 "const_int_operand")))
17459 (clobber (reg:CC FLAGS_REG))])]
17460 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17461 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17463 ;; Two pops case is tricky, since pop causes dependency
17464 ;; on destination register. We use two registers if available.
17466 [(match_scratch:W 1 "r")
17467 (match_scratch:W 2 "r")
17468 (parallel [(set (reg:P SP_REG)
17469 (plus:P (reg:P SP_REG)
17470 (match_operand:P 0 "const_int_operand")))
17471 (clobber (reg:CC FLAGS_REG))])]
17472 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17473 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17474 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17477 [(match_scratch:W 1 "r")
17478 (parallel [(set (reg:P SP_REG)
17479 (plus:P (reg:P SP_REG)
17480 (match_operand:P 0 "const_int_operand")))
17481 (clobber (reg:CC FLAGS_REG))])]
17482 "optimize_insn_for_size_p ()
17483 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17484 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17485 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17487 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17488 ;; required and register dies. Similarly for 128 to -128.
17490 [(set (match_operand 0 "flags_reg_operand")
17491 (match_operator 1 "compare_operator"
17492 [(match_operand 2 "register_operand")
17493 (match_operand 3 "const_int_operand")]))]
17494 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17495 && incdec_operand (operands[3], GET_MODE (operands[3])))
17496 || (!TARGET_FUSE_CMP_AND_BRANCH
17497 && INTVAL (operands[3]) == 128))
17498 && ix86_match_ccmode (insn, CCGCmode)
17499 && peep2_reg_dead_p (1, operands[2])"
17500 [(parallel [(set (match_dup 0)
17501 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17502 (clobber (match_dup 2))])])
17504 ;; Convert imul by three, five and nine into lea
17507 [(set (match_operand:SWI48 0 "register_operand")
17508 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
17509 (match_operand:SWI48 2 "const359_operand")))
17510 (clobber (reg:CC FLAGS_REG))])]
17511 "!TARGET_PARTIAL_REG_STALL
17512 || <MODE>mode == SImode
17513 || optimize_function_for_size_p (cfun)"
17514 [(set (match_dup 0)
17515 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17517 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17521 [(set (match_operand:SWI48 0 "register_operand")
17522 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17523 (match_operand:SWI48 2 "const359_operand")))
17524 (clobber (reg:CC FLAGS_REG))])]
17525 "optimize_insn_for_speed_p ()
17526 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17527 [(set (match_dup 0) (match_dup 1))
17529 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17531 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17533 ;; imul $32bit_imm, mem, reg is vector decoded, while
17534 ;; imul $32bit_imm, reg, reg is direct decoded.
17536 [(match_scratch:SWI48 3 "r")
17537 (parallel [(set (match_operand:SWI48 0 "register_operand")
17538 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
17539 (match_operand:SWI48 2 "immediate_operand")))
17540 (clobber (reg:CC FLAGS_REG))])]
17541 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17542 && !satisfies_constraint_K (operands[2])"
17543 [(set (match_dup 3) (match_dup 1))
17544 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17545 (clobber (reg:CC FLAGS_REG))])])
17548 [(match_scratch:SI 3 "r")
17549 (parallel [(set (match_operand:DI 0 "register_operand")
17551 (mult:SI (match_operand:SI 1 "memory_operand")
17552 (match_operand:SI 2 "immediate_operand"))))
17553 (clobber (reg:CC FLAGS_REG))])]
17555 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17556 && !satisfies_constraint_K (operands[2])"
17557 [(set (match_dup 3) (match_dup 1))
17558 (parallel [(set (match_dup 0)
17559 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17560 (clobber (reg:CC FLAGS_REG))])])
17562 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17563 ;; Convert it into imul reg, reg
17564 ;; It would be better to force assembler to encode instruction using long
17565 ;; immediate, but there is apparently no way to do so.
17567 [(parallel [(set (match_operand:SWI248 0 "register_operand")
17569 (match_operand:SWI248 1 "nonimmediate_operand")
17570 (match_operand:SWI248 2 "const_int_operand")))
17571 (clobber (reg:CC FLAGS_REG))])
17572 (match_scratch:SWI248 3 "r")]
17573 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17574 && satisfies_constraint_K (operands[2])"
17575 [(set (match_dup 3) (match_dup 2))
17576 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17577 (clobber (reg:CC FLAGS_REG))])]
17579 if (!rtx_equal_p (operands[0], operands[1]))
17580 emit_move_insn (operands[0], operands[1]);
17583 ;; After splitting up read-modify operations, array accesses with memory
17584 ;; operands might end up in form:
17586 ;; movl 4(%esp), %edx
17588 ;; instead of pre-splitting:
17590 ;; addl 4(%esp), %eax
17592 ;; movl 4(%esp), %edx
17593 ;; leal (%edx,%eax,4), %eax
17596 [(match_scratch:W 5 "r")
17597 (parallel [(set (match_operand 0 "register_operand")
17598 (ashift (match_operand 1 "register_operand")
17599 (match_operand 2 "const_int_operand")))
17600 (clobber (reg:CC FLAGS_REG))])
17601 (parallel [(set (match_operand 3 "register_operand")
17602 (plus (match_dup 0)
17603 (match_operand 4 "x86_64_general_operand")))
17604 (clobber (reg:CC FLAGS_REG))])]
17605 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17606 /* Validate MODE for lea. */
17607 && ((!TARGET_PARTIAL_REG_STALL
17608 && (GET_MODE (operands[0]) == QImode
17609 || GET_MODE (operands[0]) == HImode))
17610 || GET_MODE (operands[0]) == SImode
17611 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17612 && (rtx_equal_p (operands[0], operands[3])
17613 || peep2_reg_dead_p (2, operands[0]))
17614 /* We reorder load and the shift. */
17615 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17616 [(set (match_dup 5) (match_dup 4))
17617 (set (match_dup 0) (match_dup 1))]
17619 enum machine_mode op1mode = GET_MODE (operands[1]);
17620 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17621 int scale = 1 << INTVAL (operands[2]);
17622 rtx index = gen_lowpart (word_mode, operands[1]);
17623 rtx base = gen_lowpart (word_mode, operands[5]);
17624 rtx dest = gen_lowpart (mode, operands[3]);
17626 operands[1] = gen_rtx_PLUS (word_mode, base,
17627 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
17628 operands[5] = base;
17629 if (mode != word_mode)
17630 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17631 if (op1mode != word_mode)
17632 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17633 operands[0] = dest;
17636 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17637 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17638 ;; caught for use by garbage collectors and the like. Using an insn that
17639 ;; maps to SIGILL makes it more likely the program will rightfully die.
17640 ;; Keeping with tradition, "6" is in honor of #UD.
17641 (define_insn "trap"
17642 [(trap_if (const_int 1) (const_int 6))]
17644 { return ASM_SHORT "0x0b0f"; }
17645 [(set_attr "length" "2")])
17647 (define_expand "prefetch"
17648 [(prefetch (match_operand 0 "address_operand")
17649 (match_operand:SI 1 "const_int_operand")
17650 (match_operand:SI 2 "const_int_operand"))]
17651 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17653 int rw = INTVAL (operands[1]);
17654 int locality = INTVAL (operands[2]);
17656 gcc_assert (rw == 0 || rw == 1);
17657 gcc_assert (locality >= 0 && locality <= 3);
17658 gcc_assert (GET_MODE (operands[0]) == Pmode
17659 || GET_MODE (operands[0]) == VOIDmode);
17661 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17662 supported by SSE counterpart or the SSE prefetch is not available
17663 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17665 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17666 operands[2] = GEN_INT (3);
17668 operands[1] = const0_rtx;
17671 (define_insn "*prefetch_sse_<mode>"
17672 [(prefetch (match_operand:P 0 "address_operand" "p")
17674 (match_operand:SI 1 "const_int_operand"))]
17675 "TARGET_PREFETCH_SSE"
17677 static const char * const patterns[4] = {
17678 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17681 int locality = INTVAL (operands[1]);
17682 gcc_assert (locality >= 0 && locality <= 3);
17684 return patterns[locality];
17686 [(set_attr "type" "sse")
17687 (set_attr "atom_sse_attr" "prefetch")
17688 (set (attr "length_address")
17689 (symbol_ref "memory_address_length (operands[0])"))
17690 (set_attr "memory" "none")])
17692 (define_insn "*prefetch_3dnow_<mode>"
17693 [(prefetch (match_operand:P 0 "address_operand" "p")
17694 (match_operand:SI 1 "const_int_operand" "n")
17698 if (INTVAL (operands[1]) == 0)
17699 return "prefetch\t%a0";
17701 return "prefetchw\t%a0";
17703 [(set_attr "type" "mmx")
17704 (set (attr "length_address")
17705 (symbol_ref "memory_address_length (operands[0])"))
17706 (set_attr "memory" "none")])
17708 (define_expand "stack_protect_set"
17709 [(match_operand 0 "memory_operand")
17710 (match_operand 1 "memory_operand")]
17713 rtx (*insn)(rtx, rtx);
17715 #ifdef TARGET_THREAD_SSP_OFFSET
17716 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17717 insn = (TARGET_LP64
17718 ? gen_stack_tls_protect_set_di
17719 : gen_stack_tls_protect_set_si);
17721 insn = (TARGET_LP64
17722 ? gen_stack_protect_set_di
17723 : gen_stack_protect_set_si);
17726 emit_insn (insn (operands[0], operands[1]));
17730 (define_insn "stack_protect_set_<mode>"
17731 [(set (match_operand:PTR 0 "memory_operand" "=m")
17732 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17734 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17735 (clobber (reg:CC FLAGS_REG))]
17737 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17738 [(set_attr "type" "multi")])
17740 (define_insn "stack_tls_protect_set_<mode>"
17741 [(set (match_operand:PTR 0 "memory_operand" "=m")
17742 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17743 UNSPEC_SP_TLS_SET))
17744 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17745 (clobber (reg:CC FLAGS_REG))]
17747 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17748 [(set_attr "type" "multi")])
17750 (define_expand "stack_protect_test"
17751 [(match_operand 0 "memory_operand")
17752 (match_operand 1 "memory_operand")
17756 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17758 rtx (*insn)(rtx, rtx, rtx);
17760 #ifdef TARGET_THREAD_SSP_OFFSET
17761 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17762 insn = (TARGET_LP64
17763 ? gen_stack_tls_protect_test_di
17764 : gen_stack_tls_protect_test_si);
17766 insn = (TARGET_LP64
17767 ? gen_stack_protect_test_di
17768 : gen_stack_protect_test_si);
17771 emit_insn (insn (flags, operands[0], operands[1]));
17773 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17774 flags, const0_rtx, operands[2]));
17778 (define_insn "stack_protect_test_<mode>"
17779 [(set (match_operand:CCZ 0 "flags_reg_operand")
17780 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17781 (match_operand:PTR 2 "memory_operand" "m")]
17783 (clobber (match_scratch:PTR 3 "=&r"))]
17785 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17786 [(set_attr "type" "multi")])
17788 (define_insn "stack_tls_protect_test_<mode>"
17789 [(set (match_operand:CCZ 0 "flags_reg_operand")
17790 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17791 (match_operand:PTR 2 "const_int_operand" "i")]
17792 UNSPEC_SP_TLS_TEST))
17793 (clobber (match_scratch:PTR 3 "=r"))]
17795 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17796 [(set_attr "type" "multi")])
17798 (define_insn "sse4_2_crc32<mode>"
17799 [(set (match_operand:SI 0 "register_operand" "=r")
17801 [(match_operand:SI 1 "register_operand" "0")
17802 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17804 "TARGET_SSE4_2 || TARGET_CRC32"
17805 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17806 [(set_attr "type" "sselog1")
17807 (set_attr "prefix_rep" "1")
17808 (set_attr "prefix_extra" "1")
17809 (set (attr "prefix_data16")
17810 (if_then_else (match_operand:HI 2)
17812 (const_string "*")))
17813 (set (attr "prefix_rex")
17814 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
17816 (const_string "*")))
17817 (set_attr "mode" "SI")])
17819 (define_insn "sse4_2_crc32di"
17820 [(set (match_operand:DI 0 "register_operand" "=r")
17822 [(match_operand:DI 1 "register_operand" "0")
17823 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17825 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17826 "crc32{q}\t{%2, %0|%0, %2}"
17827 [(set_attr "type" "sselog1")
17828 (set_attr "prefix_rep" "1")
17829 (set_attr "prefix_extra" "1")
17830 (set_attr "mode" "DI")])
17832 (define_expand "rdpmc"
17833 [(match_operand:DI 0 "register_operand")
17834 (match_operand:SI 1 "register_operand")]
17837 rtx reg = gen_reg_rtx (DImode);
17840 /* Force operand 1 into ECX. */
17841 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17842 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17843 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17848 rtvec vec = rtvec_alloc (2);
17849 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17850 rtx upper = gen_reg_rtx (DImode);
17851 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17852 gen_rtvec (1, const0_rtx),
17854 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17855 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17857 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17858 NULL, 1, OPTAB_DIRECT);
17859 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17863 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17864 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17868 (define_insn "*rdpmc"
17869 [(set (match_operand:DI 0 "register_operand" "=A")
17870 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17874 [(set_attr "type" "other")
17875 (set_attr "length" "2")])
17877 (define_insn "*rdpmc_rex64"
17878 [(set (match_operand:DI 0 "register_operand" "=a")
17879 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17881 (set (match_operand:DI 1 "register_operand" "=d")
17882 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17885 [(set_attr "type" "other")
17886 (set_attr "length" "2")])
17888 (define_expand "rdtsc"
17889 [(set (match_operand:DI 0 "register_operand")
17890 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17895 rtvec vec = rtvec_alloc (2);
17896 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17897 rtx upper = gen_reg_rtx (DImode);
17898 rtx lower = gen_reg_rtx (DImode);
17899 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17900 gen_rtvec (1, const0_rtx),
17902 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17903 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17905 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17906 NULL, 1, OPTAB_DIRECT);
17907 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17909 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17914 (define_insn "*rdtsc"
17915 [(set (match_operand:DI 0 "register_operand" "=A")
17916 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17919 [(set_attr "type" "other")
17920 (set_attr "length" "2")])
17922 (define_insn "*rdtsc_rex64"
17923 [(set (match_operand:DI 0 "register_operand" "=a")
17924 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17925 (set (match_operand:DI 1 "register_operand" "=d")
17926 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17929 [(set_attr "type" "other")
17930 (set_attr "length" "2")])
17932 (define_expand "rdtscp"
17933 [(match_operand:DI 0 "register_operand")
17934 (match_operand:SI 1 "memory_operand")]
17937 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17938 gen_rtvec (1, const0_rtx),
17940 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17941 gen_rtvec (1, const0_rtx),
17943 rtx reg = gen_reg_rtx (DImode);
17944 rtx tmp = gen_reg_rtx (SImode);
17948 rtvec vec = rtvec_alloc (3);
17949 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17950 rtx upper = gen_reg_rtx (DImode);
17951 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17952 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17953 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17955 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17956 NULL, 1, OPTAB_DIRECT);
17957 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17962 rtvec vec = rtvec_alloc (2);
17963 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17964 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17965 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17968 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17969 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17973 (define_insn "*rdtscp"
17974 [(set (match_operand:DI 0 "register_operand" "=A")
17975 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17976 (set (match_operand:SI 1 "register_operand" "=c")
17977 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17980 [(set_attr "type" "other")
17981 (set_attr "length" "3")])
17983 (define_insn "*rdtscp_rex64"
17984 [(set (match_operand:DI 0 "register_operand" "=a")
17985 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17986 (set (match_operand:DI 1 "register_operand" "=d")
17987 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17988 (set (match_operand:SI 2 "register_operand" "=c")
17989 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17992 [(set_attr "type" "other")
17993 (set_attr "length" "3")])
17995 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17997 ;; LWP instructions
17999 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18001 (define_expand "lwp_llwpcb"
18002 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18003 UNSPECV_LLWP_INTRINSIC)]
18006 (define_insn "*lwp_llwpcb<mode>1"
18007 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18008 UNSPECV_LLWP_INTRINSIC)]
18011 [(set_attr "type" "lwp")
18012 (set_attr "mode" "<MODE>")
18013 (set_attr "length" "5")])
18015 (define_expand "lwp_slwpcb"
18016 [(set (match_operand 0 "register_operand" "=r")
18017 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18022 insn = (Pmode == DImode
18024 : gen_lwp_slwpcbsi);
18026 emit_insn (insn (operands[0]));
18030 (define_insn "lwp_slwpcb<mode>"
18031 [(set (match_operand:P 0 "register_operand" "=r")
18032 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18035 [(set_attr "type" "lwp")
18036 (set_attr "mode" "<MODE>")
18037 (set_attr "length" "5")])
18039 (define_expand "lwp_lwpval<mode>3"
18040 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18041 (match_operand:SI 2 "nonimmediate_operand" "rm")
18042 (match_operand:SI 3 "const_int_operand" "i")]
18043 UNSPECV_LWPVAL_INTRINSIC)]
18045 ;; Avoid unused variable warning.
18046 "(void) operands[0];")
18048 (define_insn "*lwp_lwpval<mode>3_1"
18049 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18050 (match_operand:SI 1 "nonimmediate_operand" "rm")
18051 (match_operand:SI 2 "const_int_operand" "i")]
18052 UNSPECV_LWPVAL_INTRINSIC)]
18054 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18055 [(set_attr "type" "lwp")
18056 (set_attr "mode" "<MODE>")
18057 (set (attr "length")
18058 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18060 (define_expand "lwp_lwpins<mode>3"
18061 [(set (reg:CCC FLAGS_REG)
18062 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18063 (match_operand:SI 2 "nonimmediate_operand" "rm")
18064 (match_operand:SI 3 "const_int_operand" "i")]
18065 UNSPECV_LWPINS_INTRINSIC))
18066 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18067 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18070 (define_insn "*lwp_lwpins<mode>3_1"
18071 [(set (reg:CCC FLAGS_REG)
18072 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18073 (match_operand:SI 1 "nonimmediate_operand" "rm")
18074 (match_operand:SI 2 "const_int_operand" "i")]
18075 UNSPECV_LWPINS_INTRINSIC))]
18077 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18078 [(set_attr "type" "lwp")
18079 (set_attr "mode" "<MODE>")
18080 (set (attr "length")
18081 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18083 (define_int_iterator RDFSGSBASE
18087 (define_int_iterator WRFSGSBASE
18091 (define_int_attr fsgs
18092 [(UNSPECV_RDFSBASE "fs")
18093 (UNSPECV_RDGSBASE "gs")
18094 (UNSPECV_WRFSBASE "fs")
18095 (UNSPECV_WRGSBASE "gs")])
18097 (define_insn "rd<fsgs>base<mode>"
18098 [(set (match_operand:SWI48 0 "register_operand" "=r")
18099 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
18100 "TARGET_64BIT && TARGET_FSGSBASE"
18102 [(set_attr "type" "other")
18103 (set_attr "prefix_extra" "2")])
18105 (define_insn "wr<fsgs>base<mode>"
18106 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18108 "TARGET_64BIT && TARGET_FSGSBASE"
18110 [(set_attr "type" "other")
18111 (set_attr "prefix_extra" "2")])
18113 (define_insn "rdrand<mode>_1"
18114 [(set (match_operand:SWI248 0 "register_operand" "=r")
18115 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18116 (set (reg:CCC FLAGS_REG)
18117 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18120 [(set_attr "type" "other")
18121 (set_attr "prefix_extra" "1")])
18123 (define_expand "pause"
18124 [(set (match_dup 0)
18125 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18128 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18129 MEM_VOLATILE_P (operands[0]) = 1;
18132 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18133 ;; They have the same encoding.
18134 (define_insn "*pause"
18135 [(set (match_operand:BLK 0)
18136 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18139 [(set_attr "length" "2")
18140 (set_attr "memory" "unknown")])
18142 (define_expand "xbegin"
18143 [(set (match_operand:SI 0 "register_operand")
18144 (unspec_volatile:SI [(match_dup 1)] UNSPECV_XBEGIN))]
18147 rtx label = gen_label_rtx ();
18149 operands[1] = force_reg (SImode, constm1_rtx);
18151 emit_jump_insn (gen_xbegin_1 (operands[1], label));
18153 emit_label (label);
18154 LABEL_NUSES (label) = 1;
18156 emit_move_insn (operands[0], operands[1]);
18161 (define_insn "xbegin_1"
18163 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18165 (label_ref (match_operand 1))
18167 (set (match_operand:SI 0 "register_operand" "+a")
18168 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
18171 [(set_attr "type" "other")
18172 (set_attr "length" "6")])
18174 (define_insn "xend"
18175 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18178 [(set_attr "type" "other")
18179 (set_attr "length" "3")])
18181 (define_insn "xabort"
18182 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18186 [(set_attr "type" "other")
18187 (set_attr "length" "3")])
18189 (define_expand "xtest"
18190 [(set (match_operand:QI 0 "register_operand")
18191 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18194 emit_insn (gen_xtest_1 ());
18196 ix86_expand_setcc (operands[0], NE,
18197 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18201 (define_insn "xtest_1"
18202 [(set (reg:CCZ FLAGS_REG)
18203 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18206 [(set_attr "type" "other")
18207 (set_attr "length" "3")])
18211 (include "sync.md")