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 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
42 ;; s -- print a shift double count, followed by the assemblers argument
44 ;; b -- print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; w -- likewise, print the HImode name of the register.
47 ;; k -- likewise, print the SImode name of the register.
48 ;; q -- likewise, print the DImode name of the register.
49 ;; x -- likewise, print the V4SFmode name of the register.
50 ;; t -- likewise, print the V8SFmode name of the register.
51 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
52 ;; y -- print "st(0)" instead of "st" as a register.
53 ;; d -- print duplicated register operand for AVX instruction.
54 ;; D -- print condition for SSE cmp instruction.
55 ;; P -- if PIC, print an @PLT suffix.
56 ;; p -- print raw symbol name.
57 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
58 ;; & -- print some in-use local-dynamic symbol name.
59 ;; H -- print a memory address offset by 8; used for sse high-parts
60 ;; Y -- print condition for XOP pcom* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
63 ;; ~ -- print "i" if TARGET_AVX2, "f" otherwise.
64 ;; @ -- print a segment register of thread base pointer load
65 ;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
67 (define_c_enum "unspec" [
68 ;; Relocation specifiers
79 UNSPEC_MACHOPIC_OFFSET
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
115 ;; For SSE/MMX support:
123 ;; Generic math support
125 UNSPEC_IEEE_MIN ; not commutative
126 UNSPEC_IEEE_MAX ; not commutative
128 ;; x87 Floating point
144 UNSPEC_FRNDINT_MASK_PM
148 ;; x87 Double output FP
175 ;; For RDRAND support
186 (define_c_enum "unspecv" [
189 UNSPECV_PROBE_STACK_RANGE
192 UNSPECV_SPLIT_STACK_RETURN
198 UNSPECV_LLWP_INTRINSIC
199 UNSPECV_SLWP_INTRINSIC
200 UNSPECV_LWPVAL_INTRINSIC
201 UNSPECV_LWPINS_INTRINSIC
208 ;; Constants to represent rounding modes in the ROUND instruction
217 ;; Constants to represent pcomtrue/pcomfalse variants
227 ;; Constants used in the XOP pperm instruction
229 [(PPERM_SRC 0x00) /* copy source */
230 (PPERM_INVERT 0x20) /* invert source */
231 (PPERM_REVERSE 0x40) /* bit reverse source */
232 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
233 (PPERM_ZERO 0x80) /* all 0's */
234 (PPERM_ONES 0xa0) /* all 1's */
235 (PPERM_SIGN 0xc0) /* propagate sign bit */
236 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
237 (PPERM_SRC1 0x00) /* use first source byte */
238 (PPERM_SRC2 0x10) /* use second source byte */
241 ;; Registers by name.
294 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
297 ;; In C guard expressions, put expressions which may be compile-time
298 ;; constants first. This allows for better optimization. For
299 ;; example, write "TARGET_64BIT && reload_completed", not
300 ;; "reload_completed && TARGET_64BIT".
304 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
305 atom,generic64,amdfam10,bdver1,bdver2,btver1"
306 (const (symbol_ref "ix86_schedule")))
308 ;; A basic instruction type. Refinements due to arguments to be
309 ;; provided in other attributes.
312 alu,alu1,negnot,imov,imovx,lea,
313 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,imul,imulx,idiv,
314 icmp,test,ibr,setcc,icmov,
315 push,pop,call,callv,leave,
317 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
318 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
319 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
320 ssemuladd,sse4arg,lwp,
321 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
322 (const_string "other"))
324 ;; Main data type used by the insn
326 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
327 (const_string "unknown"))
329 ;; The CPU unit operations uses.
330 (define_attr "unit" "integer,i387,sse,mmx,unknown"
331 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
332 (const_string "i387")
333 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
334 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
335 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
337 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
339 (eq_attr "type" "other")
340 (const_string "unknown")]
341 (const_string "integer")))
343 ;; The (bounding maximum) length of an instruction immediate.
344 (define_attr "length_immediate" ""
345 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
348 (eq_attr "unit" "i387,sse,mmx")
350 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
351 rotate,rotatex,rotate1,imul,icmp,push,pop")
352 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
353 (eq_attr "type" "imov,test")
354 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
355 (eq_attr "type" "call")
356 (if_then_else (match_operand 0 "constant_call_address_operand" "")
359 (eq_attr "type" "callv")
360 (if_then_else (match_operand 1 "constant_call_address_operand" "")
363 ;; We don't know the size before shorten_branches. Expect
364 ;; the instruction to fit for better scheduling.
365 (eq_attr "type" "ibr")
368 (symbol_ref "/* Update immediate_length and other attributes! */
369 gcc_unreachable (),1")))
371 ;; The (bounding maximum) length of an instruction address.
372 (define_attr "length_address" ""
373 (cond [(eq_attr "type" "str,other,multi,fxch")
375 (and (eq_attr "type" "call")
376 (match_operand 0 "constant_call_address_operand" ""))
378 (and (eq_attr "type" "callv")
379 (match_operand 1 "constant_call_address_operand" ""))
382 (symbol_ref "ix86_attr_length_address_default (insn)")))
384 ;; Set when length prefix is used.
385 (define_attr "prefix_data16" ""
386 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
388 (eq_attr "mode" "HI")
390 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
395 ;; Set when string REP prefix is used.
396 (define_attr "prefix_rep" ""
397 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
399 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
404 ;; Set when 0f opcode prefix is used.
405 (define_attr "prefix_0f" ""
407 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
408 (eq_attr "unit" "sse,mmx"))
412 ;; Set when REX opcode prefix is used.
413 (define_attr "prefix_rex" ""
414 (cond [(not (match_test "TARGET_64BIT"))
416 (and (eq_attr "mode" "DI")
417 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
418 (eq_attr "unit" "!mmx")))
420 (and (eq_attr "mode" "QI")
421 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
423 (match_test "x86_extended_reg_mentioned_p (insn)")
425 (and (eq_attr "type" "imovx")
426 (match_operand:QI 1 "ext_QIreg_operand" ""))
431 ;; There are also additional prefixes in 3DNOW, SSSE3.
432 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
433 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
434 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
435 (define_attr "prefix_extra" ""
436 (cond [(eq_attr "type" "ssemuladd,sse4arg")
438 (eq_attr "type" "sseiadd1,ssecvt1")
443 ;; Prefix used: original, VEX or maybe VEX.
444 (define_attr "prefix" "orig,vex,maybe_vex"
445 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
447 (const_string "orig")))
449 ;; VEX W bit is used.
450 (define_attr "prefix_vex_w" "" (const_int 0))
452 ;; The length of VEX prefix
453 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
454 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
455 ;; still prefix_0f 1, with prefix_extra 1.
456 (define_attr "length_vex" ""
457 (if_then_else (and (eq_attr "prefix_0f" "1")
458 (eq_attr "prefix_extra" "0"))
459 (if_then_else (eq_attr "prefix_vex_w" "1")
460 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
461 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
462 (if_then_else (eq_attr "prefix_vex_w" "1")
463 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
464 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
466 ;; Set when modrm byte is used.
467 (define_attr "modrm" ""
468 (cond [(eq_attr "type" "str,leave")
470 (eq_attr "unit" "i387")
472 (and (eq_attr "type" "incdec")
473 (and (not (match_test "TARGET_64BIT"))
474 (ior (match_operand:SI 1 "register_operand" "")
475 (match_operand:HI 1 "register_operand" ""))))
477 (and (eq_attr "type" "push")
478 (not (match_operand 1 "memory_operand" "")))
480 (and (eq_attr "type" "pop")
481 (not (match_operand 0 "memory_operand" "")))
483 (and (eq_attr "type" "imov")
484 (and (not (eq_attr "mode" "DI"))
485 (ior (and (match_operand 0 "register_operand" "")
486 (match_operand 1 "immediate_operand" ""))
487 (ior (and (match_operand 0 "ax_reg_operand" "")
488 (match_operand 1 "memory_displacement_only_operand" ""))
489 (and (match_operand 0 "memory_displacement_only_operand" "")
490 (match_operand 1 "ax_reg_operand" ""))))))
492 (and (eq_attr "type" "call")
493 (match_operand 0 "constant_call_address_operand" ""))
495 (and (eq_attr "type" "callv")
496 (match_operand 1 "constant_call_address_operand" ""))
498 (and (eq_attr "type" "alu,alu1,icmp,test")
499 (match_operand 0 "ax_reg_operand" ""))
500 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
504 ;; The (bounding maximum) length of an instruction in bytes.
505 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
506 ;; Later we may want to split them and compute proper length as for
508 (define_attr "length" ""
509 (cond [(eq_attr "type" "other,multi,fistp,frndint")
511 (eq_attr "type" "fcmp")
513 (eq_attr "unit" "i387")
515 (plus (attr "prefix_data16")
516 (attr "length_address")))
517 (ior (eq_attr "prefix" "vex")
518 (and (eq_attr "prefix" "maybe_vex")
519 (match_test "TARGET_AVX")))
520 (plus (attr "length_vex")
521 (plus (attr "length_immediate")
523 (attr "length_address"))))]
524 (plus (plus (attr "modrm")
525 (plus (attr "prefix_0f")
526 (plus (attr "prefix_rex")
527 (plus (attr "prefix_extra")
529 (plus (attr "prefix_rep")
530 (plus (attr "prefix_data16")
531 (plus (attr "length_immediate")
532 (attr "length_address")))))))
534 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
535 ;; `store' if there is a simple memory reference therein, or `unknown'
536 ;; if the instruction is complex.
538 (define_attr "memory" "none,load,store,both,unknown"
539 (cond [(eq_attr "type" "other,multi,str,lwp")
540 (const_string "unknown")
541 (eq_attr "type" "lea,fcmov,fpspc")
542 (const_string "none")
543 (eq_attr "type" "fistp,leave")
544 (const_string "both")
545 (eq_attr "type" "frndint")
546 (const_string "load")
547 (eq_attr "type" "push")
548 (if_then_else (match_operand 1 "memory_operand" "")
549 (const_string "both")
550 (const_string "store"))
551 (eq_attr "type" "pop")
552 (if_then_else (match_operand 0 "memory_operand" "")
553 (const_string "both")
554 (const_string "load"))
555 (eq_attr "type" "setcc")
556 (if_then_else (match_operand 0 "memory_operand" "")
557 (const_string "store")
558 (const_string "none"))
559 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
560 (if_then_else (ior (match_operand 0 "memory_operand" "")
561 (match_operand 1 "memory_operand" ""))
562 (const_string "load")
563 (const_string "none"))
564 (eq_attr "type" "ibr")
565 (if_then_else (match_operand 0 "memory_operand" "")
566 (const_string "load")
567 (const_string "none"))
568 (eq_attr "type" "call")
569 (if_then_else (match_operand 0 "constant_call_address_operand" "")
570 (const_string "none")
571 (const_string "load"))
572 (eq_attr "type" "callv")
573 (if_then_else (match_operand 1 "constant_call_address_operand" "")
574 (const_string "none")
575 (const_string "load"))
576 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
577 (match_operand 1 "memory_operand" ""))
578 (const_string "both")
579 (and (match_operand 0 "memory_operand" "")
580 (match_operand 1 "memory_operand" ""))
581 (const_string "both")
582 (match_operand 0 "memory_operand" "")
583 (const_string "store")
584 (match_operand 1 "memory_operand" "")
585 (const_string "load")
587 "!alu1,negnot,ishift1,
588 imov,imovx,icmp,test,bitmanip,
590 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
591 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
592 (match_operand 2 "memory_operand" ""))
593 (const_string "load")
594 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
595 (match_operand 3 "memory_operand" ""))
596 (const_string "load")
598 (const_string "none")))
600 ;; Indicates if an instruction has both an immediate and a displacement.
602 (define_attr "imm_disp" "false,true,unknown"
603 (cond [(eq_attr "type" "other,multi")
604 (const_string "unknown")
605 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
606 (and (match_operand 0 "memory_displacement_operand" "")
607 (match_operand 1 "immediate_operand" "")))
608 (const_string "true")
609 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
610 (and (match_operand 0 "memory_displacement_operand" "")
611 (match_operand 2 "immediate_operand" "")))
612 (const_string "true")
614 (const_string "false")))
616 ;; Indicates if an FP operation has an integer source.
618 (define_attr "fp_int_src" "false,true"
619 (const_string "false"))
621 ;; Defines rounding mode of an FP operation.
623 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
624 (const_string "any"))
626 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
627 (define_attr "use_carry" "0,1" (const_string "0"))
629 ;; Define attribute to indicate unaligned ssemov insns
630 (define_attr "movu" "0,1" (const_string "0"))
632 ;; Used to control the "enabled" attribute on a per-instruction basis.
633 (define_attr "isa" "base,sse2,sse2_noavx,sse3,sse4,sse4_noavx,noavx,avx,bmi2"
634 (const_string "base"))
636 (define_attr "enabled" ""
637 (cond [(eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
638 (eq_attr "isa" "sse2_noavx")
639 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
640 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
641 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
642 (eq_attr "isa" "sse4_noavx")
643 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
644 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
645 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
646 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
650 ;; Describe a user's asm statement.
651 (define_asm_attributes
652 [(set_attr "length" "128")
653 (set_attr "type" "multi")])
655 (define_code_iterator plusminus [plus minus])
657 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
659 ;; Base name for define_insn
660 (define_code_attr plusminus_insn
661 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
662 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
664 ;; Base name for insn mnemonic.
665 (define_code_attr plusminus_mnemonic
666 [(plus "add") (ss_plus "adds") (us_plus "addus")
667 (minus "sub") (ss_minus "subs") (us_minus "subus")])
668 (define_code_attr plusminus_carry_mnemonic
669 [(plus "adc") (minus "sbb")])
671 ;; Mark commutative operators as such in constraints.
672 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
673 (minus "") (ss_minus "") (us_minus "")])
675 ;; Mapping of max and min
676 (define_code_iterator maxmin [smax smin umax umin])
678 ;; Mapping of signed max and min
679 (define_code_iterator smaxmin [smax smin])
681 ;; Mapping of unsigned max and min
682 (define_code_iterator umaxmin [umax umin])
684 ;; Base name for integer and FP insn mnemonic
685 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
686 (umax "maxu") (umin "minu")])
687 (define_code_attr maxmin_float [(smax "max") (smin "min")])
689 ;; Mapping of logic operators
690 (define_code_iterator any_logic [and ior xor])
691 (define_code_iterator any_or [ior xor])
693 ;; Base name for insn mnemonic.
694 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
696 ;; Mapping of logic-shift operators
697 (define_code_iterator any_lshift [ashift lshiftrt])
699 ;; Mapping of shift-right operators
700 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
702 ;; Base name for define_insn
703 (define_code_attr shift_insn
704 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
706 ;; Base name for insn mnemonic.
707 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
708 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
710 ;; Mapping of rotate operators
711 (define_code_iterator any_rotate [rotate rotatert])
713 ;; Base name for define_insn
714 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
716 ;; Base name for insn mnemonic.
717 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
719 ;; Mapping of abs neg operators
720 (define_code_iterator absneg [abs neg])
722 ;; Base name for x87 insn mnemonic.
723 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
725 ;; Used in signed and unsigned widening multiplications.
726 (define_code_iterator any_extend [sign_extend zero_extend])
728 ;; Prefix for insn menmonic.
729 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
731 ;; Prefix for define_insn
732 (define_code_attr u [(sign_extend "") (zero_extend "u")])
733 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
735 ;; All integer modes.
736 (define_mode_iterator SWI1248x [QI HI SI DI])
738 ;; All integer modes without QImode.
739 (define_mode_iterator SWI248x [HI SI DI])
741 ;; All integer modes without QImode and HImode.
742 (define_mode_iterator SWI48x [SI DI])
744 ;; All integer modes without SImode and DImode.
745 (define_mode_iterator SWI12 [QI HI])
747 ;; All integer modes without DImode.
748 (define_mode_iterator SWI124 [QI HI SI])
750 ;; All integer modes without QImode and DImode.
751 (define_mode_iterator SWI24 [HI SI])
753 ;; Single word integer modes.
754 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
756 ;; Single word integer modes without QImode.
757 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
759 ;; Single word integer modes without QImode and HImode.
760 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
762 ;; All math-dependant single and double word integer modes.
763 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
764 (HI "TARGET_HIMODE_MATH")
765 SI DI (TI "TARGET_64BIT")])
767 ;; Math-dependant single word integer modes.
768 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
769 (HI "TARGET_HIMODE_MATH")
770 SI (DI "TARGET_64BIT")])
772 ;; Math-dependant integer modes without DImode.
773 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
774 (HI "TARGET_HIMODE_MATH")
777 ;; Math-dependant single word integer modes without QImode.
778 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
779 SI (DI "TARGET_64BIT")])
781 ;; Double word integer modes.
782 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
783 (TI "TARGET_64BIT")])
785 ;; Double word integer modes as mode attribute.
786 (define_mode_attr DWI [(SI "DI") (DI "TI")])
787 (define_mode_attr dwi [(SI "di") (DI "ti")])
789 ;; Half mode for double word integer modes.
790 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
791 (DI "TARGET_64BIT")])
793 ;; Instruction suffix for integer modes.
794 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
796 ;; Pointer size prefix for integer modes (Intel asm dialect)
797 (define_mode_attr iptrsize [(QI "BYTE")
802 ;; Register class for integer modes.
803 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
805 ;; Immediate operand constraint for integer modes.
806 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
808 ;; General operand constraint for word modes.
809 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
811 ;; Immediate operand constraint for double integer modes.
812 (define_mode_attr di [(SI "nF") (DI "e")])
814 ;; Immediate operand constraint for shifts.
815 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
817 ;; General operand predicate for integer modes.
818 (define_mode_attr general_operand
819 [(QI "general_operand")
820 (HI "general_operand")
821 (SI "x86_64_general_operand")
822 (DI "x86_64_general_operand")
823 (TI "x86_64_general_operand")])
825 ;; General sign/zero extend operand predicate for integer modes.
826 (define_mode_attr general_szext_operand
827 [(QI "general_operand")
828 (HI "general_operand")
829 (SI "x86_64_szext_general_operand")
830 (DI "x86_64_szext_general_operand")])
832 ;; Immediate operand predicate for integer modes.
833 (define_mode_attr immediate_operand
834 [(QI "immediate_operand")
835 (HI "immediate_operand")
836 (SI "x86_64_immediate_operand")
837 (DI "x86_64_immediate_operand")])
839 ;; Nonmemory operand predicate for integer modes.
840 (define_mode_attr nonmemory_operand
841 [(QI "nonmemory_operand")
842 (HI "nonmemory_operand")
843 (SI "x86_64_nonmemory_operand")
844 (DI "x86_64_nonmemory_operand")])
846 ;; Operand predicate for shifts.
847 (define_mode_attr shift_operand
848 [(QI "nonimmediate_operand")
849 (HI "nonimmediate_operand")
850 (SI "nonimmediate_operand")
851 (DI "shiftdi_operand")
852 (TI "register_operand")])
854 ;; Operand predicate for shift argument.
855 (define_mode_attr shift_immediate_operand
856 [(QI "const_1_to_31_operand")
857 (HI "const_1_to_31_operand")
858 (SI "const_1_to_31_operand")
859 (DI "const_1_to_63_operand")])
861 ;; Input operand predicate for arithmetic left shifts.
862 (define_mode_attr ashl_input_operand
863 [(QI "nonimmediate_operand")
864 (HI "nonimmediate_operand")
865 (SI "nonimmediate_operand")
866 (DI "ashldi_input_operand")
867 (TI "reg_or_pm1_operand")])
869 ;; SSE and x87 SFmode and DFmode floating point modes
870 (define_mode_iterator MODEF [SF DF])
872 ;; All x87 floating point modes
873 (define_mode_iterator X87MODEF [SF DF XF])
875 ;; SSE instruction suffix for various modes
876 (define_mode_attr ssemodesuffix
878 (V8SF "ps") (V4DF "pd")
879 (V4SF "ps") (V2DF "pd")
880 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
881 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
883 ;; SSE vector suffix for floating point modes
884 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
886 ;; SSE vector mode corresponding to a scalar mode
887 (define_mode_attr ssevecmode
888 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
890 ;; Instruction suffix for REX 64bit operators.
891 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
893 ;; This mode iterator allows :P to be used for patterns that operate on
894 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
895 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
897 ;; This mode iterator allows :W to be used for patterns that operate on
898 ;; word_mode sized quantities.
899 (define_mode_iterator W
900 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
902 ;; This mode iterator allows :PTR to be used for patterns that operate on
903 ;; ptr_mode sized quantities.
904 (define_mode_iterator PTR
905 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
907 ;; Scheduling descriptions
909 (include "pentium.md")
912 (include "athlon.md")
913 (include "bdver1.md")
919 ;; Operand and operator predicates and constraints
921 (include "predicates.md")
922 (include "constraints.md")
925 ;; Compare and branch/compare and store instructions.
927 (define_expand "cbranch<mode>4"
928 [(set (reg:CC FLAGS_REG)
929 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
930 (match_operand:SDWIM 2 "<general_operand>" "")))
931 (set (pc) (if_then_else
932 (match_operator 0 "ordered_comparison_operator"
933 [(reg:CC FLAGS_REG) (const_int 0)])
934 (label_ref (match_operand 3 "" ""))
938 if (MEM_P (operands[1]) && MEM_P (operands[2]))
939 operands[1] = force_reg (<MODE>mode, operands[1]);
940 ix86_expand_branch (GET_CODE (operands[0]),
941 operands[1], operands[2], operands[3]);
945 (define_expand "cstore<mode>4"
946 [(set (reg:CC FLAGS_REG)
947 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
948 (match_operand:SWIM 3 "<general_operand>" "")))
949 (set (match_operand:QI 0 "register_operand" "")
950 (match_operator 1 "ordered_comparison_operator"
951 [(reg:CC FLAGS_REG) (const_int 0)]))]
954 if (MEM_P (operands[2]) && MEM_P (operands[3]))
955 operands[2] = force_reg (<MODE>mode, operands[2]);
956 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
957 operands[2], operands[3]);
961 (define_expand "cmp<mode>_1"
962 [(set (reg:CC FLAGS_REG)
963 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
964 (match_operand:SWI48 1 "<general_operand>" "")))])
966 (define_insn "*cmp<mode>_ccno_1"
967 [(set (reg FLAGS_REG)
968 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
969 (match_operand:SWI 1 "const0_operand" "")))]
970 "ix86_match_ccmode (insn, CCNOmode)"
972 test{<imodesuffix>}\t%0, %0
973 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
974 [(set_attr "type" "test,icmp")
975 (set_attr "length_immediate" "0,1")
976 (set_attr "mode" "<MODE>")])
978 (define_insn "*cmp<mode>_1"
979 [(set (reg FLAGS_REG)
980 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
981 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
982 "ix86_match_ccmode (insn, CCmode)"
983 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
984 [(set_attr "type" "icmp")
985 (set_attr "mode" "<MODE>")])
987 (define_insn "*cmp<mode>_minus_1"
988 [(set (reg FLAGS_REG)
990 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
991 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
993 "ix86_match_ccmode (insn, CCGOCmode)"
994 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
995 [(set_attr "type" "icmp")
996 (set_attr "mode" "<MODE>")])
998 (define_insn "*cmpqi_ext_1"
999 [(set (reg FLAGS_REG)
1001 (match_operand:QI 0 "general_operand" "Qm")
1004 (match_operand 1 "ext_register_operand" "Q")
1006 (const_int 8)) 0)))]
1007 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1008 "cmp{b}\t{%h1, %0|%0, %h1}"
1009 [(set_attr "type" "icmp")
1010 (set_attr "mode" "QI")])
1012 (define_insn "*cmpqi_ext_1_rex64"
1013 [(set (reg FLAGS_REG)
1015 (match_operand:QI 0 "register_operand" "Q")
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_2"
1027 [(set (reg FLAGS_REG)
1031 (match_operand 0 "ext_register_operand" "Q")
1034 (match_operand:QI 1 "const0_operand" "")))]
1035 "ix86_match_ccmode (insn, CCNOmode)"
1037 [(set_attr "type" "test")
1038 (set_attr "length_immediate" "0")
1039 (set_attr "mode" "QI")])
1041 (define_expand "cmpqi_ext_3"
1042 [(set (reg:CC FLAGS_REG)
1046 (match_operand 0 "ext_register_operand" "")
1049 (match_operand:QI 1 "immediate_operand" "")))])
1051 (define_insn "*cmpqi_ext_3_insn"
1052 [(set (reg FLAGS_REG)
1056 (match_operand 0 "ext_register_operand" "Q")
1059 (match_operand:QI 1 "general_operand" "Qmn")))]
1060 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1061 "cmp{b}\t{%1, %h0|%h0, %1}"
1062 [(set_attr "type" "icmp")
1063 (set_attr "modrm" "1")
1064 (set_attr "mode" "QI")])
1066 (define_insn "*cmpqi_ext_3_insn_rex64"
1067 [(set (reg FLAGS_REG)
1071 (match_operand 0 "ext_register_operand" "Q")
1074 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1075 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1076 "cmp{b}\t{%1, %h0|%h0, %1}"
1077 [(set_attr "type" "icmp")
1078 (set_attr "modrm" "1")
1079 (set_attr "mode" "QI")])
1081 (define_insn "*cmpqi_ext_4"
1082 [(set (reg FLAGS_REG)
1086 (match_operand 0 "ext_register_operand" "Q")
1091 (match_operand 1 "ext_register_operand" "Q")
1093 (const_int 8)) 0)))]
1094 "ix86_match_ccmode (insn, CCmode)"
1095 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1096 [(set_attr "type" "icmp")
1097 (set_attr "mode" "QI")])
1099 ;; These implement float point compares.
1100 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1101 ;; which would allow mix and match FP modes on the compares. Which is what
1102 ;; the old patterns did, but with many more of them.
1104 (define_expand "cbranchxf4"
1105 [(set (reg:CC FLAGS_REG)
1106 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1107 (match_operand:XF 2 "nonmemory_operand" "")))
1108 (set (pc) (if_then_else
1109 (match_operator 0 "ix86_fp_comparison_operator"
1112 (label_ref (match_operand 3 "" ""))
1116 ix86_expand_branch (GET_CODE (operands[0]),
1117 operands[1], operands[2], operands[3]);
1121 (define_expand "cstorexf4"
1122 [(set (reg:CC FLAGS_REG)
1123 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1124 (match_operand:XF 3 "nonmemory_operand" "")))
1125 (set (match_operand:QI 0 "register_operand" "")
1126 (match_operator 1 "ix86_fp_comparison_operator"
1131 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1132 operands[2], operands[3]);
1136 (define_expand "cbranch<mode>4"
1137 [(set (reg:CC FLAGS_REG)
1138 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1139 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1140 (set (pc) (if_then_else
1141 (match_operator 0 "ix86_fp_comparison_operator"
1144 (label_ref (match_operand 3 "" ""))
1146 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1148 ix86_expand_branch (GET_CODE (operands[0]),
1149 operands[1], operands[2], operands[3]);
1153 (define_expand "cstore<mode>4"
1154 [(set (reg:CC FLAGS_REG)
1155 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1156 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1157 (set (match_operand:QI 0 "register_operand" "")
1158 (match_operator 1 "ix86_fp_comparison_operator"
1161 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1163 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1164 operands[2], operands[3]);
1168 (define_expand "cbranchcc4"
1169 [(set (pc) (if_then_else
1170 (match_operator 0 "comparison_operator"
1171 [(match_operand 1 "flags_reg_operand" "")
1172 (match_operand 2 "const0_operand" "")])
1173 (label_ref (match_operand 3 "" ""))
1177 ix86_expand_branch (GET_CODE (operands[0]),
1178 operands[1], operands[2], operands[3]);
1182 (define_expand "cstorecc4"
1183 [(set (match_operand:QI 0 "register_operand" "")
1184 (match_operator 1 "comparison_operator"
1185 [(match_operand 2 "flags_reg_operand" "")
1186 (match_operand 3 "const0_operand" "")]))]
1189 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1190 operands[2], operands[3]);
1195 ;; FP compares, step 1:
1196 ;; Set the FP condition codes.
1198 ;; CCFPmode compare with exceptions
1199 ;; CCFPUmode compare with no exceptions
1201 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1202 ;; used to manage the reg stack popping would not be preserved.
1204 (define_insn "*cmpfp_0"
1205 [(set (match_operand:HI 0 "register_operand" "=a")
1208 (match_operand 1 "register_operand" "f")
1209 (match_operand 2 "const0_operand" ""))]
1211 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1212 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1213 "* return output_fp_compare (insn, operands, false, false);"
1214 [(set_attr "type" "multi")
1215 (set_attr "unit" "i387")
1217 (cond [(match_operand:SF 1 "" "")
1219 (match_operand:DF 1 "" "")
1222 (const_string "XF")))])
1224 (define_insn_and_split "*cmpfp_0_cc"
1225 [(set (reg:CCFP FLAGS_REG)
1227 (match_operand 1 "register_operand" "f")
1228 (match_operand 2 "const0_operand" "")))
1229 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1230 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1231 && TARGET_SAHF && !TARGET_CMOVE
1232 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1234 "&& reload_completed"
1237 [(compare:CCFP (match_dup 1)(match_dup 2))]
1239 (set (reg:CC FLAGS_REG)
1240 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1242 [(set_attr "type" "multi")
1243 (set_attr "unit" "i387")
1245 (cond [(match_operand:SF 1 "" "")
1247 (match_operand:DF 1 "" "")
1250 (const_string "XF")))])
1252 (define_insn "*cmpfp_xf"
1253 [(set (match_operand:HI 0 "register_operand" "=a")
1256 (match_operand:XF 1 "register_operand" "f")
1257 (match_operand:XF 2 "register_operand" "f"))]
1260 "* return output_fp_compare (insn, operands, false, false);"
1261 [(set_attr "type" "multi")
1262 (set_attr "unit" "i387")
1263 (set_attr "mode" "XF")])
1265 (define_insn_and_split "*cmpfp_xf_cc"
1266 [(set (reg:CCFP FLAGS_REG)
1268 (match_operand:XF 1 "register_operand" "f")
1269 (match_operand:XF 2 "register_operand" "f")))
1270 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1272 && TARGET_SAHF && !TARGET_CMOVE"
1274 "&& reload_completed"
1277 [(compare:CCFP (match_dup 1)(match_dup 2))]
1279 (set (reg:CC FLAGS_REG)
1280 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1282 [(set_attr "type" "multi")
1283 (set_attr "unit" "i387")
1284 (set_attr "mode" "XF")])
1286 (define_insn "*cmpfp_<mode>"
1287 [(set (match_operand:HI 0 "register_operand" "=a")
1290 (match_operand:MODEF 1 "register_operand" "f")
1291 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1294 "* return output_fp_compare (insn, operands, false, false);"
1295 [(set_attr "type" "multi")
1296 (set_attr "unit" "i387")
1297 (set_attr "mode" "<MODE>")])
1299 (define_insn_and_split "*cmpfp_<mode>_cc"
1300 [(set (reg:CCFP FLAGS_REG)
1302 (match_operand:MODEF 1 "register_operand" "f")
1303 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1304 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1306 && TARGET_SAHF && !TARGET_CMOVE"
1308 "&& reload_completed"
1311 [(compare:CCFP (match_dup 1)(match_dup 2))]
1313 (set (reg:CC FLAGS_REG)
1314 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1316 [(set_attr "type" "multi")
1317 (set_attr "unit" "i387")
1318 (set_attr "mode" "<MODE>")])
1320 (define_insn "*cmpfp_u"
1321 [(set (match_operand:HI 0 "register_operand" "=a")
1324 (match_operand 1 "register_operand" "f")
1325 (match_operand 2 "register_operand" "f"))]
1327 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1328 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1329 "* return output_fp_compare (insn, operands, false, true);"
1330 [(set_attr "type" "multi")
1331 (set_attr "unit" "i387")
1333 (cond [(match_operand:SF 1 "" "")
1335 (match_operand:DF 1 "" "")
1338 (const_string "XF")))])
1340 (define_insn_and_split "*cmpfp_u_cc"
1341 [(set (reg:CCFPU FLAGS_REG)
1343 (match_operand 1 "register_operand" "f")
1344 (match_operand 2 "register_operand" "f")))
1345 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1346 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1347 && TARGET_SAHF && !TARGET_CMOVE
1348 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1350 "&& reload_completed"
1353 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1355 (set (reg:CC FLAGS_REG)
1356 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1358 [(set_attr "type" "multi")
1359 (set_attr "unit" "i387")
1361 (cond [(match_operand:SF 1 "" "")
1363 (match_operand:DF 1 "" "")
1366 (const_string "XF")))])
1368 (define_insn "*cmpfp_<mode>"
1369 [(set (match_operand:HI 0 "register_operand" "=a")
1372 (match_operand 1 "register_operand" "f")
1373 (match_operator 3 "float_operator"
1374 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1376 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1377 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1378 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1379 "* return output_fp_compare (insn, operands, false, false);"
1380 [(set_attr "type" "multi")
1381 (set_attr "unit" "i387")
1382 (set_attr "fp_int_src" "true")
1383 (set_attr "mode" "<MODE>")])
1385 (define_insn_and_split "*cmpfp_<mode>_cc"
1386 [(set (reg:CCFP FLAGS_REG)
1388 (match_operand 1 "register_operand" "f")
1389 (match_operator 3 "float_operator"
1390 [(match_operand:SWI24 2 "memory_operand" "m")])))
1391 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1392 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1393 && TARGET_SAHF && !TARGET_CMOVE
1394 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1395 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1397 "&& reload_completed"
1402 (match_op_dup 3 [(match_dup 2)]))]
1404 (set (reg:CC FLAGS_REG)
1405 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1407 [(set_attr "type" "multi")
1408 (set_attr "unit" "i387")
1409 (set_attr "fp_int_src" "true")
1410 (set_attr "mode" "<MODE>")])
1412 ;; FP compares, step 2
1413 ;; Move the fpsw to ax.
1415 (define_insn "x86_fnstsw_1"
1416 [(set (match_operand:HI 0 "register_operand" "=a")
1417 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1420 [(set (attr "length")
1421 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1422 (set_attr "mode" "SI")
1423 (set_attr "unit" "i387")])
1425 ;; FP compares, step 3
1426 ;; Get ax into flags, general case.
1428 (define_insn "x86_sahf_1"
1429 [(set (reg:CC FLAGS_REG)
1430 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1434 #ifndef HAVE_AS_IX86_SAHF
1436 return ASM_BYTE "0x9e";
1441 [(set_attr "length" "1")
1442 (set_attr "athlon_decode" "vector")
1443 (set_attr "amdfam10_decode" "direct")
1444 (set_attr "bdver1_decode" "direct")
1445 (set_attr "mode" "SI")])
1447 ;; Pentium Pro can do steps 1 through 3 in one go.
1448 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1449 ;; (these i387 instructions set flags directly)
1450 (define_insn "*cmpfp_i_mixed"
1451 [(set (reg:CCFP FLAGS_REG)
1452 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1453 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1454 "TARGET_MIX_SSE_I387
1455 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1456 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1457 "* return output_fp_compare (insn, operands, true, false);"
1458 [(set_attr "type" "fcmp,ssecomi")
1459 (set_attr "prefix" "orig,maybe_vex")
1461 (if_then_else (match_operand:SF 1 "" "")
1463 (const_string "DF")))
1464 (set (attr "prefix_rep")
1465 (if_then_else (eq_attr "type" "ssecomi")
1467 (const_string "*")))
1468 (set (attr "prefix_data16")
1469 (cond [(eq_attr "type" "fcmp")
1471 (eq_attr "mode" "DF")
1474 (const_string "0")))
1475 (set_attr "athlon_decode" "vector")
1476 (set_attr "amdfam10_decode" "direct")
1477 (set_attr "bdver1_decode" "double")])
1479 (define_insn "*cmpfp_i_sse"
1480 [(set (reg:CCFP FLAGS_REG)
1481 (compare:CCFP (match_operand 0 "register_operand" "x")
1482 (match_operand 1 "nonimmediate_operand" "xm")))]
1484 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1485 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1486 "* return output_fp_compare (insn, operands, true, false);"
1487 [(set_attr "type" "ssecomi")
1488 (set_attr "prefix" "maybe_vex")
1490 (if_then_else (match_operand:SF 1 "" "")
1492 (const_string "DF")))
1493 (set_attr "prefix_rep" "0")
1494 (set (attr "prefix_data16")
1495 (if_then_else (eq_attr "mode" "DF")
1497 (const_string "0")))
1498 (set_attr "athlon_decode" "vector")
1499 (set_attr "amdfam10_decode" "direct")
1500 (set_attr "bdver1_decode" "double")])
1502 (define_insn "*cmpfp_i_i387"
1503 [(set (reg:CCFP FLAGS_REG)
1504 (compare:CCFP (match_operand 0 "register_operand" "f")
1505 (match_operand 1 "register_operand" "f")))]
1506 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1508 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1509 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1510 "* return output_fp_compare (insn, operands, true, false);"
1511 [(set_attr "type" "fcmp")
1513 (cond [(match_operand:SF 1 "" "")
1515 (match_operand:DF 1 "" "")
1518 (const_string "XF")))
1519 (set_attr "athlon_decode" "vector")
1520 (set_attr "amdfam10_decode" "direct")
1521 (set_attr "bdver1_decode" "double")])
1523 (define_insn "*cmpfp_iu_mixed"
1524 [(set (reg:CCFPU FLAGS_REG)
1525 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1526 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1527 "TARGET_MIX_SSE_I387
1528 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1529 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1530 "* return output_fp_compare (insn, operands, true, true);"
1531 [(set_attr "type" "fcmp,ssecomi")
1532 (set_attr "prefix" "orig,maybe_vex")
1534 (if_then_else (match_operand:SF 1 "" "")
1536 (const_string "DF")))
1537 (set (attr "prefix_rep")
1538 (if_then_else (eq_attr "type" "ssecomi")
1540 (const_string "*")))
1541 (set (attr "prefix_data16")
1542 (cond [(eq_attr "type" "fcmp")
1544 (eq_attr "mode" "DF")
1547 (const_string "0")))
1548 (set_attr "athlon_decode" "vector")
1549 (set_attr "amdfam10_decode" "direct")
1550 (set_attr "bdver1_decode" "double")])
1552 (define_insn "*cmpfp_iu_sse"
1553 [(set (reg:CCFPU FLAGS_REG)
1554 (compare:CCFPU (match_operand 0 "register_operand" "x")
1555 (match_operand 1 "nonimmediate_operand" "xm")))]
1557 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1558 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1559 "* return output_fp_compare (insn, operands, true, true);"
1560 [(set_attr "type" "ssecomi")
1561 (set_attr "prefix" "maybe_vex")
1563 (if_then_else (match_operand:SF 1 "" "")
1565 (const_string "DF")))
1566 (set_attr "prefix_rep" "0")
1567 (set (attr "prefix_data16")
1568 (if_then_else (eq_attr "mode" "DF")
1570 (const_string "0")))
1571 (set_attr "athlon_decode" "vector")
1572 (set_attr "amdfam10_decode" "direct")
1573 (set_attr "bdver1_decode" "double")])
1575 (define_insn "*cmpfp_iu_387"
1576 [(set (reg:CCFPU FLAGS_REG)
1577 (compare:CCFPU (match_operand 0 "register_operand" "f")
1578 (match_operand 1 "register_operand" "f")))]
1579 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1581 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1582 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1583 "* return output_fp_compare (insn, operands, true, true);"
1584 [(set_attr "type" "fcmp")
1586 (cond [(match_operand:SF 1 "" "")
1588 (match_operand:DF 1 "" "")
1591 (const_string "XF")))
1592 (set_attr "athlon_decode" "vector")
1593 (set_attr "amdfam10_decode" "direct")
1594 (set_attr "bdver1_decode" "direct")])
1596 ;; Push/pop instructions.
1598 (define_insn "*push<mode>2"
1599 [(set (match_operand:DWI 0 "push_operand" "=<")
1600 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1603 [(set_attr "type" "multi")
1604 (set_attr "mode" "<MODE>")])
1607 [(set (match_operand:TI 0 "push_operand" "")
1608 (match_operand:TI 1 "general_operand" ""))]
1609 "TARGET_64BIT && reload_completed
1610 && !SSE_REG_P (operands[1])"
1612 "ix86_split_long_move (operands); DONE;")
1614 (define_insn "*pushdi2_rex64"
1615 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1616 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1621 [(set_attr "type" "push,multi")
1622 (set_attr "mode" "DI")])
1624 ;; Convert impossible pushes of immediate to existing instructions.
1625 ;; First try to get scratch register and go through it. In case this
1626 ;; fails, push sign extended lower part first and then overwrite
1627 ;; upper part by 32bit move.
1629 [(match_scratch:DI 2 "r")
1630 (set (match_operand:DI 0 "push_operand" "")
1631 (match_operand:DI 1 "immediate_operand" ""))]
1632 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1633 && !x86_64_immediate_operand (operands[1], DImode)"
1634 [(set (match_dup 2) (match_dup 1))
1635 (set (match_dup 0) (match_dup 2))])
1637 ;; We need to define this as both peepholer and splitter for case
1638 ;; peephole2 pass is not run.
1639 ;; "&& 1" is needed to keep it from matching the previous pattern.
1641 [(set (match_operand:DI 0 "push_operand" "")
1642 (match_operand:DI 1 "immediate_operand" ""))]
1643 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1644 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1645 [(set (match_dup 0) (match_dup 1))
1646 (set (match_dup 2) (match_dup 3))]
1648 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1650 operands[1] = gen_lowpart (DImode, operands[2]);
1651 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1656 [(set (match_operand:DI 0 "push_operand" "")
1657 (match_operand:DI 1 "immediate_operand" ""))]
1658 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1659 ? epilogue_completed : reload_completed)
1660 && !symbolic_operand (operands[1], DImode)
1661 && !x86_64_immediate_operand (operands[1], DImode)"
1662 [(set (match_dup 0) (match_dup 1))
1663 (set (match_dup 2) (match_dup 3))]
1665 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1667 operands[1] = gen_lowpart (DImode, operands[2]);
1668 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1673 [(set (match_operand:DI 0 "push_operand" "")
1674 (match_operand:DI 1 "general_operand" ""))]
1675 "!TARGET_64BIT && reload_completed
1676 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1678 "ix86_split_long_move (operands); DONE;")
1680 (define_insn "*pushsi2"
1681 [(set (match_operand:SI 0 "push_operand" "=<")
1682 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1685 [(set_attr "type" "push")
1686 (set_attr "mode" "SI")])
1688 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1689 ;; "push a byte/word". But actually we use pushl, which has the effect
1690 ;; of rounding the amount pushed up to a word.
1692 ;; For TARGET_64BIT we always round up to 8 bytes.
1693 (define_insn "*push<mode>2_rex64"
1694 [(set (match_operand:SWI124 0 "push_operand" "=X")
1695 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1698 [(set_attr "type" "push")
1699 (set_attr "mode" "DI")])
1701 (define_insn "*push<mode>2"
1702 [(set (match_operand:SWI12 0 "push_operand" "=X")
1703 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1706 [(set_attr "type" "push")
1707 (set_attr "mode" "SI")])
1709 (define_insn "*push<mode>2_prologue"
1710 [(set (match_operand:W 0 "push_operand" "=<")
1711 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1712 (clobber (mem:BLK (scratch)))]
1714 "push{<imodesuffix>}\t%1"
1715 [(set_attr "type" "push")
1716 (set_attr "mode" "<MODE>")])
1718 (define_insn "*pop<mode>1"
1719 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1720 (match_operand:W 1 "pop_operand" ">"))]
1722 "pop{<imodesuffix>}\t%0"
1723 [(set_attr "type" "pop")
1724 (set_attr "mode" "<MODE>")])
1726 (define_insn "*pop<mode>1_epilogue"
1727 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1728 (match_operand:W 1 "pop_operand" ">"))
1729 (clobber (mem:BLK (scratch)))]
1731 "pop{<imodesuffix>}\t%0"
1732 [(set_attr "type" "pop")
1733 (set_attr "mode" "<MODE>")])
1735 ;; Move instructions.
1737 (define_expand "movoi"
1738 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1739 (match_operand:OI 1 "general_operand" ""))]
1741 "ix86_expand_move (OImode, operands); DONE;")
1743 (define_expand "movti"
1744 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1745 (match_operand:TI 1 "nonimmediate_operand" ""))]
1746 "TARGET_64BIT || TARGET_SSE"
1749 ix86_expand_move (TImode, operands);
1750 else if (push_operand (operands[0], TImode))
1751 ix86_expand_push (TImode, operands[1]);
1753 ix86_expand_vector_move (TImode, operands);
1757 ;; This expands to what emit_move_complex would generate if we didn't
1758 ;; have a movti pattern. Having this avoids problems with reload on
1759 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1760 ;; to have around all the time.
1761 (define_expand "movcdi"
1762 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1763 (match_operand:CDI 1 "general_operand" ""))]
1766 if (push_operand (operands[0], CDImode))
1767 emit_move_complex_push (CDImode, operands[0], operands[1]);
1769 emit_move_complex_parts (operands[0], operands[1]);
1773 (define_expand "mov<mode>"
1774 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1775 (match_operand:SWI1248x 1 "general_operand" ""))]
1777 "ix86_expand_move (<MODE>mode, operands); DONE;")
1779 (define_insn "*mov<mode>_xor"
1780 [(set (match_operand:SWI48 0 "register_operand" "=r")
1781 (match_operand:SWI48 1 "const0_operand" ""))
1782 (clobber (reg:CC FLAGS_REG))]
1785 [(set_attr "type" "alu1")
1786 (set_attr "mode" "SI")
1787 (set_attr "length_immediate" "0")])
1789 (define_insn "*mov<mode>_or"
1790 [(set (match_operand:SWI48 0 "register_operand" "=r")
1791 (match_operand:SWI48 1 "const_int_operand" ""))
1792 (clobber (reg:CC FLAGS_REG))]
1794 && operands[1] == constm1_rtx"
1795 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1796 [(set_attr "type" "alu1")
1797 (set_attr "mode" "<MODE>")
1798 (set_attr "length_immediate" "1")])
1800 (define_insn "*movoi_internal_avx"
1801 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1802 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1803 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1805 switch (which_alternative)
1808 return standard_sse_constant_opcode (insn, operands[1]);
1811 if (misaligned_operand (operands[0], OImode)
1812 || misaligned_operand (operands[1], OImode))
1813 return "vmovdqu\t{%1, %0|%0, %1}";
1815 return "vmovdqa\t{%1, %0|%0, %1}";
1820 [(set_attr "type" "sselog1,ssemov,ssemov")
1821 (set_attr "prefix" "vex")
1822 (set_attr "mode" "OI")])
1824 (define_insn "*movti_internal_rex64"
1825 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1826 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1827 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1829 switch (which_alternative)
1835 return standard_sse_constant_opcode (insn, operands[1]);
1838 /* TDmode values are passed as TImode on the stack. Moving them
1839 to stack may result in unaligned memory access. */
1840 if (misaligned_operand (operands[0], TImode)
1841 || misaligned_operand (operands[1], TImode))
1843 if (get_attr_mode (insn) == MODE_V4SF)
1844 return "%vmovups\t{%1, %0|%0, %1}";
1846 return "%vmovdqu\t{%1, %0|%0, %1}";
1850 if (get_attr_mode (insn) == MODE_V4SF)
1851 return "%vmovaps\t{%1, %0|%0, %1}";
1853 return "%vmovdqa\t{%1, %0|%0, %1}";
1859 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1860 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1862 (cond [(eq_attr "alternative" "2,3")
1864 (match_test "optimize_function_for_size_p (cfun)")
1865 (const_string "V4SF")
1866 (const_string "TI"))
1867 (eq_attr "alternative" "4")
1869 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
1870 (match_test "optimize_function_for_size_p (cfun)"))
1871 (const_string "V4SF")
1872 (const_string "TI"))]
1873 (const_string "DI")))])
1876 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1877 (match_operand:TI 1 "general_operand" ""))]
1879 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1881 "ix86_split_long_move (operands); DONE;")
1883 (define_insn "*movti_internal_sse"
1884 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1885 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1886 "TARGET_SSE && !TARGET_64BIT
1887 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1889 switch (which_alternative)
1892 return standard_sse_constant_opcode (insn, operands[1]);
1895 /* TDmode values are passed as TImode on the stack. Moving them
1896 to stack may result in unaligned memory access. */
1897 if (misaligned_operand (operands[0], TImode)
1898 || misaligned_operand (operands[1], TImode))
1900 if (get_attr_mode (insn) == MODE_V4SF)
1901 return "%vmovups\t{%1, %0|%0, %1}";
1903 return "%vmovdqu\t{%1, %0|%0, %1}";
1907 if (get_attr_mode (insn) == MODE_V4SF)
1908 return "%vmovaps\t{%1, %0|%0, %1}";
1910 return "%vmovdqa\t{%1, %0|%0, %1}";
1916 [(set_attr "type" "sselog1,ssemov,ssemov")
1917 (set_attr "prefix" "maybe_vex")
1919 (cond [(ior (not (match_test "TARGET_SSE2"))
1920 (match_test "optimize_function_for_size_p (cfun)"))
1921 (const_string "V4SF")
1922 (and (eq_attr "alternative" "2")
1923 (match_test "TARGET_SSE_TYPELESS_STORES"))
1924 (const_string "V4SF")]
1925 (const_string "TI")))])
1927 (define_insn "*movdi_internal_rex64"
1928 [(set (match_operand:DI 0 "nonimmediate_operand"
1929 "=r,r ,r,m ,!o,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1930 (match_operand:DI 1 "general_operand"
1931 "Z ,rem,i,re,n ,C ,*y ,m ,*Ym,r ,C ,*x,*x,m ,*Yi,r ,*Ym,*x"))]
1932 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1934 switch (get_attr_type (insn))
1937 if (SSE_REG_P (operands[0]))
1938 return "movq2dq\t{%1, %0|%0, %1}";
1940 return "movdq2q\t{%1, %0|%0, %1}";
1943 if (get_attr_mode (insn) == MODE_TI)
1944 return "%vmovdqa\t{%1, %0|%0, %1}";
1945 /* Handle broken assemblers that require movd instead of movq. */
1946 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1947 return "%vmovd\t{%1, %0|%0, %1}";
1949 return "%vmovq\t{%1, %0|%0, %1}";
1952 /* Handle broken assemblers that require movd instead of movq. */
1953 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1954 return "movd\t{%1, %0|%0, %1}";
1956 return "movq\t{%1, %0|%0, %1}";
1959 return standard_sse_constant_opcode (insn, operands[1]);
1962 return "pxor\t%0, %0";
1968 return "lea{q}\t{%a1, %0|%0, %a1}";
1971 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1972 if (get_attr_mode (insn) == MODE_SI)
1973 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1974 else if (which_alternative == 2)
1975 return "movabs{q}\t{%1, %0|%0, %1}";
1976 else if (ix86_use_lea_for_mov (insn, operands))
1977 return "lea{q}\t{%a1, %0|%0, %a1}";
1979 return "mov{q}\t{%1, %0|%0, %1}";
1983 (cond [(eq_attr "alternative" "4")
1984 (const_string "multi")
1985 (eq_attr "alternative" "5")
1986 (const_string "mmx")
1987 (eq_attr "alternative" "6,7,8,9")
1988 (const_string "mmxmov")
1989 (eq_attr "alternative" "10")
1990 (const_string "sselog1")
1991 (eq_attr "alternative" "11,12,13,14,15")
1992 (const_string "ssemov")
1993 (eq_attr "alternative" "16,17")
1994 (const_string "ssecvt")
1995 (match_operand 1 "pic_32bit_operand" "")
1996 (const_string "lea")
1998 (const_string "imov")))
2001 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2003 (const_string "*")))
2004 (set (attr "length_immediate")
2006 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2008 (const_string "*")))
2009 (set (attr "prefix_rex")
2010 (if_then_else (eq_attr "alternative" "8,9")
2012 (const_string "*")))
2013 (set (attr "prefix_data16")
2014 (if_then_else (eq_attr "alternative" "11")
2016 (const_string "*")))
2017 (set (attr "prefix")
2018 (if_then_else (eq_attr "alternative" "10,11,12,13,14,15")
2019 (const_string "maybe_vex")
2020 (const_string "orig")))
2021 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,TI,DI,TI,DI,DI,DI,DI,DI")])
2023 ;; Reload patterns to support multi-word load/store
2024 ;; with non-offsetable address.
2025 (define_expand "reload_noff_store"
2026 [(parallel [(match_operand 0 "memory_operand" "=m")
2027 (match_operand 1 "register_operand" "r")
2028 (match_operand:DI 2 "register_operand" "=&r")])]
2031 rtx mem = operands[0];
2032 rtx addr = XEXP (mem, 0);
2034 emit_move_insn (operands[2], addr);
2035 mem = replace_equiv_address_nv (mem, operands[2]);
2037 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
2041 (define_expand "reload_noff_load"
2042 [(parallel [(match_operand 0 "register_operand" "=r")
2043 (match_operand 1 "memory_operand" "m")
2044 (match_operand:DI 2 "register_operand" "=r")])]
2047 rtx mem = operands[1];
2048 rtx addr = XEXP (mem, 0);
2050 emit_move_insn (operands[2], addr);
2051 mem = replace_equiv_address_nv (mem, operands[2]);
2053 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
2057 ;; Convert impossible stores of immediate to existing instructions.
2058 ;; First try to get scratch register and go through it. In case this
2059 ;; fails, move by 32bit parts.
2061 [(match_scratch:DI 2 "r")
2062 (set (match_operand:DI 0 "memory_operand" "")
2063 (match_operand:DI 1 "immediate_operand" ""))]
2064 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2065 && !x86_64_immediate_operand (operands[1], DImode)"
2066 [(set (match_dup 2) (match_dup 1))
2067 (set (match_dup 0) (match_dup 2))])
2069 ;; We need to define this as both peepholer and splitter for case
2070 ;; peephole2 pass is not run.
2071 ;; "&& 1" is needed to keep it from matching the previous pattern.
2073 [(set (match_operand:DI 0 "memory_operand" "")
2074 (match_operand:DI 1 "immediate_operand" ""))]
2075 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2076 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2077 [(set (match_dup 2) (match_dup 3))
2078 (set (match_dup 4) (match_dup 5))]
2079 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2082 [(set (match_operand:DI 0 "memory_operand" "")
2083 (match_operand:DI 1 "immediate_operand" ""))]
2084 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2085 ? epilogue_completed : reload_completed)
2086 && !symbolic_operand (operands[1], DImode)
2087 && !x86_64_immediate_operand (operands[1], DImode)"
2088 [(set (match_dup 2) (match_dup 3))
2089 (set (match_dup 4) (match_dup 5))]
2090 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2092 (define_insn "*movdi_internal"
2093 [(set (match_operand:DI 0 "nonimmediate_operand"
2094 "=r ,o ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym")
2095 (match_operand:DI 1 "general_operand"
2096 "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))]
2097 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2099 switch (get_attr_type (insn))
2102 if (SSE_REG_P (operands[0]))
2103 return "movq2dq\t{%1, %0|%0, %1}";
2105 return "movdq2q\t{%1, %0|%0, %1}";
2108 switch (get_attr_mode (insn))
2111 return "%vmovdqa\t{%1, %0|%0, %1}";
2113 return "%vmovq\t{%1, %0|%0, %1}";
2115 return "movaps\t{%1, %0|%0, %1}";
2117 return "movlps\t{%1, %0|%0, %1}";
2123 return "movq\t{%1, %0|%0, %1}";
2126 return standard_sse_constant_opcode (insn, operands[1]);
2129 return "pxor\t%0, %0";
2139 (cond [(eq_attr "alternative" "5,6,7,8,13,14")
2140 (const_string "sse2")
2141 (eq_attr "alternative" "9,10,11,12")
2142 (const_string "noavx")
2144 (const_string "*")))
2146 (cond [(eq_attr "alternative" "0,1")
2147 (const_string "multi")
2148 (eq_attr "alternative" "2")
2149 (const_string "mmx")
2150 (eq_attr "alternative" "3,4")
2151 (const_string "mmxmov")
2152 (eq_attr "alternative" "5,9")
2153 (const_string "sselog1")
2154 (eq_attr "alternative" "13,14")
2155 (const_string "ssecvt")
2157 (const_string "ssemov")))
2158 (set (attr "prefix")
2159 (if_then_else (eq_attr "alternative" "5,6,7,8")
2160 (const_string "maybe_vex")
2161 (const_string "orig")))
2162 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")])
2165 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2166 (match_operand:DI 1 "general_operand" ""))]
2167 "!TARGET_64BIT && reload_completed
2168 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2169 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2171 "ix86_split_long_move (operands); DONE;")
2173 (define_insn "*movsi_internal"
2174 [(set (match_operand:SI 0 "nonimmediate_operand"
2175 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2176 (match_operand:SI 1 "general_operand"
2177 "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2178 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2180 switch (get_attr_type (insn))
2183 return standard_sse_constant_opcode (insn, operands[1]);
2186 switch (get_attr_mode (insn))
2189 return "%vmovdqa\t{%1, %0|%0, %1}";
2191 return "%vmovaps\t{%1, %0|%0, %1}";
2193 return "%vmovd\t{%1, %0|%0, %1}";
2195 return "%vmovss\t{%1, %0|%0, %1}";
2201 return "pxor\t%0, %0";
2204 if (get_attr_mode (insn) == MODE_DI)
2205 return "movq\t{%1, %0|%0, %1}";
2206 return "movd\t{%1, %0|%0, %1}";
2209 return "lea{l}\t{%a1, %0|%0, %a1}";
2212 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2213 if (ix86_use_lea_for_mov (insn, operands))
2214 return "lea{l}\t{%a1, %0|%0, %a1}";
2216 return "mov{l}\t{%1, %0|%0, %1}";
2220 (cond [(eq_attr "alternative" "2")
2221 (const_string "mmx")
2222 (eq_attr "alternative" "3,4,5")
2223 (const_string "mmxmov")
2224 (eq_attr "alternative" "6")
2225 (const_string "sselog1")
2226 (eq_attr "alternative" "7,8,9,10,11")
2227 (const_string "ssemov")
2228 (match_operand 1 "pic_32bit_operand" "")
2229 (const_string "lea")
2231 (const_string "imov")))
2232 (set (attr "prefix")
2233 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2234 (const_string "orig")
2235 (const_string "maybe_vex")))
2236 (set (attr "prefix_data16")
2237 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2239 (const_string "*")))
2241 (cond [(eq_attr "alternative" "2,3")
2243 (eq_attr "alternative" "6,7")
2245 (not (match_test "TARGET_SSE2"))
2246 (const_string "V4SF")
2247 (const_string "TI"))
2248 (and (eq_attr "alternative" "8,9,10,11")
2249 (not (match_test "TARGET_SSE2")))
2252 (const_string "SI")))])
2254 (define_insn "*movhi_internal"
2255 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2256 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2257 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2259 switch (get_attr_type (insn))
2262 /* movzwl is faster than movw on p2 due to partial word stalls,
2263 though not as fast as an aligned movl. */
2264 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2266 if (get_attr_mode (insn) == MODE_SI)
2267 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2269 return "mov{w}\t{%1, %0|%0, %1}";
2273 (cond [(match_test "optimize_function_for_size_p (cfun)")
2274 (const_string "imov")
2275 (and (eq_attr "alternative" "0")
2276 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2277 (not (match_test "TARGET_HIMODE_MATH"))))
2278 (const_string "imov")
2279 (and (eq_attr "alternative" "1,2")
2280 (match_operand:HI 1 "aligned_operand" ""))
2281 (const_string "imov")
2282 (and (match_test "TARGET_MOVX")
2283 (eq_attr "alternative" "0,2"))
2284 (const_string "imovx")
2286 (const_string "imov")))
2288 (cond [(eq_attr "type" "imovx")
2290 (and (eq_attr "alternative" "1,2")
2291 (match_operand:HI 1 "aligned_operand" ""))
2293 (and (eq_attr "alternative" "0")
2294 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2295 (not (match_test "TARGET_HIMODE_MATH"))))
2298 (const_string "HI")))])
2300 ;; Situation is quite tricky about when to choose full sized (SImode) move
2301 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2302 ;; partial register dependency machines (such as AMD Athlon), where QImode
2303 ;; moves issue extra dependency and for partial register stalls machines
2304 ;; that don't use QImode patterns (and QImode move cause stall on the next
2307 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2308 ;; register stall machines with, where we use QImode instructions, since
2309 ;; partial register stall can be caused there. Then we use movzx.
2310 (define_insn "*movqi_internal"
2311 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2312 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2313 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2315 switch (get_attr_type (insn))
2318 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2319 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2321 if (get_attr_mode (insn) == MODE_SI)
2322 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2324 return "mov{b}\t{%1, %0|%0, %1}";
2328 (cond [(and (eq_attr "alternative" "5")
2329 (not (match_operand:QI 1 "aligned_operand" "")))
2330 (const_string "imovx")
2331 (match_test "optimize_function_for_size_p (cfun)")
2332 (const_string "imov")
2333 (and (eq_attr "alternative" "3")
2334 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2335 (not (match_test "TARGET_QIMODE_MATH"))))
2336 (const_string "imov")
2337 (eq_attr "alternative" "3,5")
2338 (const_string "imovx")
2339 (and (match_test "TARGET_MOVX")
2340 (eq_attr "alternative" "2"))
2341 (const_string "imovx")
2343 (const_string "imov")))
2345 (cond [(eq_attr "alternative" "3,4,5")
2347 (eq_attr "alternative" "6")
2349 (eq_attr "type" "imovx")
2351 (and (eq_attr "type" "imov")
2352 (and (eq_attr "alternative" "0,1")
2353 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2354 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2355 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2357 ;; Avoid partial register stalls when not using QImode arithmetic
2358 (and (eq_attr "type" "imov")
2359 (and (eq_attr "alternative" "0,1")
2360 (and (match_test "TARGET_PARTIAL_REG_STALL")
2361 (not (match_test "TARGET_QIMODE_MATH")))))
2364 (const_string "QI")))])
2366 ;; Stores and loads of ax to arbitrary constant address.
2367 ;; We fake an second form of instruction to force reload to load address
2368 ;; into register when rax is not available
2369 (define_insn "*movabs<mode>_1"
2370 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2371 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2372 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2374 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2375 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2376 [(set_attr "type" "imov")
2377 (set_attr "modrm" "0,*")
2378 (set_attr "length_address" "8,0")
2379 (set_attr "length_immediate" "0,*")
2380 (set_attr "memory" "store")
2381 (set_attr "mode" "<MODE>")])
2383 (define_insn "*movabs<mode>_2"
2384 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2385 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2386 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2388 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2389 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2390 [(set_attr "type" "imov")
2391 (set_attr "modrm" "0,*")
2392 (set_attr "length_address" "8,0")
2393 (set_attr "length_immediate" "0")
2394 (set_attr "memory" "load")
2395 (set_attr "mode" "<MODE>")])
2397 (define_insn "*swap<mode>"
2398 [(set (match_operand:SWI48 0 "register_operand" "+r")
2399 (match_operand:SWI48 1 "register_operand" "+r"))
2403 "xchg{<imodesuffix>}\t%1, %0"
2404 [(set_attr "type" "imov")
2405 (set_attr "mode" "<MODE>")
2406 (set_attr "pent_pair" "np")
2407 (set_attr "athlon_decode" "vector")
2408 (set_attr "amdfam10_decode" "double")
2409 (set_attr "bdver1_decode" "double")])
2411 (define_insn "*swap<mode>_1"
2412 [(set (match_operand:SWI12 0 "register_operand" "+r")
2413 (match_operand:SWI12 1 "register_operand" "+r"))
2416 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2418 [(set_attr "type" "imov")
2419 (set_attr "mode" "SI")
2420 (set_attr "pent_pair" "np")
2421 (set_attr "athlon_decode" "vector")
2422 (set_attr "amdfam10_decode" "double")
2423 (set_attr "bdver1_decode" "double")])
2425 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2426 ;; is disabled for AMDFAM10
2427 (define_insn "*swap<mode>_2"
2428 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2429 (match_operand:SWI12 1 "register_operand" "+<r>"))
2432 "TARGET_PARTIAL_REG_STALL"
2433 "xchg{<imodesuffix>}\t%1, %0"
2434 [(set_attr "type" "imov")
2435 (set_attr "mode" "<MODE>")
2436 (set_attr "pent_pair" "np")
2437 (set_attr "athlon_decode" "vector")])
2439 (define_expand "movstrict<mode>"
2440 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2441 (match_operand:SWI12 1 "general_operand" ""))]
2444 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2446 if (GET_CODE (operands[0]) == SUBREG
2447 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2449 /* Don't generate memory->memory moves, go through a register */
2450 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2451 operands[1] = force_reg (<MODE>mode, operands[1]);
2454 (define_insn "*movstrict<mode>_1"
2455 [(set (strict_low_part
2456 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2457 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2458 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2459 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2460 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2461 [(set_attr "type" "imov")
2462 (set_attr "mode" "<MODE>")])
2464 (define_insn "*movstrict<mode>_xor"
2465 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2466 (match_operand:SWI12 1 "const0_operand" ""))
2467 (clobber (reg:CC FLAGS_REG))]
2469 "xor{<imodesuffix>}\t%0, %0"
2470 [(set_attr "type" "alu1")
2471 (set_attr "mode" "<MODE>")
2472 (set_attr "length_immediate" "0")])
2474 (define_insn "*mov<mode>_extv_1"
2475 [(set (match_operand:SWI24 0 "register_operand" "=R")
2476 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2480 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2481 [(set_attr "type" "imovx")
2482 (set_attr "mode" "SI")])
2484 (define_insn "*movqi_extv_1_rex64"
2485 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2486 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2491 switch (get_attr_type (insn))
2494 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2496 return "mov{b}\t{%h1, %0|%0, %h1}";
2500 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2501 (match_test "TARGET_MOVX"))
2502 (const_string "imovx")
2503 (const_string "imov")))
2505 (if_then_else (eq_attr "type" "imovx")
2507 (const_string "QI")))])
2509 (define_insn "*movqi_extv_1"
2510 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2511 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2516 switch (get_attr_type (insn))
2519 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2521 return "mov{b}\t{%h1, %0|%0, %h1}";
2525 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2526 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2527 (match_test "TARGET_MOVX")))
2528 (const_string "imovx")
2529 (const_string "imov")))
2531 (if_then_else (eq_attr "type" "imovx")
2533 (const_string "QI")))])
2535 (define_insn "*mov<mode>_extzv_1"
2536 [(set (match_operand:SWI48 0 "register_operand" "=R")
2537 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2541 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2542 [(set_attr "type" "imovx")
2543 (set_attr "mode" "SI")])
2545 (define_insn "*movqi_extzv_2_rex64"
2546 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2548 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2553 switch (get_attr_type (insn))
2556 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2558 return "mov{b}\t{%h1, %0|%0, %h1}";
2562 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2563 (match_test "TARGET_MOVX"))
2564 (const_string "imovx")
2565 (const_string "imov")))
2567 (if_then_else (eq_attr "type" "imovx")
2569 (const_string "QI")))])
2571 (define_insn "*movqi_extzv_2"
2572 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2574 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2579 switch (get_attr_type (insn))
2582 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2584 return "mov{b}\t{%h1, %0|%0, %h1}";
2588 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2589 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2590 (match_test "TARGET_MOVX")))
2591 (const_string "imovx")
2592 (const_string "imov")))
2594 (if_then_else (eq_attr "type" "imovx")
2596 (const_string "QI")))])
2598 (define_expand "mov<mode>_insv_1"
2599 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2602 (match_operand:SWI48 1 "nonmemory_operand" ""))])
2604 (define_insn "*mov<mode>_insv_1_rex64"
2605 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2608 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2610 "mov{b}\t{%b1, %h0|%h0, %b1}"
2611 [(set_attr "type" "imov")
2612 (set_attr "mode" "QI")])
2614 (define_insn "*movsi_insv_1"
2615 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2618 (match_operand:SI 1 "general_operand" "Qmn"))]
2620 "mov{b}\t{%b1, %h0|%h0, %b1}"
2621 [(set_attr "type" "imov")
2622 (set_attr "mode" "QI")])
2624 (define_insn "*movqi_insv_2"
2625 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2628 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2631 "mov{b}\t{%h1, %h0|%h0, %h1}"
2632 [(set_attr "type" "imov")
2633 (set_attr "mode" "QI")])
2635 ;; Floating point push instructions.
2637 (define_insn "*pushtf"
2638 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2639 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2642 /* This insn should be already split before reg-stack. */
2645 [(set_attr "type" "multi")
2646 (set_attr "unit" "sse,*,*")
2647 (set_attr "mode" "TF,SI,SI")])
2649 ;; %%% Kill this when call knows how to work this out.
2651 [(set (match_operand:TF 0 "push_operand" "")
2652 (match_operand:TF 1 "sse_reg_operand" ""))]
2653 "TARGET_SSE2 && reload_completed"
2654 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2655 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2657 (define_insn "*pushxf"
2658 [(set (match_operand:XF 0 "push_operand" "=<,<")
2659 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2660 "optimize_function_for_speed_p (cfun)"
2662 /* This insn should be already split before reg-stack. */
2665 [(set_attr "type" "multi")
2666 (set_attr "unit" "i387,*")
2667 (set_attr "mode" "XF,SI")])
2669 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2670 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2671 ;; Pushing using integer instructions is longer except for constants
2672 ;; and direct memory references (assuming that any given constant is pushed
2673 ;; only once, but this ought to be handled elsewhere).
2675 (define_insn "*pushxf_nointeger"
2676 [(set (match_operand:XF 0 "push_operand" "=<,<")
2677 (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2678 "optimize_function_for_size_p (cfun)"
2680 /* This insn should be already split before reg-stack. */
2683 [(set_attr "type" "multi")
2684 (set_attr "unit" "i387,*")
2685 (set_attr "mode" "XF,SI")])
2687 ;; %%% Kill this when call knows how to work this out.
2689 [(set (match_operand:XF 0 "push_operand" "")
2690 (match_operand:XF 1 "fp_register_operand" ""))]
2692 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2693 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2694 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2696 (define_insn "*pushdf_rex64"
2697 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2698 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
2701 /* This insn should be already split before reg-stack. */
2704 [(set_attr "type" "multi")
2705 (set_attr "unit" "i387,*,*")
2706 (set_attr "mode" "DF,DI,DF")])
2708 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2709 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2710 ;; On the average, pushdf using integers can be still shorter.
2712 (define_insn "*pushdf"
2713 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2714 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
2717 /* This insn should be already split before reg-stack. */
2720 [(set_attr "isa" "*,*,sse2")
2721 (set_attr "type" "multi")
2722 (set_attr "unit" "i387,*,*")
2723 (set_attr "mode" "DF,DI,DF")])
2725 ;; %%% Kill this when call knows how to work this out.
2727 [(set (match_operand:DF 0 "push_operand" "")
2728 (match_operand:DF 1 "any_fp_register_operand" ""))]
2730 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2731 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2733 (define_insn "*pushsf_rex64"
2734 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2735 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2738 /* Anything else should be already split before reg-stack. */
2739 gcc_assert (which_alternative == 1);
2740 return "push{q}\t%q1";
2742 [(set_attr "type" "multi,push,multi")
2743 (set_attr "unit" "i387,*,*")
2744 (set_attr "mode" "SF,DI,SF")])
2746 (define_insn "*pushsf"
2747 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2748 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2751 /* Anything else should be already split before reg-stack. */
2752 gcc_assert (which_alternative == 1);
2753 return "push{l}\t%1";
2755 [(set_attr "type" "multi,push,multi")
2756 (set_attr "unit" "i387,*,*")
2757 (set_attr "mode" "SF,SI,SF")])
2759 ;; %%% Kill this when call knows how to work this out.
2761 [(set (match_operand:SF 0 "push_operand" "")
2762 (match_operand:SF 1 "any_fp_register_operand" ""))]
2764 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2765 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2766 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2769 [(set (match_operand:SF 0 "push_operand" "")
2770 (match_operand:SF 1 "memory_operand" ""))]
2772 && (operands[2] = find_constant_src (insn))"
2773 [(set (match_dup 0) (match_dup 2))])
2776 [(set (match_operand 0 "push_operand" "")
2777 (match_operand 1 "general_operand" ""))]
2779 && (GET_MODE (operands[0]) == TFmode
2780 || GET_MODE (operands[0]) == XFmode
2781 || GET_MODE (operands[0]) == DFmode)
2782 && !ANY_FP_REG_P (operands[1])"
2784 "ix86_split_long_move (operands); DONE;")
2786 ;; Floating point move instructions.
2788 (define_expand "movtf"
2789 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2790 (match_operand:TF 1 "nonimmediate_operand" ""))]
2793 ix86_expand_move (TFmode, operands);
2797 (define_expand "mov<mode>"
2798 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2799 (match_operand:X87MODEF 1 "general_operand" ""))]
2801 "ix86_expand_move (<MODE>mode, operands); DONE;")
2803 (define_insn "*movtf_internal"
2804 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o")
2805 (match_operand:TF 1 "general_operand" "xm,x,C,*roF,F*r"))]
2807 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2808 && (!can_create_pseudo_p ()
2809 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2810 || GET_CODE (operands[1]) != CONST_DOUBLE
2811 || (optimize_function_for_size_p (cfun)
2812 && standard_sse_constant_p (operands[1])
2813 && !memory_operand (operands[0], TFmode))
2814 || (!TARGET_MEMORY_MISMATCH_STALL
2815 && memory_operand (operands[0], TFmode)))"
2817 switch (which_alternative)
2821 /* Handle misaligned load/store since we
2822 don't have movmisaligntf pattern. */
2823 if (misaligned_operand (operands[0], TFmode)
2824 || misaligned_operand (operands[1], TFmode))
2826 if (get_attr_mode (insn) == MODE_V4SF)
2827 return "%vmovups\t{%1, %0|%0, %1}";
2829 return "%vmovdqu\t{%1, %0|%0, %1}";
2833 if (get_attr_mode (insn) == MODE_V4SF)
2834 return "%vmovaps\t{%1, %0|%0, %1}";
2836 return "%vmovdqa\t{%1, %0|%0, %1}";
2840 return standard_sse_constant_opcode (insn, operands[1]);
2850 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2851 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2853 (cond [(eq_attr "alternative" "0,2")
2855 (match_test "optimize_function_for_size_p (cfun)")
2856 (const_string "V4SF")
2857 (const_string "TI"))
2858 (eq_attr "alternative" "1")
2860 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
2861 (match_test "optimize_function_for_size_p (cfun)"))
2862 (const_string "V4SF")
2863 (const_string "TI"))]
2864 (const_string "DI")))])
2866 ;; Possible store forwarding (partial memory) stall in alternative 4.
2867 (define_insn "*movxf_internal"
2868 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2869 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,FYx*r"))]
2870 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2871 && (!can_create_pseudo_p ()
2872 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2873 || GET_CODE (operands[1]) != CONST_DOUBLE
2874 || (optimize_function_for_size_p (cfun)
2875 && standard_80387_constant_p (operands[1]) > 0
2876 && !memory_operand (operands[0], XFmode))
2877 || (!TARGET_MEMORY_MISMATCH_STALL
2878 && memory_operand (operands[0], XFmode)))"
2880 switch (which_alternative)
2884 return output_387_reg_move (insn, operands);
2887 return standard_80387_constant_opcode (operands[1]);
2897 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2898 (set_attr "mode" "XF,XF,XF,SI,SI")])
2900 (define_insn "*movdf_internal_rex64"
2901 [(set (match_operand:DF 0 "nonimmediate_operand"
2902 "=f,m,f,?r,?m,?r,!o,x,x,x,m,Yi,r ")
2903 (match_operand:DF 1 "general_operand"
2904 "fm,f,G,rm,r ,F ,F ,C,x,m,x,r ,Yi"))]
2905 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2906 && (!can_create_pseudo_p ()
2907 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2908 || GET_CODE (operands[1]) != CONST_DOUBLE
2909 || (optimize_function_for_size_p (cfun)
2910 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2911 && standard_80387_constant_p (operands[1]) > 0)
2912 || (TARGET_SSE2 && TARGET_SSE_MATH
2913 && standard_sse_constant_p (operands[1]))))
2914 || memory_operand (operands[0], DFmode))"
2916 switch (which_alternative)
2920 return output_387_reg_move (insn, operands);
2923 return standard_80387_constant_opcode (operands[1]);
2927 return "mov{q}\t{%1, %0|%0, %1}";
2930 return "movabs{q}\t{%1, %0|%0, %1}";
2936 return standard_sse_constant_opcode (insn, operands[1]);
2941 switch (get_attr_mode (insn))
2944 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2945 return "%vmovapd\t{%1, %0|%0, %1}";
2947 return "%vmovaps\t{%1, %0|%0, %1}";
2950 return "%vmovq\t{%1, %0|%0, %1}";
2952 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2953 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2954 return "%vmovsd\t{%1, %0|%0, %1}";
2956 return "%vmovlpd\t{%1, %d0|%d0, %1}";
2958 return "%vmovlps\t{%1, %d0|%d0, %1}";
2965 /* Handle broken assemblers that require movd instead of movq. */
2966 return "%vmovd\t{%1, %0|%0, %1}";
2973 (cond [(eq_attr "alternative" "0,1,2")
2974 (const_string "fmov")
2975 (eq_attr "alternative" "3,4,5")
2976 (const_string "imov")
2977 (eq_attr "alternative" "6")
2978 (const_string "multi")
2979 (eq_attr "alternative" "7")
2980 (const_string "sselog1")
2982 (const_string "ssemov")))
2985 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2987 (const_string "*")))
2988 (set (attr "length_immediate")
2990 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2992 (const_string "*")))
2993 (set (attr "prefix")
2994 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
2995 (const_string "orig")
2996 (const_string "maybe_vex")))
2997 (set (attr "prefix_data16")
2998 (if_then_else (eq_attr "mode" "V1DF")
3000 (const_string "*")))
3002 (cond [(eq_attr "alternative" "0,1,2")
3004 (eq_attr "alternative" "3,4,5,6,11,12")
3007 /* xorps is one byte shorter. */
3008 (eq_attr "alternative" "7")
3009 (cond [(match_test "optimize_function_for_size_p (cfun)")
3010 (const_string "V4SF")
3011 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3014 (const_string "V2DF"))
3016 /* For architectures resolving dependencies on
3017 whole SSE registers use APD move to break dependency
3018 chains, otherwise use short move to avoid extra work.
3020 movaps encodes one byte shorter. */
3021 (eq_attr "alternative" "8")
3023 [(match_test "optimize_function_for_size_p (cfun)")
3024 (const_string "V4SF")
3025 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3026 (const_string "V2DF")
3028 (const_string "DF"))
3029 /* For architectures resolving dependencies on register
3030 parts we may avoid extra work to zero out upper part
3032 (eq_attr "alternative" "9")
3034 (match_test "TARGET_SSE_SPLIT_REGS")
3035 (const_string "V1DF")
3036 (const_string "DF"))
3038 (const_string "DF")))])
3040 ;; Possible store forwarding (partial memory) stall in alternative 4.
3041 (define_insn "*movdf_internal"
3042 [(set (match_operand:DF 0 "nonimmediate_operand"
3043 "=f,m,f,?Yd*r ,!o ,x,x,x,m,*x,*x,*x,m")
3044 (match_operand:DF 1 "general_operand"
3045 "fm,f,G,Yd*roF,FYd*r,C,x,m,x,C ,*x,m ,*x"))]
3046 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3047 && (!can_create_pseudo_p ()
3048 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3049 || GET_CODE (operands[1]) != CONST_DOUBLE
3050 || (optimize_function_for_size_p (cfun)
3051 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3052 && standard_80387_constant_p (operands[1]) > 0)
3053 || (TARGET_SSE2 && TARGET_SSE_MATH
3054 && standard_sse_constant_p (operands[1])))
3055 && !memory_operand (operands[0], DFmode))
3056 || (!TARGET_MEMORY_MISMATCH_STALL
3057 && memory_operand (operands[0], DFmode)))"
3059 switch (which_alternative)
3063 return output_387_reg_move (insn, operands);
3066 return standard_80387_constant_opcode (operands[1]);
3074 return standard_sse_constant_opcode (insn, operands[1]);
3082 switch (get_attr_mode (insn))
3085 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3086 return "%vmovapd\t{%1, %0|%0, %1}";
3088 return "%vmovaps\t{%1, %0|%0, %1}";
3091 return "%vmovq\t{%1, %0|%0, %1}";
3093 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3094 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3095 return "%vmovsd\t{%1, %0|%0, %1}";
3097 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3099 return "%vmovlps\t{%1, %d0|%d0, %1}";
3109 (if_then_else (eq_attr "alternative" "5,6,7,8")
3110 (const_string "sse2")
3111 (const_string "*")))
3113 (cond [(eq_attr "alternative" "0,1,2")
3114 (const_string "fmov")
3115 (eq_attr "alternative" "3,4")
3116 (const_string "multi")
3117 (eq_attr "alternative" "5,9")
3118 (const_string "sselog1")
3120 (const_string "ssemov")))
3121 (set (attr "prefix")
3122 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3123 (const_string "orig")
3124 (const_string "maybe_vex")))
3125 (set (attr "prefix_data16")
3126 (if_then_else (eq_attr "mode" "V1DF")
3128 (const_string "*")))
3130 (cond [(eq_attr "alternative" "0,1,2")
3132 (eq_attr "alternative" "3,4")
3135 /* For SSE1, we have many fewer alternatives. */
3136 (not (match_test "TARGET_SSE2"))
3138 (eq_attr "alternative" "5,6,9,10")
3139 (const_string "V4SF")
3140 (const_string "V2SF"))
3142 /* xorps is one byte shorter. */
3143 (eq_attr "alternative" "5,9")
3144 (cond [(match_test "optimize_function_for_size_p (cfun)")
3145 (const_string "V4SF")
3146 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3149 (const_string "V2DF"))
3151 /* For architectures resolving dependencies on
3152 whole SSE registers use APD move to break dependency
3153 chains, otherwise use short move to avoid extra work.
3155 movaps encodes one byte shorter. */
3156 (eq_attr "alternative" "6,10")
3158 [(match_test "optimize_function_for_size_p (cfun)")
3159 (const_string "V4SF")
3160 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3161 (const_string "V2DF")
3163 (const_string "DF"))
3164 /* For architectures resolving dependencies on register
3165 parts we may avoid extra work to zero out upper part
3167 (eq_attr "alternative" "7,11")
3169 (match_test "TARGET_SSE_SPLIT_REGS")
3170 (const_string "V1DF")
3171 (const_string "DF"))
3173 (const_string "DF")))])
3175 (define_insn "*movsf_internal"
3176 [(set (match_operand:SF 0 "nonimmediate_operand"
3177 "=f,m,f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3178 (match_operand:SF 1 "general_operand"
3179 "fm,f,G,rmF,Fr,C,x,m,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3180 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3181 && (!can_create_pseudo_p ()
3182 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3183 || GET_CODE (operands[1]) != CONST_DOUBLE
3184 || (optimize_function_for_size_p (cfun)
3185 && ((!TARGET_SSE_MATH
3186 && standard_80387_constant_p (operands[1]) > 0)
3188 && standard_sse_constant_p (operands[1]))))
3189 || memory_operand (operands[0], SFmode))"
3191 switch (which_alternative)
3195 return output_387_reg_move (insn, operands);
3198 return standard_80387_constant_opcode (operands[1]);
3202 return "mov{l}\t{%1, %0|%0, %1}";
3205 return standard_sse_constant_opcode (insn, operands[1]);
3208 if (get_attr_mode (insn) == MODE_V4SF)
3209 return "%vmovaps\t{%1, %0|%0, %1}";
3211 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3215 return "%vmovss\t{%1, %0|%0, %1}";
3221 return "movd\t{%1, %0|%0, %1}";
3224 return "movq\t{%1, %0|%0, %1}";
3228 return "%vmovd\t{%1, %0|%0, %1}";
3235 (cond [(eq_attr "alternative" "0,1,2")
3236 (const_string "fmov")
3237 (eq_attr "alternative" "3,4")
3238 (const_string "multi")
3239 (eq_attr "alternative" "5")
3240 (const_string "sselog1")
3241 (eq_attr "alternative" "9,10,11,14,15")
3242 (const_string "mmxmov")
3244 (const_string "ssemov")))
3245 (set (attr "prefix")
3246 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3247 (const_string "maybe_vex")
3248 (const_string "orig")))
3250 (cond [(eq_attr "alternative" "3,4,9,10")
3252 (eq_attr "alternative" "5")
3254 (and (and (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3255 (match_test "TARGET_SSE2"))
3256 (not (match_test "optimize_function_for_size_p (cfun)")))
3258 (const_string "V4SF"))
3259 /* For architectures resolving dependencies on
3260 whole SSE registers use APS move to break dependency
3261 chains, otherwise use short move to avoid extra work.
3263 Do the same for architectures resolving dependencies on
3264 the parts. While in DF mode it is better to always handle
3265 just register parts, the SF mode is different due to lack
3266 of instructions to load just part of the register. It is
3267 better to maintain the whole registers in single format
3268 to avoid problems on using packed logical operations. */
3269 (eq_attr "alternative" "6")
3271 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3272 (match_test "TARGET_SSE_SPLIT_REGS"))
3273 (const_string "V4SF")
3274 (const_string "SF"))
3275 (eq_attr "alternative" "11")
3276 (const_string "DI")]
3277 (const_string "SF")))])
3280 [(set (match_operand 0 "any_fp_register_operand" "")
3281 (match_operand 1 "memory_operand" ""))]
3283 && (GET_MODE (operands[0]) == TFmode
3284 || GET_MODE (operands[0]) == XFmode
3285 || GET_MODE (operands[0]) == DFmode
3286 || GET_MODE (operands[0]) == SFmode)
3287 && (operands[2] = find_constant_src (insn))"
3288 [(set (match_dup 0) (match_dup 2))]
3290 rtx c = operands[2];
3291 int r = REGNO (operands[0]);
3293 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3294 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3299 [(set (match_operand 0 "any_fp_register_operand" "")
3300 (float_extend (match_operand 1 "memory_operand" "")))]
3302 && (GET_MODE (operands[0]) == TFmode
3303 || GET_MODE (operands[0]) == XFmode
3304 || GET_MODE (operands[0]) == DFmode)
3305 && (operands[2] = find_constant_src (insn))"
3306 [(set (match_dup 0) (match_dup 2))]
3308 rtx c = operands[2];
3309 int r = REGNO (operands[0]);
3311 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3312 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3316 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3318 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
3319 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3321 && (standard_80387_constant_p (operands[1]) == 8
3322 || standard_80387_constant_p (operands[1]) == 9)"
3323 [(set (match_dup 0)(match_dup 1))
3325 (neg:X87MODEF (match_dup 0)))]
3329 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3330 if (real_isnegzero (&r))
3331 operands[1] = CONST0_RTX (<MODE>mode);
3333 operands[1] = CONST1_RTX (<MODE>mode);
3337 [(set (match_operand 0 "nonimmediate_operand" "")
3338 (match_operand 1 "general_operand" ""))]
3340 && (GET_MODE (operands[0]) == TFmode
3341 || GET_MODE (operands[0]) == XFmode
3342 || GET_MODE (operands[0]) == DFmode)
3343 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3345 "ix86_split_long_move (operands); DONE;")
3347 (define_insn "swapxf"
3348 [(set (match_operand:XF 0 "register_operand" "+f")
3349 (match_operand:XF 1 "register_operand" "+f"))
3354 if (STACK_TOP_P (operands[0]))
3359 [(set_attr "type" "fxch")
3360 (set_attr "mode" "XF")])
3362 (define_insn "*swap<mode>"
3363 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3364 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3367 "TARGET_80387 || reload_completed"
3369 if (STACK_TOP_P (operands[0]))
3374 [(set_attr "type" "fxch")
3375 (set_attr "mode" "<MODE>")])
3377 ;; Zero extension instructions
3379 (define_expand "zero_extendsidi2"
3380 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3381 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))])
3383 (define_insn "*zero_extendsidi2_rex64"
3384 [(set (match_operand:DI 0 "nonimmediate_operand"
3385 "=r ,o,?*Ym,?*y,?*Yi,!*x")
3387 (match_operand:SI 1 "x86_64_zext_general_operand"
3388 "rmZ,0,r ,m ,r ,m*x")))]
3391 mov{l}\t{%1, %k0|%k0, %1}
3393 movd\t{%1, %0|%0, %1}
3394 movd\t{%1, %0|%0, %1}
3395 %vmovd\t{%1, %0|%0, %1}
3396 %vmovd\t{%1, %0|%0, %1}"
3397 [(set_attr "isa" "*,*,*,*,*,sse2")
3398 (set_attr "type" "imovx,multi,mmxmov,mmxmov,ssemov,ssemov")
3399 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3400 (set_attr "prefix_0f" "0,*,*,*,*,*")
3401 (set_attr "mode" "SI,SI,DI,DI,TI,TI")])
3403 (define_insn "*zero_extendsidi2"
3404 [(set (match_operand:DI 0 "nonimmediate_operand"
3405 "=ro,?r,?o,?*Ym,?*y,?*Yi,!*x")
3406 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand"
3407 "0 ,rm,r ,r ,m ,r ,m*x")))]
3413 movd\t{%1, %0|%0, %1}
3414 movd\t{%1, %0|%0, %1}
3415 %vmovd\t{%1, %0|%0, %1}
3416 %vmovd\t{%1, %0|%0, %1}"
3417 [(set_attr "isa" "*,*,*,*,*,*,sse2")
3418 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3419 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3420 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3423 [(set (match_operand:DI 0 "memory_operand" "")
3424 (zero_extend:DI (match_operand:SI 1 "memory_operand" "")))]
3426 [(set (match_dup 4) (const_int 0))]
3427 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3430 [(set (match_operand:DI 0 "register_operand" "")
3431 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
3432 "!TARGET_64BIT && reload_completed
3433 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3434 && true_regnum (operands[0]) == true_regnum (operands[1])"
3435 [(set (match_dup 4) (const_int 0))]
3436 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3439 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3440 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3441 "!TARGET_64BIT && reload_completed
3442 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3443 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3444 [(set (match_dup 3) (match_dup 1))
3445 (set (match_dup 4) (const_int 0))]
3446 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3448 (define_insn "zero_extend<mode>di2"
3449 [(set (match_operand:DI 0 "register_operand" "=r")
3451 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3453 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3454 [(set_attr "type" "imovx")
3455 (set_attr "mode" "SI")])
3457 (define_expand "zero_extend<mode>si2"
3458 [(set (match_operand:SI 0 "register_operand" "")
3459 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand" "")))]
3462 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3464 operands[1] = force_reg (<MODE>mode, operands[1]);
3465 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3470 (define_insn_and_split "zero_extend<mode>si2_and"
3471 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3473 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3474 (clobber (reg:CC FLAGS_REG))]
3475 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3477 "&& reload_completed"
3478 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3479 (clobber (reg:CC FLAGS_REG))])]
3481 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3483 ix86_expand_clear (operands[0]);
3485 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3486 emit_insn (gen_movstrict<mode>
3487 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3491 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3493 [(set_attr "type" "alu1")
3494 (set_attr "mode" "SI")])
3496 (define_insn "*zero_extend<mode>si2"
3497 [(set (match_operand:SI 0 "register_operand" "=r")
3499 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3500 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3501 "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3502 [(set_attr "type" "imovx")
3503 (set_attr "mode" "SI")])
3505 (define_expand "zero_extendqihi2"
3506 [(set (match_operand:HI 0 "register_operand" "")
3507 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
3510 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3512 operands[1] = force_reg (QImode, operands[1]);
3513 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3518 (define_insn_and_split "zero_extendqihi2_and"
3519 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3520 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3521 (clobber (reg:CC FLAGS_REG))]
3522 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3524 "&& reload_completed"
3525 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3526 (clobber (reg:CC FLAGS_REG))])]
3528 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3530 ix86_expand_clear (operands[0]);
3532 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3533 emit_insn (gen_movstrictqi
3534 (gen_lowpart (QImode, operands[0]), operands[1]));
3538 operands[0] = gen_lowpart (SImode, operands[0]);
3540 [(set_attr "type" "alu1")
3541 (set_attr "mode" "SI")])
3543 ; zero extend to SImode to avoid partial register stalls
3544 (define_insn "*zero_extendqihi2"
3545 [(set (match_operand:HI 0 "register_operand" "=r")
3546 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3547 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3548 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3549 [(set_attr "type" "imovx")
3550 (set_attr "mode" "SI")])
3552 ;; Sign extension instructions
3554 (define_expand "extendsidi2"
3555 [(set (match_operand:DI 0 "register_operand" "")
3556 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3561 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3566 (define_insn "*extendsidi2_rex64"
3567 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3568 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3572 movs{lq|x}\t{%1, %0|%0, %1}"
3573 [(set_attr "type" "imovx")
3574 (set_attr "mode" "DI")
3575 (set_attr "prefix_0f" "0")
3576 (set_attr "modrm" "0,1")])
3578 (define_insn "extendsidi2_1"
3579 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3580 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3581 (clobber (reg:CC FLAGS_REG))
3582 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3586 ;; Extend to memory case when source register does die.
3588 [(set (match_operand:DI 0 "memory_operand" "")
3589 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3590 (clobber (reg:CC FLAGS_REG))
3591 (clobber (match_operand:SI 2 "register_operand" ""))]
3593 && dead_or_set_p (insn, operands[1])
3594 && !reg_mentioned_p (operands[1], operands[0]))"
3595 [(set (match_dup 3) (match_dup 1))
3596 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3597 (clobber (reg:CC FLAGS_REG))])
3598 (set (match_dup 4) (match_dup 1))]
3599 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3601 ;; Extend to memory case when source register does not die.
3603 [(set (match_operand:DI 0 "memory_operand" "")
3604 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3605 (clobber (reg:CC FLAGS_REG))
3606 (clobber (match_operand:SI 2 "register_operand" ""))]
3610 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3612 emit_move_insn (operands[3], operands[1]);
3614 /* Generate a cltd if possible and doing so it profitable. */
3615 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3616 && true_regnum (operands[1]) == AX_REG
3617 && true_regnum (operands[2]) == DX_REG)
3619 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3623 emit_move_insn (operands[2], operands[1]);
3624 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3626 emit_move_insn (operands[4], operands[2]);
3630 ;; Extend to register case. Optimize case where source and destination
3631 ;; registers match and cases where we can use cltd.
3633 [(set (match_operand:DI 0 "register_operand" "")
3634 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3635 (clobber (reg:CC FLAGS_REG))
3636 (clobber (match_scratch:SI 2 ""))]
3640 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3642 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3643 emit_move_insn (operands[3], operands[1]);
3645 /* Generate a cltd if possible and doing so it profitable. */
3646 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3647 && true_regnum (operands[3]) == AX_REG
3648 && true_regnum (operands[4]) == DX_REG)
3650 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3654 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3655 emit_move_insn (operands[4], operands[1]);
3657 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3661 (define_insn "extend<mode>di2"
3662 [(set (match_operand:DI 0 "register_operand" "=r")
3664 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3666 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3667 [(set_attr "type" "imovx")
3668 (set_attr "mode" "DI")])
3670 (define_insn "extendhisi2"
3671 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3672 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3675 switch (get_attr_prefix_0f (insn))
3678 return "{cwtl|cwde}";
3680 return "movs{wl|x}\t{%1, %0|%0, %1}";
3683 [(set_attr "type" "imovx")
3684 (set_attr "mode" "SI")
3685 (set (attr "prefix_0f")
3686 ;; movsx is short decodable while cwtl is vector decoded.
3687 (if_then_else (and (eq_attr "cpu" "!k6")
3688 (eq_attr "alternative" "0"))
3690 (const_string "1")))
3692 (if_then_else (eq_attr "prefix_0f" "0")
3694 (const_string "1")))])
3696 (define_insn "*extendhisi2_zext"
3697 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3700 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3703 switch (get_attr_prefix_0f (insn))
3706 return "{cwtl|cwde}";
3708 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3711 [(set_attr "type" "imovx")
3712 (set_attr "mode" "SI")
3713 (set (attr "prefix_0f")
3714 ;; movsx is short decodable while cwtl is vector decoded.
3715 (if_then_else (and (eq_attr "cpu" "!k6")
3716 (eq_attr "alternative" "0"))
3718 (const_string "1")))
3720 (if_then_else (eq_attr "prefix_0f" "0")
3722 (const_string "1")))])
3724 (define_insn "extendqisi2"
3725 [(set (match_operand:SI 0 "register_operand" "=r")
3726 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3728 "movs{bl|x}\t{%1, %0|%0, %1}"
3729 [(set_attr "type" "imovx")
3730 (set_attr "mode" "SI")])
3732 (define_insn "*extendqisi2_zext"
3733 [(set (match_operand:DI 0 "register_operand" "=r")
3735 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3737 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3738 [(set_attr "type" "imovx")
3739 (set_attr "mode" "SI")])
3741 (define_insn "extendqihi2"
3742 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3743 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3746 switch (get_attr_prefix_0f (insn))
3749 return "{cbtw|cbw}";
3751 return "movs{bw|x}\t{%1, %0|%0, %1}";
3754 [(set_attr "type" "imovx")
3755 (set_attr "mode" "HI")
3756 (set (attr "prefix_0f")
3757 ;; movsx is short decodable while cwtl is vector decoded.
3758 (if_then_else (and (eq_attr "cpu" "!k6")
3759 (eq_attr "alternative" "0"))
3761 (const_string "1")))
3763 (if_then_else (eq_attr "prefix_0f" "0")
3765 (const_string "1")))])
3767 ;; Conversions between float and double.
3769 ;; These are all no-ops in the model used for the 80387.
3770 ;; So just emit moves.
3772 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3774 [(set (match_operand:DF 0 "push_operand" "")
3775 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3777 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3778 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3781 [(set (match_operand:XF 0 "push_operand" "")
3782 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3784 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3785 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3786 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3788 (define_expand "extendsfdf2"
3789 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3790 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3791 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3793 /* ??? Needed for compress_float_constant since all fp constants
3794 are TARGET_LEGITIMATE_CONSTANT_P. */
3795 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3797 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3798 && standard_80387_constant_p (operands[1]) > 0)
3800 operands[1] = simplify_const_unary_operation
3801 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3802 emit_move_insn_1 (operands[0], operands[1]);
3805 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3809 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3811 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3813 We do the conversion post reload to avoid producing of 128bit spills
3814 that might lead to ICE on 32bit target. The sequence unlikely combine
3817 [(set (match_operand:DF 0 "register_operand" "")
3819 (match_operand:SF 1 "nonimmediate_operand" "")))]
3820 "TARGET_USE_VECTOR_FP_CONVERTS
3821 && optimize_insn_for_speed_p ()
3822 && reload_completed && SSE_REG_P (operands[0])"
3827 (parallel [(const_int 0) (const_int 1)]))))]
3829 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3830 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3831 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3832 Try to avoid move when unpacking can be done in source. */
3833 if (REG_P (operands[1]))
3835 /* If it is unsafe to overwrite upper half of source, we need
3836 to move to destination and unpack there. */
3837 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3838 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3839 && true_regnum (operands[0]) != true_regnum (operands[1]))
3841 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3842 emit_move_insn (tmp, operands[1]);
3845 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3846 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3850 emit_insn (gen_vec_setv4sf_0 (operands[3],
3851 CONST0_RTX (V4SFmode), operands[1]));
3854 (define_insn "*extendsfdf2_mixed"
3855 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3857 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3858 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3860 switch (which_alternative)
3864 return output_387_reg_move (insn, operands);
3867 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3873 [(set_attr "type" "fmov,fmov,ssecvt")
3874 (set_attr "prefix" "orig,orig,maybe_vex")
3875 (set_attr "mode" "SF,XF,DF")])
3877 (define_insn "*extendsfdf2_sse"
3878 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3879 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3880 "TARGET_SSE2 && TARGET_SSE_MATH"
3881 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3882 [(set_attr "type" "ssecvt")
3883 (set_attr "prefix" "maybe_vex")
3884 (set_attr "mode" "DF")])
3886 (define_insn "*extendsfdf2_i387"
3887 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3888 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3890 "* return output_387_reg_move (insn, operands);"
3891 [(set_attr "type" "fmov")
3892 (set_attr "mode" "SF,XF")])
3894 (define_expand "extend<mode>xf2"
3895 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3896 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3899 /* ??? Needed for compress_float_constant since all fp constants
3900 are TARGET_LEGITIMATE_CONSTANT_P. */
3901 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3903 if (standard_80387_constant_p (operands[1]) > 0)
3905 operands[1] = simplify_const_unary_operation
3906 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3907 emit_move_insn_1 (operands[0], operands[1]);
3910 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3914 (define_insn "*extend<mode>xf2_i387"
3915 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3917 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3919 "* return output_387_reg_move (insn, operands);"
3920 [(set_attr "type" "fmov")
3921 (set_attr "mode" "<MODE>,XF")])
3923 ;; %%% This seems bad bad news.
3924 ;; This cannot output into an f-reg because there is no way to be sure
3925 ;; of truncating in that case. Otherwise this is just like a simple move
3926 ;; insn. So we pretend we can output to a reg in order to get better
3927 ;; register preferencing, but we really use a stack slot.
3929 ;; Conversion from DFmode to SFmode.
3931 (define_expand "truncdfsf2"
3932 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3934 (match_operand:DF 1 "nonimmediate_operand" "")))]
3935 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3937 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3939 else if (flag_unsafe_math_optimizations)
3943 enum ix86_stack_slot slot = (virtuals_instantiated
3946 rtx temp = assign_386_stack_local (SFmode, slot);
3947 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3952 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
3954 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3956 We do the conversion post reload to avoid producing of 128bit spills
3957 that might lead to ICE on 32bit target. The sequence unlikely combine
3960 [(set (match_operand:SF 0 "register_operand" "")
3962 (match_operand:DF 1 "nonimmediate_operand" "")))]
3963 "TARGET_USE_VECTOR_FP_CONVERTS
3964 && optimize_insn_for_speed_p ()
3965 && reload_completed && SSE_REG_P (operands[0])"
3968 (float_truncate:V2SF
3972 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3973 operands[3] = CONST0_RTX (V2SFmode);
3974 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
3975 /* Use movsd for loading from memory, unpcklpd for registers.
3976 Try to avoid move when unpacking can be done in source, or SSE3
3977 movddup is available. */
3978 if (REG_P (operands[1]))
3981 && true_regnum (operands[0]) != true_regnum (operands[1])
3982 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3983 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
3985 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
3986 emit_move_insn (tmp, operands[1]);
3989 else if (!TARGET_SSE3)
3990 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3991 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
3994 emit_insn (gen_sse2_loadlpd (operands[4],
3995 CONST0_RTX (V2DFmode), operands[1]));
3998 (define_expand "truncdfsf2_with_temp"
3999 [(parallel [(set (match_operand:SF 0 "" "")
4000 (float_truncate:SF (match_operand:DF 1 "" "")))
4001 (clobber (match_operand:SF 2 "" ""))])])
4003 (define_insn "*truncdfsf_fast_mixed"
4004 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4006 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4007 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4009 switch (which_alternative)
4012 return output_387_reg_move (insn, operands);
4014 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4019 [(set_attr "type" "fmov,ssecvt")
4020 (set_attr "prefix" "orig,maybe_vex")
4021 (set_attr "mode" "SF")])
4023 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4024 ;; because nothing we do here is unsafe.
4025 (define_insn "*truncdfsf_fast_sse"
4026 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4028 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4029 "TARGET_SSE2 && TARGET_SSE_MATH"
4030 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4031 [(set_attr "type" "ssecvt")
4032 (set_attr "prefix" "maybe_vex")
4033 (set_attr "mode" "SF")])
4035 (define_insn "*truncdfsf_fast_i387"
4036 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4038 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4039 "TARGET_80387 && flag_unsafe_math_optimizations"
4040 "* return output_387_reg_move (insn, operands);"
4041 [(set_attr "type" "fmov")
4042 (set_attr "mode" "SF")])
4044 (define_insn "*truncdfsf_mixed"
4045 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4047 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4048 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4049 "TARGET_MIX_SSE_I387"
4051 switch (which_alternative)
4054 return output_387_reg_move (insn, operands);
4056 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4062 [(set_attr "isa" "*,sse2,*,*,*")
4063 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4064 (set_attr "unit" "*,*,i387,i387,i387")
4065 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4066 (set_attr "mode" "SF")])
4068 (define_insn "*truncdfsf_i387"
4069 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4071 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4072 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4075 switch (which_alternative)
4078 return output_387_reg_move (insn, operands);
4084 [(set_attr "type" "fmov,multi,multi,multi")
4085 (set_attr "unit" "*,i387,i387,i387")
4086 (set_attr "mode" "SF")])
4088 (define_insn "*truncdfsf2_i387_1"
4089 [(set (match_operand:SF 0 "memory_operand" "=m")
4091 (match_operand:DF 1 "register_operand" "f")))]
4093 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4094 && !TARGET_MIX_SSE_I387"
4095 "* return output_387_reg_move (insn, operands);"
4096 [(set_attr "type" "fmov")
4097 (set_attr "mode" "SF")])
4100 [(set (match_operand:SF 0 "register_operand" "")
4102 (match_operand:DF 1 "fp_register_operand" "")))
4103 (clobber (match_operand 2 "" ""))]
4105 [(set (match_dup 2) (match_dup 1))
4106 (set (match_dup 0) (match_dup 2))]
4107 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4109 ;; Conversion from XFmode to {SF,DF}mode
4111 (define_expand "truncxf<mode>2"
4112 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4113 (float_truncate:MODEF
4114 (match_operand:XF 1 "register_operand" "")))
4115 (clobber (match_dup 2))])]
4118 if (flag_unsafe_math_optimizations)
4120 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4121 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4122 if (reg != operands[0])
4123 emit_move_insn (operands[0], reg);
4128 enum ix86_stack_slot slot = (virtuals_instantiated
4131 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4135 (define_insn "*truncxfsf2_mixed"
4136 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4138 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4139 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4142 gcc_assert (!which_alternative);
4143 return output_387_reg_move (insn, operands);
4145 [(set_attr "type" "fmov,multi,multi,multi")
4146 (set_attr "unit" "*,i387,i387,i387")
4147 (set_attr "mode" "SF")])
4149 (define_insn "*truncxfdf2_mixed"
4150 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4152 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4153 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4156 gcc_assert (!which_alternative);
4157 return output_387_reg_move (insn, operands);
4159 [(set_attr "isa" "*,*,sse2,*")
4160 (set_attr "type" "fmov,multi,multi,multi")
4161 (set_attr "unit" "*,i387,i387,i387")
4162 (set_attr "mode" "DF")])
4164 (define_insn "truncxf<mode>2_i387_noop"
4165 [(set (match_operand:MODEF 0 "register_operand" "=f")
4166 (float_truncate:MODEF
4167 (match_operand:XF 1 "register_operand" "f")))]
4168 "TARGET_80387 && flag_unsafe_math_optimizations"
4169 "* return output_387_reg_move (insn, operands);"
4170 [(set_attr "type" "fmov")
4171 (set_attr "mode" "<MODE>")])
4173 (define_insn "*truncxf<mode>2_i387"
4174 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4175 (float_truncate:MODEF
4176 (match_operand:XF 1 "register_operand" "f")))]
4178 "* return output_387_reg_move (insn, operands);"
4179 [(set_attr "type" "fmov")
4180 (set_attr "mode" "<MODE>")])
4183 [(set (match_operand:MODEF 0 "register_operand" "")
4184 (float_truncate:MODEF
4185 (match_operand:XF 1 "register_operand" "")))
4186 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4187 "TARGET_80387 && reload_completed"
4188 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4189 (set (match_dup 0) (match_dup 2))])
4192 [(set (match_operand:MODEF 0 "memory_operand" "")
4193 (float_truncate:MODEF
4194 (match_operand:XF 1 "register_operand" "")))
4195 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4197 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4199 ;; Signed conversion to DImode.
4201 (define_expand "fix_truncxfdi2"
4202 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4203 (fix:DI (match_operand:XF 1 "register_operand" "")))
4204 (clobber (reg:CC FLAGS_REG))])]
4209 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4214 (define_expand "fix_trunc<mode>di2"
4215 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4216 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4217 (clobber (reg:CC FLAGS_REG))])]
4218 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4221 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4223 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4226 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4228 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4229 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4230 if (out != operands[0])
4231 emit_move_insn (operands[0], out);
4236 ;; Signed conversion to SImode.
4238 (define_expand "fix_truncxfsi2"
4239 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4240 (fix:SI (match_operand:XF 1 "register_operand" "")))
4241 (clobber (reg:CC FLAGS_REG))])]
4246 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4251 (define_expand "fix_trunc<mode>si2"
4252 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4253 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4254 (clobber (reg:CC FLAGS_REG))])]
4255 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4258 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4260 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4263 if (SSE_FLOAT_MODE_P (<MODE>mode))
4265 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4266 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4267 if (out != operands[0])
4268 emit_move_insn (operands[0], out);
4273 ;; Signed conversion to HImode.
4275 (define_expand "fix_trunc<mode>hi2"
4276 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4277 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4278 (clobber (reg:CC FLAGS_REG))])]
4280 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4284 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4289 ;; Unsigned conversion to SImode.
4291 (define_expand "fixuns_trunc<mode>si2"
4293 [(set (match_operand:SI 0 "register_operand" "")
4295 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4297 (clobber (match_scratch:<ssevecmode> 3 ""))
4298 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4299 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4301 enum machine_mode mode = <MODE>mode;
4302 enum machine_mode vecmode = <ssevecmode>mode;
4303 REAL_VALUE_TYPE TWO31r;
4306 if (optimize_insn_for_size_p ())
4309 real_ldexp (&TWO31r, &dconst1, 31);
4310 two31 = const_double_from_real_value (TWO31r, mode);
4311 two31 = ix86_build_const_vector (vecmode, true, two31);
4312 operands[2] = force_reg (vecmode, two31);
4315 (define_insn_and_split "*fixuns_trunc<mode>_1"
4316 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4318 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4319 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4320 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4321 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4322 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4323 && optimize_function_for_speed_p (cfun)"
4325 "&& reload_completed"
4328 ix86_split_convert_uns_si_sse (operands);
4332 ;; Unsigned conversion to HImode.
4333 ;; Without these patterns, we'll try the unsigned SI conversion which
4334 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4336 (define_expand "fixuns_trunc<mode>hi2"
4338 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4339 (set (match_operand:HI 0 "nonimmediate_operand" "")
4340 (subreg:HI (match_dup 2) 0))]
4341 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4342 "operands[2] = gen_reg_rtx (SImode);")
4344 ;; When SSE is available, it is always faster to use it!
4345 (define_insn "fix_trunc<mode>di_sse"
4346 [(set (match_operand:DI 0 "register_operand" "=r,r")
4347 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4348 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4349 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4350 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4351 [(set_attr "type" "sseicvt")
4352 (set_attr "prefix" "maybe_vex")
4353 (set_attr "prefix_rex" "1")
4354 (set_attr "mode" "<MODE>")
4355 (set_attr "athlon_decode" "double,vector")
4356 (set_attr "amdfam10_decode" "double,double")
4357 (set_attr "bdver1_decode" "double,double")])
4359 (define_insn "fix_trunc<mode>si_sse"
4360 [(set (match_operand:SI 0 "register_operand" "=r,r")
4361 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4362 "SSE_FLOAT_MODE_P (<MODE>mode)
4363 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4364 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4365 [(set_attr "type" "sseicvt")
4366 (set_attr "prefix" "maybe_vex")
4367 (set_attr "mode" "<MODE>")
4368 (set_attr "athlon_decode" "double,vector")
4369 (set_attr "amdfam10_decode" "double,double")
4370 (set_attr "bdver1_decode" "double,double")])
4372 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4374 [(set (match_operand:MODEF 0 "register_operand" "")
4375 (match_operand:MODEF 1 "memory_operand" ""))
4376 (set (match_operand:SWI48x 2 "register_operand" "")
4377 (fix:SWI48x (match_dup 0)))]
4378 "TARGET_SHORTEN_X87_SSE
4379 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4380 && peep2_reg_dead_p (2, operands[0])"
4381 [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4383 ;; Avoid vector decoded forms of the instruction.
4385 [(match_scratch:DF 2 "x")
4386 (set (match_operand:SWI48x 0 "register_operand" "")
4387 (fix:SWI48x (match_operand:DF 1 "memory_operand" "")))]
4388 "TARGET_SSE2 && TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4389 [(set (match_dup 2) (match_dup 1))
4390 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4393 [(match_scratch:SF 2 "x")
4394 (set (match_operand:SWI48x 0 "register_operand" "")
4395 (fix:SWI48x (match_operand:SF 1 "memory_operand" "")))]
4396 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4397 [(set (match_dup 2) (match_dup 1))
4398 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4400 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4401 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4402 (fix:SWI248x (match_operand 1 "register_operand" "")))]
4403 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4405 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4406 && (TARGET_64BIT || <MODE>mode != DImode))
4408 && can_create_pseudo_p ()"
4413 if (memory_operand (operands[0], VOIDmode))
4414 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4417 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4418 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4424 [(set_attr "type" "fisttp")
4425 (set_attr "mode" "<MODE>")])
4427 (define_insn "fix_trunc<mode>_i387_fisttp"
4428 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4429 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4430 (clobber (match_scratch:XF 2 "=&1f"))]
4431 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4433 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4434 && (TARGET_64BIT || <MODE>mode != DImode))
4435 && TARGET_SSE_MATH)"
4436 "* return output_fix_trunc (insn, operands, true);"
4437 [(set_attr "type" "fisttp")
4438 (set_attr "mode" "<MODE>")])
4440 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4441 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4442 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4443 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4444 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4445 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4447 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4448 && (TARGET_64BIT || <MODE>mode != DImode))
4449 && TARGET_SSE_MATH)"
4451 [(set_attr "type" "fisttp")
4452 (set_attr "mode" "<MODE>")])
4455 [(set (match_operand:SWI248x 0 "register_operand" "")
4456 (fix:SWI248x (match_operand 1 "register_operand" "")))
4457 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4458 (clobber (match_scratch 3 ""))]
4460 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4461 (clobber (match_dup 3))])
4462 (set (match_dup 0) (match_dup 2))])
4465 [(set (match_operand:SWI248x 0 "memory_operand" "")
4466 (fix:SWI248x (match_operand 1 "register_operand" "")))
4467 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4468 (clobber (match_scratch 3 ""))]
4470 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4471 (clobber (match_dup 3))])])
4473 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4474 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4475 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4476 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4477 ;; function in i386.c.
4478 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4479 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4480 (fix:SWI248x (match_operand 1 "register_operand" "")))
4481 (clobber (reg:CC FLAGS_REG))]
4482 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4484 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4485 && (TARGET_64BIT || <MODE>mode != DImode))
4486 && can_create_pseudo_p ()"
4491 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4493 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4494 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4495 if (memory_operand (operands[0], VOIDmode))
4496 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4497 operands[2], operands[3]));
4500 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4501 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4502 operands[2], operands[3],
4507 [(set_attr "type" "fistp")
4508 (set_attr "i387_cw" "trunc")
4509 (set_attr "mode" "<MODE>")])
4511 (define_insn "fix_truncdi_i387"
4512 [(set (match_operand:DI 0 "memory_operand" "=m")
4513 (fix:DI (match_operand 1 "register_operand" "f")))
4514 (use (match_operand:HI 2 "memory_operand" "m"))
4515 (use (match_operand:HI 3 "memory_operand" "m"))
4516 (clobber (match_scratch:XF 4 "=&1f"))]
4517 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4519 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4520 "* return output_fix_trunc (insn, operands, false);"
4521 [(set_attr "type" "fistp")
4522 (set_attr "i387_cw" "trunc")
4523 (set_attr "mode" "DI")])
4525 (define_insn "fix_truncdi_i387_with_temp"
4526 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4527 (fix:DI (match_operand 1 "register_operand" "f,f")))
4528 (use (match_operand:HI 2 "memory_operand" "m,m"))
4529 (use (match_operand:HI 3 "memory_operand" "m,m"))
4530 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4531 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4532 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4534 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4536 [(set_attr "type" "fistp")
4537 (set_attr "i387_cw" "trunc")
4538 (set_attr "mode" "DI")])
4541 [(set (match_operand:DI 0 "register_operand" "")
4542 (fix:DI (match_operand 1 "register_operand" "")))
4543 (use (match_operand:HI 2 "memory_operand" ""))
4544 (use (match_operand:HI 3 "memory_operand" ""))
4545 (clobber (match_operand:DI 4 "memory_operand" ""))
4546 (clobber (match_scratch 5 ""))]
4548 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4551 (clobber (match_dup 5))])
4552 (set (match_dup 0) (match_dup 4))])
4555 [(set (match_operand:DI 0 "memory_operand" "")
4556 (fix:DI (match_operand 1 "register_operand" "")))
4557 (use (match_operand:HI 2 "memory_operand" ""))
4558 (use (match_operand:HI 3 "memory_operand" ""))
4559 (clobber (match_operand:DI 4 "memory_operand" ""))
4560 (clobber (match_scratch 5 ""))]
4562 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4565 (clobber (match_dup 5))])])
4567 (define_insn "fix_trunc<mode>_i387"
4568 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4569 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4570 (use (match_operand:HI 2 "memory_operand" "m"))
4571 (use (match_operand:HI 3 "memory_operand" "m"))]
4572 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4574 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4575 "* return output_fix_trunc (insn, operands, false);"
4576 [(set_attr "type" "fistp")
4577 (set_attr "i387_cw" "trunc")
4578 (set_attr "mode" "<MODE>")])
4580 (define_insn "fix_trunc<mode>_i387_with_temp"
4581 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4582 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4583 (use (match_operand:HI 2 "memory_operand" "m,m"))
4584 (use (match_operand:HI 3 "memory_operand" "m,m"))
4585 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4586 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4588 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4590 [(set_attr "type" "fistp")
4591 (set_attr "i387_cw" "trunc")
4592 (set_attr "mode" "<MODE>")])
4595 [(set (match_operand:SWI24 0 "register_operand" "")
4596 (fix:SWI24 (match_operand 1 "register_operand" "")))
4597 (use (match_operand:HI 2 "memory_operand" ""))
4598 (use (match_operand:HI 3 "memory_operand" ""))
4599 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4601 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4603 (use (match_dup 3))])
4604 (set (match_dup 0) (match_dup 4))])
4607 [(set (match_operand:SWI24 0 "memory_operand" "")
4608 (fix:SWI24 (match_operand 1 "register_operand" "")))
4609 (use (match_operand:HI 2 "memory_operand" ""))
4610 (use (match_operand:HI 3 "memory_operand" ""))
4611 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4613 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4615 (use (match_dup 3))])])
4617 (define_insn "x86_fnstcw_1"
4618 [(set (match_operand:HI 0 "memory_operand" "=m")
4619 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4622 [(set (attr "length")
4623 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4624 (set_attr "mode" "HI")
4625 (set_attr "unit" "i387")
4626 (set_attr "bdver1_decode" "vector")])
4628 (define_insn "x86_fldcw_1"
4629 [(set (reg:HI FPCR_REG)
4630 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4633 [(set (attr "length")
4634 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4635 (set_attr "mode" "HI")
4636 (set_attr "unit" "i387")
4637 (set_attr "athlon_decode" "vector")
4638 (set_attr "amdfam10_decode" "vector")
4639 (set_attr "bdver1_decode" "vector")])
4641 ;; Conversion between fixed point and floating point.
4643 ;; Even though we only accept memory inputs, the backend _really_
4644 ;; wants to be able to do this between registers.
4646 (define_expand "floathi<mode>2"
4647 [(set (match_operand:X87MODEF 0 "register_operand" "")
4648 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4650 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4651 || TARGET_MIX_SSE_I387)")
4653 ;; Pre-reload splitter to add memory clobber to the pattern.
4654 (define_insn_and_split "*floathi<mode>2_1"
4655 [(set (match_operand:X87MODEF 0 "register_operand" "")
4656 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4658 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4659 || TARGET_MIX_SSE_I387)
4660 && can_create_pseudo_p ()"
4663 [(parallel [(set (match_dup 0)
4664 (float:X87MODEF (match_dup 1)))
4665 (clobber (match_dup 2))])]
4666 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4668 (define_insn "*floathi<mode>2_i387_with_temp"
4669 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4670 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4671 (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4673 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4674 || TARGET_MIX_SSE_I387)"
4676 [(set_attr "type" "fmov,multi")
4677 (set_attr "mode" "<MODE>")
4678 (set_attr "unit" "*,i387")
4679 (set_attr "fp_int_src" "true")])
4681 (define_insn "*floathi<mode>2_i387"
4682 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4683 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4685 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4686 || TARGET_MIX_SSE_I387)"
4688 [(set_attr "type" "fmov")
4689 (set_attr "mode" "<MODE>")
4690 (set_attr "fp_int_src" "true")])
4693 [(set (match_operand:X87MODEF 0 "register_operand" "")
4694 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4695 (clobber (match_operand:HI 2 "memory_operand" ""))]
4697 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4698 || TARGET_MIX_SSE_I387)
4699 && reload_completed"
4700 [(set (match_dup 2) (match_dup 1))
4701 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4704 [(set (match_operand:X87MODEF 0 "register_operand" "")
4705 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4706 (clobber (match_operand:HI 2 "memory_operand" ""))]
4708 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4709 || TARGET_MIX_SSE_I387)
4710 && reload_completed"
4711 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4713 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4714 [(set (match_operand:X87MODEF 0 "register_operand" "")
4716 (match_operand:SWI48x 1 "nonimmediate_operand" "")))]
4718 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4719 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4721 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4722 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4723 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4725 rtx reg = gen_reg_rtx (XFmode);
4726 rtx (*insn)(rtx, rtx);
4728 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4730 if (<X87MODEF:MODE>mode == SFmode)
4731 insn = gen_truncxfsf2;
4732 else if (<X87MODEF:MODE>mode == DFmode)
4733 insn = gen_truncxfdf2;
4737 emit_insn (insn (operands[0], reg));
4742 ;; Pre-reload splitter to add memory clobber to the pattern.
4743 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4744 [(set (match_operand:X87MODEF 0 "register_operand" "")
4745 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))]
4747 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4748 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4749 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4750 || TARGET_MIX_SSE_I387))
4751 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4752 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4753 && ((<SWI48x:MODE>mode == SImode
4754 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4755 && optimize_function_for_speed_p (cfun)
4756 && flag_trapping_math)
4757 || !(TARGET_INTER_UNIT_CONVERSIONS
4758 || optimize_function_for_size_p (cfun)))))
4759 && can_create_pseudo_p ()"
4762 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4763 (clobber (match_dup 2))])]
4765 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4767 /* Avoid store forwarding (partial memory) stall penalty
4768 by passing DImode value through XMM registers. */
4769 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4770 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4771 && optimize_function_for_speed_p (cfun))
4773 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4780 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4781 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4783 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4784 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4785 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4786 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4788 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4789 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4790 (set_attr "unit" "*,i387,*,*,*")
4791 (set_attr "athlon_decode" "*,*,double,direct,double")
4792 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4793 (set_attr "bdver1_decode" "*,*,double,direct,double")
4794 (set_attr "fp_int_src" "true")])
4796 (define_insn "*floatsi<mode>2_vector_mixed"
4797 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4798 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4799 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4800 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4804 [(set_attr "type" "fmov,sseicvt")
4805 (set_attr "mode" "<MODE>,<ssevecmode>")
4806 (set_attr "unit" "i387,*")
4807 (set_attr "athlon_decode" "*,direct")
4808 (set_attr "amdfam10_decode" "*,double")
4809 (set_attr "bdver1_decode" "*,direct")
4810 (set_attr "fp_int_src" "true")])
4812 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4813 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4815 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4816 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4817 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4818 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4820 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4821 (set_attr "mode" "<MODEF:MODE>")
4822 (set_attr "unit" "*,i387,*,*")
4823 (set_attr "athlon_decode" "*,*,double,direct")
4824 (set_attr "amdfam10_decode" "*,*,vector,double")
4825 (set_attr "bdver1_decode" "*,*,double,direct")
4826 (set_attr "fp_int_src" "true")])
4829 [(set (match_operand:MODEF 0 "register_operand" "")
4830 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4831 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4832 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4833 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4834 && TARGET_INTER_UNIT_CONVERSIONS
4836 && (SSE_REG_P (operands[0])
4837 || (GET_CODE (operands[0]) == SUBREG
4838 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4839 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4842 [(set (match_operand:MODEF 0 "register_operand" "")
4843 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4844 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4845 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4846 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4847 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4849 && (SSE_REG_P (operands[0])
4850 || (GET_CODE (operands[0]) == SUBREG
4851 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4852 [(set (match_dup 2) (match_dup 1))
4853 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4855 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4856 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4858 (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4859 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4860 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4861 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4864 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4865 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4866 [(set_attr "type" "fmov,sseicvt,sseicvt")
4867 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4868 (set_attr "mode" "<MODEF:MODE>")
4869 (set (attr "prefix_rex")
4871 (and (eq_attr "prefix" "maybe_vex")
4872 (match_test "<SWI48x:MODE>mode == DImode"))
4874 (const_string "*")))
4875 (set_attr "unit" "i387,*,*")
4876 (set_attr "athlon_decode" "*,double,direct")
4877 (set_attr "amdfam10_decode" "*,vector,double")
4878 (set_attr "bdver1_decode" "*,double,direct")
4879 (set_attr "fp_int_src" "true")])
4881 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4882 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4884 (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4885 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4886 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4887 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4890 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4891 [(set_attr "type" "fmov,sseicvt")
4892 (set_attr "prefix" "orig,maybe_vex")
4893 (set_attr "mode" "<MODEF:MODE>")
4894 (set (attr "prefix_rex")
4896 (and (eq_attr "prefix" "maybe_vex")
4897 (match_test "<SWI48x:MODE>mode == DImode"))
4899 (const_string "*")))
4900 (set_attr "athlon_decode" "*,direct")
4901 (set_attr "amdfam10_decode" "*,double")
4902 (set_attr "bdver1_decode" "*,direct")
4903 (set_attr "fp_int_src" "true")])
4905 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4906 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4908 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4909 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4910 "TARGET_SSE2 && TARGET_SSE_MATH
4911 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4913 [(set_attr "type" "sseicvt")
4914 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4915 (set_attr "athlon_decode" "double,direct,double")
4916 (set_attr "amdfam10_decode" "vector,double,double")
4917 (set_attr "bdver1_decode" "double,direct,double")
4918 (set_attr "fp_int_src" "true")])
4920 (define_insn "*floatsi<mode>2_vector_sse"
4921 [(set (match_operand:MODEF 0 "register_operand" "=x")
4922 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4923 "TARGET_SSE2 && TARGET_SSE_MATH
4924 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4926 [(set_attr "type" "sseicvt")
4927 (set_attr "mode" "<MODE>")
4928 (set_attr "athlon_decode" "direct")
4929 (set_attr "amdfam10_decode" "double")
4930 (set_attr "bdver1_decode" "direct")
4931 (set_attr "fp_int_src" "true")])
4934 [(set (match_operand:MODEF 0 "register_operand" "")
4935 (float:MODEF (match_operand:SI 1 "register_operand" "")))
4936 (clobber (match_operand:SI 2 "memory_operand" ""))]
4937 "TARGET_SSE2 && TARGET_SSE_MATH
4938 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4940 && (SSE_REG_P (operands[0])
4941 || (GET_CODE (operands[0]) == SUBREG
4942 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4945 rtx op1 = operands[1];
4947 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4949 if (GET_CODE (op1) == SUBREG)
4950 op1 = SUBREG_REG (op1);
4952 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
4954 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4955 emit_insn (gen_sse2_loadld (operands[4],
4956 CONST0_RTX (V4SImode), operands[1]));
4958 /* We can ignore possible trapping value in the
4959 high part of SSE register for non-trapping math. */
4960 else if (SSE_REG_P (op1) && !flag_trapping_math)
4961 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4964 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4965 emit_move_insn (operands[2], operands[1]);
4966 emit_insn (gen_sse2_loadld (operands[4],
4967 CONST0_RTX (V4SImode), operands[2]));
4969 if (<ssevecmode>mode == V4SFmode)
4970 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4972 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4977 [(set (match_operand:MODEF 0 "register_operand" "")
4978 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
4979 (clobber (match_operand:SI 2 "memory_operand" ""))]
4980 "TARGET_SSE2 && TARGET_SSE_MATH
4981 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4983 && (SSE_REG_P (operands[0])
4984 || (GET_CODE (operands[0]) == SUBREG
4985 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4988 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4990 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4992 emit_insn (gen_sse2_loadld (operands[4],
4993 CONST0_RTX (V4SImode), operands[1]));
4994 if (<ssevecmode>mode == V4SFmode)
4995 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4997 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5002 [(set (match_operand:MODEF 0 "register_operand" "")
5003 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5004 "TARGET_SSE2 && TARGET_SSE_MATH
5005 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5007 && (SSE_REG_P (operands[0])
5008 || (GET_CODE (operands[0]) == SUBREG
5009 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5012 rtx op1 = operands[1];
5014 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5016 if (GET_CODE (op1) == SUBREG)
5017 op1 = SUBREG_REG (op1);
5019 if (GENERAL_REG_P (op1))
5021 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5022 if (TARGET_INTER_UNIT_MOVES)
5023 emit_insn (gen_sse2_loadld (operands[4],
5024 CONST0_RTX (V4SImode), operands[1]));
5027 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5029 emit_insn (gen_sse2_loadld (operands[4],
5030 CONST0_RTX (V4SImode), operands[5]));
5031 ix86_free_from_memory (GET_MODE (operands[1]));
5034 /* We can ignore possible trapping value in the
5035 high part of SSE register for non-trapping math. */
5036 else if (SSE_REG_P (op1) && !flag_trapping_math)
5037 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5040 if (<ssevecmode>mode == V4SFmode)
5041 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5043 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5048 [(set (match_operand:MODEF 0 "register_operand" "")
5049 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5050 "TARGET_SSE2 && TARGET_SSE_MATH
5051 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5053 && (SSE_REG_P (operands[0])
5054 || (GET_CODE (operands[0]) == SUBREG
5055 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5058 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5060 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5062 emit_insn (gen_sse2_loadld (operands[4],
5063 CONST0_RTX (V4SImode), operands[1]));
5064 if (<ssevecmode>mode == V4SFmode)
5065 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5067 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5071 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5072 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5074 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5075 (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5076 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5077 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5079 [(set_attr "type" "sseicvt")
5080 (set_attr "mode" "<MODEF:MODE>")
5081 (set_attr "athlon_decode" "double,direct")
5082 (set_attr "amdfam10_decode" "vector,double")
5083 (set_attr "bdver1_decode" "double,direct")
5084 (set_attr "fp_int_src" "true")])
5086 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5087 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5089 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5090 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5091 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5092 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5093 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5094 [(set_attr "type" "sseicvt")
5095 (set_attr "prefix" "maybe_vex")
5096 (set_attr "mode" "<MODEF:MODE>")
5097 (set (attr "prefix_rex")
5099 (and (eq_attr "prefix" "maybe_vex")
5100 (match_test "<SWI48x:MODE>mode == DImode"))
5102 (const_string "*")))
5103 (set_attr "athlon_decode" "double,direct")
5104 (set_attr "amdfam10_decode" "vector,double")
5105 (set_attr "bdver1_decode" "double,direct")
5106 (set_attr "fp_int_src" "true")])
5109 [(set (match_operand:MODEF 0 "register_operand" "")
5110 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "")))
5111 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5112 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5113 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5114 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5116 && (SSE_REG_P (operands[0])
5117 || (GET_CODE (operands[0]) == SUBREG
5118 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5119 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5121 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5122 [(set (match_operand:MODEF 0 "register_operand" "=x")
5124 (match_operand:SWI48x 1 "memory_operand" "m")))]
5125 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5126 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5127 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5128 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5129 [(set_attr "type" "sseicvt")
5130 (set_attr "prefix" "maybe_vex")
5131 (set_attr "mode" "<MODEF:MODE>")
5132 (set (attr "prefix_rex")
5134 (and (eq_attr "prefix" "maybe_vex")
5135 (match_test "<SWI48x:MODE>mode == DImode"))
5137 (const_string "*")))
5138 (set_attr "athlon_decode" "direct")
5139 (set_attr "amdfam10_decode" "double")
5140 (set_attr "bdver1_decode" "direct")
5141 (set_attr "fp_int_src" "true")])
5144 [(set (match_operand:MODEF 0 "register_operand" "")
5145 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
5146 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5147 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5148 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5149 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5151 && (SSE_REG_P (operands[0])
5152 || (GET_CODE (operands[0]) == SUBREG
5153 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5154 [(set (match_dup 2) (match_dup 1))
5155 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5158 [(set (match_operand:MODEF 0 "register_operand" "")
5159 (float:MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5160 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5161 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5162 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5164 && (SSE_REG_P (operands[0])
5165 || (GET_CODE (operands[0]) == SUBREG
5166 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5167 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5169 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5170 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5172 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5173 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5175 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5179 [(set_attr "type" "fmov,multi")
5180 (set_attr "mode" "<X87MODEF:MODE>")
5181 (set_attr "unit" "*,i387")
5182 (set_attr "fp_int_src" "true")])
5184 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5185 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5187 (match_operand:SWI48x 1 "memory_operand" "m")))]
5189 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5191 [(set_attr "type" "fmov")
5192 (set_attr "mode" "<X87MODEF:MODE>")
5193 (set_attr "fp_int_src" "true")])
5196 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5197 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))
5198 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5200 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5201 && reload_completed"
5202 [(set (match_dup 2) (match_dup 1))
5203 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5206 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5207 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5208 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5210 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5211 && reload_completed"
5212 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5214 ;; Avoid store forwarding (partial memory) stall penalty
5215 ;; by passing DImode value through XMM registers. */
5217 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5218 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5220 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5221 (clobber (match_scratch:V4SI 3 "=X,x"))
5222 (clobber (match_scratch:V4SI 4 "=X,x"))
5223 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5224 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5225 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5226 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5228 [(set_attr "type" "multi")
5229 (set_attr "mode" "<X87MODEF:MODE>")
5230 (set_attr "unit" "i387")
5231 (set_attr "fp_int_src" "true")])
5234 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5235 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5236 (clobber (match_scratch:V4SI 3 ""))
5237 (clobber (match_scratch:V4SI 4 ""))
5238 (clobber (match_operand:DI 2 "memory_operand" ""))]
5239 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5240 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5241 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5242 && reload_completed"
5243 [(set (match_dup 2) (match_dup 3))
5244 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5246 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5247 Assemble the 64-bit DImode value in an xmm register. */
5248 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5249 gen_rtx_SUBREG (SImode, operands[1], 0)));
5250 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5251 gen_rtx_SUBREG (SImode, operands[1], 4)));
5252 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5255 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5259 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5260 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5261 (clobber (match_scratch:V4SI 3 ""))
5262 (clobber (match_scratch:V4SI 4 ""))
5263 (clobber (match_operand:DI 2 "memory_operand" ""))]
5264 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5265 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5266 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5267 && reload_completed"
5268 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5270 ;; Avoid store forwarding (partial memory) stall penalty by extending
5271 ;; SImode value to DImode through XMM register instead of pushing two
5272 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5273 ;; targets benefit from this optimization. Also note that fild
5274 ;; loads from memory only.
5276 (define_insn "*floatunssi<mode>2_1"
5277 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5278 (unsigned_float:X87MODEF
5279 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5280 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5281 (clobber (match_scratch:SI 3 "=X,x"))]
5283 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5286 [(set_attr "type" "multi")
5287 (set_attr "mode" "<MODE>")])
5290 [(set (match_operand:X87MODEF 0 "register_operand" "")
5291 (unsigned_float:X87MODEF
5292 (match_operand:SI 1 "register_operand" "")))
5293 (clobber (match_operand:DI 2 "memory_operand" ""))
5294 (clobber (match_scratch:SI 3 ""))]
5296 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5298 && reload_completed"
5299 [(set (match_dup 2) (match_dup 1))
5301 (float:X87MODEF (match_dup 2)))]
5302 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5305 [(set (match_operand:X87MODEF 0 "register_operand" "")
5306 (unsigned_float:X87MODEF
5307 (match_operand:SI 1 "memory_operand" "")))
5308 (clobber (match_operand:DI 2 "memory_operand" ""))
5309 (clobber (match_scratch:SI 3 ""))]
5311 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5313 && reload_completed"
5314 [(set (match_dup 2) (match_dup 3))
5316 (float:X87MODEF (match_dup 2)))]
5318 emit_move_insn (operands[3], operands[1]);
5319 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5322 (define_expand "floatunssi<mode>2"
5324 [(set (match_operand:X87MODEF 0 "register_operand" "")
5325 (unsigned_float:X87MODEF
5326 (match_operand:SI 1 "nonimmediate_operand" "")))
5327 (clobber (match_dup 2))
5328 (clobber (match_scratch:SI 3 ""))])]
5330 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5332 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5334 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5336 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5341 enum ix86_stack_slot slot = (virtuals_instantiated
5344 operands[2] = assign_386_stack_local (DImode, slot);
5348 (define_expand "floatunsdisf2"
5349 [(use (match_operand:SF 0 "register_operand" ""))
5350 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5351 "TARGET_64BIT && TARGET_SSE_MATH"
5352 "x86_emit_floatuns (operands); DONE;")
5354 (define_expand "floatunsdidf2"
5355 [(use (match_operand:DF 0 "register_operand" ""))
5356 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5357 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5358 && TARGET_SSE2 && TARGET_SSE_MATH"
5361 x86_emit_floatuns (operands);
5363 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5369 (define_expand "add<mode>3"
5370 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5371 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5372 (match_operand:SDWIM 2 "<general_operand>" "")))]
5374 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5376 (define_insn_and_split "*add<dwi>3_doubleword"
5377 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5379 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5380 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5381 (clobber (reg:CC FLAGS_REG))]
5382 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5385 [(parallel [(set (reg:CC FLAGS_REG)
5386 (unspec:CC [(match_dup 1) (match_dup 2)]
5389 (plus:DWIH (match_dup 1) (match_dup 2)))])
5390 (parallel [(set (match_dup 3)
5394 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5396 (clobber (reg:CC FLAGS_REG))])]
5397 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5399 (define_insn "*add<mode>3_cc"
5400 [(set (reg:CC FLAGS_REG)
5402 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5403 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5405 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5406 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5407 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5408 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5409 [(set_attr "type" "alu")
5410 (set_attr "mode" "<MODE>")])
5412 (define_insn "addqi3_cc"
5413 [(set (reg:CC FLAGS_REG)
5415 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5416 (match_operand:QI 2 "general_operand" "qn,qm")]
5418 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5419 (plus:QI (match_dup 1) (match_dup 2)))]
5420 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5421 "add{b}\t{%2, %0|%0, %2}"
5422 [(set_attr "type" "alu")
5423 (set_attr "mode" "QI")])
5425 (define_insn_and_split "*lea_1"
5426 [(set (match_operand:SI 0 "register_operand" "=r")
5427 (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0))]
5429 "lea{l}\t{%a1, %0|%0, %a1}"
5430 "&& reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5433 ix86_split_lea_for_addr (operands, SImode);
5436 [(set_attr "type" "lea")
5437 (set_attr "mode" "SI")])
5439 (define_insn_and_split "*lea<mode>_2"
5440 [(set (match_operand:SWI48 0 "register_operand" "=r")
5441 (match_operand:SWI48 1 "lea_address_operand" "p"))]
5443 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5444 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5447 ix86_split_lea_for_addr (operands, <MODE>mode);
5450 [(set_attr "type" "lea")
5451 (set_attr "mode" "<MODE>")])
5453 (define_insn "*lea_3_zext"
5454 [(set (match_operand:DI 0 "register_operand" "=r")
5456 (subreg:SI (match_operand:DI 1 "lea_address_operand" "j") 0)))]
5458 "lea{l}\t{%a1, %k0|%k0, %a1}"
5459 [(set_attr "type" "lea")
5460 (set_attr "mode" "SI")])
5462 (define_insn "*lea_4_zext"
5463 [(set (match_operand:DI 0 "register_operand" "=r")
5465 (match_operand:SI 1 "lea_address_operand" "j")))]
5467 "lea{l}\t{%a1, %k0|%k0, %a1}"
5468 [(set_attr "type" "lea")
5469 (set_attr "mode" "SI")])
5471 (define_insn "*lea_5_zext"
5472 [(set (match_operand:DI 0 "register_operand" "=r")
5474 (subreg:DI (match_operand:SI 1 "lea_address_operand" "p") 0)
5475 (match_operand:DI 2 "const_32bit_mask" "n")))]
5477 "lea{l}\t{%a1, %k0|%k0, %a1}"
5478 [(set_attr "type" "lea")
5479 (set_attr "mode" "SI")])
5481 (define_insn "*lea_6_zext"
5482 [(set (match_operand:DI 0 "register_operand" "=r")
5484 (match_operand:DI 1 "lea_address_operand" "p")
5485 (match_operand:DI 2 "const_32bit_mask" "n")))]
5487 "lea{l}\t{%a1, %k0|%k0, %a1}"
5488 [(set_attr "type" "lea")
5489 (set_attr "mode" "SI")])
5491 (define_insn "*add<mode>_1"
5492 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5494 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5495 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5496 (clobber (reg:CC FLAGS_REG))]
5497 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5499 switch (get_attr_type (insn))
5505 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5506 if (operands[2] == const1_rtx)
5507 return "inc{<imodesuffix>}\t%0";
5510 gcc_assert (operands[2] == constm1_rtx);
5511 return "dec{<imodesuffix>}\t%0";
5515 /* For most processors, ADD is faster than LEA. This alternative
5516 was added to use ADD as much as possible. */
5517 if (which_alternative == 2)
5520 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5523 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5524 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5525 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5527 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5531 (cond [(eq_attr "alternative" "3")
5532 (const_string "lea")
5533 (match_operand:SWI48 2 "incdec_operand" "")
5534 (const_string "incdec")
5536 (const_string "alu")))
5537 (set (attr "length_immediate")
5539 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5541 (const_string "*")))
5542 (set_attr "mode" "<MODE>")])
5544 ;; It may seem that nonimmediate operand is proper one for operand 1.
5545 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5546 ;; we take care in ix86_binary_operator_ok to not allow two memory
5547 ;; operands so proper swapping will be done in reload. This allow
5548 ;; patterns constructed from addsi_1 to match.
5550 (define_insn "addsi_1_zext"
5551 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5553 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5554 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5555 (clobber (reg:CC FLAGS_REG))]
5556 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5558 switch (get_attr_type (insn))
5564 if (operands[2] == const1_rtx)
5565 return "inc{l}\t%k0";
5568 gcc_assert (operands[2] == constm1_rtx);
5569 return "dec{l}\t%k0";
5573 /* For most processors, ADD is faster than LEA. This alternative
5574 was added to use ADD as much as possible. */
5575 if (which_alternative == 1)
5578 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5581 if (x86_maybe_negate_const_int (&operands[2], SImode))
5582 return "sub{l}\t{%2, %k0|%k0, %2}";
5584 return "add{l}\t{%2, %k0|%k0, %2}";
5588 (cond [(eq_attr "alternative" "2")
5589 (const_string "lea")
5590 (match_operand:SI 2 "incdec_operand" "")
5591 (const_string "incdec")
5593 (const_string "alu")))
5594 (set (attr "length_immediate")
5596 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5598 (const_string "*")))
5599 (set_attr "mode" "SI")])
5601 (define_insn "*addhi_1"
5602 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5603 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5604 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5605 (clobber (reg:CC FLAGS_REG))]
5606 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5608 switch (get_attr_type (insn))
5614 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5615 if (operands[2] == const1_rtx)
5616 return "inc{w}\t%0";
5619 gcc_assert (operands[2] == constm1_rtx);
5620 return "dec{w}\t%0";
5624 /* For most processors, ADD is faster than LEA. This alternative
5625 was added to use ADD as much as possible. */
5626 if (which_alternative == 2)
5629 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5632 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5633 if (x86_maybe_negate_const_int (&operands[2], HImode))
5634 return "sub{w}\t{%2, %0|%0, %2}";
5636 return "add{w}\t{%2, %0|%0, %2}";
5640 (cond [(eq_attr "alternative" "3")
5641 (const_string "lea")
5642 (match_operand:HI 2 "incdec_operand" "")
5643 (const_string "incdec")
5645 (const_string "alu")))
5646 (set (attr "length_immediate")
5648 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5650 (const_string "*")))
5651 (set_attr "mode" "HI,HI,HI,SI")])
5653 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5654 (define_insn "*addqi_1"
5655 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5656 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5657 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5658 (clobber (reg:CC FLAGS_REG))]
5659 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5661 bool widen = (which_alternative == 3 || which_alternative == 4);
5663 switch (get_attr_type (insn))
5669 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5670 if (operands[2] == const1_rtx)
5671 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5674 gcc_assert (operands[2] == constm1_rtx);
5675 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5679 /* For most processors, ADD is faster than LEA. These alternatives
5680 were added to use ADD as much as possible. */
5681 if (which_alternative == 2 || which_alternative == 4)
5684 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5687 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5688 if (x86_maybe_negate_const_int (&operands[2], QImode))
5691 return "sub{l}\t{%2, %k0|%k0, %2}";
5693 return "sub{b}\t{%2, %0|%0, %2}";
5696 return "add{l}\t{%k2, %k0|%k0, %k2}";
5698 return "add{b}\t{%2, %0|%0, %2}";
5702 (cond [(eq_attr "alternative" "5")
5703 (const_string "lea")
5704 (match_operand:QI 2 "incdec_operand" "")
5705 (const_string "incdec")
5707 (const_string "alu")))
5708 (set (attr "length_immediate")
5710 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5712 (const_string "*")))
5713 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5715 (define_insn "*addqi_1_slp"
5716 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5717 (plus:QI (match_dup 0)
5718 (match_operand:QI 1 "general_operand" "qn,qm")))
5719 (clobber (reg:CC FLAGS_REG))]
5720 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5721 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5723 switch (get_attr_type (insn))
5726 if (operands[1] == const1_rtx)
5727 return "inc{b}\t%0";
5730 gcc_assert (operands[1] == constm1_rtx);
5731 return "dec{b}\t%0";
5735 if (x86_maybe_negate_const_int (&operands[1], QImode))
5736 return "sub{b}\t{%1, %0|%0, %1}";
5738 return "add{b}\t{%1, %0|%0, %1}";
5742 (if_then_else (match_operand:QI 1 "incdec_operand" "")
5743 (const_string "incdec")
5744 (const_string "alu1")))
5745 (set (attr "memory")
5746 (if_then_else (match_operand 1 "memory_operand" "")
5747 (const_string "load")
5748 (const_string "none")))
5749 (set_attr "mode" "QI")])
5751 ;; Split non destructive adds if we cannot use lea.
5753 [(set (match_operand:SWI48 0 "register_operand" "")
5754 (plus:SWI48 (match_operand:SWI48 1 "register_operand" "")
5755 (match_operand:SWI48 2 "nonmemory_operand" "")))
5756 (clobber (reg:CC FLAGS_REG))]
5757 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5758 [(set (match_dup 0) (match_dup 1))
5759 (parallel [(set (match_dup 0) (plus:<MODE> (match_dup 0) (match_dup 2)))
5760 (clobber (reg:CC FLAGS_REG))])])
5762 ;; Convert add to the lea pattern to avoid flags dependency.
5764 [(set (match_operand:SWI 0 "register_operand" "")
5765 (plus:SWI (match_operand:SWI 1 "register_operand" "")
5766 (match_operand:SWI 2 "<nonmemory_operand>" "")))
5767 (clobber (reg:CC FLAGS_REG))]
5768 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5771 enum machine_mode mode = <MODE>mode;
5774 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5777 operands[0] = gen_lowpart (mode, operands[0]);
5778 operands[1] = gen_lowpart (mode, operands[1]);
5779 operands[2] = gen_lowpart (mode, operands[2]);
5782 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5784 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5788 ;; Convert add to the lea pattern to avoid flags dependency.
5790 [(set (match_operand:DI 0 "register_operand" "")
5792 (plus:SI (match_operand:SI 1 "register_operand" "")
5793 (match_operand:SI 2 "x86_64_nonmemory_operand" ""))))
5794 (clobber (reg:CC FLAGS_REG))]
5795 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5797 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5799 (define_insn "*add<mode>_2"
5800 [(set (reg FLAGS_REG)
5803 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
5804 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
5806 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5807 (plus:SWI (match_dup 1) (match_dup 2)))]
5808 "ix86_match_ccmode (insn, CCGOCmode)
5809 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5811 switch (get_attr_type (insn))
5814 if (operands[2] == const1_rtx)
5815 return "inc{<imodesuffix>}\t%0";
5818 gcc_assert (operands[2] == constm1_rtx);
5819 return "dec{<imodesuffix>}\t%0";
5823 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5824 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5826 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5830 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5831 (const_string "incdec")
5832 (const_string "alu")))
5833 (set (attr "length_immediate")
5835 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5837 (const_string "*")))
5838 (set_attr "mode" "<MODE>")])
5840 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5841 (define_insn "*addsi_2_zext"
5842 [(set (reg FLAGS_REG)
5844 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5845 (match_operand:SI 2 "x86_64_general_operand" "rme"))
5847 (set (match_operand:DI 0 "register_operand" "=r")
5848 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5849 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5850 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5852 switch (get_attr_type (insn))
5855 if (operands[2] == const1_rtx)
5856 return "inc{l}\t%k0";
5859 gcc_assert (operands[2] == constm1_rtx);
5860 return "dec{l}\t%k0";
5864 if (x86_maybe_negate_const_int (&operands[2], SImode))
5865 return "sub{l}\t{%2, %k0|%k0, %2}";
5867 return "add{l}\t{%2, %k0|%k0, %2}";
5871 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5872 (const_string "incdec")
5873 (const_string "alu")))
5874 (set (attr "length_immediate")
5876 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5878 (const_string "*")))
5879 (set_attr "mode" "SI")])
5881 (define_insn "*add<mode>_3"
5882 [(set (reg FLAGS_REG)
5884 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
5885 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
5886 (clobber (match_scratch:SWI 0 "=<r>"))]
5887 "ix86_match_ccmode (insn, CCZmode)
5888 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5890 switch (get_attr_type (insn))
5893 if (operands[2] == const1_rtx)
5894 return "inc{<imodesuffix>}\t%0";
5897 gcc_assert (operands[2] == constm1_rtx);
5898 return "dec{<imodesuffix>}\t%0";
5902 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5903 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5905 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5909 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5910 (const_string "incdec")
5911 (const_string "alu")))
5912 (set (attr "length_immediate")
5914 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5916 (const_string "*")))
5917 (set_attr "mode" "<MODE>")])
5919 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5920 (define_insn "*addsi_3_zext"
5921 [(set (reg FLAGS_REG)
5923 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme"))
5924 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5925 (set (match_operand:DI 0 "register_operand" "=r")
5926 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5927 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5928 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5930 switch (get_attr_type (insn))
5933 if (operands[2] == const1_rtx)
5934 return "inc{l}\t%k0";
5937 gcc_assert (operands[2] == constm1_rtx);
5938 return "dec{l}\t%k0";
5942 if (x86_maybe_negate_const_int (&operands[2], SImode))
5943 return "sub{l}\t{%2, %k0|%k0, %2}";
5945 return "add{l}\t{%2, %k0|%k0, %2}";
5949 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5950 (const_string "incdec")
5951 (const_string "alu")))
5952 (set (attr "length_immediate")
5954 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5956 (const_string "*")))
5957 (set_attr "mode" "SI")])
5959 ; For comparisons against 1, -1 and 128, we may generate better code
5960 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5961 ; is matched then. We can't accept general immediate, because for
5962 ; case of overflows, the result is messed up.
5963 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5964 ; only for comparisons not depending on it.
5966 (define_insn "*adddi_4"
5967 [(set (reg FLAGS_REG)
5969 (match_operand:DI 1 "nonimmediate_operand" "0")
5970 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5971 (clobber (match_scratch:DI 0 "=rm"))]
5973 && ix86_match_ccmode (insn, CCGCmode)"
5975 switch (get_attr_type (insn))
5978 if (operands[2] == constm1_rtx)
5979 return "inc{q}\t%0";
5982 gcc_assert (operands[2] == const1_rtx);
5983 return "dec{q}\t%0";
5987 if (x86_maybe_negate_const_int (&operands[2], DImode))
5988 return "add{q}\t{%2, %0|%0, %2}";
5990 return "sub{q}\t{%2, %0|%0, %2}";
5994 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5995 (const_string "incdec")
5996 (const_string "alu")))
5997 (set (attr "length_immediate")
5999 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6001 (const_string "*")))
6002 (set_attr "mode" "DI")])
6004 ; For comparisons against 1, -1 and 128, we may generate better code
6005 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6006 ; is matched then. We can't accept general immediate, because for
6007 ; case of overflows, the result is messed up.
6008 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6009 ; only for comparisons not depending on it.
6011 (define_insn "*add<mode>_4"
6012 [(set (reg FLAGS_REG)
6014 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6015 (match_operand:SWI124 2 "const_int_operand" "n")))
6016 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6017 "ix86_match_ccmode (insn, CCGCmode)"
6019 switch (get_attr_type (insn))
6022 if (operands[2] == constm1_rtx)
6023 return "inc{<imodesuffix>}\t%0";
6026 gcc_assert (operands[2] == const1_rtx);
6027 return "dec{<imodesuffix>}\t%0";
6031 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6032 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6034 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6038 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6039 (const_string "incdec")
6040 (const_string "alu")))
6041 (set (attr "length_immediate")
6043 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6045 (const_string "*")))
6046 (set_attr "mode" "<MODE>")])
6048 (define_insn "*add<mode>_5"
6049 [(set (reg FLAGS_REG)
6052 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6053 (match_operand:SWI 2 "<general_operand>" "<g>"))
6055 (clobber (match_scratch:SWI 0 "=<r>"))]
6056 "ix86_match_ccmode (insn, CCGOCmode)
6057 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6059 switch (get_attr_type (insn))
6062 if (operands[2] == const1_rtx)
6063 return "inc{<imodesuffix>}\t%0";
6066 gcc_assert (operands[2] == constm1_rtx);
6067 return "dec{<imodesuffix>}\t%0";
6071 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6072 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6074 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6078 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6079 (const_string "incdec")
6080 (const_string "alu")))
6081 (set (attr "length_immediate")
6083 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6085 (const_string "*")))
6086 (set_attr "mode" "<MODE>")])
6088 (define_insn "*addqi_ext_1_rex64"
6089 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6094 (match_operand 1 "ext_register_operand" "0")
6097 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6098 (clobber (reg:CC FLAGS_REG))]
6101 switch (get_attr_type (insn))
6104 if (operands[2] == const1_rtx)
6105 return "inc{b}\t%h0";
6108 gcc_assert (operands[2] == constm1_rtx);
6109 return "dec{b}\t%h0";
6113 return "add{b}\t{%2, %h0|%h0, %2}";
6117 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6118 (const_string "incdec")
6119 (const_string "alu")))
6120 (set_attr "modrm" "1")
6121 (set_attr "mode" "QI")])
6123 (define_insn "addqi_ext_1"
6124 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6129 (match_operand 1 "ext_register_operand" "0")
6132 (match_operand:QI 2 "general_operand" "Qmn")))
6133 (clobber (reg:CC FLAGS_REG))]
6136 switch (get_attr_type (insn))
6139 if (operands[2] == const1_rtx)
6140 return "inc{b}\t%h0";
6143 gcc_assert (operands[2] == constm1_rtx);
6144 return "dec{b}\t%h0";
6148 return "add{b}\t{%2, %h0|%h0, %2}";
6152 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6153 (const_string "incdec")
6154 (const_string "alu")))
6155 (set_attr "modrm" "1")
6156 (set_attr "mode" "QI")])
6158 (define_insn "*addqi_ext_2"
6159 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6164 (match_operand 1 "ext_register_operand" "%0")
6168 (match_operand 2 "ext_register_operand" "Q")
6171 (clobber (reg:CC FLAGS_REG))]
6173 "add{b}\t{%h2, %h0|%h0, %h2}"
6174 [(set_attr "type" "alu")
6175 (set_attr "mode" "QI")])
6177 ;; The lea patterns for modes less than 32 bits need to be matched by
6178 ;; several insns converted to real lea by splitters.
6180 (define_insn_and_split "*lea_general_1"
6181 [(set (match_operand 0 "register_operand" "=r")
6182 (plus (plus (match_operand 1 "index_register_operand" "l")
6183 (match_operand 2 "register_operand" "r"))
6184 (match_operand 3 "immediate_operand" "i")))]
6185 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6186 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6187 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6188 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6189 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6190 || GET_MODE (operands[3]) == VOIDmode)"
6192 "&& reload_completed"
6195 enum machine_mode mode = SImode;
6198 operands[0] = gen_lowpart (mode, operands[0]);
6199 operands[1] = gen_lowpart (mode, operands[1]);
6200 operands[2] = gen_lowpart (mode, operands[2]);
6201 operands[3] = gen_lowpart (mode, operands[3]);
6203 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6206 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6209 [(set_attr "type" "lea")
6210 (set_attr "mode" "SI")])
6212 (define_insn_and_split "*lea_general_2"
6213 [(set (match_operand 0 "register_operand" "=r")
6214 (plus (mult (match_operand 1 "index_register_operand" "l")
6215 (match_operand 2 "const248_operand" "n"))
6216 (match_operand 3 "nonmemory_operand" "ri")))]
6217 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6218 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6219 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6220 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6221 || GET_MODE (operands[3]) == VOIDmode)"
6223 "&& reload_completed"
6226 enum machine_mode mode = SImode;
6229 operands[0] = gen_lowpart (mode, operands[0]);
6230 operands[1] = gen_lowpart (mode, operands[1]);
6231 operands[3] = gen_lowpart (mode, operands[3]);
6233 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6236 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6239 [(set_attr "type" "lea")
6240 (set_attr "mode" "SI")])
6242 (define_insn_and_split "*lea_general_3"
6243 [(set (match_operand 0 "register_operand" "=r")
6244 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6245 (match_operand 2 "const248_operand" "n"))
6246 (match_operand 3 "register_operand" "r"))
6247 (match_operand 4 "immediate_operand" "i")))]
6248 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6249 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6250 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6251 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6253 "&& reload_completed"
6256 enum machine_mode mode = SImode;
6259 operands[0] = gen_lowpart (mode, operands[0]);
6260 operands[1] = gen_lowpart (mode, operands[1]);
6261 operands[3] = gen_lowpart (mode, operands[3]);
6262 operands[4] = gen_lowpart (mode, operands[4]);
6264 pat = gen_rtx_PLUS (mode,
6266 gen_rtx_MULT (mode, operands[1],
6271 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6274 [(set_attr "type" "lea")
6275 (set_attr "mode" "SI")])
6277 (define_insn_and_split "*lea_general_4"
6278 [(set (match_operand 0 "register_operand" "=r")
6280 (match_operand 1 "index_register_operand" "l")
6281 (match_operand 2 "const_int_operand" "n"))
6282 (match_operand 3 "const_int_operand" "n")))]
6283 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6284 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6285 || GET_MODE (operands[0]) == SImode
6286 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6287 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6288 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6289 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6290 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6292 "&& reload_completed"
6295 enum machine_mode mode = GET_MODE (operands[0]);
6298 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6301 operands[0] = gen_lowpart (mode, operands[0]);
6302 operands[1] = gen_lowpart (mode, operands[1]);
6305 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6307 pat = plus_constant (gen_rtx_MULT (mode, operands[1], operands[2]),
6308 INTVAL (operands[3]));
6310 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6313 [(set_attr "type" "lea")
6315 (if_then_else (match_operand:DI 0 "" "")
6317 (const_string "SI")))])
6319 ;; Subtract instructions
6321 (define_expand "sub<mode>3"
6322 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6323 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6324 (match_operand:SDWIM 2 "<general_operand>" "")))]
6326 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6328 (define_insn_and_split "*sub<dwi>3_doubleword"
6329 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6331 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6332 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6333 (clobber (reg:CC FLAGS_REG))]
6334 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6337 [(parallel [(set (reg:CC FLAGS_REG)
6338 (compare:CC (match_dup 1) (match_dup 2)))
6340 (minus:DWIH (match_dup 1) (match_dup 2)))])
6341 (parallel [(set (match_dup 3)
6345 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6347 (clobber (reg:CC FLAGS_REG))])]
6348 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6350 (define_insn "*sub<mode>_1"
6351 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6353 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6354 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6355 (clobber (reg:CC FLAGS_REG))]
6356 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6357 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6358 [(set_attr "type" "alu")
6359 (set_attr "mode" "<MODE>")])
6361 (define_insn "*subsi_1_zext"
6362 [(set (match_operand:DI 0 "register_operand" "=r")
6364 (minus:SI (match_operand:SI 1 "register_operand" "0")
6365 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6366 (clobber (reg:CC FLAGS_REG))]
6367 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6368 "sub{l}\t{%2, %k0|%k0, %2}"
6369 [(set_attr "type" "alu")
6370 (set_attr "mode" "SI")])
6372 (define_insn "*subqi_1_slp"
6373 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6374 (minus:QI (match_dup 0)
6375 (match_operand:QI 1 "general_operand" "qn,qm")))
6376 (clobber (reg:CC FLAGS_REG))]
6377 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6378 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6379 "sub{b}\t{%1, %0|%0, %1}"
6380 [(set_attr "type" "alu1")
6381 (set_attr "mode" "QI")])
6383 (define_insn "*sub<mode>_2"
6384 [(set (reg FLAGS_REG)
6387 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6388 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6390 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6391 (minus:SWI (match_dup 1) (match_dup 2)))]
6392 "ix86_match_ccmode (insn, CCGOCmode)
6393 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6394 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6395 [(set_attr "type" "alu")
6396 (set_attr "mode" "<MODE>")])
6398 (define_insn "*subsi_2_zext"
6399 [(set (reg FLAGS_REG)
6401 (minus:SI (match_operand:SI 1 "register_operand" "0")
6402 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6404 (set (match_operand:DI 0 "register_operand" "=r")
6406 (minus:SI (match_dup 1)
6408 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6409 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6410 "sub{l}\t{%2, %k0|%k0, %2}"
6411 [(set_attr "type" "alu")
6412 (set_attr "mode" "SI")])
6414 (define_insn "*sub<mode>_3"
6415 [(set (reg FLAGS_REG)
6416 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6417 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6418 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6419 (minus:SWI (match_dup 1) (match_dup 2)))]
6420 "ix86_match_ccmode (insn, CCmode)
6421 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6422 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6423 [(set_attr "type" "alu")
6424 (set_attr "mode" "<MODE>")])
6426 (define_insn "*subsi_3_zext"
6427 [(set (reg FLAGS_REG)
6428 (compare (match_operand:SI 1 "register_operand" "0")
6429 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6430 (set (match_operand:DI 0 "register_operand" "=r")
6432 (minus:SI (match_dup 1)
6434 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6435 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6436 "sub{l}\t{%2, %1|%1, %2}"
6437 [(set_attr "type" "alu")
6438 (set_attr "mode" "SI")])
6440 ;; Add with carry and subtract with borrow
6442 (define_expand "<plusminus_insn><mode>3_carry"
6444 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6446 (match_operand:SWI 1 "nonimmediate_operand" "")
6447 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6448 [(match_operand 3 "flags_reg_operand" "")
6450 (match_operand:SWI 2 "<general_operand>" ""))))
6451 (clobber (reg:CC FLAGS_REG))])]
6452 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6454 (define_insn "*<plusminus_insn><mode>3_carry"
6455 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6457 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6459 (match_operator 3 "ix86_carry_flag_operator"
6460 [(reg FLAGS_REG) (const_int 0)])
6461 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6462 (clobber (reg:CC FLAGS_REG))]
6463 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6464 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6465 [(set_attr "type" "alu")
6466 (set_attr "use_carry" "1")
6467 (set_attr "pent_pair" "pu")
6468 (set_attr "mode" "<MODE>")])
6470 (define_insn "*addsi3_carry_zext"
6471 [(set (match_operand:DI 0 "register_operand" "=r")
6473 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6474 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6475 [(reg FLAGS_REG) (const_int 0)])
6476 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6477 (clobber (reg:CC FLAGS_REG))]
6478 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6479 "adc{l}\t{%2, %k0|%k0, %2}"
6480 [(set_attr "type" "alu")
6481 (set_attr "use_carry" "1")
6482 (set_attr "pent_pair" "pu")
6483 (set_attr "mode" "SI")])
6485 (define_insn "*subsi3_carry_zext"
6486 [(set (match_operand:DI 0 "register_operand" "=r")
6488 (minus:SI (match_operand:SI 1 "register_operand" "0")
6489 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6490 [(reg FLAGS_REG) (const_int 0)])
6491 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6492 (clobber (reg:CC FLAGS_REG))]
6493 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6494 "sbb{l}\t{%2, %k0|%k0, %2}"
6495 [(set_attr "type" "alu")
6496 (set_attr "pent_pair" "pu")
6497 (set_attr "mode" "SI")])
6499 ;; Overflow setting add and subtract instructions
6501 (define_insn "*add<mode>3_cconly_overflow"
6502 [(set (reg:CCC FLAGS_REG)
6505 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6506 (match_operand:SWI 2 "<general_operand>" "<g>"))
6508 (clobber (match_scratch:SWI 0 "=<r>"))]
6509 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6510 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6511 [(set_attr "type" "alu")
6512 (set_attr "mode" "<MODE>")])
6514 (define_insn "*sub<mode>3_cconly_overflow"
6515 [(set (reg:CCC FLAGS_REG)
6518 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6519 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6522 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6523 [(set_attr "type" "icmp")
6524 (set_attr "mode" "<MODE>")])
6526 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6527 [(set (reg:CCC FLAGS_REG)
6530 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6531 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6533 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6534 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6535 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6536 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6537 [(set_attr "type" "alu")
6538 (set_attr "mode" "<MODE>")])
6540 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6541 [(set (reg:CCC FLAGS_REG)
6544 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6545 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6547 (set (match_operand:DI 0 "register_operand" "=r")
6548 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6549 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6550 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6551 [(set_attr "type" "alu")
6552 (set_attr "mode" "SI")])
6554 ;; The patterns that match these are at the end of this file.
6556 (define_expand "<plusminus_insn>xf3"
6557 [(set (match_operand:XF 0 "register_operand" "")
6559 (match_operand:XF 1 "register_operand" "")
6560 (match_operand:XF 2 "register_operand" "")))]
6563 (define_expand "<plusminus_insn><mode>3"
6564 [(set (match_operand:MODEF 0 "register_operand" "")
6566 (match_operand:MODEF 1 "register_operand" "")
6567 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6568 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6569 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6571 ;; Multiply instructions
6573 (define_expand "mul<mode>3"
6574 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6576 (match_operand:SWIM248 1 "register_operand" "")
6577 (match_operand:SWIM248 2 "<general_operand>" "")))
6578 (clobber (reg:CC FLAGS_REG))])])
6580 (define_expand "mulqi3"
6581 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6583 (match_operand:QI 1 "register_operand" "")
6584 (match_operand:QI 2 "nonimmediate_operand" "")))
6585 (clobber (reg:CC FLAGS_REG))])]
6586 "TARGET_QIMODE_MATH")
6589 ;; IMUL reg32/64, reg32/64, imm8 Direct
6590 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6591 ;; IMUL reg32/64, reg32/64, imm32 Direct
6592 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6593 ;; IMUL reg32/64, reg32/64 Direct
6594 ;; IMUL reg32/64, mem32/64 Direct
6596 ;; On BDVER1, all above IMULs use DirectPath
6598 (define_insn "*mul<mode>3_1"
6599 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6601 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6602 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6603 (clobber (reg:CC FLAGS_REG))]
6604 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6606 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6607 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6608 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6609 [(set_attr "type" "imul")
6610 (set_attr "prefix_0f" "0,0,1")
6611 (set (attr "athlon_decode")
6612 (cond [(eq_attr "cpu" "athlon")
6613 (const_string "vector")
6614 (eq_attr "alternative" "1")
6615 (const_string "vector")
6616 (and (eq_attr "alternative" "2")
6617 (match_operand 1 "memory_operand" ""))
6618 (const_string "vector")]
6619 (const_string "direct")))
6620 (set (attr "amdfam10_decode")
6621 (cond [(and (eq_attr "alternative" "0,1")
6622 (match_operand 1 "memory_operand" ""))
6623 (const_string "vector")]
6624 (const_string "direct")))
6625 (set_attr "bdver1_decode" "direct")
6626 (set_attr "mode" "<MODE>")])
6628 (define_insn "*mulsi3_1_zext"
6629 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6631 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6632 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6633 (clobber (reg:CC FLAGS_REG))]
6635 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6637 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6638 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6639 imul{l}\t{%2, %k0|%k0, %2}"
6640 [(set_attr "type" "imul")
6641 (set_attr "prefix_0f" "0,0,1")
6642 (set (attr "athlon_decode")
6643 (cond [(eq_attr "cpu" "athlon")
6644 (const_string "vector")
6645 (eq_attr "alternative" "1")
6646 (const_string "vector")
6647 (and (eq_attr "alternative" "2")
6648 (match_operand 1 "memory_operand" ""))
6649 (const_string "vector")]
6650 (const_string "direct")))
6651 (set (attr "amdfam10_decode")
6652 (cond [(and (eq_attr "alternative" "0,1")
6653 (match_operand 1 "memory_operand" ""))
6654 (const_string "vector")]
6655 (const_string "direct")))
6656 (set_attr "bdver1_decode" "direct")
6657 (set_attr "mode" "SI")])
6660 ;; IMUL reg16, reg16, imm8 VectorPath
6661 ;; IMUL reg16, mem16, imm8 VectorPath
6662 ;; IMUL reg16, reg16, imm16 VectorPath
6663 ;; IMUL reg16, mem16, imm16 VectorPath
6664 ;; IMUL reg16, reg16 Direct
6665 ;; IMUL reg16, mem16 Direct
6667 ;; On BDVER1, all HI MULs use DoublePath
6669 (define_insn "*mulhi3_1"
6670 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6671 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6672 (match_operand:HI 2 "general_operand" "K,n,mr")))
6673 (clobber (reg:CC FLAGS_REG))]
6675 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6677 imul{w}\t{%2, %1, %0|%0, %1, %2}
6678 imul{w}\t{%2, %1, %0|%0, %1, %2}
6679 imul{w}\t{%2, %0|%0, %2}"
6680 [(set_attr "type" "imul")
6681 (set_attr "prefix_0f" "0,0,1")
6682 (set (attr "athlon_decode")
6683 (cond [(eq_attr "cpu" "athlon")
6684 (const_string "vector")
6685 (eq_attr "alternative" "1,2")
6686 (const_string "vector")]
6687 (const_string "direct")))
6688 (set (attr "amdfam10_decode")
6689 (cond [(eq_attr "alternative" "0,1")
6690 (const_string "vector")]
6691 (const_string "direct")))
6692 (set_attr "bdver1_decode" "double")
6693 (set_attr "mode" "HI")])
6695 ;;On AMDFAM10 and BDVER1
6699 (define_insn "*mulqi3_1"
6700 [(set (match_operand:QI 0 "register_operand" "=a")
6701 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6702 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6703 (clobber (reg:CC FLAGS_REG))]
6705 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6707 [(set_attr "type" "imul")
6708 (set_attr "length_immediate" "0")
6709 (set (attr "athlon_decode")
6710 (if_then_else (eq_attr "cpu" "athlon")
6711 (const_string "vector")
6712 (const_string "direct")))
6713 (set_attr "amdfam10_decode" "direct")
6714 (set_attr "bdver1_decode" "direct")
6715 (set_attr "mode" "QI")])
6717 (define_expand "<u>mul<mode><dwi>3"
6718 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6721 (match_operand:DWIH 1 "nonimmediate_operand" ""))
6723 (match_operand:DWIH 2 "register_operand" ""))))
6724 (clobber (reg:CC FLAGS_REG))])])
6726 (define_expand "<u>mulqihi3"
6727 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6730 (match_operand:QI 1 "nonimmediate_operand" ""))
6732 (match_operand:QI 2 "register_operand" ""))))
6733 (clobber (reg:CC FLAGS_REG))])]
6734 "TARGET_QIMODE_MATH")
6736 (define_insn "*bmi2_umulditi3_1"
6737 [(set (match_operand:DI 0 "register_operand" "=r")
6739 (match_operand:DI 2 "nonimmediate_operand" "%d")
6740 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6741 (set (match_operand:DI 1 "register_operand" "=r")
6744 (mult:TI (zero_extend:TI (match_dup 2))
6745 (zero_extend:TI (match_dup 3)))
6747 "TARGET_64BIT && TARGET_BMI2
6748 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6749 "mulx\t{%3, %0, %1|%1, %0, %3}"
6750 [(set_attr "type" "imulx")
6751 (set_attr "prefix" "vex")
6752 (set_attr "mode" "DI")])
6754 (define_insn "*bmi2_umulsidi3_1"
6755 [(set (match_operand:SI 0 "register_operand" "=r")
6757 (match_operand:SI 2 "nonimmediate_operand" "%d")
6758 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6759 (set (match_operand:SI 1 "register_operand" "=r")
6762 (mult:DI (zero_extend:DI (match_dup 2))
6763 (zero_extend:DI (match_dup 3)))
6765 "!TARGET_64BIT && TARGET_BMI2
6766 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6767 "mulx\t{%3, %0, %1|%1, %0, %3}"
6768 [(set_attr "type" "imulx")
6769 (set_attr "prefix" "vex")
6770 (set_attr "mode" "SI")])
6772 (define_insn "*umul<mode><dwi>3_1"
6773 [(set (match_operand:<DWI> 0 "register_operand" "=A,r")
6776 (match_operand:DWIH 1 "nonimmediate_operand" "%0,d"))
6778 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6779 (clobber (reg:CC FLAGS_REG))]
6780 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6782 mul{<imodesuffix>}\t%2
6784 [(set_attr "isa" "*,bmi2")
6785 (set_attr "type" "imul,imulx")
6786 (set_attr "length_immediate" "0,*")
6787 (set (attr "athlon_decode")
6788 (cond [(eq_attr "alternative" "0")
6789 (if_then_else (eq_attr "cpu" "athlon")
6790 (const_string "vector")
6791 (const_string "double"))]
6792 (const_string "*")))
6793 (set_attr "amdfam10_decode" "double,*")
6794 (set_attr "bdver1_decode" "direct,*")
6795 (set_attr "prefix" "orig,vex")
6796 (set_attr "mode" "<MODE>")])
6798 ;; Convert mul to the mulx pattern to avoid flags dependency.
6800 [(set (match_operand:<DWI> 0 "register_operand" "")
6803 (match_operand:DWIH 1 "register_operand" ""))
6805 (match_operand:DWIH 2 "nonimmediate_operand" ""))))
6806 (clobber (reg:CC FLAGS_REG))]
6807 "TARGET_BMI2 && reload_completed
6808 && true_regnum (operands[1]) == DX_REG"
6809 [(parallel [(set (match_dup 3)
6810 (mult:DWIH (match_dup 1) (match_dup 2)))
6814 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6815 (zero_extend:<DWI> (match_dup 2)))
6818 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6820 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6823 (define_insn "*mul<mode><dwi>3_1"
6824 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6827 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6829 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6830 (clobber (reg:CC FLAGS_REG))]
6831 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6832 "imul{<imodesuffix>}\t%2"
6833 [(set_attr "type" "imul")
6834 (set_attr "length_immediate" "0")
6835 (set (attr "athlon_decode")
6836 (if_then_else (eq_attr "cpu" "athlon")
6837 (const_string "vector")
6838 (const_string "double")))
6839 (set_attr "amdfam10_decode" "double")
6840 (set_attr "bdver1_decode" "direct")
6841 (set_attr "mode" "<MODE>")])
6843 (define_insn "*<u>mulqihi3_1"
6844 [(set (match_operand:HI 0 "register_operand" "=a")
6847 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6849 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6850 (clobber (reg:CC FLAGS_REG))]
6852 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6853 "<sgnprefix>mul{b}\t%2"
6854 [(set_attr "type" "imul")
6855 (set_attr "length_immediate" "0")
6856 (set (attr "athlon_decode")
6857 (if_then_else (eq_attr "cpu" "athlon")
6858 (const_string "vector")
6859 (const_string "direct")))
6860 (set_attr "amdfam10_decode" "direct")
6861 (set_attr "bdver1_decode" "direct")
6862 (set_attr "mode" "QI")])
6864 (define_expand "<s>mul<mode>3_highpart"
6865 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6870 (match_operand:SWI48 1 "nonimmediate_operand" ""))
6872 (match_operand:SWI48 2 "register_operand" "")))
6874 (clobber (match_scratch:SWI48 3 ""))
6875 (clobber (reg:CC FLAGS_REG))])]
6877 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6879 (define_insn "*<s>muldi3_highpart_1"
6880 [(set (match_operand:DI 0 "register_operand" "=d")
6885 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6887 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6889 (clobber (match_scratch:DI 3 "=1"))
6890 (clobber (reg:CC FLAGS_REG))]
6892 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6893 "<sgnprefix>mul{q}\t%2"
6894 [(set_attr "type" "imul")
6895 (set_attr "length_immediate" "0")
6896 (set (attr "athlon_decode")
6897 (if_then_else (eq_attr "cpu" "athlon")
6898 (const_string "vector")
6899 (const_string "double")))
6900 (set_attr "amdfam10_decode" "double")
6901 (set_attr "bdver1_decode" "direct")
6902 (set_attr "mode" "DI")])
6904 (define_insn "*<s>mulsi3_highpart_1"
6905 [(set (match_operand:SI 0 "register_operand" "=d")
6910 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6912 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6914 (clobber (match_scratch:SI 3 "=1"))
6915 (clobber (reg:CC FLAGS_REG))]
6916 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6917 "<sgnprefix>mul{l}\t%2"
6918 [(set_attr "type" "imul")
6919 (set_attr "length_immediate" "0")
6920 (set (attr "athlon_decode")
6921 (if_then_else (eq_attr "cpu" "athlon")
6922 (const_string "vector")
6923 (const_string "double")))
6924 (set_attr "amdfam10_decode" "double")
6925 (set_attr "bdver1_decode" "direct")
6926 (set_attr "mode" "SI")])
6928 (define_insn "*<s>mulsi3_highpart_zext"
6929 [(set (match_operand:DI 0 "register_operand" "=d")
6930 (zero_extend:DI (truncate:SI
6932 (mult:DI (any_extend:DI
6933 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6935 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6937 (clobber (match_scratch:SI 3 "=1"))
6938 (clobber (reg:CC FLAGS_REG))]
6940 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6941 "<sgnprefix>mul{l}\t%2"
6942 [(set_attr "type" "imul")
6943 (set_attr "length_immediate" "0")
6944 (set (attr "athlon_decode")
6945 (if_then_else (eq_attr "cpu" "athlon")
6946 (const_string "vector")
6947 (const_string "double")))
6948 (set_attr "amdfam10_decode" "double")
6949 (set_attr "bdver1_decode" "direct")
6950 (set_attr "mode" "SI")])
6952 ;; The patterns that match these are at the end of this file.
6954 (define_expand "mulxf3"
6955 [(set (match_operand:XF 0 "register_operand" "")
6956 (mult:XF (match_operand:XF 1 "register_operand" "")
6957 (match_operand:XF 2 "register_operand" "")))]
6960 (define_expand "mul<mode>3"
6961 [(set (match_operand:MODEF 0 "register_operand" "")
6962 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
6963 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6964 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6965 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6967 ;; Divide instructions
6969 ;; The patterns that match these are at the end of this file.
6971 (define_expand "divxf3"
6972 [(set (match_operand:XF 0 "register_operand" "")
6973 (div:XF (match_operand:XF 1 "register_operand" "")
6974 (match_operand:XF 2 "register_operand" "")))]
6977 (define_expand "divdf3"
6978 [(set (match_operand:DF 0 "register_operand" "")
6979 (div:DF (match_operand:DF 1 "register_operand" "")
6980 (match_operand:DF 2 "nonimmediate_operand" "")))]
6981 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
6982 || (TARGET_SSE2 && TARGET_SSE_MATH)")
6984 (define_expand "divsf3"
6985 [(set (match_operand:SF 0 "register_operand" "")
6986 (div:SF (match_operand:SF 1 "register_operand" "")
6987 (match_operand:SF 2 "nonimmediate_operand" "")))]
6988 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
6993 && optimize_insn_for_speed_p ()
6994 && flag_finite_math_only && !flag_trapping_math
6995 && flag_unsafe_math_optimizations)
6997 ix86_emit_swdivsf (operands[0], operands[1],
6998 operands[2], SFmode);
7003 ;; Divmod instructions.
7005 (define_expand "divmod<mode>4"
7006 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7008 (match_operand:SWIM248 1 "register_operand" "")
7009 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7010 (set (match_operand:SWIM248 3 "register_operand" "")
7011 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7012 (clobber (reg:CC FLAGS_REG))])])
7014 ;; Split with 8bit unsigned divide:
7015 ;; if (dividend an divisor are in [0-255])
7016 ;; use 8bit unsigned integer divide
7018 ;; use original integer divide
7020 [(set (match_operand:SWI48 0 "register_operand" "")
7021 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7022 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7023 (set (match_operand:SWI48 1 "register_operand" "")
7024 (mod:SWI48 (match_dup 2) (match_dup 3)))
7025 (clobber (reg:CC FLAGS_REG))]
7026 "TARGET_USE_8BIT_IDIV
7027 && TARGET_QIMODE_MATH
7028 && can_create_pseudo_p ()
7029 && !optimize_insn_for_size_p ()"
7031 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7033 (define_insn_and_split "divmod<mode>4_1"
7034 [(set (match_operand:SWI48 0 "register_operand" "=a")
7035 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7036 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7037 (set (match_operand:SWI48 1 "register_operand" "=&d")
7038 (mod:SWI48 (match_dup 2) (match_dup 3)))
7039 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7040 (clobber (reg:CC FLAGS_REG))]
7044 [(parallel [(set (match_dup 1)
7045 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7046 (clobber (reg:CC FLAGS_REG))])
7047 (parallel [(set (match_dup 0)
7048 (div:SWI48 (match_dup 2) (match_dup 3)))
7050 (mod:SWI48 (match_dup 2) (match_dup 3)))
7052 (clobber (reg:CC FLAGS_REG))])]
7054 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7056 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7057 operands[4] = operands[2];
7060 /* Avoid use of cltd in favor of a mov+shift. */
7061 emit_move_insn (operands[1], operands[2]);
7062 operands[4] = operands[1];
7065 [(set_attr "type" "multi")
7066 (set_attr "mode" "<MODE>")])
7068 (define_insn_and_split "*divmod<mode>4"
7069 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7070 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7071 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7072 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7073 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7074 (clobber (reg:CC FLAGS_REG))]
7078 [(parallel [(set (match_dup 1)
7079 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7080 (clobber (reg:CC FLAGS_REG))])
7081 (parallel [(set (match_dup 0)
7082 (div:SWIM248 (match_dup 2) (match_dup 3)))
7084 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7086 (clobber (reg:CC FLAGS_REG))])]
7088 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7090 if (<MODE>mode != HImode
7091 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7092 operands[4] = operands[2];
7095 /* Avoid use of cltd in favor of a mov+shift. */
7096 emit_move_insn (operands[1], operands[2]);
7097 operands[4] = operands[1];
7100 [(set_attr "type" "multi")
7101 (set_attr "mode" "<MODE>")])
7103 (define_insn "*divmod<mode>4_noext"
7104 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7105 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7106 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7107 (set (match_operand:SWIM248 1 "register_operand" "=d")
7108 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7109 (use (match_operand:SWIM248 4 "register_operand" "1"))
7110 (clobber (reg:CC FLAGS_REG))]
7112 "idiv{<imodesuffix>}\t%3"
7113 [(set_attr "type" "idiv")
7114 (set_attr "mode" "<MODE>")])
7116 (define_expand "divmodqi4"
7117 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7119 (match_operand:QI 1 "register_operand" "")
7120 (match_operand:QI 2 "nonimmediate_operand" "")))
7121 (set (match_operand:QI 3 "register_operand" "")
7122 (mod:QI (match_dup 1) (match_dup 2)))
7123 (clobber (reg:CC FLAGS_REG))])]
7124 "TARGET_QIMODE_MATH"
7129 tmp0 = gen_reg_rtx (HImode);
7130 tmp1 = gen_reg_rtx (HImode);
7132 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7134 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7135 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7137 /* Extract remainder from AH. */
7138 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7139 insn = emit_move_insn (operands[3], tmp1);
7141 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7142 set_unique_reg_note (insn, REG_EQUAL, mod);
7144 /* Extract quotient from AL. */
7145 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7147 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7148 set_unique_reg_note (insn, REG_EQUAL, div);
7153 ;; Divide AX by r/m8, with result stored in
7156 ;; Change div/mod to HImode and extend the second argument to HImode
7157 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7158 ;; combine may fail.
7159 (define_insn "divmodhiqi3"
7160 [(set (match_operand:HI 0 "register_operand" "=a")
7165 (mod:HI (match_operand:HI 1 "register_operand" "0")
7167 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7171 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7172 (clobber (reg:CC FLAGS_REG))]
7173 "TARGET_QIMODE_MATH"
7175 [(set_attr "type" "idiv")
7176 (set_attr "mode" "QI")])
7178 (define_expand "udivmod<mode>4"
7179 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7181 (match_operand:SWIM248 1 "register_operand" "")
7182 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7183 (set (match_operand:SWIM248 3 "register_operand" "")
7184 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7185 (clobber (reg:CC FLAGS_REG))])])
7187 ;; Split with 8bit unsigned divide:
7188 ;; if (dividend an divisor are in [0-255])
7189 ;; use 8bit unsigned integer divide
7191 ;; use original integer divide
7193 [(set (match_operand:SWI48 0 "register_operand" "")
7194 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7195 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7196 (set (match_operand:SWI48 1 "register_operand" "")
7197 (umod:SWI48 (match_dup 2) (match_dup 3)))
7198 (clobber (reg:CC FLAGS_REG))]
7199 "TARGET_USE_8BIT_IDIV
7200 && TARGET_QIMODE_MATH
7201 && can_create_pseudo_p ()
7202 && !optimize_insn_for_size_p ()"
7204 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7206 (define_insn_and_split "udivmod<mode>4_1"
7207 [(set (match_operand:SWI48 0 "register_operand" "=a")
7208 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7209 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7210 (set (match_operand:SWI48 1 "register_operand" "=&d")
7211 (umod:SWI48 (match_dup 2) (match_dup 3)))
7212 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7213 (clobber (reg:CC FLAGS_REG))]
7217 [(set (match_dup 1) (const_int 0))
7218 (parallel [(set (match_dup 0)
7219 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7221 (umod:SWI48 (match_dup 2) (match_dup 3)))
7223 (clobber (reg:CC FLAGS_REG))])]
7225 [(set_attr "type" "multi")
7226 (set_attr "mode" "<MODE>")])
7228 (define_insn_and_split "*udivmod<mode>4"
7229 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7230 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7231 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7232 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7233 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7234 (clobber (reg:CC FLAGS_REG))]
7238 [(set (match_dup 1) (const_int 0))
7239 (parallel [(set (match_dup 0)
7240 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7242 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7244 (clobber (reg:CC FLAGS_REG))])]
7246 [(set_attr "type" "multi")
7247 (set_attr "mode" "<MODE>")])
7249 (define_insn "*udivmod<mode>4_noext"
7250 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7251 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7252 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7253 (set (match_operand:SWIM248 1 "register_operand" "=d")
7254 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7255 (use (match_operand:SWIM248 4 "register_operand" "1"))
7256 (clobber (reg:CC FLAGS_REG))]
7258 "div{<imodesuffix>}\t%3"
7259 [(set_attr "type" "idiv")
7260 (set_attr "mode" "<MODE>")])
7262 (define_expand "udivmodqi4"
7263 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7265 (match_operand:QI 1 "register_operand" "")
7266 (match_operand:QI 2 "nonimmediate_operand" "")))
7267 (set (match_operand:QI 3 "register_operand" "")
7268 (umod:QI (match_dup 1) (match_dup 2)))
7269 (clobber (reg:CC FLAGS_REG))])]
7270 "TARGET_QIMODE_MATH"
7275 tmp0 = gen_reg_rtx (HImode);
7276 tmp1 = gen_reg_rtx (HImode);
7278 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7280 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7281 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7283 /* Extract remainder from AH. */
7284 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7285 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7286 insn = emit_move_insn (operands[3], tmp1);
7288 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7289 set_unique_reg_note (insn, REG_EQUAL, mod);
7291 /* Extract quotient from AL. */
7292 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7294 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7295 set_unique_reg_note (insn, REG_EQUAL, div);
7300 (define_insn "udivmodhiqi3"
7301 [(set (match_operand:HI 0 "register_operand" "=a")
7306 (mod:HI (match_operand:HI 1 "register_operand" "0")
7308 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7312 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7313 (clobber (reg:CC FLAGS_REG))]
7314 "TARGET_QIMODE_MATH"
7316 [(set_attr "type" "idiv")
7317 (set_attr "mode" "QI")])
7319 ;; We cannot use div/idiv for double division, because it causes
7320 ;; "division by zero" on the overflow and that's not what we expect
7321 ;; from truncate. Because true (non truncating) double division is
7322 ;; never generated, we can't create this insn anyway.
7325 ; [(set (match_operand:SI 0 "register_operand" "=a")
7327 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7329 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7330 ; (set (match_operand:SI 3 "register_operand" "=d")
7332 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7333 ; (clobber (reg:CC FLAGS_REG))]
7335 ; "div{l}\t{%2, %0|%0, %2}"
7336 ; [(set_attr "type" "idiv")])
7338 ;;- Logical AND instructions
7340 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7341 ;; Note that this excludes ah.
7343 (define_expand "testsi_ccno_1"
7344 [(set (reg:CCNO FLAGS_REG)
7346 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7347 (match_operand:SI 1 "x86_64_nonmemory_operand" ""))
7350 (define_expand "testqi_ccz_1"
7351 [(set (reg:CCZ FLAGS_REG)
7352 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7353 (match_operand:QI 1 "nonmemory_operand" ""))
7356 (define_expand "testdi_ccno_1"
7357 [(set (reg:CCNO FLAGS_REG)
7359 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7360 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7362 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7364 (define_insn "*testdi_1"
7365 [(set (reg FLAGS_REG)
7368 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7369 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7371 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7372 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7374 test{l}\t{%k1, %k0|%k0, %k1}
7375 test{l}\t{%k1, %k0|%k0, %k1}
7376 test{q}\t{%1, %0|%0, %1}
7377 test{q}\t{%1, %0|%0, %1}
7378 test{q}\t{%1, %0|%0, %1}"
7379 [(set_attr "type" "test")
7380 (set_attr "modrm" "0,1,0,1,1")
7381 (set_attr "mode" "SI,SI,DI,DI,DI")])
7383 (define_insn "*testqi_1_maybe_si"
7384 [(set (reg FLAGS_REG)
7387 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7388 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7390 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7391 && ix86_match_ccmode (insn,
7392 CONST_INT_P (operands[1])
7393 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7395 if (which_alternative == 3)
7397 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7398 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7399 return "test{l}\t{%1, %k0|%k0, %1}";
7401 return "test{b}\t{%1, %0|%0, %1}";
7403 [(set_attr "type" "test")
7404 (set_attr "modrm" "0,1,1,1")
7405 (set_attr "mode" "QI,QI,QI,SI")
7406 (set_attr "pent_pair" "uv,np,uv,np")])
7408 (define_insn "*test<mode>_1"
7409 [(set (reg FLAGS_REG)
7412 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7413 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7415 "ix86_match_ccmode (insn, CCNOmode)
7416 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7417 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7418 [(set_attr "type" "test")
7419 (set_attr "modrm" "0,1,1")
7420 (set_attr "mode" "<MODE>")
7421 (set_attr "pent_pair" "uv,np,uv")])
7423 (define_expand "testqi_ext_ccno_0"
7424 [(set (reg:CCNO FLAGS_REG)
7428 (match_operand 0 "ext_register_operand" "")
7431 (match_operand 1 "const_int_operand" ""))
7434 (define_insn "*testqi_ext_0"
7435 [(set (reg FLAGS_REG)
7439 (match_operand 0 "ext_register_operand" "Q")
7442 (match_operand 1 "const_int_operand" "n"))
7444 "ix86_match_ccmode (insn, CCNOmode)"
7445 "test{b}\t{%1, %h0|%h0, %1}"
7446 [(set_attr "type" "test")
7447 (set_attr "mode" "QI")
7448 (set_attr "length_immediate" "1")
7449 (set_attr "modrm" "1")
7450 (set_attr "pent_pair" "np")])
7452 (define_insn "*testqi_ext_1_rex64"
7453 [(set (reg FLAGS_REG)
7457 (match_operand 0 "ext_register_operand" "Q")
7461 (match_operand:QI 1 "register_operand" "Q")))
7463 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7464 "test{b}\t{%1, %h0|%h0, %1}"
7465 [(set_attr "type" "test")
7466 (set_attr "mode" "QI")])
7468 (define_insn "*testqi_ext_1"
7469 [(set (reg FLAGS_REG)
7473 (match_operand 0 "ext_register_operand" "Q")
7477 (match_operand:QI 1 "general_operand" "Qm")))
7479 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7480 "test{b}\t{%1, %h0|%h0, %1}"
7481 [(set_attr "type" "test")
7482 (set_attr "mode" "QI")])
7484 (define_insn "*testqi_ext_2"
7485 [(set (reg FLAGS_REG)
7489 (match_operand 0 "ext_register_operand" "Q")
7493 (match_operand 1 "ext_register_operand" "Q")
7497 "ix86_match_ccmode (insn, CCNOmode)"
7498 "test{b}\t{%h1, %h0|%h0, %h1}"
7499 [(set_attr "type" "test")
7500 (set_attr "mode" "QI")])
7502 (define_insn "*testqi_ext_3_rex64"
7503 [(set (reg FLAGS_REG)
7504 (compare (zero_extract:DI
7505 (match_operand 0 "nonimmediate_operand" "rm")
7506 (match_operand:DI 1 "const_int_operand" "")
7507 (match_operand:DI 2 "const_int_operand" ""))
7510 && ix86_match_ccmode (insn, CCNOmode)
7511 && INTVAL (operands[1]) > 0
7512 && INTVAL (operands[2]) >= 0
7513 /* Ensure that resulting mask is zero or sign extended operand. */
7514 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7515 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7516 && INTVAL (operands[1]) > 32))
7517 && (GET_MODE (operands[0]) == SImode
7518 || GET_MODE (operands[0]) == DImode
7519 || GET_MODE (operands[0]) == HImode
7520 || GET_MODE (operands[0]) == QImode)"
7523 ;; Combine likes to form bit extractions for some tests. Humor it.
7524 (define_insn "*testqi_ext_3"
7525 [(set (reg FLAGS_REG)
7526 (compare (zero_extract:SI
7527 (match_operand 0 "nonimmediate_operand" "rm")
7528 (match_operand:SI 1 "const_int_operand" "")
7529 (match_operand:SI 2 "const_int_operand" ""))
7531 "ix86_match_ccmode (insn, CCNOmode)
7532 && INTVAL (operands[1]) > 0
7533 && INTVAL (operands[2]) >= 0
7534 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7535 && (GET_MODE (operands[0]) == SImode
7536 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7537 || GET_MODE (operands[0]) == HImode
7538 || GET_MODE (operands[0]) == QImode)"
7542 [(set (match_operand 0 "flags_reg_operand" "")
7543 (match_operator 1 "compare_operator"
7545 (match_operand 2 "nonimmediate_operand" "")
7546 (match_operand 3 "const_int_operand" "")
7547 (match_operand 4 "const_int_operand" ""))
7549 "ix86_match_ccmode (insn, CCNOmode)"
7550 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7552 rtx val = operands[2];
7553 HOST_WIDE_INT len = INTVAL (operands[3]);
7554 HOST_WIDE_INT pos = INTVAL (operands[4]);
7556 enum machine_mode mode, submode;
7558 mode = GET_MODE (val);
7561 /* ??? Combine likes to put non-volatile mem extractions in QImode
7562 no matter the size of the test. So find a mode that works. */
7563 if (! MEM_VOLATILE_P (val))
7565 mode = smallest_mode_for_size (pos + len, MODE_INT);
7566 val = adjust_address (val, mode, 0);
7569 else if (GET_CODE (val) == SUBREG
7570 && (submode = GET_MODE (SUBREG_REG (val)),
7571 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7572 && pos + len <= GET_MODE_BITSIZE (submode)
7573 && GET_MODE_CLASS (submode) == MODE_INT)
7575 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7577 val = SUBREG_REG (val);
7579 else if (mode == HImode && pos + len <= 8)
7581 /* Small HImode tests can be converted to QImode. */
7583 val = gen_lowpart (QImode, val);
7586 if (len == HOST_BITS_PER_WIDE_INT)
7589 mask = ((HOST_WIDE_INT)1 << len) - 1;
7592 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7595 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7596 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7597 ;; this is relatively important trick.
7598 ;; Do the conversion only post-reload to avoid limiting of the register class
7601 [(set (match_operand 0 "flags_reg_operand" "")
7602 (match_operator 1 "compare_operator"
7603 [(and (match_operand 2 "register_operand" "")
7604 (match_operand 3 "const_int_operand" ""))
7607 && QI_REG_P (operands[2])
7608 && GET_MODE (operands[2]) != QImode
7609 && ((ix86_match_ccmode (insn, CCZmode)
7610 && !(INTVAL (operands[3]) & ~(255 << 8)))
7611 || (ix86_match_ccmode (insn, CCNOmode)
7612 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7615 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7619 operands[2] = gen_lowpart (SImode, operands[2]);
7620 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7624 [(set (match_operand 0 "flags_reg_operand" "")
7625 (match_operator 1 "compare_operator"
7626 [(and (match_operand 2 "nonimmediate_operand" "")
7627 (match_operand 3 "const_int_operand" ""))
7630 && GET_MODE (operands[2]) != QImode
7631 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7632 && ((ix86_match_ccmode (insn, CCZmode)
7633 && !(INTVAL (operands[3]) & ~255))
7634 || (ix86_match_ccmode (insn, CCNOmode)
7635 && !(INTVAL (operands[3]) & ~127)))"
7637 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7640 operands[2] = gen_lowpart (QImode, operands[2]);
7641 operands[3] = gen_lowpart (QImode, operands[3]);
7644 ;; %%% This used to optimize known byte-wide and operations to memory,
7645 ;; and sometimes to QImode registers. If this is considered useful,
7646 ;; it should be done with splitters.
7648 (define_expand "and<mode>3"
7649 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7650 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7651 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7653 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7655 (define_insn "*anddi_1"
7656 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7658 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7659 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7660 (clobber (reg:CC FLAGS_REG))]
7661 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7663 switch (get_attr_type (insn))
7669 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7670 if (get_attr_mode (insn) == MODE_SI)
7671 return "and{l}\t{%k2, %k0|%k0, %k2}";
7673 return "and{q}\t{%2, %0|%0, %2}";
7676 [(set_attr "type" "alu,alu,alu,imovx")
7677 (set_attr "length_immediate" "*,*,*,0")
7678 (set (attr "prefix_rex")
7680 (and (eq_attr "type" "imovx")
7681 (and (match_test "INTVAL (operands[2]) == 0xff")
7682 (match_operand 1 "ext_QIreg_operand" "")))
7684 (const_string "*")))
7685 (set_attr "mode" "SI,DI,DI,SI")])
7687 (define_insn "*andsi_1"
7688 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya")
7689 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7690 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7691 (clobber (reg:CC FLAGS_REG))]
7692 "ix86_binary_operator_ok (AND, SImode, operands)"
7694 switch (get_attr_type (insn))
7700 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7701 return "and{l}\t{%2, %0|%0, %2}";
7704 [(set_attr "type" "alu,alu,imovx")
7705 (set (attr "prefix_rex")
7707 (and (eq_attr "type" "imovx")
7708 (and (match_test "INTVAL (operands[2]) == 0xff")
7709 (match_operand 1 "ext_QIreg_operand" "")))
7711 (const_string "*")))
7712 (set_attr "length_immediate" "*,*,0")
7713 (set_attr "mode" "SI")])
7715 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7716 (define_insn "*andsi_1_zext"
7717 [(set (match_operand:DI 0 "register_operand" "=r")
7719 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7720 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7721 (clobber (reg:CC FLAGS_REG))]
7722 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7723 "and{l}\t{%2, %k0|%k0, %2}"
7724 [(set_attr "type" "alu")
7725 (set_attr "mode" "SI")])
7727 (define_insn "*andhi_1"
7728 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya")
7729 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7730 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7731 (clobber (reg:CC FLAGS_REG))]
7732 "ix86_binary_operator_ok (AND, HImode, operands)"
7734 switch (get_attr_type (insn))
7740 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7741 return "and{w}\t{%2, %0|%0, %2}";
7744 [(set_attr "type" "alu,alu,imovx")
7745 (set_attr "length_immediate" "*,*,0")
7746 (set (attr "prefix_rex")
7748 (and (eq_attr "type" "imovx")
7749 (match_operand 1 "ext_QIreg_operand" ""))
7751 (const_string "*")))
7752 (set_attr "mode" "HI,HI,SI")])
7754 ;; %%% Potential partial reg stall on alternative 2. What to do?
7755 (define_insn "*andqi_1"
7756 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7757 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7758 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7759 (clobber (reg:CC FLAGS_REG))]
7760 "ix86_binary_operator_ok (AND, QImode, operands)"
7762 and{b}\t{%2, %0|%0, %2}
7763 and{b}\t{%2, %0|%0, %2}
7764 and{l}\t{%k2, %k0|%k0, %k2}"
7765 [(set_attr "type" "alu")
7766 (set_attr "mode" "QI,QI,SI")])
7768 (define_insn "*andqi_1_slp"
7769 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7770 (and:QI (match_dup 0)
7771 (match_operand:QI 1 "general_operand" "qn,qmn")))
7772 (clobber (reg:CC FLAGS_REG))]
7773 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7774 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7775 "and{b}\t{%1, %0|%0, %1}"
7776 [(set_attr "type" "alu1")
7777 (set_attr "mode" "QI")])
7780 [(set (match_operand:SWI248 0 "register_operand" "")
7781 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "")
7782 (match_operand:SWI248 2 "const_int_operand" "")))
7783 (clobber (reg:CC FLAGS_REG))]
7785 && true_regnum (operands[0]) != true_regnum (operands[1])"
7788 enum machine_mode mode;
7790 if (INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffffffff)
7792 else if (INTVAL (operands[2]) == 0xffff)
7796 gcc_assert (INTVAL (operands[2]) == 0xff);
7800 operands[1] = gen_lowpart (mode, operands[1]);
7803 emit_insn (gen_zero_extendsidi2 (operands[0], operands[1]));
7806 rtx (*insn) (rtx, rtx);
7808 /* Zero extend to SImode to avoid partial register stalls. */
7809 operands[0] = gen_lowpart (SImode, operands[0]);
7811 insn = (mode == HImode) ? gen_zero_extendhisi2 : gen_zero_extendqisi2;
7812 emit_insn (insn (operands[0], operands[1]));
7818 [(set (match_operand 0 "register_operand" "")
7820 (const_int -65536)))
7821 (clobber (reg:CC FLAGS_REG))]
7822 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7823 || optimize_function_for_size_p (cfun)"
7824 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7825 "operands[1] = gen_lowpart (HImode, operands[0]);")
7828 [(set (match_operand 0 "ext_register_operand" "")
7831 (clobber (reg:CC FLAGS_REG))]
7832 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7833 && reload_completed"
7834 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7835 "operands[1] = gen_lowpart (QImode, operands[0]);")
7838 [(set (match_operand 0 "ext_register_operand" "")
7840 (const_int -65281)))
7841 (clobber (reg:CC FLAGS_REG))]
7842 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7843 && reload_completed"
7844 [(parallel [(set (zero_extract:SI (match_dup 0)
7848 (zero_extract:SI (match_dup 0)
7851 (zero_extract:SI (match_dup 0)
7854 (clobber (reg:CC FLAGS_REG))])]
7855 "operands[0] = gen_lowpart (SImode, operands[0]);")
7857 (define_insn "*anddi_2"
7858 [(set (reg FLAGS_REG)
7861 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7862 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7864 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7865 (and:DI (match_dup 1) (match_dup 2)))]
7866 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7867 && ix86_binary_operator_ok (AND, DImode, operands)"
7869 and{l}\t{%k2, %k0|%k0, %k2}
7870 and{q}\t{%2, %0|%0, %2}
7871 and{q}\t{%2, %0|%0, %2}"
7872 [(set_attr "type" "alu")
7873 (set_attr "mode" "SI,DI,DI")])
7875 (define_insn "*andqi_2_maybe_si"
7876 [(set (reg FLAGS_REG)
7878 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7879 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7881 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7882 (and:QI (match_dup 1) (match_dup 2)))]
7883 "ix86_binary_operator_ok (AND, QImode, operands)
7884 && ix86_match_ccmode (insn,
7885 CONST_INT_P (operands[2])
7886 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7888 if (which_alternative == 2)
7890 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7891 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7892 return "and{l}\t{%2, %k0|%k0, %2}";
7894 return "and{b}\t{%2, %0|%0, %2}";
7896 [(set_attr "type" "alu")
7897 (set_attr "mode" "QI,QI,SI")])
7899 (define_insn "*and<mode>_2"
7900 [(set (reg FLAGS_REG)
7901 (compare (and:SWI124
7902 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7903 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7905 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7906 (and:SWI124 (match_dup 1) (match_dup 2)))]
7907 "ix86_match_ccmode (insn, CCNOmode)
7908 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7909 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7910 [(set_attr "type" "alu")
7911 (set_attr "mode" "<MODE>")])
7913 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7914 (define_insn "*andsi_2_zext"
7915 [(set (reg FLAGS_REG)
7917 (match_operand:SI 1 "nonimmediate_operand" "%0")
7918 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7920 (set (match_operand:DI 0 "register_operand" "=r")
7921 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7922 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7923 && ix86_binary_operator_ok (AND, SImode, operands)"
7924 "and{l}\t{%2, %k0|%k0, %2}"
7925 [(set_attr "type" "alu")
7926 (set_attr "mode" "SI")])
7928 (define_insn "*andqi_2_slp"
7929 [(set (reg FLAGS_REG)
7931 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7932 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
7934 (set (strict_low_part (match_dup 0))
7935 (and:QI (match_dup 0) (match_dup 1)))]
7936 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7937 && ix86_match_ccmode (insn, CCNOmode)
7938 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7939 "and{b}\t{%1, %0|%0, %1}"
7940 [(set_attr "type" "alu1")
7941 (set_attr "mode" "QI")])
7943 ;; ??? A bug in recog prevents it from recognizing a const_int as an
7944 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
7945 ;; for a QImode operand, which of course failed.
7946 (define_insn "andqi_ext_0"
7947 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7952 (match_operand 1 "ext_register_operand" "0")
7955 (match_operand 2 "const_int_operand" "n")))
7956 (clobber (reg:CC FLAGS_REG))]
7958 "and{b}\t{%2, %h0|%h0, %2}"
7959 [(set_attr "type" "alu")
7960 (set_attr "length_immediate" "1")
7961 (set_attr "modrm" "1")
7962 (set_attr "mode" "QI")])
7964 ;; Generated by peephole translating test to and. This shows up
7965 ;; often in fp comparisons.
7966 (define_insn "*andqi_ext_0_cc"
7967 [(set (reg FLAGS_REG)
7971 (match_operand 1 "ext_register_operand" "0")
7974 (match_operand 2 "const_int_operand" "n"))
7976 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7985 "ix86_match_ccmode (insn, CCNOmode)"
7986 "and{b}\t{%2, %h0|%h0, %2}"
7987 [(set_attr "type" "alu")
7988 (set_attr "length_immediate" "1")
7989 (set_attr "modrm" "1")
7990 (set_attr "mode" "QI")])
7992 (define_insn "*andqi_ext_1_rex64"
7993 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7998 (match_operand 1 "ext_register_operand" "0")
8002 (match_operand 2 "ext_register_operand" "Q"))))
8003 (clobber (reg:CC FLAGS_REG))]
8005 "and{b}\t{%2, %h0|%h0, %2}"
8006 [(set_attr "type" "alu")
8007 (set_attr "length_immediate" "0")
8008 (set_attr "mode" "QI")])
8010 (define_insn "*andqi_ext_1"
8011 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8016 (match_operand 1 "ext_register_operand" "0")
8020 (match_operand:QI 2 "general_operand" "Qm"))))
8021 (clobber (reg:CC FLAGS_REG))]
8023 "and{b}\t{%2, %h0|%h0, %2}"
8024 [(set_attr "type" "alu")
8025 (set_attr "length_immediate" "0")
8026 (set_attr "mode" "QI")])
8028 (define_insn "*andqi_ext_2"
8029 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8034 (match_operand 1 "ext_register_operand" "%0")
8038 (match_operand 2 "ext_register_operand" "Q")
8041 (clobber (reg:CC FLAGS_REG))]
8043 "and{b}\t{%h2, %h0|%h0, %h2}"
8044 [(set_attr "type" "alu")
8045 (set_attr "length_immediate" "0")
8046 (set_attr "mode" "QI")])
8048 ;; Convert wide AND instructions with immediate operand to shorter QImode
8049 ;; equivalents when possible.
8050 ;; Don't do the splitting with memory operands, since it introduces risk
8051 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8052 ;; for size, but that can (should?) be handled by generic code instead.
8054 [(set (match_operand 0 "register_operand" "")
8055 (and (match_operand 1 "register_operand" "")
8056 (match_operand 2 "const_int_operand" "")))
8057 (clobber (reg:CC FLAGS_REG))]
8059 && QI_REG_P (operands[0])
8060 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8061 && !(~INTVAL (operands[2]) & ~(255 << 8))
8062 && GET_MODE (operands[0]) != QImode"
8063 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8064 (and:SI (zero_extract:SI (match_dup 1)
8065 (const_int 8) (const_int 8))
8067 (clobber (reg:CC FLAGS_REG))])]
8069 operands[0] = gen_lowpart (SImode, operands[0]);
8070 operands[1] = gen_lowpart (SImode, operands[1]);
8071 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8074 ;; Since AND can be encoded with sign extended immediate, this is only
8075 ;; profitable when 7th bit is not set.
8077 [(set (match_operand 0 "register_operand" "")
8078 (and (match_operand 1 "general_operand" "")
8079 (match_operand 2 "const_int_operand" "")))
8080 (clobber (reg:CC FLAGS_REG))]
8082 && ANY_QI_REG_P (operands[0])
8083 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8084 && !(~INTVAL (operands[2]) & ~255)
8085 && !(INTVAL (operands[2]) & 128)
8086 && GET_MODE (operands[0]) != QImode"
8087 [(parallel [(set (strict_low_part (match_dup 0))
8088 (and:QI (match_dup 1)
8090 (clobber (reg:CC FLAGS_REG))])]
8092 operands[0] = gen_lowpart (QImode, operands[0]);
8093 operands[1] = gen_lowpart (QImode, operands[1]);
8094 operands[2] = gen_lowpart (QImode, operands[2]);
8097 ;; Logical inclusive and exclusive OR instructions
8099 ;; %%% This used to optimize known byte-wide and operations to memory.
8100 ;; If this is considered useful, it should be done with splitters.
8102 (define_expand "<code><mode>3"
8103 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8104 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8105 (match_operand:SWIM 2 "<general_operand>" "")))]
8107 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8109 (define_insn "*<code><mode>_1"
8110 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8112 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8113 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8114 (clobber (reg:CC FLAGS_REG))]
8115 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8116 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8117 [(set_attr "type" "alu")
8118 (set_attr "mode" "<MODE>")])
8120 ;; %%% Potential partial reg stall on alternative 2. What to do?
8121 (define_insn "*<code>qi_1"
8122 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8123 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8124 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8125 (clobber (reg:CC FLAGS_REG))]
8126 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8128 <logic>{b}\t{%2, %0|%0, %2}
8129 <logic>{b}\t{%2, %0|%0, %2}
8130 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8131 [(set_attr "type" "alu")
8132 (set_attr "mode" "QI,QI,SI")])
8134 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8135 (define_insn "*<code>si_1_zext"
8136 [(set (match_operand:DI 0 "register_operand" "=r")
8138 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8139 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8140 (clobber (reg:CC FLAGS_REG))]
8141 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8142 "<logic>{l}\t{%2, %k0|%k0, %2}"
8143 [(set_attr "type" "alu")
8144 (set_attr "mode" "SI")])
8146 (define_insn "*<code>si_1_zext_imm"
8147 [(set (match_operand:DI 0 "register_operand" "=r")
8149 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8150 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8151 (clobber (reg:CC FLAGS_REG))]
8152 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8153 "<logic>{l}\t{%2, %k0|%k0, %2}"
8154 [(set_attr "type" "alu")
8155 (set_attr "mode" "SI")])
8157 (define_insn "*<code>qi_1_slp"
8158 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8159 (any_or:QI (match_dup 0)
8160 (match_operand:QI 1 "general_operand" "qmn,qn")))
8161 (clobber (reg:CC FLAGS_REG))]
8162 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8163 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8164 "<logic>{b}\t{%1, %0|%0, %1}"
8165 [(set_attr "type" "alu1")
8166 (set_attr "mode" "QI")])
8168 (define_insn "*<code><mode>_2"
8169 [(set (reg FLAGS_REG)
8170 (compare (any_or:SWI
8171 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8172 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8174 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8175 (any_or:SWI (match_dup 1) (match_dup 2)))]
8176 "ix86_match_ccmode (insn, CCNOmode)
8177 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8178 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8179 [(set_attr "type" "alu")
8180 (set_attr "mode" "<MODE>")])
8182 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8183 ;; ??? Special case for immediate operand is missing - it is tricky.
8184 (define_insn "*<code>si_2_zext"
8185 [(set (reg FLAGS_REG)
8186 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8187 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8189 (set (match_operand:DI 0 "register_operand" "=r")
8190 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8191 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8192 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8193 "<logic>{l}\t{%2, %k0|%k0, %2}"
8194 [(set_attr "type" "alu")
8195 (set_attr "mode" "SI")])
8197 (define_insn "*<code>si_2_zext_imm"
8198 [(set (reg FLAGS_REG)
8200 (match_operand:SI 1 "nonimmediate_operand" "%0")
8201 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8203 (set (match_operand:DI 0 "register_operand" "=r")
8204 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8205 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8206 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8207 "<logic>{l}\t{%2, %k0|%k0, %2}"
8208 [(set_attr "type" "alu")
8209 (set_attr "mode" "SI")])
8211 (define_insn "*<code>qi_2_slp"
8212 [(set (reg FLAGS_REG)
8213 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8214 (match_operand:QI 1 "general_operand" "qmn,qn"))
8216 (set (strict_low_part (match_dup 0))
8217 (any_or:QI (match_dup 0) (match_dup 1)))]
8218 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8219 && ix86_match_ccmode (insn, CCNOmode)
8220 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8221 "<logic>{b}\t{%1, %0|%0, %1}"
8222 [(set_attr "type" "alu1")
8223 (set_attr "mode" "QI")])
8225 (define_insn "*<code><mode>_3"
8226 [(set (reg FLAGS_REG)
8227 (compare (any_or:SWI
8228 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8229 (match_operand:SWI 2 "<general_operand>" "<g>"))
8231 (clobber (match_scratch:SWI 0 "=<r>"))]
8232 "ix86_match_ccmode (insn, CCNOmode)
8233 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8234 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8235 [(set_attr "type" "alu")
8236 (set_attr "mode" "<MODE>")])
8238 (define_insn "*<code>qi_ext_0"
8239 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8244 (match_operand 1 "ext_register_operand" "0")
8247 (match_operand 2 "const_int_operand" "n")))
8248 (clobber (reg:CC FLAGS_REG))]
8249 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8250 "<logic>{b}\t{%2, %h0|%h0, %2}"
8251 [(set_attr "type" "alu")
8252 (set_attr "length_immediate" "1")
8253 (set_attr "modrm" "1")
8254 (set_attr "mode" "QI")])
8256 (define_insn "*<code>qi_ext_1_rex64"
8257 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8262 (match_operand 1 "ext_register_operand" "0")
8266 (match_operand 2 "ext_register_operand" "Q"))))
8267 (clobber (reg:CC FLAGS_REG))]
8269 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8270 "<logic>{b}\t{%2, %h0|%h0, %2}"
8271 [(set_attr "type" "alu")
8272 (set_attr "length_immediate" "0")
8273 (set_attr "mode" "QI")])
8275 (define_insn "*<code>qi_ext_1"
8276 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8281 (match_operand 1 "ext_register_operand" "0")
8285 (match_operand:QI 2 "general_operand" "Qm"))))
8286 (clobber (reg:CC FLAGS_REG))]
8288 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8289 "<logic>{b}\t{%2, %h0|%h0, %2}"
8290 [(set_attr "type" "alu")
8291 (set_attr "length_immediate" "0")
8292 (set_attr "mode" "QI")])
8294 (define_insn "*<code>qi_ext_2"
8295 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8299 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8302 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8305 (clobber (reg:CC FLAGS_REG))]
8306 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8307 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8308 [(set_attr "type" "alu")
8309 (set_attr "length_immediate" "0")
8310 (set_attr "mode" "QI")])
8313 [(set (match_operand 0 "register_operand" "")
8314 (any_or (match_operand 1 "register_operand" "")
8315 (match_operand 2 "const_int_operand" "")))
8316 (clobber (reg:CC FLAGS_REG))]
8318 && QI_REG_P (operands[0])
8319 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8320 && !(INTVAL (operands[2]) & ~(255 << 8))
8321 && GET_MODE (operands[0]) != QImode"
8322 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8323 (any_or:SI (zero_extract:SI (match_dup 1)
8324 (const_int 8) (const_int 8))
8326 (clobber (reg:CC FLAGS_REG))])]
8328 operands[0] = gen_lowpart (SImode, operands[0]);
8329 operands[1] = gen_lowpart (SImode, operands[1]);
8330 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8333 ;; Since OR can be encoded with sign extended immediate, this is only
8334 ;; profitable when 7th bit is set.
8336 [(set (match_operand 0 "register_operand" "")
8337 (any_or (match_operand 1 "general_operand" "")
8338 (match_operand 2 "const_int_operand" "")))
8339 (clobber (reg:CC FLAGS_REG))]
8341 && ANY_QI_REG_P (operands[0])
8342 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8343 && !(INTVAL (operands[2]) & ~255)
8344 && (INTVAL (operands[2]) & 128)
8345 && GET_MODE (operands[0]) != QImode"
8346 [(parallel [(set (strict_low_part (match_dup 0))
8347 (any_or:QI (match_dup 1)
8349 (clobber (reg:CC FLAGS_REG))])]
8351 operands[0] = gen_lowpart (QImode, operands[0]);
8352 operands[1] = gen_lowpart (QImode, operands[1]);
8353 operands[2] = gen_lowpart (QImode, operands[2]);
8356 (define_expand "xorqi_cc_ext_1"
8358 (set (reg:CCNO FLAGS_REG)
8362 (match_operand 1 "ext_register_operand" "")
8365 (match_operand:QI 2 "general_operand" ""))
8367 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8377 (define_insn "*xorqi_cc_ext_1_rex64"
8378 [(set (reg FLAGS_REG)
8382 (match_operand 1 "ext_register_operand" "0")
8385 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8387 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8396 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8397 "xor{b}\t{%2, %h0|%h0, %2}"
8398 [(set_attr "type" "alu")
8399 (set_attr "modrm" "1")
8400 (set_attr "mode" "QI")])
8402 (define_insn "*xorqi_cc_ext_1"
8403 [(set (reg FLAGS_REG)
8407 (match_operand 1 "ext_register_operand" "0")
8410 (match_operand:QI 2 "general_operand" "qmn"))
8412 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8421 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8422 "xor{b}\t{%2, %h0|%h0, %2}"
8423 [(set_attr "type" "alu")
8424 (set_attr "modrm" "1")
8425 (set_attr "mode" "QI")])
8427 ;; Negation instructions
8429 (define_expand "neg<mode>2"
8430 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8431 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8433 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8435 (define_insn_and_split "*neg<dwi>2_doubleword"
8436 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8437 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8438 (clobber (reg:CC FLAGS_REG))]
8439 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8443 [(set (reg:CCZ FLAGS_REG)
8444 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8445 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8448 (plus:DWIH (match_dup 3)
8449 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8451 (clobber (reg:CC FLAGS_REG))])
8454 (neg:DWIH (match_dup 2)))
8455 (clobber (reg:CC FLAGS_REG))])]
8456 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8458 (define_insn "*neg<mode>2_1"
8459 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8460 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8461 (clobber (reg:CC FLAGS_REG))]
8462 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8463 "neg{<imodesuffix>}\t%0"
8464 [(set_attr "type" "negnot")
8465 (set_attr "mode" "<MODE>")])
8467 ;; Combine is quite creative about this pattern.
8468 (define_insn "*negsi2_1_zext"
8469 [(set (match_operand:DI 0 "register_operand" "=r")
8471 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8474 (clobber (reg:CC FLAGS_REG))]
8475 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8477 [(set_attr "type" "negnot")
8478 (set_attr "mode" "SI")])
8480 ;; The problem with neg is that it does not perform (compare x 0),
8481 ;; it really performs (compare 0 x), which leaves us with the zero
8482 ;; flag being the only useful item.
8484 (define_insn "*neg<mode>2_cmpz"
8485 [(set (reg:CCZ FLAGS_REG)
8487 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8489 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8490 (neg:SWI (match_dup 1)))]
8491 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8492 "neg{<imodesuffix>}\t%0"
8493 [(set_attr "type" "negnot")
8494 (set_attr "mode" "<MODE>")])
8496 (define_insn "*negsi2_cmpz_zext"
8497 [(set (reg:CCZ FLAGS_REG)
8501 (match_operand:DI 1 "register_operand" "0")
8505 (set (match_operand:DI 0 "register_operand" "=r")
8506 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8509 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8511 [(set_attr "type" "negnot")
8512 (set_attr "mode" "SI")])
8514 ;; Changing of sign for FP values is doable using integer unit too.
8516 (define_expand "<code><mode>2"
8517 [(set (match_operand:X87MODEF 0 "register_operand" "")
8518 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8519 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8520 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8522 (define_insn "*absneg<mode>2_mixed"
8523 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8524 (match_operator:MODEF 3 "absneg_operator"
8525 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8526 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8527 (clobber (reg:CC FLAGS_REG))]
8528 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8531 (define_insn "*absneg<mode>2_sse"
8532 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8533 (match_operator:MODEF 3 "absneg_operator"
8534 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8535 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8536 (clobber (reg:CC FLAGS_REG))]
8537 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8540 (define_insn "*absneg<mode>2_i387"
8541 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8542 (match_operator:X87MODEF 3 "absneg_operator"
8543 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8544 (use (match_operand 2 "" ""))
8545 (clobber (reg:CC FLAGS_REG))]
8546 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8549 (define_expand "<code>tf2"
8550 [(set (match_operand:TF 0 "register_operand" "")
8551 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8553 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8555 (define_insn "*absnegtf2_sse"
8556 [(set (match_operand:TF 0 "register_operand" "=x,x")
8557 (match_operator:TF 3 "absneg_operator"
8558 [(match_operand:TF 1 "register_operand" "0,x")]))
8559 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8560 (clobber (reg:CC FLAGS_REG))]
8564 ;; Splitters for fp abs and neg.
8567 [(set (match_operand 0 "fp_register_operand" "")
8568 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8569 (use (match_operand 2 "" ""))
8570 (clobber (reg:CC FLAGS_REG))]
8572 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8575 [(set (match_operand 0 "register_operand" "")
8576 (match_operator 3 "absneg_operator"
8577 [(match_operand 1 "register_operand" "")]))
8578 (use (match_operand 2 "nonimmediate_operand" ""))
8579 (clobber (reg:CC FLAGS_REG))]
8580 "reload_completed && SSE_REG_P (operands[0])"
8581 [(set (match_dup 0) (match_dup 3))]
8583 enum machine_mode mode = GET_MODE (operands[0]);
8584 enum machine_mode vmode = GET_MODE (operands[2]);
8587 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8588 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8589 if (operands_match_p (operands[0], operands[2]))
8592 operands[1] = operands[2];
8595 if (GET_CODE (operands[3]) == ABS)
8596 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8598 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8603 [(set (match_operand:SF 0 "register_operand" "")
8604 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8605 (use (match_operand:V4SF 2 "" ""))
8606 (clobber (reg:CC FLAGS_REG))]
8608 [(parallel [(set (match_dup 0) (match_dup 1))
8609 (clobber (reg:CC FLAGS_REG))])]
8612 operands[0] = gen_lowpart (SImode, operands[0]);
8613 if (GET_CODE (operands[1]) == ABS)
8615 tmp = gen_int_mode (0x7fffffff, SImode);
8616 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8620 tmp = gen_int_mode (0x80000000, SImode);
8621 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8627 [(set (match_operand:DF 0 "register_operand" "")
8628 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8629 (use (match_operand 2 "" ""))
8630 (clobber (reg:CC FLAGS_REG))]
8632 [(parallel [(set (match_dup 0) (match_dup 1))
8633 (clobber (reg:CC FLAGS_REG))])]
8638 tmp = gen_lowpart (DImode, operands[0]);
8639 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8642 if (GET_CODE (operands[1]) == ABS)
8645 tmp = gen_rtx_NOT (DImode, tmp);
8649 operands[0] = gen_highpart (SImode, operands[0]);
8650 if (GET_CODE (operands[1]) == ABS)
8652 tmp = gen_int_mode (0x7fffffff, SImode);
8653 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8657 tmp = gen_int_mode (0x80000000, SImode);
8658 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8665 [(set (match_operand:XF 0 "register_operand" "")
8666 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8667 (use (match_operand 2 "" ""))
8668 (clobber (reg:CC FLAGS_REG))]
8670 [(parallel [(set (match_dup 0) (match_dup 1))
8671 (clobber (reg:CC FLAGS_REG))])]
8674 operands[0] = gen_rtx_REG (SImode,
8675 true_regnum (operands[0])
8676 + (TARGET_64BIT ? 1 : 2));
8677 if (GET_CODE (operands[1]) == ABS)
8679 tmp = GEN_INT (0x7fff);
8680 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8684 tmp = GEN_INT (0x8000);
8685 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8690 ;; Conditionalize these after reload. If they match before reload, we
8691 ;; lose the clobber and ability to use integer instructions.
8693 (define_insn "*<code><mode>2_1"
8694 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8695 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8697 && (reload_completed
8698 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8699 "f<absneg_mnemonic>"
8700 [(set_attr "type" "fsgn")
8701 (set_attr "mode" "<MODE>")])
8703 (define_insn "*<code>extendsfdf2"
8704 [(set (match_operand:DF 0 "register_operand" "=f")
8705 (absneg:DF (float_extend:DF
8706 (match_operand:SF 1 "register_operand" "0"))))]
8707 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8708 "f<absneg_mnemonic>"
8709 [(set_attr "type" "fsgn")
8710 (set_attr "mode" "DF")])
8712 (define_insn "*<code>extendsfxf2"
8713 [(set (match_operand:XF 0 "register_operand" "=f")
8714 (absneg:XF (float_extend:XF
8715 (match_operand:SF 1 "register_operand" "0"))))]
8717 "f<absneg_mnemonic>"
8718 [(set_attr "type" "fsgn")
8719 (set_attr "mode" "XF")])
8721 (define_insn "*<code>extenddfxf2"
8722 [(set (match_operand:XF 0 "register_operand" "=f")
8723 (absneg:XF (float_extend:XF
8724 (match_operand:DF 1 "register_operand" "0"))))]
8726 "f<absneg_mnemonic>"
8727 [(set_attr "type" "fsgn")
8728 (set_attr "mode" "XF")])
8730 ;; Copysign instructions
8732 (define_mode_iterator CSGNMODE [SF DF TF])
8733 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8735 (define_expand "copysign<mode>3"
8736 [(match_operand:CSGNMODE 0 "register_operand" "")
8737 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8738 (match_operand:CSGNMODE 2 "register_operand" "")]
8739 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8740 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8741 "ix86_expand_copysign (operands); DONE;")
8743 (define_insn_and_split "copysign<mode>3_const"
8744 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8746 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8747 (match_operand:CSGNMODE 2 "register_operand" "0")
8748 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8750 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8751 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8753 "&& reload_completed"
8755 "ix86_split_copysign_const (operands); DONE;")
8757 (define_insn "copysign<mode>3_var"
8758 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8760 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8761 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8762 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8763 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8765 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8766 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8767 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8771 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8773 [(match_operand:CSGNMODE 2 "register_operand" "")
8774 (match_operand:CSGNMODE 3 "register_operand" "")
8775 (match_operand:<CSGNVMODE> 4 "" "")
8776 (match_operand:<CSGNVMODE> 5 "" "")]
8778 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8779 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8780 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8781 && reload_completed"
8783 "ix86_split_copysign_var (operands); DONE;")
8785 ;; One complement instructions
8787 (define_expand "one_cmpl<mode>2"
8788 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8789 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8791 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8793 (define_insn "*one_cmpl<mode>2_1"
8794 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8795 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8796 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8797 "not{<imodesuffix>}\t%0"
8798 [(set_attr "type" "negnot")
8799 (set_attr "mode" "<MODE>")])
8801 ;; %%% Potential partial reg stall on alternative 1. What to do?
8802 (define_insn "*one_cmplqi2_1"
8803 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8804 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8805 "ix86_unary_operator_ok (NOT, QImode, operands)"
8809 [(set_attr "type" "negnot")
8810 (set_attr "mode" "QI,SI")])
8812 ;; ??? Currently never generated - xor is used instead.
8813 (define_insn "*one_cmplsi2_1_zext"
8814 [(set (match_operand:DI 0 "register_operand" "=r")
8816 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8817 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8819 [(set_attr "type" "negnot")
8820 (set_attr "mode" "SI")])
8822 (define_insn "*one_cmpl<mode>2_2"
8823 [(set (reg FLAGS_REG)
8824 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8826 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8827 (not:SWI (match_dup 1)))]
8828 "ix86_match_ccmode (insn, CCNOmode)
8829 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8831 [(set_attr "type" "alu1")
8832 (set_attr "mode" "<MODE>")])
8835 [(set (match_operand 0 "flags_reg_operand" "")
8836 (match_operator 2 "compare_operator"
8837 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8839 (set (match_operand:SWI 1 "nonimmediate_operand" "")
8840 (not:SWI (match_dup 3)))]
8841 "ix86_match_ccmode (insn, CCNOmode)"
8842 [(parallel [(set (match_dup 0)
8843 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8846 (xor:SWI (match_dup 3) (const_int -1)))])])
8848 ;; ??? Currently never generated - xor is used instead.
8849 (define_insn "*one_cmplsi2_2_zext"
8850 [(set (reg FLAGS_REG)
8851 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8853 (set (match_operand:DI 0 "register_operand" "=r")
8854 (zero_extend:DI (not:SI (match_dup 1))))]
8855 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8856 && ix86_unary_operator_ok (NOT, SImode, operands)"
8858 [(set_attr "type" "alu1")
8859 (set_attr "mode" "SI")])
8862 [(set (match_operand 0 "flags_reg_operand" "")
8863 (match_operator 2 "compare_operator"
8864 [(not:SI (match_operand:SI 3 "register_operand" ""))
8866 (set (match_operand:DI 1 "register_operand" "")
8867 (zero_extend:DI (not:SI (match_dup 3))))]
8868 "ix86_match_ccmode (insn, CCNOmode)"
8869 [(parallel [(set (match_dup 0)
8870 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8873 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8875 ;; Shift instructions
8877 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8878 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8879 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8880 ;; from the assembler input.
8882 ;; This instruction shifts the target reg/mem as usual, but instead of
8883 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8884 ;; is a left shift double, bits are taken from the high order bits of
8885 ;; reg, else if the insn is a shift right double, bits are taken from the
8886 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8887 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8889 ;; Since sh[lr]d does not change the `reg' operand, that is done
8890 ;; separately, making all shifts emit pairs of shift double and normal
8891 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8892 ;; support a 63 bit shift, each shift where the count is in a reg expands
8893 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8895 ;; If the shift count is a constant, we need never emit more than one
8896 ;; shift pair, instead using moves and sign extension for counts greater
8899 (define_expand "ashl<mode>3"
8900 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8901 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8902 (match_operand:QI 2 "nonmemory_operand" "")))]
8904 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8906 (define_insn "*ashl<mode>3_doubleword"
8907 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8908 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8909 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8910 (clobber (reg:CC FLAGS_REG))]
8913 [(set_attr "type" "multi")])
8916 [(set (match_operand:DWI 0 "register_operand" "")
8917 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8918 (match_operand:QI 2 "nonmemory_operand" "")))
8919 (clobber (reg:CC FLAGS_REG))]
8920 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8922 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8924 ;; By default we don't ask for a scratch register, because when DWImode
8925 ;; values are manipulated, registers are already at a premium. But if
8926 ;; we have one handy, we won't turn it away.
8929 [(match_scratch:DWIH 3 "r")
8930 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
8932 (match_operand:<DWI> 1 "nonmemory_operand" "")
8933 (match_operand:QI 2 "nonmemory_operand" "")))
8934 (clobber (reg:CC FLAGS_REG))])
8938 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
8940 (define_insn "x86_64_shld"
8941 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
8942 (ior:DI (ashift:DI (match_dup 0)
8943 (match_operand:QI 2 "nonmemory_operand" "Jc"))
8944 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8945 (minus:QI (const_int 64) (match_dup 2)))))
8946 (clobber (reg:CC FLAGS_REG))]
8948 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
8949 [(set_attr "type" "ishift")
8950 (set_attr "prefix_0f" "1")
8951 (set_attr "mode" "DI")
8952 (set_attr "athlon_decode" "vector")
8953 (set_attr "amdfam10_decode" "vector")
8954 (set_attr "bdver1_decode" "vector")])
8956 (define_insn "x86_shld"
8957 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
8958 (ior:SI (ashift:SI (match_dup 0)
8959 (match_operand:QI 2 "nonmemory_operand" "Ic"))
8960 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8961 (minus:QI (const_int 32) (match_dup 2)))))
8962 (clobber (reg:CC FLAGS_REG))]
8964 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
8965 [(set_attr "type" "ishift")
8966 (set_attr "prefix_0f" "1")
8967 (set_attr "mode" "SI")
8968 (set_attr "pent_pair" "np")
8969 (set_attr "athlon_decode" "vector")
8970 (set_attr "amdfam10_decode" "vector")
8971 (set_attr "bdver1_decode" "vector")])
8973 (define_expand "x86_shift<mode>_adj_1"
8974 [(set (reg:CCZ FLAGS_REG)
8975 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
8978 (set (match_operand:SWI48 0 "register_operand" "")
8979 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8980 (match_operand:SWI48 1 "register_operand" "")
8983 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8984 (match_operand:SWI48 3 "register_operand" "")
8987 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
8989 (define_expand "x86_shift<mode>_adj_2"
8990 [(use (match_operand:SWI48 0 "register_operand" ""))
8991 (use (match_operand:SWI48 1 "register_operand" ""))
8992 (use (match_operand:QI 2 "register_operand" ""))]
8995 rtx label = gen_label_rtx ();
8998 emit_insn (gen_testqi_ccz_1 (operands[2],
8999 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9001 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9002 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9003 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9004 gen_rtx_LABEL_REF (VOIDmode, label),
9006 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9007 JUMP_LABEL (tmp) = label;
9009 emit_move_insn (operands[0], operands[1]);
9010 ix86_expand_clear (operands[1]);
9013 LABEL_NUSES (label) = 1;
9018 ;; Avoid useless masking of count operand.
9019 (define_insn_and_split "*ashl<mode>3_mask"
9020 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9022 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9025 (match_operand:SI 2 "nonimmediate_operand" "c")
9026 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9027 (clobber (reg:CC FLAGS_REG))]
9028 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9029 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9030 == GET_MODE_BITSIZE (<MODE>mode)-1"
9033 [(parallel [(set (match_dup 0)
9034 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9035 (clobber (reg:CC FLAGS_REG))])]
9037 if (can_create_pseudo_p ())
9038 operands [2] = force_reg (SImode, operands[2]);
9040 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9042 [(set_attr "type" "ishift")
9043 (set_attr "mode" "<MODE>")])
9045 (define_insn "*bmi2_ashl<mode>3_1"
9046 [(set (match_operand:SWI48 0 "register_operand" "=r")
9047 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9048 (match_operand:SWI48 2 "register_operand" "r")))]
9050 "shlx\t{%2, %1, %0|%0, %1, %2}"
9051 [(set_attr "type" "ishiftx")
9052 (set_attr "mode" "<MODE>")])
9054 (define_insn "*ashl<mode>3_1"
9055 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9056 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9057 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9058 (clobber (reg:CC FLAGS_REG))]
9059 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9061 switch (get_attr_type (insn))
9068 gcc_assert (operands[2] == const1_rtx);
9069 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9070 return "add{<imodesuffix>}\t%0, %0";
9073 if (operands[2] == const1_rtx
9074 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9075 return "sal{<imodesuffix>}\t%0";
9077 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9080 [(set_attr "isa" "*,*,bmi2")
9082 (cond [(eq_attr "alternative" "1")
9083 (const_string "lea")
9084 (eq_attr "alternative" "2")
9085 (const_string "ishiftx")
9086 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9087 (match_operand 0 "register_operand" ""))
9088 (match_operand 2 "const1_operand" ""))
9089 (const_string "alu")
9091 (const_string "ishift")))
9092 (set (attr "length_immediate")
9094 (ior (eq_attr "type" "alu")
9095 (and (eq_attr "type" "ishift")
9096 (and (match_operand 2 "const1_operand" "")
9097 (ior (match_test "TARGET_SHIFT1")
9098 (match_test "optimize_function_for_size_p (cfun)")))))
9100 (const_string "*")))
9101 (set_attr "mode" "<MODE>")])
9103 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9105 [(set (match_operand:SWI48 0 "register_operand" "")
9106 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9107 (match_operand:QI 2 "register_operand" "")))
9108 (clobber (reg:CC FLAGS_REG))]
9109 "TARGET_BMI2 && reload_completed"
9111 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9112 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9114 (define_insn "*bmi2_ashlsi3_1_zext"
9115 [(set (match_operand:DI 0 "register_operand" "=r")
9117 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9118 (match_operand:SI 2 "register_operand" "r"))))]
9119 "TARGET_64BIT && TARGET_BMI2"
9120 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9121 [(set_attr "type" "ishiftx")
9122 (set_attr "mode" "SI")])
9124 (define_insn "*ashlsi3_1_zext"
9125 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9127 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9128 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9129 (clobber (reg:CC FLAGS_REG))]
9130 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9132 switch (get_attr_type (insn))
9139 gcc_assert (operands[2] == const1_rtx);
9140 return "add{l}\t%k0, %k0";
9143 if (operands[2] == const1_rtx
9144 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9145 return "sal{l}\t%k0";
9147 return "sal{l}\t{%2, %k0|%k0, %2}";
9150 [(set_attr "isa" "*,*,bmi2")
9152 (cond [(eq_attr "alternative" "1")
9153 (const_string "lea")
9154 (eq_attr "alternative" "2")
9155 (const_string "ishiftx")
9156 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9157 (match_operand 2 "const1_operand" ""))
9158 (const_string "alu")
9160 (const_string "ishift")))
9161 (set (attr "length_immediate")
9163 (ior (eq_attr "type" "alu")
9164 (and (eq_attr "type" "ishift")
9165 (and (match_operand 2 "const1_operand" "")
9166 (ior (match_test "TARGET_SHIFT1")
9167 (match_test "optimize_function_for_size_p (cfun)")))))
9169 (const_string "*")))
9170 (set_attr "mode" "SI")])
9172 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9174 [(set (match_operand:DI 0 "register_operand" "")
9176 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
9177 (match_operand:QI 2 "register_operand" ""))))
9178 (clobber (reg:CC FLAGS_REG))]
9179 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9181 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9182 "operands[2] = gen_lowpart (SImode, operands[2]);")
9184 (define_insn "*ashlhi3_1"
9185 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9186 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9187 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9188 (clobber (reg:CC FLAGS_REG))]
9189 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9191 switch (get_attr_type (insn))
9197 gcc_assert (operands[2] == const1_rtx);
9198 return "add{w}\t%0, %0";
9201 if (operands[2] == const1_rtx
9202 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9203 return "sal{w}\t%0";
9205 return "sal{w}\t{%2, %0|%0, %2}";
9209 (cond [(eq_attr "alternative" "1")
9210 (const_string "lea")
9211 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9212 (match_operand 0 "register_operand" ""))
9213 (match_operand 2 "const1_operand" ""))
9214 (const_string "alu")
9216 (const_string "ishift")))
9217 (set (attr "length_immediate")
9219 (ior (eq_attr "type" "alu")
9220 (and (eq_attr "type" "ishift")
9221 (and (match_operand 2 "const1_operand" "")
9222 (ior (match_test "TARGET_SHIFT1")
9223 (match_test "optimize_function_for_size_p (cfun)")))))
9225 (const_string "*")))
9226 (set_attr "mode" "HI,SI")])
9228 ;; %%% Potential partial reg stall on alternative 1. What to do?
9229 (define_insn "*ashlqi3_1"
9230 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9231 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9232 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9233 (clobber (reg:CC FLAGS_REG))]
9234 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9236 switch (get_attr_type (insn))
9242 gcc_assert (operands[2] == const1_rtx);
9243 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9244 return "add{l}\t%k0, %k0";
9246 return "add{b}\t%0, %0";
9249 if (operands[2] == const1_rtx
9250 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9252 if (get_attr_mode (insn) == MODE_SI)
9253 return "sal{l}\t%k0";
9255 return "sal{b}\t%0";
9259 if (get_attr_mode (insn) == MODE_SI)
9260 return "sal{l}\t{%2, %k0|%k0, %2}";
9262 return "sal{b}\t{%2, %0|%0, %2}";
9267 (cond [(eq_attr "alternative" "2")
9268 (const_string "lea")
9269 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9270 (match_operand 0 "register_operand" ""))
9271 (match_operand 2 "const1_operand" ""))
9272 (const_string "alu")
9274 (const_string "ishift")))
9275 (set (attr "length_immediate")
9277 (ior (eq_attr "type" "alu")
9278 (and (eq_attr "type" "ishift")
9279 (and (match_operand 2 "const1_operand" "")
9280 (ior (match_test "TARGET_SHIFT1")
9281 (match_test "optimize_function_for_size_p (cfun)")))))
9283 (const_string "*")))
9284 (set_attr "mode" "QI,SI,SI")])
9286 (define_insn "*ashlqi3_1_slp"
9287 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9288 (ashift:QI (match_dup 0)
9289 (match_operand:QI 1 "nonmemory_operand" "cI")))
9290 (clobber (reg:CC FLAGS_REG))]
9291 "(optimize_function_for_size_p (cfun)
9292 || !TARGET_PARTIAL_FLAG_REG_STALL
9293 || (operands[1] == const1_rtx
9295 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9297 switch (get_attr_type (insn))
9300 gcc_assert (operands[1] == const1_rtx);
9301 return "add{b}\t%0, %0";
9304 if (operands[1] == const1_rtx
9305 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9306 return "sal{b}\t%0";
9308 return "sal{b}\t{%1, %0|%0, %1}";
9312 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9313 (match_operand 0 "register_operand" ""))
9314 (match_operand 1 "const1_operand" ""))
9315 (const_string "alu")
9317 (const_string "ishift1")))
9318 (set (attr "length_immediate")
9320 (ior (eq_attr "type" "alu")
9321 (and (eq_attr "type" "ishift1")
9322 (and (match_operand 1 "const1_operand" "")
9323 (ior (match_test "TARGET_SHIFT1")
9324 (match_test "optimize_function_for_size_p (cfun)")))))
9326 (const_string "*")))
9327 (set_attr "mode" "QI")])
9329 ;; Convert ashift to the lea pattern to avoid flags dependency.
9331 [(set (match_operand 0 "register_operand" "")
9332 (ashift (match_operand 1 "index_register_operand" "")
9333 (match_operand:QI 2 "const_int_operand" "")))
9334 (clobber (reg:CC FLAGS_REG))]
9335 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9337 && true_regnum (operands[0]) != true_regnum (operands[1])"
9340 enum machine_mode mode = GET_MODE (operands[0]);
9343 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9346 operands[0] = gen_lowpart (mode, operands[0]);
9347 operands[1] = gen_lowpart (mode, operands[1]);
9350 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9352 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9354 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9358 ;; Convert ashift to the lea pattern to avoid flags dependency.
9360 [(set (match_operand:DI 0 "register_operand" "")
9362 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9363 (match_operand:QI 2 "const_int_operand" ""))))
9364 (clobber (reg:CC FLAGS_REG))]
9365 "TARGET_64BIT && reload_completed
9366 && true_regnum (operands[0]) != true_regnum (operands[1])"
9368 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9370 operands[1] = gen_lowpart (DImode, operands[1]);
9371 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9374 ;; This pattern can't accept a variable shift count, since shifts by
9375 ;; zero don't affect the flags. We assume that shifts by constant
9376 ;; zero are optimized away.
9377 (define_insn "*ashl<mode>3_cmp"
9378 [(set (reg FLAGS_REG)
9380 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9381 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9383 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9384 (ashift:SWI (match_dup 1) (match_dup 2)))]
9385 "(optimize_function_for_size_p (cfun)
9386 || !TARGET_PARTIAL_FLAG_REG_STALL
9387 || (operands[2] == const1_rtx
9389 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9390 && ix86_match_ccmode (insn, CCGOCmode)
9391 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9393 switch (get_attr_type (insn))
9396 gcc_assert (operands[2] == const1_rtx);
9397 return "add{<imodesuffix>}\t%0, %0";
9400 if (operands[2] == const1_rtx
9401 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9402 return "sal{<imodesuffix>}\t%0";
9404 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9408 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9409 (match_operand 0 "register_operand" ""))
9410 (match_operand 2 "const1_operand" ""))
9411 (const_string "alu")
9413 (const_string "ishift")))
9414 (set (attr "length_immediate")
9416 (ior (eq_attr "type" "alu")
9417 (and (eq_attr "type" "ishift")
9418 (and (match_operand 2 "const1_operand" "")
9419 (ior (match_test "TARGET_SHIFT1")
9420 (match_test "optimize_function_for_size_p (cfun)")))))
9422 (const_string "*")))
9423 (set_attr "mode" "<MODE>")])
9425 (define_insn "*ashlsi3_cmp_zext"
9426 [(set (reg FLAGS_REG)
9428 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9429 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9431 (set (match_operand:DI 0 "register_operand" "=r")
9432 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9434 && (optimize_function_for_size_p (cfun)
9435 || !TARGET_PARTIAL_FLAG_REG_STALL
9436 || (operands[2] == const1_rtx
9438 || TARGET_DOUBLE_WITH_ADD)))
9439 && ix86_match_ccmode (insn, CCGOCmode)
9440 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9442 switch (get_attr_type (insn))
9445 gcc_assert (operands[2] == const1_rtx);
9446 return "add{l}\t%k0, %k0";
9449 if (operands[2] == const1_rtx
9450 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9451 return "sal{l}\t%k0";
9453 return "sal{l}\t{%2, %k0|%k0, %2}";
9457 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9458 (match_operand 2 "const1_operand" ""))
9459 (const_string "alu")
9461 (const_string "ishift")))
9462 (set (attr "length_immediate")
9464 (ior (eq_attr "type" "alu")
9465 (and (eq_attr "type" "ishift")
9466 (and (match_operand 2 "const1_operand" "")
9467 (ior (match_test "TARGET_SHIFT1")
9468 (match_test "optimize_function_for_size_p (cfun)")))))
9470 (const_string "*")))
9471 (set_attr "mode" "SI")])
9473 (define_insn "*ashl<mode>3_cconly"
9474 [(set (reg FLAGS_REG)
9476 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9477 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9479 (clobber (match_scratch:SWI 0 "=<r>"))]
9480 "(optimize_function_for_size_p (cfun)
9481 || !TARGET_PARTIAL_FLAG_REG_STALL
9482 || (operands[2] == const1_rtx
9484 || TARGET_DOUBLE_WITH_ADD)))
9485 && ix86_match_ccmode (insn, CCGOCmode)"
9487 switch (get_attr_type (insn))
9490 gcc_assert (operands[2] == const1_rtx);
9491 return "add{<imodesuffix>}\t%0, %0";
9494 if (operands[2] == const1_rtx
9495 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9496 return "sal{<imodesuffix>}\t%0";
9498 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9502 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9503 (match_operand 0 "register_operand" ""))
9504 (match_operand 2 "const1_operand" ""))
9505 (const_string "alu")
9507 (const_string "ishift")))
9508 (set (attr "length_immediate")
9510 (ior (eq_attr "type" "alu")
9511 (and (eq_attr "type" "ishift")
9512 (and (match_operand 2 "const1_operand" "")
9513 (ior (match_test "TARGET_SHIFT1")
9514 (match_test "optimize_function_for_size_p (cfun)")))))
9516 (const_string "*")))
9517 (set_attr "mode" "<MODE>")])
9519 ;; See comment above `ashl<mode>3' about how this works.
9521 (define_expand "<shift_insn><mode>3"
9522 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9523 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9524 (match_operand:QI 2 "nonmemory_operand" "")))]
9526 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9528 ;; Avoid useless masking of count operand.
9529 (define_insn_and_split "*<shift_insn><mode>3_mask"
9530 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9532 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9535 (match_operand:SI 2 "nonimmediate_operand" "c")
9536 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9537 (clobber (reg:CC FLAGS_REG))]
9538 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9539 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9540 == GET_MODE_BITSIZE (<MODE>mode)-1"
9543 [(parallel [(set (match_dup 0)
9544 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9545 (clobber (reg:CC FLAGS_REG))])]
9547 if (can_create_pseudo_p ())
9548 operands [2] = force_reg (SImode, operands[2]);
9550 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9552 [(set_attr "type" "ishift")
9553 (set_attr "mode" "<MODE>")])
9555 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9556 [(set (match_operand:DWI 0 "register_operand" "=r")
9557 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9558 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9559 (clobber (reg:CC FLAGS_REG))]
9562 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9564 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9565 [(set_attr "type" "multi")])
9567 ;; By default we don't ask for a scratch register, because when DWImode
9568 ;; values are manipulated, registers are already at a premium. But if
9569 ;; we have one handy, we won't turn it away.
9572 [(match_scratch:DWIH 3 "r")
9573 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9575 (match_operand:<DWI> 1 "register_operand" "")
9576 (match_operand:QI 2 "nonmemory_operand" "")))
9577 (clobber (reg:CC FLAGS_REG))])
9581 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9583 (define_insn "x86_64_shrd"
9584 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9585 (ior:DI (ashiftrt:DI (match_dup 0)
9586 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9587 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9588 (minus:QI (const_int 64) (match_dup 2)))))
9589 (clobber (reg:CC FLAGS_REG))]
9591 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9592 [(set_attr "type" "ishift")
9593 (set_attr "prefix_0f" "1")
9594 (set_attr "mode" "DI")
9595 (set_attr "athlon_decode" "vector")
9596 (set_attr "amdfam10_decode" "vector")
9597 (set_attr "bdver1_decode" "vector")])
9599 (define_insn "x86_shrd"
9600 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9601 (ior:SI (ashiftrt:SI (match_dup 0)
9602 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9603 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9604 (minus:QI (const_int 32) (match_dup 2)))))
9605 (clobber (reg:CC FLAGS_REG))]
9607 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9608 [(set_attr "type" "ishift")
9609 (set_attr "prefix_0f" "1")
9610 (set_attr "mode" "SI")
9611 (set_attr "pent_pair" "np")
9612 (set_attr "athlon_decode" "vector")
9613 (set_attr "amdfam10_decode" "vector")
9614 (set_attr "bdver1_decode" "vector")])
9616 (define_insn "ashrdi3_cvt"
9617 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9618 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9619 (match_operand:QI 2 "const_int_operand" "")))
9620 (clobber (reg:CC FLAGS_REG))]
9621 "TARGET_64BIT && INTVAL (operands[2]) == 63
9622 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9623 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9626 sar{q}\t{%2, %0|%0, %2}"
9627 [(set_attr "type" "imovx,ishift")
9628 (set_attr "prefix_0f" "0,*")
9629 (set_attr "length_immediate" "0,*")
9630 (set_attr "modrm" "0,1")
9631 (set_attr "mode" "DI")])
9633 (define_insn "ashrsi3_cvt"
9634 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9635 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9636 (match_operand:QI 2 "const_int_operand" "")))
9637 (clobber (reg:CC FLAGS_REG))]
9638 "INTVAL (operands[2]) == 31
9639 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9640 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9643 sar{l}\t{%2, %0|%0, %2}"
9644 [(set_attr "type" "imovx,ishift")
9645 (set_attr "prefix_0f" "0,*")
9646 (set_attr "length_immediate" "0,*")
9647 (set_attr "modrm" "0,1")
9648 (set_attr "mode" "SI")])
9650 (define_insn "*ashrsi3_cvt_zext"
9651 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9653 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9654 (match_operand:QI 2 "const_int_operand" ""))))
9655 (clobber (reg:CC FLAGS_REG))]
9656 "TARGET_64BIT && INTVAL (operands[2]) == 31
9657 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9658 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9661 sar{l}\t{%2, %k0|%k0, %2}"
9662 [(set_attr "type" "imovx,ishift")
9663 (set_attr "prefix_0f" "0,*")
9664 (set_attr "length_immediate" "0,*")
9665 (set_attr "modrm" "0,1")
9666 (set_attr "mode" "SI")])
9668 (define_expand "x86_shift<mode>_adj_3"
9669 [(use (match_operand:SWI48 0 "register_operand" ""))
9670 (use (match_operand:SWI48 1 "register_operand" ""))
9671 (use (match_operand:QI 2 "register_operand" ""))]
9674 rtx label = gen_label_rtx ();
9677 emit_insn (gen_testqi_ccz_1 (operands[2],
9678 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9680 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9681 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9682 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9683 gen_rtx_LABEL_REF (VOIDmode, label),
9685 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9686 JUMP_LABEL (tmp) = label;
9688 emit_move_insn (operands[0], operands[1]);
9689 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9690 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9692 LABEL_NUSES (label) = 1;
9697 (define_insn "*bmi2_<shift_insn><mode>3_1"
9698 [(set (match_operand:SWI48 0 "register_operand" "=r")
9699 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9700 (match_operand:SWI48 2 "register_operand" "r")))]
9702 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9703 [(set_attr "type" "ishiftx")
9704 (set_attr "mode" "<MODE>")])
9706 (define_insn "*<shift_insn><mode>3_1"
9707 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9709 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9710 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9711 (clobber (reg:CC FLAGS_REG))]
9712 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9714 switch (get_attr_type (insn))
9720 if (operands[2] == const1_rtx
9721 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9722 return "<shift>{<imodesuffix>}\t%0";
9724 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9727 [(set_attr "isa" "*,bmi2")
9728 (set_attr "type" "ishift,ishiftx")
9729 (set (attr "length_immediate")
9731 (and (match_operand 2 "const1_operand" "")
9732 (ior (match_test "TARGET_SHIFT1")
9733 (match_test "optimize_function_for_size_p (cfun)")))
9735 (const_string "*")))
9736 (set_attr "mode" "<MODE>")])
9738 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9740 [(set (match_operand:SWI48 0 "register_operand" "")
9741 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9742 (match_operand:QI 2 "register_operand" "")))
9743 (clobber (reg:CC FLAGS_REG))]
9744 "TARGET_BMI2 && reload_completed"
9746 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9747 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9749 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9750 [(set (match_operand:DI 0 "register_operand" "=r")
9752 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9753 (match_operand:SI 2 "register_operand" "r"))))]
9754 "TARGET_64BIT && TARGET_BMI2"
9755 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9756 [(set_attr "type" "ishiftx")
9757 (set_attr "mode" "SI")])
9759 (define_insn "*<shift_insn>si3_1_zext"
9760 [(set (match_operand:DI 0 "register_operand" "=r,r")
9762 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9763 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9764 (clobber (reg:CC FLAGS_REG))]
9765 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9767 switch (get_attr_type (insn))
9773 if (operands[2] == const1_rtx
9774 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9775 return "<shift>{l}\t%k0";
9777 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9780 [(set_attr "isa" "*,bmi2")
9781 (set_attr "type" "ishift,ishiftx")
9782 (set (attr "length_immediate")
9784 (and (match_operand 2 "const1_operand" "")
9785 (ior (match_test "TARGET_SHIFT1")
9786 (match_test "optimize_function_for_size_p (cfun)")))
9788 (const_string "*")))
9789 (set_attr "mode" "SI")])
9791 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9793 [(set (match_operand:DI 0 "register_operand" "")
9795 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
9796 (match_operand:QI 2 "register_operand" ""))))
9797 (clobber (reg:CC FLAGS_REG))]
9798 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9800 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9801 "operands[2] = gen_lowpart (SImode, operands[2]);")
9803 (define_insn "*<shift_insn><mode>3_1"
9804 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9806 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9807 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9808 (clobber (reg:CC FLAGS_REG))]
9809 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9811 if (operands[2] == const1_rtx
9812 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9813 return "<shift>{<imodesuffix>}\t%0";
9815 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9817 [(set_attr "type" "ishift")
9818 (set (attr "length_immediate")
9820 (and (match_operand 2 "const1_operand" "")
9821 (ior (match_test "TARGET_SHIFT1")
9822 (match_test "optimize_function_for_size_p (cfun)")))
9824 (const_string "*")))
9825 (set_attr "mode" "<MODE>")])
9827 (define_insn "*<shift_insn>qi3_1_slp"
9828 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9829 (any_shiftrt:QI (match_dup 0)
9830 (match_operand:QI 1 "nonmemory_operand" "cI")))
9831 (clobber (reg:CC FLAGS_REG))]
9832 "(optimize_function_for_size_p (cfun)
9833 || !TARGET_PARTIAL_REG_STALL
9834 || (operands[1] == const1_rtx
9837 if (operands[1] == const1_rtx
9838 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9839 return "<shift>{b}\t%0";
9841 return "<shift>{b}\t{%1, %0|%0, %1}";
9843 [(set_attr "type" "ishift1")
9844 (set (attr "length_immediate")
9846 (and (match_operand 1 "const1_operand" "")
9847 (ior (match_test "TARGET_SHIFT1")
9848 (match_test "optimize_function_for_size_p (cfun)")))
9850 (const_string "*")))
9851 (set_attr "mode" "QI")])
9853 ;; This pattern can't accept a variable shift count, since shifts by
9854 ;; zero don't affect the flags. We assume that shifts by constant
9855 ;; zero are optimized away.
9856 (define_insn "*<shift_insn><mode>3_cmp"
9857 [(set (reg FLAGS_REG)
9860 (match_operand:SWI 1 "nonimmediate_operand" "0")
9861 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9863 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9864 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9865 "(optimize_function_for_size_p (cfun)
9866 || !TARGET_PARTIAL_FLAG_REG_STALL
9867 || (operands[2] == const1_rtx
9869 && ix86_match_ccmode (insn, CCGOCmode)
9870 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9872 if (operands[2] == const1_rtx
9873 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9874 return "<shift>{<imodesuffix>}\t%0";
9876 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9878 [(set_attr "type" "ishift")
9879 (set (attr "length_immediate")
9881 (and (match_operand 2 "const1_operand" "")
9882 (ior (match_test "TARGET_SHIFT1")
9883 (match_test "optimize_function_for_size_p (cfun)")))
9885 (const_string "*")))
9886 (set_attr "mode" "<MODE>")])
9888 (define_insn "*<shift_insn>si3_cmp_zext"
9889 [(set (reg FLAGS_REG)
9891 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9892 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9894 (set (match_operand:DI 0 "register_operand" "=r")
9895 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9897 && (optimize_function_for_size_p (cfun)
9898 || !TARGET_PARTIAL_FLAG_REG_STALL
9899 || (operands[2] == const1_rtx
9901 && ix86_match_ccmode (insn, CCGOCmode)
9902 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9904 if (operands[2] == const1_rtx
9905 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9906 return "<shift>{l}\t%k0";
9908 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9910 [(set_attr "type" "ishift")
9911 (set (attr "length_immediate")
9913 (and (match_operand 2 "const1_operand" "")
9914 (ior (match_test "TARGET_SHIFT1")
9915 (match_test "optimize_function_for_size_p (cfun)")))
9917 (const_string "*")))
9918 (set_attr "mode" "SI")])
9920 (define_insn "*<shift_insn><mode>3_cconly"
9921 [(set (reg FLAGS_REG)
9924 (match_operand:SWI 1 "register_operand" "0")
9925 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9927 (clobber (match_scratch:SWI 0 "=<r>"))]
9928 "(optimize_function_for_size_p (cfun)
9929 || !TARGET_PARTIAL_FLAG_REG_STALL
9930 || (operands[2] == const1_rtx
9932 && ix86_match_ccmode (insn, CCGOCmode)"
9934 if (operands[2] == const1_rtx
9935 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9936 return "<shift>{<imodesuffix>}\t%0";
9938 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9940 [(set_attr "type" "ishift")
9941 (set (attr "length_immediate")
9943 (and (match_operand 2 "const1_operand" "")
9944 (ior (match_test "TARGET_SHIFT1")
9945 (match_test "optimize_function_for_size_p (cfun)")))
9947 (const_string "*")))
9948 (set_attr "mode" "<MODE>")])
9950 ;; Rotate instructions
9952 (define_expand "<rotate_insn>ti3"
9953 [(set (match_operand:TI 0 "register_operand" "")
9954 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
9955 (match_operand:QI 2 "nonmemory_operand" "")))]
9958 if (const_1_to_63_operand (operands[2], VOIDmode))
9959 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
9960 (operands[0], operands[1], operands[2]));
9967 (define_expand "<rotate_insn>di3"
9968 [(set (match_operand:DI 0 "shiftdi_operand" "")
9969 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
9970 (match_operand:QI 2 "nonmemory_operand" "")))]
9974 ix86_expand_binary_operator (<CODE>, DImode, operands);
9975 else if (const_1_to_31_operand (operands[2], VOIDmode))
9976 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
9977 (operands[0], operands[1], operands[2]));
9984 (define_expand "<rotate_insn><mode>3"
9985 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
9986 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
9987 (match_operand:QI 2 "nonmemory_operand" "")))]
9989 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9991 ;; Avoid useless masking of count operand.
9992 (define_insn_and_split "*<rotate_insn><mode>3_mask"
9993 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9995 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9998 (match_operand:SI 2 "nonimmediate_operand" "c")
9999 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10000 (clobber (reg:CC FLAGS_REG))]
10001 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10002 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10003 == GET_MODE_BITSIZE (<MODE>mode)-1"
10006 [(parallel [(set (match_dup 0)
10007 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10008 (clobber (reg:CC FLAGS_REG))])]
10010 if (can_create_pseudo_p ())
10011 operands [2] = force_reg (SImode, operands[2]);
10013 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10015 [(set_attr "type" "rotate")
10016 (set_attr "mode" "<MODE>")])
10018 ;; Implement rotation using two double-precision
10019 ;; shift instructions and a scratch register.
10021 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10022 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10023 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10024 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10025 (clobber (reg:CC FLAGS_REG))
10026 (clobber (match_scratch:DWIH 3 "=&r"))]
10030 [(set (match_dup 3) (match_dup 4))
10032 [(set (match_dup 4)
10033 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10034 (lshiftrt:DWIH (match_dup 5)
10035 (minus:QI (match_dup 6) (match_dup 2)))))
10036 (clobber (reg:CC FLAGS_REG))])
10038 [(set (match_dup 5)
10039 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10040 (lshiftrt:DWIH (match_dup 3)
10041 (minus:QI (match_dup 6) (match_dup 2)))))
10042 (clobber (reg:CC FLAGS_REG))])]
10044 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10046 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10049 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10050 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10051 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10052 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10053 (clobber (reg:CC FLAGS_REG))
10054 (clobber (match_scratch:DWIH 3 "=&r"))]
10058 [(set (match_dup 3) (match_dup 4))
10060 [(set (match_dup 4)
10061 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10062 (ashift:DWIH (match_dup 5)
10063 (minus:QI (match_dup 6) (match_dup 2)))))
10064 (clobber (reg:CC FLAGS_REG))])
10066 [(set (match_dup 5)
10067 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10068 (ashift:DWIH (match_dup 3)
10069 (minus:QI (match_dup 6) (match_dup 2)))))
10070 (clobber (reg:CC FLAGS_REG))])]
10072 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10074 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10077 (define_insn "*bmi2_rorx<mode>3_1"
10078 [(set (match_operand:SWI48 0 "register_operand" "=r")
10079 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10080 (match_operand:QI 2 "immediate_operand" "<S>")))]
10082 "rorx\t{%2, %1, %0|%0, %1, %2}"
10083 [(set_attr "type" "rotatex")
10084 (set_attr "mode" "<MODE>")])
10086 (define_insn "*<rotate_insn><mode>3_1"
10087 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10089 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10090 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10091 (clobber (reg:CC FLAGS_REG))]
10092 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10094 switch (get_attr_type (insn))
10100 if (operands[2] == const1_rtx
10101 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10102 return "<rotate>{<imodesuffix>}\t%0";
10104 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10107 [(set_attr "isa" "*,bmi2")
10108 (set_attr "type" "rotate,rotatex")
10109 (set (attr "length_immediate")
10111 (and (eq_attr "type" "rotate")
10112 (and (match_operand 2 "const1_operand" "")
10113 (ior (match_test "TARGET_SHIFT1")
10114 (match_test "optimize_function_for_size_p (cfun)"))))
10116 (const_string "*")))
10117 (set_attr "mode" "<MODE>")])
10119 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10121 [(set (match_operand:SWI48 0 "register_operand" "")
10122 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10123 (match_operand:QI 2 "immediate_operand" "")))
10124 (clobber (reg:CC FLAGS_REG))]
10125 "TARGET_BMI2 && reload_completed"
10126 [(set (match_dup 0)
10127 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10130 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10134 [(set (match_operand:SWI48 0 "register_operand" "")
10135 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10136 (match_operand:QI 2 "immediate_operand" "")))
10137 (clobber (reg:CC FLAGS_REG))]
10138 "TARGET_BMI2 && reload_completed"
10139 [(set (match_dup 0)
10140 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10142 (define_insn "*bmi2_rorxsi3_1_zext"
10143 [(set (match_operand:DI 0 "register_operand" "=r")
10145 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10146 (match_operand:QI 2 "immediate_operand" "I"))))]
10147 "TARGET_64BIT && TARGET_BMI2"
10148 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10149 [(set_attr "type" "rotatex")
10150 (set_attr "mode" "SI")])
10152 (define_insn "*<rotate_insn>si3_1_zext"
10153 [(set (match_operand:DI 0 "register_operand" "=r,r")
10155 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10156 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10157 (clobber (reg:CC FLAGS_REG))]
10158 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10160 switch (get_attr_type (insn))
10166 if (operands[2] == const1_rtx
10167 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10168 return "<rotate>{l}\t%k0";
10170 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10173 [(set_attr "isa" "*,bmi2")
10174 (set_attr "type" "rotate,rotatex")
10175 (set (attr "length_immediate")
10177 (and (eq_attr "type" "rotate")
10178 (and (match_operand 2 "const1_operand" "")
10179 (ior (match_test "TARGET_SHIFT1")
10180 (match_test "optimize_function_for_size_p (cfun)"))))
10182 (const_string "*")))
10183 (set_attr "mode" "SI")])
10185 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10187 [(set (match_operand:DI 0 "register_operand" "")
10189 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
10190 (match_operand:QI 2 "immediate_operand" ""))))
10191 (clobber (reg:CC FLAGS_REG))]
10192 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10193 [(set (match_dup 0)
10194 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10197 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10201 [(set (match_operand:DI 0 "register_operand" "")
10203 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
10204 (match_operand:QI 2 "immediate_operand" ""))))
10205 (clobber (reg:CC FLAGS_REG))]
10206 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10207 [(set (match_dup 0)
10208 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10210 (define_insn "*<rotate_insn><mode>3_1"
10211 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10212 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10213 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10214 (clobber (reg:CC FLAGS_REG))]
10215 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10217 if (operands[2] == const1_rtx
10218 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10219 return "<rotate>{<imodesuffix>}\t%0";
10221 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10223 [(set_attr "type" "rotate")
10224 (set (attr "length_immediate")
10226 (and (match_operand 2 "const1_operand" "")
10227 (ior (match_test "TARGET_SHIFT1")
10228 (match_test "optimize_function_for_size_p (cfun)")))
10230 (const_string "*")))
10231 (set_attr "mode" "<MODE>")])
10233 (define_insn "*<rotate_insn>qi3_1_slp"
10234 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10235 (any_rotate:QI (match_dup 0)
10236 (match_operand:QI 1 "nonmemory_operand" "cI")))
10237 (clobber (reg:CC FLAGS_REG))]
10238 "(optimize_function_for_size_p (cfun)
10239 || !TARGET_PARTIAL_REG_STALL
10240 || (operands[1] == const1_rtx
10241 && TARGET_SHIFT1))"
10243 if (operands[1] == const1_rtx
10244 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10245 return "<rotate>{b}\t%0";
10247 return "<rotate>{b}\t{%1, %0|%0, %1}";
10249 [(set_attr "type" "rotate1")
10250 (set (attr "length_immediate")
10252 (and (match_operand 1 "const1_operand" "")
10253 (ior (match_test "TARGET_SHIFT1")
10254 (match_test "optimize_function_for_size_p (cfun)")))
10256 (const_string "*")))
10257 (set_attr "mode" "QI")])
10260 [(set (match_operand:HI 0 "register_operand" "")
10261 (any_rotate:HI (match_dup 0) (const_int 8)))
10262 (clobber (reg:CC FLAGS_REG))]
10264 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10265 [(parallel [(set (strict_low_part (match_dup 0))
10266 (bswap:HI (match_dup 0)))
10267 (clobber (reg:CC FLAGS_REG))])])
10269 ;; Bit set / bit test instructions
10271 (define_expand "extv"
10272 [(set (match_operand:SI 0 "register_operand" "")
10273 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10274 (match_operand:SI 2 "const8_operand" "")
10275 (match_operand:SI 3 "const8_operand" "")))]
10278 /* Handle extractions from %ah et al. */
10279 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10282 /* From mips.md: extract_bit_field doesn't verify that our source
10283 matches the predicate, so check it again here. */
10284 if (! ext_register_operand (operands[1], VOIDmode))
10288 (define_expand "extzv"
10289 [(set (match_operand:SI 0 "register_operand" "")
10290 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10291 (match_operand:SI 2 "const8_operand" "")
10292 (match_operand:SI 3 "const8_operand" "")))]
10295 /* Handle extractions from %ah et al. */
10296 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10299 /* From mips.md: extract_bit_field doesn't verify that our source
10300 matches the predicate, so check it again here. */
10301 if (! ext_register_operand (operands[1], VOIDmode))
10305 (define_expand "insv"
10306 [(set (zero_extract (match_operand 0 "register_operand" "")
10307 (match_operand 1 "const_int_operand" "")
10308 (match_operand 2 "const_int_operand" ""))
10309 (match_operand 3 "register_operand" ""))]
10312 rtx (*gen_mov_insv_1) (rtx, rtx);
10314 if (ix86_expand_pinsr (operands))
10317 /* Handle insertions to %ah et al. */
10318 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10321 /* From mips.md: insert_bit_field doesn't verify that our source
10322 matches the predicate, so check it again here. */
10323 if (! ext_register_operand (operands[0], VOIDmode))
10326 gen_mov_insv_1 = (TARGET_64BIT
10327 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10329 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10333 ;; %%% bts, btr, btc, bt.
10334 ;; In general these instructions are *slow* when applied to memory,
10335 ;; since they enforce atomic operation. When applied to registers,
10336 ;; it depends on the cpu implementation. They're never faster than
10337 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10338 ;; no point. But in 64-bit, we can't hold the relevant immediates
10339 ;; within the instruction itself, so operating on bits in the high
10340 ;; 32-bits of a register becomes easier.
10342 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10343 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10344 ;; negdf respectively, so they can never be disabled entirely.
10346 (define_insn "*btsq"
10347 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10349 (match_operand:DI 1 "const_0_to_63_operand" ""))
10351 (clobber (reg:CC FLAGS_REG))]
10352 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10353 "bts{q}\t{%1, %0|%0, %1}"
10354 [(set_attr "type" "alu1")
10355 (set_attr "prefix_0f" "1")
10356 (set_attr "mode" "DI")])
10358 (define_insn "*btrq"
10359 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10361 (match_operand:DI 1 "const_0_to_63_operand" ""))
10363 (clobber (reg:CC FLAGS_REG))]
10364 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10365 "btr{q}\t{%1, %0|%0, %1}"
10366 [(set_attr "type" "alu1")
10367 (set_attr "prefix_0f" "1")
10368 (set_attr "mode" "DI")])
10370 (define_insn "*btcq"
10371 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10373 (match_operand:DI 1 "const_0_to_63_operand" ""))
10374 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10375 (clobber (reg:CC FLAGS_REG))]
10376 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10377 "btc{q}\t{%1, %0|%0, %1}"
10378 [(set_attr "type" "alu1")
10379 (set_attr "prefix_0f" "1")
10380 (set_attr "mode" "DI")])
10382 ;; Allow Nocona to avoid these instructions if a register is available.
10385 [(match_scratch:DI 2 "r")
10386 (parallel [(set (zero_extract:DI
10387 (match_operand:DI 0 "register_operand" "")
10389 (match_operand:DI 1 "const_0_to_63_operand" ""))
10391 (clobber (reg:CC FLAGS_REG))])]
10392 "TARGET_64BIT && !TARGET_USE_BT"
10395 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10398 if (HOST_BITS_PER_WIDE_INT >= 64)
10399 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10400 else if (i < HOST_BITS_PER_WIDE_INT)
10401 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10403 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10405 op1 = immed_double_const (lo, hi, DImode);
10408 emit_move_insn (operands[2], op1);
10412 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10417 [(match_scratch:DI 2 "r")
10418 (parallel [(set (zero_extract:DI
10419 (match_operand:DI 0 "register_operand" "")
10421 (match_operand:DI 1 "const_0_to_63_operand" ""))
10423 (clobber (reg:CC FLAGS_REG))])]
10424 "TARGET_64BIT && !TARGET_USE_BT"
10427 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10430 if (HOST_BITS_PER_WIDE_INT >= 64)
10431 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10432 else if (i < HOST_BITS_PER_WIDE_INT)
10433 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10435 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10437 op1 = immed_double_const (~lo, ~hi, DImode);
10440 emit_move_insn (operands[2], op1);
10444 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10449 [(match_scratch:DI 2 "r")
10450 (parallel [(set (zero_extract:DI
10451 (match_operand:DI 0 "register_operand" "")
10453 (match_operand:DI 1 "const_0_to_63_operand" ""))
10454 (not:DI (zero_extract:DI
10455 (match_dup 0) (const_int 1) (match_dup 1))))
10456 (clobber (reg:CC FLAGS_REG))])]
10457 "TARGET_64BIT && !TARGET_USE_BT"
10460 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10463 if (HOST_BITS_PER_WIDE_INT >= 64)
10464 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10465 else if (i < HOST_BITS_PER_WIDE_INT)
10466 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10468 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10470 op1 = immed_double_const (lo, hi, DImode);
10473 emit_move_insn (operands[2], op1);
10477 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10481 (define_insn "*bt<mode>"
10482 [(set (reg:CCC FLAGS_REG)
10484 (zero_extract:SWI48
10485 (match_operand:SWI48 0 "register_operand" "r")
10487 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10489 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10490 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10491 [(set_attr "type" "alu1")
10492 (set_attr "prefix_0f" "1")
10493 (set_attr "mode" "<MODE>")])
10495 ;; Store-flag instructions.
10497 ;; For all sCOND expanders, also expand the compare or test insn that
10498 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10500 (define_insn_and_split "*setcc_di_1"
10501 [(set (match_operand:DI 0 "register_operand" "=q")
10502 (match_operator:DI 1 "ix86_comparison_operator"
10503 [(reg FLAGS_REG) (const_int 0)]))]
10504 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10506 "&& reload_completed"
10507 [(set (match_dup 2) (match_dup 1))
10508 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10510 PUT_MODE (operands[1], QImode);
10511 operands[2] = gen_lowpart (QImode, operands[0]);
10514 (define_insn_and_split "*setcc_si_1_and"
10515 [(set (match_operand:SI 0 "register_operand" "=q")
10516 (match_operator:SI 1 "ix86_comparison_operator"
10517 [(reg FLAGS_REG) (const_int 0)]))
10518 (clobber (reg:CC FLAGS_REG))]
10519 "!TARGET_PARTIAL_REG_STALL
10520 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10522 "&& reload_completed"
10523 [(set (match_dup 2) (match_dup 1))
10524 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10525 (clobber (reg:CC FLAGS_REG))])]
10527 PUT_MODE (operands[1], QImode);
10528 operands[2] = gen_lowpart (QImode, operands[0]);
10531 (define_insn_and_split "*setcc_si_1_movzbl"
10532 [(set (match_operand:SI 0 "register_operand" "=q")
10533 (match_operator:SI 1 "ix86_comparison_operator"
10534 [(reg FLAGS_REG) (const_int 0)]))]
10535 "!TARGET_PARTIAL_REG_STALL
10536 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10538 "&& reload_completed"
10539 [(set (match_dup 2) (match_dup 1))
10540 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10542 PUT_MODE (operands[1], QImode);
10543 operands[2] = gen_lowpart (QImode, operands[0]);
10546 (define_insn "*setcc_qi"
10547 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10548 (match_operator:QI 1 "ix86_comparison_operator"
10549 [(reg FLAGS_REG) (const_int 0)]))]
10552 [(set_attr "type" "setcc")
10553 (set_attr "mode" "QI")])
10555 (define_insn "*setcc_qi_slp"
10556 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10557 (match_operator:QI 1 "ix86_comparison_operator"
10558 [(reg FLAGS_REG) (const_int 0)]))]
10561 [(set_attr "type" "setcc")
10562 (set_attr "mode" "QI")])
10564 ;; In general it is not safe to assume too much about CCmode registers,
10565 ;; so simplify-rtx stops when it sees a second one. Under certain
10566 ;; conditions this is safe on x86, so help combine not create
10573 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10574 (ne:QI (match_operator 1 "ix86_comparison_operator"
10575 [(reg FLAGS_REG) (const_int 0)])
10578 [(set (match_dup 0) (match_dup 1))]
10579 "PUT_MODE (operands[1], QImode);")
10582 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10583 (ne:QI (match_operator 1 "ix86_comparison_operator"
10584 [(reg FLAGS_REG) (const_int 0)])
10587 [(set (match_dup 0) (match_dup 1))]
10588 "PUT_MODE (operands[1], QImode);")
10591 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10592 (eq:QI (match_operator 1 "ix86_comparison_operator"
10593 [(reg FLAGS_REG) (const_int 0)])
10596 [(set (match_dup 0) (match_dup 1))]
10598 rtx new_op1 = copy_rtx (operands[1]);
10599 operands[1] = new_op1;
10600 PUT_MODE (new_op1, QImode);
10601 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10602 GET_MODE (XEXP (new_op1, 0))));
10604 /* Make sure that (a) the CCmode we have for the flags is strong
10605 enough for the reversed compare or (b) we have a valid FP compare. */
10606 if (! ix86_comparison_operator (new_op1, VOIDmode))
10611 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10612 (eq:QI (match_operator 1 "ix86_comparison_operator"
10613 [(reg FLAGS_REG) (const_int 0)])
10616 [(set (match_dup 0) (match_dup 1))]
10618 rtx new_op1 = copy_rtx (operands[1]);
10619 operands[1] = new_op1;
10620 PUT_MODE (new_op1, QImode);
10621 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10622 GET_MODE (XEXP (new_op1, 0))));
10624 /* Make sure that (a) the CCmode we have for the flags is strong
10625 enough for the reversed compare or (b) we have a valid FP compare. */
10626 if (! ix86_comparison_operator (new_op1, VOIDmode))
10630 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10631 ;; subsequent logical operations are used to imitate conditional moves.
10632 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10635 (define_insn "setcc_<mode>_sse"
10636 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10637 (match_operator:MODEF 3 "sse_comparison_operator"
10638 [(match_operand:MODEF 1 "register_operand" "0,x")
10639 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10640 "SSE_FLOAT_MODE_P (<MODE>mode)"
10642 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10643 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10644 [(set_attr "isa" "noavx,avx")
10645 (set_attr "type" "ssecmp")
10646 (set_attr "length_immediate" "1")
10647 (set_attr "prefix" "orig,vex")
10648 (set_attr "mode" "<MODE>")])
10650 ;; Basic conditional jump instructions.
10651 ;; We ignore the overflow flag for signed branch instructions.
10653 (define_insn "*jcc_1"
10655 (if_then_else (match_operator 1 "ix86_comparison_operator"
10656 [(reg FLAGS_REG) (const_int 0)])
10657 (label_ref (match_operand 0 "" ""))
10661 [(set_attr "type" "ibr")
10662 (set_attr "modrm" "0")
10663 (set (attr "length")
10664 (if_then_else (and (ge (minus (match_dup 0) (pc))
10666 (lt (minus (match_dup 0) (pc))
10671 (define_insn "*jcc_2"
10673 (if_then_else (match_operator 1 "ix86_comparison_operator"
10674 [(reg FLAGS_REG) (const_int 0)])
10676 (label_ref (match_operand 0 "" ""))))]
10679 [(set_attr "type" "ibr")
10680 (set_attr "modrm" "0")
10681 (set (attr "length")
10682 (if_then_else (and (ge (minus (match_dup 0) (pc))
10684 (lt (minus (match_dup 0) (pc))
10689 ;; In general it is not safe to assume too much about CCmode registers,
10690 ;; so simplify-rtx stops when it sees a second one. Under certain
10691 ;; conditions this is safe on x86, so help combine not create
10699 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10700 [(reg FLAGS_REG) (const_int 0)])
10702 (label_ref (match_operand 1 "" ""))
10706 (if_then_else (match_dup 0)
10707 (label_ref (match_dup 1))
10709 "PUT_MODE (operands[0], VOIDmode);")
10713 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10714 [(reg FLAGS_REG) (const_int 0)])
10716 (label_ref (match_operand 1 "" ""))
10720 (if_then_else (match_dup 0)
10721 (label_ref (match_dup 1))
10724 rtx new_op0 = copy_rtx (operands[0]);
10725 operands[0] = new_op0;
10726 PUT_MODE (new_op0, VOIDmode);
10727 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10728 GET_MODE (XEXP (new_op0, 0))));
10730 /* Make sure that (a) the CCmode we have for the flags is strong
10731 enough for the reversed compare or (b) we have a valid FP compare. */
10732 if (! ix86_comparison_operator (new_op0, VOIDmode))
10736 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10737 ;; pass generates from shift insn with QImode operand. Actually, the mode
10738 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10739 ;; appropriate modulo of the bit offset value.
10741 (define_insn_and_split "*jcc_bt<mode>"
10743 (if_then_else (match_operator 0 "bt_comparison_operator"
10744 [(zero_extract:SWI48
10745 (match_operand:SWI48 1 "register_operand" "r")
10748 (match_operand:QI 2 "register_operand" "r")))
10750 (label_ref (match_operand 3 "" ""))
10752 (clobber (reg:CC FLAGS_REG))]
10753 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10756 [(set (reg:CCC FLAGS_REG)
10758 (zero_extract:SWI48
10764 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10765 (label_ref (match_dup 3))
10768 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10770 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10773 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10774 ;; also for DImode, this is what combine produces.
10775 (define_insn_and_split "*jcc_bt<mode>_mask"
10777 (if_then_else (match_operator 0 "bt_comparison_operator"
10778 [(zero_extract:SWI48
10779 (match_operand:SWI48 1 "register_operand" "r")
10782 (match_operand:SI 2 "register_operand" "r")
10783 (match_operand:SI 3 "const_int_operand" "n")))])
10784 (label_ref (match_operand 4 "" ""))
10786 (clobber (reg:CC FLAGS_REG))]
10787 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10788 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10789 == GET_MODE_BITSIZE (<MODE>mode)-1"
10792 [(set (reg:CCC FLAGS_REG)
10794 (zero_extract:SWI48
10800 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10801 (label_ref (match_dup 4))
10804 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10806 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10809 (define_insn_and_split "*jcc_btsi_1"
10811 (if_then_else (match_operator 0 "bt_comparison_operator"
10814 (match_operand:SI 1 "register_operand" "r")
10815 (match_operand:QI 2 "register_operand" "r"))
10818 (label_ref (match_operand 3 "" ""))
10820 (clobber (reg:CC FLAGS_REG))]
10821 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10824 [(set (reg:CCC FLAGS_REG)
10832 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10833 (label_ref (match_dup 3))
10836 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10838 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10841 ;; avoid useless masking of bit offset operand
10842 (define_insn_and_split "*jcc_btsi_mask_1"
10845 (match_operator 0 "bt_comparison_operator"
10848 (match_operand:SI 1 "register_operand" "r")
10851 (match_operand:SI 2 "register_operand" "r")
10852 (match_operand:SI 3 "const_int_operand" "n")) 0))
10855 (label_ref (match_operand 4 "" ""))
10857 (clobber (reg:CC FLAGS_REG))]
10858 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10859 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10862 [(set (reg:CCC FLAGS_REG)
10870 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10871 (label_ref (match_dup 4))
10873 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10875 ;; Define combination compare-and-branch fp compare instructions to help
10878 (define_insn "*fp_jcc_1_387"
10880 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10881 [(match_operand 1 "register_operand" "f")
10882 (match_operand 2 "nonimmediate_operand" "fm")])
10883 (label_ref (match_operand 3 "" ""))
10885 (clobber (reg:CCFP FPSR_REG))
10886 (clobber (reg:CCFP FLAGS_REG))
10887 (clobber (match_scratch:HI 4 "=a"))]
10889 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10890 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10891 && SELECT_CC_MODE (GET_CODE (operands[0]),
10892 operands[1], operands[2]) == CCFPmode
10896 (define_insn "*fp_jcc_1r_387"
10898 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10899 [(match_operand 1 "register_operand" "f")
10900 (match_operand 2 "nonimmediate_operand" "fm")])
10902 (label_ref (match_operand 3 "" ""))))
10903 (clobber (reg:CCFP FPSR_REG))
10904 (clobber (reg:CCFP FLAGS_REG))
10905 (clobber (match_scratch:HI 4 "=a"))]
10907 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10908 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10909 && SELECT_CC_MODE (GET_CODE (operands[0]),
10910 operands[1], operands[2]) == CCFPmode
10914 (define_insn "*fp_jcc_2_387"
10916 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10917 [(match_operand 1 "register_operand" "f")
10918 (match_operand 2 "register_operand" "f")])
10919 (label_ref (match_operand 3 "" ""))
10921 (clobber (reg:CCFP FPSR_REG))
10922 (clobber (reg:CCFP FLAGS_REG))
10923 (clobber (match_scratch:HI 4 "=a"))]
10924 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10925 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10929 (define_insn "*fp_jcc_2r_387"
10931 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10932 [(match_operand 1 "register_operand" "f")
10933 (match_operand 2 "register_operand" "f")])
10935 (label_ref (match_operand 3 "" ""))))
10936 (clobber (reg:CCFP FPSR_REG))
10937 (clobber (reg:CCFP FLAGS_REG))
10938 (clobber (match_scratch:HI 4 "=a"))]
10939 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10940 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10944 (define_insn "*fp_jcc_3_387"
10946 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10947 [(match_operand 1 "register_operand" "f")
10948 (match_operand 2 "const0_operand" "")])
10949 (label_ref (match_operand 3 "" ""))
10951 (clobber (reg:CCFP FPSR_REG))
10952 (clobber (reg:CCFP FLAGS_REG))
10953 (clobber (match_scratch:HI 4 "=a"))]
10954 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10955 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10956 && SELECT_CC_MODE (GET_CODE (operands[0]),
10957 operands[1], operands[2]) == CCFPmode
10963 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10964 [(match_operand 1 "register_operand" "")
10965 (match_operand 2 "nonimmediate_operand" "")])
10966 (match_operand 3 "" "")
10967 (match_operand 4 "" "")))
10968 (clobber (reg:CCFP FPSR_REG))
10969 (clobber (reg:CCFP FLAGS_REG))]
10973 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10974 operands[3], operands[4], NULL_RTX, NULL_RTX);
10980 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10981 [(match_operand 1 "register_operand" "")
10982 (match_operand 2 "general_operand" "")])
10983 (match_operand 3 "" "")
10984 (match_operand 4 "" "")))
10985 (clobber (reg:CCFP FPSR_REG))
10986 (clobber (reg:CCFP FLAGS_REG))
10987 (clobber (match_scratch:HI 5 "=a"))]
10991 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10992 operands[3], operands[4], operands[5], NULL_RTX);
10996 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
10997 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
10998 ;; with a precedence over other operators and is always put in the first
10999 ;; place. Swap condition and operands to match ficom instruction.
11001 (define_insn "*fp_jcc_4_<mode>_387"
11004 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11005 [(match_operator 1 "float_operator"
11006 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11007 (match_operand 3 "register_operand" "f,f")])
11008 (label_ref (match_operand 4 "" ""))
11010 (clobber (reg:CCFP FPSR_REG))
11011 (clobber (reg:CCFP FLAGS_REG))
11012 (clobber (match_scratch:HI 5 "=a,a"))]
11013 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11014 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11015 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11016 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11023 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11024 [(match_operator 1 "float_operator"
11025 [(match_operand:SWI24 2 "memory_operand" "")])
11026 (match_operand 3 "register_operand" "")])
11027 (match_operand 4 "" "")
11028 (match_operand 5 "" "")))
11029 (clobber (reg:CCFP FPSR_REG))
11030 (clobber (reg:CCFP FLAGS_REG))
11031 (clobber (match_scratch:HI 6 "=a"))]
11035 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11037 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11038 operands[3], operands[7],
11039 operands[4], operands[5], operands[6], NULL_RTX);
11043 ;; %%% Kill this when reload knows how to do it.
11047 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11048 [(match_operator 1 "float_operator"
11049 [(match_operand:SWI24 2 "register_operand" "")])
11050 (match_operand 3 "register_operand" "")])
11051 (match_operand 4 "" "")
11052 (match_operand 5 "" "")))
11053 (clobber (reg:CCFP FPSR_REG))
11054 (clobber (reg:CCFP FLAGS_REG))
11055 (clobber (match_scratch:HI 6 "=a"))]
11059 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11060 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11062 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11063 operands[3], operands[7],
11064 operands[4], operands[5], operands[6], operands[2]);
11068 ;; Unconditional and other jump instructions
11070 (define_insn "jump"
11072 (label_ref (match_operand 0 "" "")))]
11075 [(set_attr "type" "ibr")
11076 (set (attr "length")
11077 (if_then_else (and (ge (minus (match_dup 0) (pc))
11079 (lt (minus (match_dup 0) (pc))
11083 (set_attr "modrm" "0")])
11085 (define_expand "indirect_jump"
11086 [(set (pc) (match_operand 0 "indirect_branch_operand" ""))])
11088 (define_insn "*indirect_jump"
11089 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))]
11092 [(set_attr "type" "ibr")
11093 (set_attr "length_immediate" "0")])
11095 (define_expand "tablejump"
11096 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand" ""))
11097 (use (label_ref (match_operand 1 "" "")))])]
11100 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11101 relative. Convert the relative address to an absolute address. */
11105 enum rtx_code code;
11107 /* We can't use @GOTOFF for text labels on VxWorks;
11108 see gotoff_operand. */
11109 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11113 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11115 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11119 op1 = pic_offset_table_rtx;
11124 op0 = pic_offset_table_rtx;
11128 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11131 else if (TARGET_X32)
11132 operands[0] = convert_memory_address (Pmode, operands[0]);
11135 (define_insn "*tablejump_1"
11136 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))
11137 (use (label_ref (match_operand 1 "" "")))]
11140 [(set_attr "type" "ibr")
11141 (set_attr "length_immediate" "0")])
11143 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11146 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11147 (set (match_operand:QI 1 "register_operand" "")
11148 (match_operator:QI 2 "ix86_comparison_operator"
11149 [(reg FLAGS_REG) (const_int 0)]))
11150 (set (match_operand 3 "q_regs_operand" "")
11151 (zero_extend (match_dup 1)))]
11152 "(peep2_reg_dead_p (3, operands[1])
11153 || operands_match_p (operands[1], operands[3]))
11154 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11155 [(set (match_dup 4) (match_dup 0))
11156 (set (strict_low_part (match_dup 5))
11159 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11160 operands[5] = gen_lowpart (QImode, operands[3]);
11161 ix86_expand_clear (operands[3]);
11164 ;; Similar, but match zero extend with andsi3.
11167 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11168 (set (match_operand:QI 1 "register_operand" "")
11169 (match_operator:QI 2 "ix86_comparison_operator"
11170 [(reg FLAGS_REG) (const_int 0)]))
11171 (parallel [(set (match_operand:SI 3 "q_regs_operand" "")
11172 (and:SI (match_dup 3) (const_int 255)))
11173 (clobber (reg:CC FLAGS_REG))])]
11174 "REGNO (operands[1]) == REGNO (operands[3])
11175 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11176 [(set (match_dup 4) (match_dup 0))
11177 (set (strict_low_part (match_dup 5))
11180 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11181 operands[5] = gen_lowpart (QImode, operands[3]);
11182 ix86_expand_clear (operands[3]);
11185 ;; Call instructions.
11187 ;; The predicates normally associated with named expanders are not properly
11188 ;; checked for calls. This is a bug in the generic code, but it isn't that
11189 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11191 ;; P6 processors will jump to the address after the decrement when %esp
11192 ;; is used as a call operand, so they will execute return address as a code.
11193 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11195 ;; Register constraint for call instruction.
11196 (define_mode_attr c [(SI "l") (DI "r")])
11198 ;; Call subroutine returning no value.
11200 (define_expand "call"
11201 [(call (match_operand:QI 0 "" "")
11202 (match_operand 1 "" ""))
11203 (use (match_operand 2 "" ""))]
11206 ix86_expand_call (NULL, operands[0], operands[1],
11207 operands[2], NULL, false);
11211 (define_expand "sibcall"
11212 [(call (match_operand:QI 0 "" "")
11213 (match_operand 1 "" ""))
11214 (use (match_operand 2 "" ""))]
11217 ix86_expand_call (NULL, operands[0], operands[1],
11218 operands[2], NULL, true);
11222 (define_insn_and_split "*call_vzeroupper"
11223 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11224 (match_operand 1 "" ""))
11225 (unspec [(match_operand 2 "const_int_operand" "")]
11226 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11227 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11229 "&& reload_completed"
11231 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11232 [(set_attr "type" "call")])
11234 (define_insn "*call"
11235 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11236 (match_operand 1 "" ""))]
11237 "!SIBLING_CALL_P (insn)"
11238 "* return ix86_output_call_insn (insn, operands[0]);"
11239 [(set_attr "type" "call")])
11241 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11242 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11243 (match_operand 1 "" ""))
11244 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11245 (clobber (reg:TI XMM6_REG))
11246 (clobber (reg:TI XMM7_REG))
11247 (clobber (reg:TI XMM8_REG))
11248 (clobber (reg:TI XMM9_REG))
11249 (clobber (reg:TI XMM10_REG))
11250 (clobber (reg:TI XMM11_REG))
11251 (clobber (reg:TI XMM12_REG))
11252 (clobber (reg:TI XMM13_REG))
11253 (clobber (reg:TI XMM14_REG))
11254 (clobber (reg:TI XMM15_REG))
11255 (clobber (reg:DI SI_REG))
11256 (clobber (reg:DI DI_REG))
11257 (unspec [(match_operand 2 "const_int_operand" "")]
11258 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11259 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11261 "&& reload_completed"
11263 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11264 [(set_attr "type" "call")])
11266 (define_insn "*call_rex64_ms_sysv"
11267 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11268 (match_operand 1 "" ""))
11269 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11270 (clobber (reg:TI XMM6_REG))
11271 (clobber (reg:TI XMM7_REG))
11272 (clobber (reg:TI XMM8_REG))
11273 (clobber (reg:TI XMM9_REG))
11274 (clobber (reg:TI XMM10_REG))
11275 (clobber (reg:TI XMM11_REG))
11276 (clobber (reg:TI XMM12_REG))
11277 (clobber (reg:TI XMM13_REG))
11278 (clobber (reg:TI XMM14_REG))
11279 (clobber (reg:TI XMM15_REG))
11280 (clobber (reg:DI SI_REG))
11281 (clobber (reg:DI DI_REG))]
11282 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11283 "* return ix86_output_call_insn (insn, operands[0]);"
11284 [(set_attr "type" "call")])
11286 (define_insn_and_split "*sibcall_vzeroupper"
11287 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11288 (match_operand 1 "" ""))
11289 (unspec [(match_operand 2 "const_int_operand" "")]
11290 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11291 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11293 "&& reload_completed"
11295 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11296 [(set_attr "type" "call")])
11298 (define_insn "*sibcall"
11299 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11300 (match_operand 1 "" ""))]
11301 "SIBLING_CALL_P (insn)"
11302 "* return ix86_output_call_insn (insn, operands[0]);"
11303 [(set_attr "type" "call")])
11305 (define_expand "call_pop"
11306 [(parallel [(call (match_operand:QI 0 "" "")
11307 (match_operand:SI 1 "" ""))
11308 (set (reg:SI SP_REG)
11309 (plus:SI (reg:SI SP_REG)
11310 (match_operand:SI 3 "" "")))])]
11313 ix86_expand_call (NULL, operands[0], operands[1],
11314 operands[2], operands[3], false);
11318 (define_insn_and_split "*call_pop_vzeroupper"
11319 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11320 (match_operand:SI 1 "" ""))
11321 (set (reg:SI SP_REG)
11322 (plus:SI (reg:SI SP_REG)
11323 (match_operand:SI 2 "immediate_operand" "i")))
11324 (unspec [(match_operand 3 "const_int_operand" "")]
11325 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11326 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11328 "&& reload_completed"
11330 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11331 [(set_attr "type" "call")])
11333 (define_insn "*call_pop"
11334 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11335 (match_operand 1 "" ""))
11336 (set (reg:SI SP_REG)
11337 (plus:SI (reg:SI SP_REG)
11338 (match_operand:SI 2 "immediate_operand" "i")))]
11339 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11340 "* return ix86_output_call_insn (insn, operands[0]);"
11341 [(set_attr "type" "call")])
11343 (define_insn_and_split "*sibcall_pop_vzeroupper"
11344 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11345 (match_operand 1 "" ""))
11346 (set (reg:SI SP_REG)
11347 (plus:SI (reg:SI SP_REG)
11348 (match_operand:SI 2 "immediate_operand" "i")))
11349 (unspec [(match_operand 3 "const_int_operand" "")]
11350 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11351 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11353 "&& reload_completed"
11355 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11356 [(set_attr "type" "call")])
11358 (define_insn "*sibcall_pop"
11359 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11360 (match_operand 1 "" ""))
11361 (set (reg:SI SP_REG)
11362 (plus:SI (reg:SI SP_REG)
11363 (match_operand:SI 2 "immediate_operand" "i")))]
11364 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11365 "* return ix86_output_call_insn (insn, operands[0]);"
11366 [(set_attr "type" "call")])
11368 ;; Call subroutine, returning value in operand 0
11370 (define_expand "call_value"
11371 [(set (match_operand 0 "" "")
11372 (call (match_operand:QI 1 "" "")
11373 (match_operand 2 "" "")))
11374 (use (match_operand 3 "" ""))]
11377 ix86_expand_call (operands[0], operands[1], operands[2],
11378 operands[3], NULL, false);
11382 (define_expand "sibcall_value"
11383 [(set (match_operand 0 "" "")
11384 (call (match_operand:QI 1 "" "")
11385 (match_operand 2 "" "")))
11386 (use (match_operand 3 "" ""))]
11389 ix86_expand_call (operands[0], operands[1], operands[2],
11390 operands[3], NULL, true);
11394 (define_insn_and_split "*call_value_vzeroupper"
11395 [(set (match_operand 0 "" "")
11396 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11397 (match_operand 2 "" "")))
11398 (unspec [(match_operand 3 "const_int_operand" "")]
11399 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11400 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11402 "&& reload_completed"
11404 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11405 [(set_attr "type" "callv")])
11407 (define_insn "*call_value"
11408 [(set (match_operand 0 "" "")
11409 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11410 (match_operand 2 "" "")))]
11411 "!SIBLING_CALL_P (insn)"
11412 "* return ix86_output_call_insn (insn, operands[1]);"
11413 [(set_attr "type" "callv")])
11415 (define_insn_and_split "*sibcall_value_vzeroupper"
11416 [(set (match_operand 0 "" "")
11417 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11418 (match_operand 2 "" "")))
11419 (unspec [(match_operand 3 "const_int_operand" "")]
11420 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11421 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11423 "&& reload_completed"
11425 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11426 [(set_attr "type" "callv")])
11428 (define_insn "*sibcall_value"
11429 [(set (match_operand 0 "" "")
11430 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11431 (match_operand 2 "" "")))]
11432 "SIBLING_CALL_P (insn)"
11433 "* return ix86_output_call_insn (insn, operands[1]);"
11434 [(set_attr "type" "callv")])
11436 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11437 [(set (match_operand 0 "" "")
11438 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11439 (match_operand 2 "" "")))
11440 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11441 (clobber (reg:TI XMM6_REG))
11442 (clobber (reg:TI XMM7_REG))
11443 (clobber (reg:TI XMM8_REG))
11444 (clobber (reg:TI XMM9_REG))
11445 (clobber (reg:TI XMM10_REG))
11446 (clobber (reg:TI XMM11_REG))
11447 (clobber (reg:TI XMM12_REG))
11448 (clobber (reg:TI XMM13_REG))
11449 (clobber (reg:TI XMM14_REG))
11450 (clobber (reg:TI XMM15_REG))
11451 (clobber (reg:DI SI_REG))
11452 (clobber (reg:DI DI_REG))
11453 (unspec [(match_operand 3 "const_int_operand" "")]
11454 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11455 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11457 "&& reload_completed"
11459 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11460 [(set_attr "type" "callv")])
11462 (define_insn "*call_value_rex64_ms_sysv"
11463 [(set (match_operand 0 "" "")
11464 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11465 (match_operand 2 "" "")))
11466 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11467 (clobber (reg:TI XMM6_REG))
11468 (clobber (reg:TI XMM7_REG))
11469 (clobber (reg:TI XMM8_REG))
11470 (clobber (reg:TI XMM9_REG))
11471 (clobber (reg:TI XMM10_REG))
11472 (clobber (reg:TI XMM11_REG))
11473 (clobber (reg:TI XMM12_REG))
11474 (clobber (reg:TI XMM13_REG))
11475 (clobber (reg:TI XMM14_REG))
11476 (clobber (reg:TI XMM15_REG))
11477 (clobber (reg:DI SI_REG))
11478 (clobber (reg:DI DI_REG))]
11479 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11480 "* return ix86_output_call_insn (insn, operands[1]);"
11481 [(set_attr "type" "callv")])
11483 (define_expand "call_value_pop"
11484 [(parallel [(set (match_operand 0 "" "")
11485 (call (match_operand:QI 1 "" "")
11486 (match_operand:SI 2 "" "")))
11487 (set (reg:SI SP_REG)
11488 (plus:SI (reg:SI SP_REG)
11489 (match_operand:SI 4 "" "")))])]
11492 ix86_expand_call (operands[0], operands[1], operands[2],
11493 operands[3], operands[4], false);
11497 (define_insn_and_split "*call_value_pop_vzeroupper"
11498 [(set (match_operand 0 "" "")
11499 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11500 (match_operand 2 "" "")))
11501 (set (reg:SI SP_REG)
11502 (plus:SI (reg:SI SP_REG)
11503 (match_operand:SI 3 "immediate_operand" "i")))
11504 (unspec [(match_operand 4 "const_int_operand" "")]
11505 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11506 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11508 "&& reload_completed"
11510 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11511 [(set_attr "type" "callv")])
11513 (define_insn "*call_value_pop"
11514 [(set (match_operand 0 "" "")
11515 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11516 (match_operand 2 "" "")))
11517 (set (reg:SI SP_REG)
11518 (plus:SI (reg:SI SP_REG)
11519 (match_operand:SI 3 "immediate_operand" "i")))]
11520 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11521 "* return ix86_output_call_insn (insn, operands[1]);"
11522 [(set_attr "type" "callv")])
11524 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11525 [(set (match_operand 0 "" "")
11526 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11527 (match_operand 2 "" "")))
11528 (set (reg:SI SP_REG)
11529 (plus:SI (reg:SI SP_REG)
11530 (match_operand:SI 3 "immediate_operand" "i")))
11531 (unspec [(match_operand 4 "const_int_operand" "")]
11532 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11533 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11535 "&& reload_completed"
11537 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11538 [(set_attr "type" "callv")])
11540 (define_insn "*sibcall_value_pop"
11541 [(set (match_operand 0 "" "")
11542 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11543 (match_operand 2 "" "")))
11544 (set (reg:SI SP_REG)
11545 (plus:SI (reg:SI SP_REG)
11546 (match_operand:SI 3 "immediate_operand" "i")))]
11547 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11548 "* return ix86_output_call_insn (insn, operands[1]);"
11549 [(set_attr "type" "callv")])
11551 ;; Call subroutine returning any type.
11553 (define_expand "untyped_call"
11554 [(parallel [(call (match_operand 0 "" "")
11556 (match_operand 1 "" "")
11557 (match_operand 2 "" "")])]
11562 /* In order to give reg-stack an easier job in validating two
11563 coprocessor registers as containing a possible return value,
11564 simply pretend the untyped call returns a complex long double
11567 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11568 and should have the default ABI. */
11570 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11571 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11572 operands[0], const0_rtx,
11573 GEN_INT ((TARGET_64BIT
11574 ? (ix86_abi == SYSV_ABI
11575 ? X86_64_SSE_REGPARM_MAX
11576 : X86_64_MS_SSE_REGPARM_MAX)
11577 : X86_32_SSE_REGPARM_MAX)
11581 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11583 rtx set = XVECEXP (operands[2], 0, i);
11584 emit_move_insn (SET_DEST (set), SET_SRC (set));
11587 /* The optimizer does not know that the call sets the function value
11588 registers we stored in the result block. We avoid problems by
11589 claiming that all hard registers are used and clobbered at this
11591 emit_insn (gen_blockage ());
11596 ;; Prologue and epilogue instructions
11598 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11599 ;; all of memory. This blocks insns from being moved across this point.
11601 (define_insn "blockage"
11602 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11605 [(set_attr "length" "0")])
11607 ;; Do not schedule instructions accessing memory across this point.
11609 (define_expand "memory_blockage"
11610 [(set (match_dup 0)
11611 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11614 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11615 MEM_VOLATILE_P (operands[0]) = 1;
11618 (define_insn "*memory_blockage"
11619 [(set (match_operand:BLK 0 "" "")
11620 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11623 [(set_attr "length" "0")])
11625 ;; As USE insns aren't meaningful after reload, this is used instead
11626 ;; to prevent deleting instructions setting registers for PIC code
11627 (define_insn "prologue_use"
11628 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11631 [(set_attr "length" "0")])
11633 ;; Insn emitted into the body of a function to return from a function.
11634 ;; This is only done if the function's epilogue is known to be simple.
11635 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11637 (define_expand "return"
11639 "ix86_can_use_return_insn_p ()"
11641 ix86_maybe_emit_epilogue_vzeroupper ();
11642 if (crtl->args.pops_args)
11644 rtx popc = GEN_INT (crtl->args.pops_args);
11645 emit_jump_insn (gen_simple_return_pop_internal (popc));
11650 ;; We need to disable this for TARGET_SEH, as otherwise
11651 ;; shrink-wrapped prologue gets enabled too. This might exceed
11652 ;; the maximum size of prologue in unwind information.
11654 (define_expand "simple_return"
11658 ix86_maybe_emit_epilogue_vzeroupper ();
11659 if (crtl->args.pops_args)
11661 rtx popc = GEN_INT (crtl->args.pops_args);
11662 emit_jump_insn (gen_simple_return_pop_internal (popc));
11667 (define_insn "simple_return_internal"
11671 [(set_attr "length" "1")
11672 (set_attr "atom_unit" "jeu")
11673 (set_attr "length_immediate" "0")
11674 (set_attr "modrm" "0")])
11676 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11677 ;; instruction Athlon and K8 have.
11679 (define_insn "simple_return_internal_long"
11681 (unspec [(const_int 0)] UNSPEC_REP)]
11684 [(set_attr "length" "2")
11685 (set_attr "atom_unit" "jeu")
11686 (set_attr "length_immediate" "0")
11687 (set_attr "prefix_rep" "1")
11688 (set_attr "modrm" "0")])
11690 (define_insn "simple_return_pop_internal"
11692 (use (match_operand:SI 0 "const_int_operand" ""))]
11695 [(set_attr "length" "3")
11696 (set_attr "atom_unit" "jeu")
11697 (set_attr "length_immediate" "2")
11698 (set_attr "modrm" "0")])
11700 (define_insn "simple_return_indirect_internal"
11702 (use (match_operand:SI 0 "register_operand" "r"))]
11705 [(set_attr "type" "ibr")
11706 (set_attr "length_immediate" "0")])
11712 [(set_attr "length" "1")
11713 (set_attr "length_immediate" "0")
11714 (set_attr "modrm" "0")])
11716 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11717 (define_insn "nops"
11718 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11722 int num = INTVAL (operands[0]);
11724 gcc_assert (num >= 1 && num <= 8);
11727 fputs ("\tnop\n", asm_out_file);
11731 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11732 (set_attr "length_immediate" "0")
11733 (set_attr "modrm" "0")])
11735 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11736 ;; branch prediction penalty for the third jump in a 16-byte
11740 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11743 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11744 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11746 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11747 The align insn is used to avoid 3 jump instructions in the row to improve
11748 branch prediction and the benefits hardly outweigh the cost of extra 8
11749 nops on the average inserted by full alignment pseudo operation. */
11753 [(set_attr "length" "16")])
11755 (define_expand "prologue"
11758 "ix86_expand_prologue (); DONE;")
11760 (define_insn "set_got"
11761 [(set (match_operand:SI 0 "register_operand" "=r")
11762 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11763 (clobber (reg:CC FLAGS_REG))]
11765 "* return output_set_got (operands[0], NULL_RTX);"
11766 [(set_attr "type" "multi")
11767 (set_attr "length" "12")])
11769 (define_insn "set_got_labelled"
11770 [(set (match_operand:SI 0 "register_operand" "=r")
11771 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11773 (clobber (reg:CC FLAGS_REG))]
11775 "* return output_set_got (operands[0], operands[1]);"
11776 [(set_attr "type" "multi")
11777 (set_attr "length" "12")])
11779 (define_insn "set_got_rex64"
11780 [(set (match_operand:DI 0 "register_operand" "=r")
11781 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11783 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11784 [(set_attr "type" "lea")
11785 (set_attr "length_address" "4")
11786 (set_attr "mode" "DI")])
11788 (define_insn "set_rip_rex64"
11789 [(set (match_operand:DI 0 "register_operand" "=r")
11790 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11792 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11793 [(set_attr "type" "lea")
11794 (set_attr "length_address" "4")
11795 (set_attr "mode" "DI")])
11797 (define_insn "set_got_offset_rex64"
11798 [(set (match_operand:DI 0 "register_operand" "=r")
11800 [(label_ref (match_operand 1 "" ""))]
11801 UNSPEC_SET_GOT_OFFSET))]
11803 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11804 [(set_attr "type" "imov")
11805 (set_attr "length_immediate" "0")
11806 (set_attr "length_address" "8")
11807 (set_attr "mode" "DI")])
11809 (define_expand "epilogue"
11812 "ix86_expand_epilogue (1); DONE;")
11814 (define_expand "sibcall_epilogue"
11817 "ix86_expand_epilogue (0); DONE;")
11819 (define_expand "eh_return"
11820 [(use (match_operand 0 "register_operand" ""))]
11823 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11825 /* Tricky bit: we write the address of the handler to which we will
11826 be returning into someone else's stack frame, one word below the
11827 stack address we wish to restore. */
11828 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11829 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11830 tmp = gen_rtx_MEM (Pmode, tmp);
11831 emit_move_insn (tmp, ra);
11833 emit_jump_insn (gen_eh_return_internal ());
11838 (define_insn_and_split "eh_return_internal"
11842 "epilogue_completed"
11844 "ix86_expand_epilogue (2); DONE;")
11846 (define_insn "leave"
11847 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11848 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11849 (clobber (mem:BLK (scratch)))]
11852 [(set_attr "type" "leave")])
11854 (define_insn "leave_rex64"
11855 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11856 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11857 (clobber (mem:BLK (scratch)))]
11860 [(set_attr "type" "leave")])
11862 ;; Handle -fsplit-stack.
11864 (define_expand "split_stack_prologue"
11868 ix86_expand_split_stack_prologue ();
11872 ;; In order to support the call/return predictor, we use a return
11873 ;; instruction which the middle-end doesn't see.
11874 (define_insn "split_stack_return"
11875 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11876 UNSPECV_SPLIT_STACK_RETURN)]
11879 if (operands[0] == const0_rtx)
11884 [(set_attr "atom_unit" "jeu")
11885 (set_attr "modrm" "0")
11886 (set (attr "length")
11887 (if_then_else (match_operand:SI 0 "const0_operand" "")
11890 (set (attr "length_immediate")
11891 (if_then_else (match_operand:SI 0 "const0_operand" "")
11895 ;; If there are operand 0 bytes available on the stack, jump to
11898 (define_expand "split_stack_space_check"
11899 [(set (pc) (if_then_else
11900 (ltu (minus (reg SP_REG)
11901 (match_operand 0 "register_operand" ""))
11902 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11903 (label_ref (match_operand 1 "" ""))
11907 rtx reg, size, limit;
11909 reg = gen_reg_rtx (Pmode);
11910 size = force_reg (Pmode, operands[0]);
11911 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11912 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11913 UNSPEC_STACK_CHECK);
11914 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11915 ix86_expand_branch (GEU, reg, limit, operands[1]);
11920 ;; Bit manipulation instructions.
11922 (define_expand "ffs<mode>2"
11923 [(set (match_dup 2) (const_int -1))
11924 (parallel [(set (reg:CCZ FLAGS_REG)
11926 (match_operand:SWI48 1 "nonimmediate_operand" "")
11928 (set (match_operand:SWI48 0 "register_operand" "")
11929 (ctz:SWI48 (match_dup 1)))])
11930 (set (match_dup 0) (if_then_else:SWI48
11931 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11934 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11935 (clobber (reg:CC FLAGS_REG))])]
11938 if (<MODE>mode == SImode && !TARGET_CMOVE)
11940 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11943 operands[2] = gen_reg_rtx (<MODE>mode);
11946 (define_insn_and_split "ffssi2_no_cmove"
11947 [(set (match_operand:SI 0 "register_operand" "=r")
11948 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11949 (clobber (match_scratch:SI 2 "=&q"))
11950 (clobber (reg:CC FLAGS_REG))]
11953 "&& reload_completed"
11954 [(parallel [(set (reg:CCZ FLAGS_REG)
11955 (compare:CCZ (match_dup 1) (const_int 0)))
11956 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11957 (set (strict_low_part (match_dup 3))
11958 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11959 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11960 (clobber (reg:CC FLAGS_REG))])
11961 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11962 (clobber (reg:CC FLAGS_REG))])
11963 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11964 (clobber (reg:CC FLAGS_REG))])]
11966 operands[3] = gen_lowpart (QImode, operands[2]);
11967 ix86_expand_clear (operands[2]);
11970 (define_insn "*ffs<mode>_1"
11971 [(set (reg:CCZ FLAGS_REG)
11972 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11974 (set (match_operand:SWI48 0 "register_operand" "=r")
11975 (ctz:SWI48 (match_dup 1)))]
11977 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11978 [(set_attr "type" "alu1")
11979 (set_attr "prefix_0f" "1")
11980 (set_attr "mode" "<MODE>")])
11982 (define_insn "ctz<mode>2"
11983 [(set (match_operand:SWI248 0 "register_operand" "=r")
11984 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11985 (clobber (reg:CC FLAGS_REG))]
11989 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11991 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
11993 [(set_attr "type" "alu1")
11994 (set_attr "prefix_0f" "1")
11995 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
11996 (set_attr "mode" "<MODE>")])
11998 (define_expand "clz<mode>2"
12000 [(set (match_operand:SWI248 0 "register_operand" "")
12003 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12004 (clobber (reg:CC FLAGS_REG))])
12006 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12007 (clobber (reg:CC FLAGS_REG))])]
12012 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12015 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12018 (define_insn "clz<mode>2_lzcnt"
12019 [(set (match_operand:SWI248 0 "register_operand" "=r")
12020 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12021 (clobber (reg:CC FLAGS_REG))]
12023 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12024 [(set_attr "prefix_rep" "1")
12025 (set_attr "type" "bitmanip")
12026 (set_attr "mode" "<MODE>")])
12028 ;; BMI instructions.
12029 (define_insn "*bmi_andn_<mode>"
12030 [(set (match_operand:SWI48 0 "register_operand" "=r")
12033 (match_operand:SWI48 1 "register_operand" "r"))
12034 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12035 (clobber (reg:CC FLAGS_REG))]
12037 "andn\t{%2, %1, %0|%0, %1, %2}"
12038 [(set_attr "type" "bitmanip")
12039 (set_attr "mode" "<MODE>")])
12041 (define_insn "bmi_bextr_<mode>"
12042 [(set (match_operand:SWI48 0 "register_operand" "=r")
12043 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12044 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12046 (clobber (reg:CC FLAGS_REG))]
12048 "bextr\t{%2, %1, %0|%0, %1, %2}"
12049 [(set_attr "type" "bitmanip")
12050 (set_attr "mode" "<MODE>")])
12052 (define_insn "*bmi_blsi_<mode>"
12053 [(set (match_operand:SWI48 0 "register_operand" "=r")
12056 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12058 (clobber (reg:CC FLAGS_REG))]
12060 "blsi\t{%1, %0|%0, %1}"
12061 [(set_attr "type" "bitmanip")
12062 (set_attr "mode" "<MODE>")])
12064 (define_insn "*bmi_blsmsk_<mode>"
12065 [(set (match_operand:SWI48 0 "register_operand" "=r")
12068 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12071 (clobber (reg:CC FLAGS_REG))]
12073 "blsmsk\t{%1, %0|%0, %1}"
12074 [(set_attr "type" "bitmanip")
12075 (set_attr "mode" "<MODE>")])
12077 (define_insn "*bmi_blsr_<mode>"
12078 [(set (match_operand:SWI48 0 "register_operand" "=r")
12081 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12084 (clobber (reg:CC FLAGS_REG))]
12086 "blsr\t{%1, %0|%0, %1}"
12087 [(set_attr "type" "bitmanip")
12088 (set_attr "mode" "<MODE>")])
12090 ;; BMI2 instructions.
12091 (define_insn "bmi2_bzhi_<mode>3"
12092 [(set (match_operand:SWI48 0 "register_operand" "=r")
12093 (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
12094 (lshiftrt:SWI48 (const_int -1)
12095 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
12096 (clobber (reg:CC FLAGS_REG))]
12098 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12099 [(set_attr "type" "bitmanip")
12100 (set_attr "prefix" "vex")
12101 (set_attr "mode" "<MODE>")])
12103 (define_insn "bmi2_pdep_<mode>3"
12104 [(set (match_operand:SWI48 0 "register_operand" "=r")
12105 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12106 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12109 "pdep\t{%2, %1, %0|%0, %1, %2}"
12110 [(set_attr "type" "bitmanip")
12111 (set_attr "prefix" "vex")
12112 (set_attr "mode" "<MODE>")])
12114 (define_insn "bmi2_pext_<mode>3"
12115 [(set (match_operand:SWI48 0 "register_operand" "=r")
12116 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12117 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12120 "pext\t{%2, %1, %0|%0, %1, %2}"
12121 [(set_attr "type" "bitmanip")
12122 (set_attr "prefix" "vex")
12123 (set_attr "mode" "<MODE>")])
12125 ;; TBM instructions.
12126 (define_insn "tbm_bextri_<mode>"
12127 [(set (match_operand:SWI48 0 "register_operand" "=r")
12128 (zero_extract:SWI48
12129 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12130 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12131 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12132 (clobber (reg:CC FLAGS_REG))]
12135 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12136 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12138 [(set_attr "type" "bitmanip")
12139 (set_attr "mode" "<MODE>")])
12141 (define_insn "*tbm_blcfill_<mode>"
12142 [(set (match_operand:SWI48 0 "register_operand" "=r")
12145 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12148 (clobber (reg:CC FLAGS_REG))]
12150 "blcfill\t{%1, %0|%0, %1}"
12151 [(set_attr "type" "bitmanip")
12152 (set_attr "mode" "<MODE>")])
12154 (define_insn "*tbm_blci_<mode>"
12155 [(set (match_operand:SWI48 0 "register_operand" "=r")
12159 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12162 (clobber (reg:CC FLAGS_REG))]
12164 "blci\t{%1, %0|%0, %1}"
12165 [(set_attr "type" "bitmanip")
12166 (set_attr "mode" "<MODE>")])
12168 (define_insn "*tbm_blcic_<mode>"
12169 [(set (match_operand:SWI48 0 "register_operand" "=r")
12172 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12176 (clobber (reg:CC FLAGS_REG))]
12178 "blcic\t{%1, %0|%0, %1}"
12179 [(set_attr "type" "bitmanip")
12180 (set_attr "mode" "<MODE>")])
12182 (define_insn "*tbm_blcmsk_<mode>"
12183 [(set (match_operand:SWI48 0 "register_operand" "=r")
12186 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12189 (clobber (reg:CC FLAGS_REG))]
12191 "blcmsk\t{%1, %0|%0, %1}"
12192 [(set_attr "type" "bitmanip")
12193 (set_attr "mode" "<MODE>")])
12195 (define_insn "*tbm_blcs_<mode>"
12196 [(set (match_operand:SWI48 0 "register_operand" "=r")
12199 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12202 (clobber (reg:CC FLAGS_REG))]
12204 "blcs\t{%1, %0|%0, %1}"
12205 [(set_attr "type" "bitmanip")
12206 (set_attr "mode" "<MODE>")])
12208 (define_insn "*tbm_blsfill_<mode>"
12209 [(set (match_operand:SWI48 0 "register_operand" "=r")
12212 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12215 (clobber (reg:CC FLAGS_REG))]
12217 "blsfill\t{%1, %0|%0, %1}"
12218 [(set_attr "type" "bitmanip")
12219 (set_attr "mode" "<MODE>")])
12221 (define_insn "*tbm_blsic_<mode>"
12222 [(set (match_operand:SWI48 0 "register_operand" "=r")
12225 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12229 (clobber (reg:CC FLAGS_REG))]
12231 "blsic\t{%1, %0|%0, %1}"
12232 [(set_attr "type" "bitmanip")
12233 (set_attr "mode" "<MODE>")])
12235 (define_insn "*tbm_t1mskc_<mode>"
12236 [(set (match_operand:SWI48 0 "register_operand" "=r")
12239 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12243 (clobber (reg:CC FLAGS_REG))]
12245 "t1mskc\t{%1, %0|%0, %1}"
12246 [(set_attr "type" "bitmanip")
12247 (set_attr "mode" "<MODE>")])
12249 (define_insn "*tbm_tzmsk_<mode>"
12250 [(set (match_operand:SWI48 0 "register_operand" "=r")
12253 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12257 (clobber (reg:CC FLAGS_REG))]
12259 "tzmsk\t{%1, %0|%0, %1}"
12260 [(set_attr "type" "bitmanip")
12261 (set_attr "mode" "<MODE>")])
12263 (define_insn "bsr_rex64"
12264 [(set (match_operand:DI 0 "register_operand" "=r")
12265 (minus:DI (const_int 63)
12266 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12267 (clobber (reg:CC FLAGS_REG))]
12269 "bsr{q}\t{%1, %0|%0, %1}"
12270 [(set_attr "type" "alu1")
12271 (set_attr "prefix_0f" "1")
12272 (set_attr "mode" "DI")])
12275 [(set (match_operand:SI 0 "register_operand" "=r")
12276 (minus:SI (const_int 31)
12277 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12278 (clobber (reg:CC FLAGS_REG))]
12280 "bsr{l}\t{%1, %0|%0, %1}"
12281 [(set_attr "type" "alu1")
12282 (set_attr "prefix_0f" "1")
12283 (set_attr "mode" "SI")])
12285 (define_insn "*bsrhi"
12286 [(set (match_operand:HI 0 "register_operand" "=r")
12287 (minus:HI (const_int 15)
12288 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12289 (clobber (reg:CC FLAGS_REG))]
12291 "bsr{w}\t{%1, %0|%0, %1}"
12292 [(set_attr "type" "alu1")
12293 (set_attr "prefix_0f" "1")
12294 (set_attr "mode" "HI")])
12296 (define_insn "popcount<mode>2"
12297 [(set (match_operand:SWI248 0 "register_operand" "=r")
12299 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12300 (clobber (reg:CC FLAGS_REG))]
12304 return "popcnt\t{%1, %0|%0, %1}";
12306 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12309 [(set_attr "prefix_rep" "1")
12310 (set_attr "type" "bitmanip")
12311 (set_attr "mode" "<MODE>")])
12313 (define_insn "*popcount<mode>2_cmp"
12314 [(set (reg FLAGS_REG)
12317 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12319 (set (match_operand:SWI248 0 "register_operand" "=r")
12320 (popcount:SWI248 (match_dup 1)))]
12321 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12324 return "popcnt\t{%1, %0|%0, %1}";
12326 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12329 [(set_attr "prefix_rep" "1")
12330 (set_attr "type" "bitmanip")
12331 (set_attr "mode" "<MODE>")])
12333 (define_insn "*popcountsi2_cmp_zext"
12334 [(set (reg FLAGS_REG)
12336 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12338 (set (match_operand:DI 0 "register_operand" "=r")
12339 (zero_extend:DI(popcount:SI (match_dup 1))))]
12340 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12343 return "popcnt\t{%1, %0|%0, %1}";
12345 return "popcnt{l}\t{%1, %0|%0, %1}";
12348 [(set_attr "prefix_rep" "1")
12349 (set_attr "type" "bitmanip")
12350 (set_attr "mode" "SI")])
12352 (define_expand "bswap<mode>2"
12353 [(set (match_operand:SWI48 0 "register_operand" "")
12354 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12357 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12359 rtx x = operands[0];
12361 emit_move_insn (x, operands[1]);
12362 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12363 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12364 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12369 (define_insn "*bswap<mode>2_movbe"
12370 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12371 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12373 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12376 movbe\t{%1, %0|%0, %1}
12377 movbe\t{%1, %0|%0, %1}"
12378 [(set_attr "type" "bitmanip,imov,imov")
12379 (set_attr "modrm" "0,1,1")
12380 (set_attr "prefix_0f" "*,1,1")
12381 (set_attr "prefix_extra" "*,1,1")
12382 (set_attr "mode" "<MODE>")])
12384 (define_insn "*bswap<mode>2_1"
12385 [(set (match_operand:SWI48 0 "register_operand" "=r")
12386 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12389 [(set_attr "type" "bitmanip")
12390 (set_attr "modrm" "0")
12391 (set_attr "mode" "<MODE>")])
12393 (define_insn "*bswaphi_lowpart_1"
12394 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12395 (bswap:HI (match_dup 0)))
12396 (clobber (reg:CC FLAGS_REG))]
12397 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12399 xchg{b}\t{%h0, %b0|%b0, %h0}
12400 rol{w}\t{$8, %0|%0, 8}"
12401 [(set_attr "length" "2,4")
12402 (set_attr "mode" "QI,HI")])
12404 (define_insn "bswaphi_lowpart"
12405 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12406 (bswap:HI (match_dup 0)))
12407 (clobber (reg:CC FLAGS_REG))]
12409 "rol{w}\t{$8, %0|%0, 8}"
12410 [(set_attr "length" "4")
12411 (set_attr "mode" "HI")])
12413 (define_expand "paritydi2"
12414 [(set (match_operand:DI 0 "register_operand" "")
12415 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12418 rtx scratch = gen_reg_rtx (QImode);
12421 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12422 NULL_RTX, operands[1]));
12424 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12425 gen_rtx_REG (CCmode, FLAGS_REG),
12427 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12430 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12433 rtx tmp = gen_reg_rtx (SImode);
12435 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12436 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12441 (define_expand "paritysi2"
12442 [(set (match_operand:SI 0 "register_operand" "")
12443 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12446 rtx scratch = gen_reg_rtx (QImode);
12449 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12451 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12452 gen_rtx_REG (CCmode, FLAGS_REG),
12454 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12456 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12460 (define_insn_and_split "paritydi2_cmp"
12461 [(set (reg:CC FLAGS_REG)
12462 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12464 (clobber (match_scratch:DI 0 "=r"))
12465 (clobber (match_scratch:SI 1 "=&r"))
12466 (clobber (match_scratch:HI 2 "=Q"))]
12469 "&& reload_completed"
12471 [(set (match_dup 1)
12472 (xor:SI (match_dup 1) (match_dup 4)))
12473 (clobber (reg:CC FLAGS_REG))])
12475 [(set (reg:CC FLAGS_REG)
12476 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12477 (clobber (match_dup 1))
12478 (clobber (match_dup 2))])]
12480 operands[4] = gen_lowpart (SImode, operands[3]);
12484 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12485 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12488 operands[1] = gen_highpart (SImode, operands[3]);
12491 (define_insn_and_split "paritysi2_cmp"
12492 [(set (reg:CC FLAGS_REG)
12493 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12495 (clobber (match_scratch:SI 0 "=r"))
12496 (clobber (match_scratch:HI 1 "=&Q"))]
12499 "&& reload_completed"
12501 [(set (match_dup 1)
12502 (xor:HI (match_dup 1) (match_dup 3)))
12503 (clobber (reg:CC FLAGS_REG))])
12505 [(set (reg:CC FLAGS_REG)
12506 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12507 (clobber (match_dup 1))])]
12509 operands[3] = gen_lowpart (HImode, operands[2]);
12511 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12512 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12515 (define_insn "*parityhi2_cmp"
12516 [(set (reg:CC FLAGS_REG)
12517 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12519 (clobber (match_scratch:HI 0 "=Q"))]
12521 "xor{b}\t{%h0, %b0|%b0, %h0}"
12522 [(set_attr "length" "2")
12523 (set_attr "mode" "HI")])
12526 ;; Thread-local storage patterns for ELF.
12528 ;; Note that these code sequences must appear exactly as shown
12529 ;; in order to allow linker relaxation.
12531 (define_insn "*tls_global_dynamic_32_gnu"
12532 [(set (match_operand:SI 0 "register_operand" "=a")
12534 [(match_operand:SI 1 "register_operand" "b")
12535 (match_operand:SI 2 "tls_symbolic_operand" "")
12536 (match_operand:SI 3 "constant_call_address_operand" "z")]
12538 (clobber (match_scratch:SI 4 "=d"))
12539 (clobber (match_scratch:SI 5 "=c"))
12540 (clobber (reg:CC FLAGS_REG))]
12541 "!TARGET_64BIT && TARGET_GNU_TLS"
12544 ("lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}", operands);
12545 if (TARGET_SUN_TLS)
12546 #ifdef HAVE_AS_IX86_TLSGDPLT
12547 return "call\t%a2@tlsgdplt";
12549 return "call\t%p3@plt";
12551 return "call\t%P3";
12553 [(set_attr "type" "multi")
12554 (set_attr "length" "12")])
12556 (define_expand "tls_global_dynamic_32"
12558 [(set (match_operand:SI 0 "register_operand" "")
12559 (unspec:SI [(match_operand:SI 2 "register_operand" "")
12560 (match_operand:SI 1 "tls_symbolic_operand" "")
12561 (match_operand:SI 3 "constant_call_address_operand" "")]
12563 (clobber (match_scratch:SI 4 ""))
12564 (clobber (match_scratch:SI 5 ""))
12565 (clobber (reg:CC FLAGS_REG))])])
12567 (define_insn "*tls_global_dynamic_64"
12568 [(set (match_operand:DI 0 "register_operand" "=a")
12570 (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12571 (match_operand:DI 3 "" "")))
12572 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12577 fputs (ASM_BYTE "0x66\n", asm_out_file);
12579 ("lea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}", operands);
12580 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12581 fputs ("\trex64\n", asm_out_file);
12582 if (TARGET_SUN_TLS)
12583 return "call\t%p2@plt";
12584 return "call\t%P2";
12586 [(set_attr "type" "multi")
12587 (set (attr "length")
12588 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12590 (define_expand "tls_global_dynamic_64"
12592 [(set (match_operand:DI 0 "register_operand" "")
12594 (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12596 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12599 (define_insn "*tls_local_dynamic_base_32_gnu"
12600 [(set (match_operand:SI 0 "register_operand" "=a")
12602 [(match_operand:SI 1 "register_operand" "b")
12603 (match_operand:SI 2 "constant_call_address_operand" "z")]
12604 UNSPEC_TLS_LD_BASE))
12605 (clobber (match_scratch:SI 3 "=d"))
12606 (clobber (match_scratch:SI 4 "=c"))
12607 (clobber (reg:CC FLAGS_REG))]
12608 "!TARGET_64BIT && TARGET_GNU_TLS"
12611 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12612 if (TARGET_SUN_TLS)
12613 #ifdef HAVE_AS_IX86_TLSLDMPLT
12614 return "call\t%&@tlsldmplt";
12616 return "call\t%p2@plt";
12618 return "call\t%P2";
12620 [(set_attr "type" "multi")
12621 (set_attr "length" "11")])
12623 (define_expand "tls_local_dynamic_base_32"
12625 [(set (match_operand:SI 0 "register_operand" "")
12627 [(match_operand:SI 1 "register_operand" "")
12628 (match_operand:SI 2 "constant_call_address_operand" "")]
12629 UNSPEC_TLS_LD_BASE))
12630 (clobber (match_scratch:SI 3 ""))
12631 (clobber (match_scratch:SI 4 ""))
12632 (clobber (reg:CC FLAGS_REG))])])
12634 (define_insn "*tls_local_dynamic_base_64"
12635 [(set (match_operand:DI 0 "register_operand" "=a")
12637 (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12638 (match_operand:DI 2 "" "")))
12639 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12643 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12644 if (TARGET_SUN_TLS)
12645 return "call\t%p1@plt";
12646 return "call\t%P1";
12648 [(set_attr "type" "multi")
12649 (set_attr "length" "12")])
12651 (define_expand "tls_local_dynamic_base_64"
12653 [(set (match_operand:DI 0 "register_operand" "")
12655 (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12657 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12659 ;; Local dynamic of a single variable is a lose. Show combine how
12660 ;; to convert that back to global dynamic.
12662 (define_insn_and_split "*tls_local_dynamic_32_once"
12663 [(set (match_operand:SI 0 "register_operand" "=a")
12665 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12666 (match_operand:SI 2 "constant_call_address_operand" "z")]
12667 UNSPEC_TLS_LD_BASE)
12668 (const:SI (unspec:SI
12669 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12671 (clobber (match_scratch:SI 4 "=d"))
12672 (clobber (match_scratch:SI 5 "=c"))
12673 (clobber (reg:CC FLAGS_REG))]
12678 [(set (match_dup 0)
12679 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12681 (clobber (match_dup 4))
12682 (clobber (match_dup 5))
12683 (clobber (reg:CC FLAGS_REG))])])
12685 ;; Segment register for the thread base ptr load
12686 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12688 ;; Load and add the thread base pointer from %<tp_seg>:0.
12689 (define_insn "*load_tp_x32"
12690 [(set (match_operand:SI 0 "register_operand" "=r")
12691 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12693 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12694 [(set_attr "type" "imov")
12695 (set_attr "modrm" "0")
12696 (set_attr "length" "7")
12697 (set_attr "memory" "load")
12698 (set_attr "imm_disp" "false")])
12700 (define_insn "*load_tp_x32_zext"
12701 [(set (match_operand:DI 0 "register_operand" "=r")
12702 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12704 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12705 [(set_attr "type" "imov")
12706 (set_attr "modrm" "0")
12707 (set_attr "length" "7")
12708 (set_attr "memory" "load")
12709 (set_attr "imm_disp" "false")])
12711 (define_insn "*load_tp_<mode>"
12712 [(set (match_operand:P 0 "register_operand" "=r")
12713 (unspec:P [(const_int 0)] UNSPEC_TP))]
12715 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12716 [(set_attr "type" "imov")
12717 (set_attr "modrm" "0")
12718 (set_attr "length" "7")
12719 (set_attr "memory" "load")
12720 (set_attr "imm_disp" "false")])
12722 (define_insn "*add_tp_x32"
12723 [(set (match_operand:SI 0 "register_operand" "=r")
12724 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12725 (match_operand:SI 1 "register_operand" "0")))
12726 (clobber (reg:CC FLAGS_REG))]
12728 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12729 [(set_attr "type" "alu")
12730 (set_attr "modrm" "0")
12731 (set_attr "length" "7")
12732 (set_attr "memory" "load")
12733 (set_attr "imm_disp" "false")])
12735 (define_insn "*add_tp_x32_zext"
12736 [(set (match_operand:DI 0 "register_operand" "=r")
12738 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12739 (match_operand:SI 1 "register_operand" "0"))))
12740 (clobber (reg:CC FLAGS_REG))]
12742 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12743 [(set_attr "type" "alu")
12744 (set_attr "modrm" "0")
12745 (set_attr "length" "7")
12746 (set_attr "memory" "load")
12747 (set_attr "imm_disp" "false")])
12749 (define_insn "*add_tp_<mode>"
12750 [(set (match_operand:P 0 "register_operand" "=r")
12751 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12752 (match_operand:P 1 "register_operand" "0")))
12753 (clobber (reg:CC FLAGS_REG))]
12755 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12756 [(set_attr "type" "alu")
12757 (set_attr "modrm" "0")
12758 (set_attr "length" "7")
12759 (set_attr "memory" "load")
12760 (set_attr "imm_disp" "false")])
12762 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12763 ;; %rax as destination of the initial executable code sequence.
12764 (define_insn "tls_initial_exec_64_sun"
12765 [(set (match_operand:DI 0 "register_operand" "=a")
12767 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12768 UNSPEC_TLS_IE_SUN))
12769 (clobber (reg:CC FLAGS_REG))]
12770 "TARGET_64BIT && TARGET_SUN_TLS"
12773 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12774 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12776 [(set_attr "type" "multi")])
12778 ;; GNU2 TLS patterns can be split.
12780 (define_expand "tls_dynamic_gnu2_32"
12781 [(set (match_dup 3)
12782 (plus:SI (match_operand:SI 2 "register_operand" "")
12784 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12787 [(set (match_operand:SI 0 "register_operand" "")
12788 (unspec:SI [(match_dup 1) (match_dup 3)
12789 (match_dup 2) (reg:SI SP_REG)]
12791 (clobber (reg:CC FLAGS_REG))])]
12792 "!TARGET_64BIT && TARGET_GNU2_TLS"
12794 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12795 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12798 (define_insn "*tls_dynamic_gnu2_lea_32"
12799 [(set (match_operand:SI 0 "register_operand" "=r")
12800 (plus:SI (match_operand:SI 1 "register_operand" "b")
12802 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12803 UNSPEC_TLSDESC))))]
12804 "!TARGET_64BIT && TARGET_GNU2_TLS"
12805 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12806 [(set_attr "type" "lea")
12807 (set_attr "mode" "SI")
12808 (set_attr "length" "6")
12809 (set_attr "length_address" "4")])
12811 (define_insn "*tls_dynamic_gnu2_call_32"
12812 [(set (match_operand:SI 0 "register_operand" "=a")
12813 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12814 (match_operand:SI 2 "register_operand" "0")
12815 ;; we have to make sure %ebx still points to the GOT
12816 (match_operand:SI 3 "register_operand" "b")
12819 (clobber (reg:CC FLAGS_REG))]
12820 "!TARGET_64BIT && TARGET_GNU2_TLS"
12821 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12822 [(set_attr "type" "call")
12823 (set_attr "length" "2")
12824 (set_attr "length_address" "0")])
12826 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12827 [(set (match_operand:SI 0 "register_operand" "=&a")
12829 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12830 (match_operand:SI 4 "" "")
12831 (match_operand:SI 2 "register_operand" "b")
12834 (const:SI (unspec:SI
12835 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12837 (clobber (reg:CC FLAGS_REG))]
12838 "!TARGET_64BIT && TARGET_GNU2_TLS"
12841 [(set (match_dup 0) (match_dup 5))]
12843 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12844 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12847 (define_expand "tls_dynamic_gnu2_64"
12848 [(set (match_dup 2)
12849 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12852 [(set (match_operand:DI 0 "register_operand" "")
12853 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12855 (clobber (reg:CC FLAGS_REG))])]
12856 "TARGET_64BIT && TARGET_GNU2_TLS"
12858 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12859 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12862 (define_insn "*tls_dynamic_gnu2_lea_64"
12863 [(set (match_operand:DI 0 "register_operand" "=r")
12864 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12866 "TARGET_64BIT && TARGET_GNU2_TLS"
12867 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12868 [(set_attr "type" "lea")
12869 (set_attr "mode" "DI")
12870 (set_attr "length" "7")
12871 (set_attr "length_address" "4")])
12873 (define_insn "*tls_dynamic_gnu2_call_64"
12874 [(set (match_operand:DI 0 "register_operand" "=a")
12875 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")
12876 (match_operand:DI 2 "register_operand" "0")
12879 (clobber (reg:CC FLAGS_REG))]
12880 "TARGET_64BIT && TARGET_GNU2_TLS"
12881 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12882 [(set_attr "type" "call")
12883 (set_attr "length" "2")
12884 (set_attr "length_address" "0")])
12886 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12887 [(set (match_operand:DI 0 "register_operand" "=&a")
12889 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12890 (match_operand:DI 3 "" "")
12893 (const:DI (unspec:DI
12894 [(match_operand 1 "tls_symbolic_operand" "")]
12896 (clobber (reg:CC FLAGS_REG))]
12897 "TARGET_64BIT && TARGET_GNU2_TLS"
12900 [(set (match_dup 0) (match_dup 4))]
12902 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12903 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12906 ;; These patterns match the binary 387 instructions for addM3, subM3,
12907 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12908 ;; SFmode. The first is the normal insn, the second the same insn but
12909 ;; with one operand a conversion, and the third the same insn but with
12910 ;; the other operand a conversion. The conversion may be SFmode or
12911 ;; SImode if the target mode DFmode, but only SImode if the target mode
12914 ;; Gcc is slightly more smart about handling normal two address instructions
12915 ;; so use special patterns for add and mull.
12917 (define_insn "*fop_<mode>_comm_mixed"
12918 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12919 (match_operator:MODEF 3 "binary_fp_operator"
12920 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12921 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12922 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12923 && COMMUTATIVE_ARITH_P (operands[3])
12924 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12925 "* return output_387_binary_op (insn, operands);"
12926 [(set (attr "type")
12927 (if_then_else (eq_attr "alternative" "1,2")
12928 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12929 (const_string "ssemul")
12930 (const_string "sseadd"))
12931 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12932 (const_string "fmul")
12933 (const_string "fop"))))
12934 (set_attr "isa" "*,noavx,avx")
12935 (set_attr "prefix" "orig,orig,vex")
12936 (set_attr "mode" "<MODE>")])
12938 (define_insn "*fop_<mode>_comm_sse"
12939 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12940 (match_operator:MODEF 3 "binary_fp_operator"
12941 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12942 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12943 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12944 && COMMUTATIVE_ARITH_P (operands[3])
12945 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12946 "* return output_387_binary_op (insn, operands);"
12947 [(set (attr "type")
12948 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12949 (const_string "ssemul")
12950 (const_string "sseadd")))
12951 (set_attr "isa" "noavx,avx")
12952 (set_attr "prefix" "orig,vex")
12953 (set_attr "mode" "<MODE>")])
12955 (define_insn "*fop_<mode>_comm_i387"
12956 [(set (match_operand:MODEF 0 "register_operand" "=f")
12957 (match_operator:MODEF 3 "binary_fp_operator"
12958 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12959 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12960 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12961 && COMMUTATIVE_ARITH_P (operands[3])
12962 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12963 "* return output_387_binary_op (insn, operands);"
12964 [(set (attr "type")
12965 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12966 (const_string "fmul")
12967 (const_string "fop")))
12968 (set_attr "mode" "<MODE>")])
12970 (define_insn "*fop_<mode>_1_mixed"
12971 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
12972 (match_operator:MODEF 3 "binary_fp_operator"
12973 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
12974 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
12975 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12976 && !COMMUTATIVE_ARITH_P (operands[3])
12977 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12978 "* return output_387_binary_op (insn, operands);"
12979 [(set (attr "type")
12980 (cond [(and (eq_attr "alternative" "2,3")
12981 (match_operand:MODEF 3 "mult_operator" ""))
12982 (const_string "ssemul")
12983 (and (eq_attr "alternative" "2,3")
12984 (match_operand:MODEF 3 "div_operator" ""))
12985 (const_string "ssediv")
12986 (eq_attr "alternative" "2,3")
12987 (const_string "sseadd")
12988 (match_operand:MODEF 3 "mult_operator" "")
12989 (const_string "fmul")
12990 (match_operand:MODEF 3 "div_operator" "")
12991 (const_string "fdiv")
12993 (const_string "fop")))
12994 (set_attr "isa" "*,*,noavx,avx")
12995 (set_attr "prefix" "orig,orig,orig,vex")
12996 (set_attr "mode" "<MODE>")])
12998 (define_insn "*rcpsf2_sse"
12999 [(set (match_operand:SF 0 "register_operand" "=x")
13000 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13003 "%vrcpss\t{%1, %d0|%d0, %1}"
13004 [(set_attr "type" "sse")
13005 (set_attr "atom_sse_attr" "rcp")
13006 (set_attr "prefix" "maybe_vex")
13007 (set_attr "mode" "SF")])
13009 (define_insn "*fop_<mode>_1_sse"
13010 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13011 (match_operator:MODEF 3 "binary_fp_operator"
13012 [(match_operand:MODEF 1 "register_operand" "0,x")
13013 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13014 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13015 && !COMMUTATIVE_ARITH_P (operands[3])"
13016 "* return output_387_binary_op (insn, operands);"
13017 [(set (attr "type")
13018 (cond [(match_operand:MODEF 3 "mult_operator" "")
13019 (const_string "ssemul")
13020 (match_operand:MODEF 3 "div_operator" "")
13021 (const_string "ssediv")
13023 (const_string "sseadd")))
13024 (set_attr "isa" "noavx,avx")
13025 (set_attr "prefix" "orig,vex")
13026 (set_attr "mode" "<MODE>")])
13028 ;; This pattern is not fully shadowed by the pattern above.
13029 (define_insn "*fop_<mode>_1_i387"
13030 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13031 (match_operator:MODEF 3 "binary_fp_operator"
13032 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13033 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13034 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13035 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13036 && !COMMUTATIVE_ARITH_P (operands[3])
13037 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13038 "* return output_387_binary_op (insn, operands);"
13039 [(set (attr "type")
13040 (cond [(match_operand:MODEF 3 "mult_operator" "")
13041 (const_string "fmul")
13042 (match_operand:MODEF 3 "div_operator" "")
13043 (const_string "fdiv")
13045 (const_string "fop")))
13046 (set_attr "mode" "<MODE>")])
13048 ;; ??? Add SSE splitters for these!
13049 (define_insn "*fop_<MODEF:mode>_2_i387"
13050 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13051 (match_operator:MODEF 3 "binary_fp_operator"
13053 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13054 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13055 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13056 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13057 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13058 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13059 [(set (attr "type")
13060 (cond [(match_operand:MODEF 3 "mult_operator" "")
13061 (const_string "fmul")
13062 (match_operand:MODEF 3 "div_operator" "")
13063 (const_string "fdiv")
13065 (const_string "fop")))
13066 (set_attr "fp_int_src" "true")
13067 (set_attr "mode" "<SWI24:MODE>")])
13069 (define_insn "*fop_<MODEF:mode>_3_i387"
13070 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13071 (match_operator:MODEF 3 "binary_fp_operator"
13072 [(match_operand:MODEF 1 "register_operand" "0,0")
13074 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13075 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13076 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13077 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13078 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13079 [(set (attr "type")
13080 (cond [(match_operand:MODEF 3 "mult_operator" "")
13081 (const_string "fmul")
13082 (match_operand:MODEF 3 "div_operator" "")
13083 (const_string "fdiv")
13085 (const_string "fop")))
13086 (set_attr "fp_int_src" "true")
13087 (set_attr "mode" "<MODE>")])
13089 (define_insn "*fop_df_4_i387"
13090 [(set (match_operand:DF 0 "register_operand" "=f,f")
13091 (match_operator:DF 3 "binary_fp_operator"
13093 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13094 (match_operand:DF 2 "register_operand" "0,f")]))]
13095 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13096 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13097 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13098 "* return output_387_binary_op (insn, operands);"
13099 [(set (attr "type")
13100 (cond [(match_operand:DF 3 "mult_operator" "")
13101 (const_string "fmul")
13102 (match_operand:DF 3 "div_operator" "")
13103 (const_string "fdiv")
13105 (const_string "fop")))
13106 (set_attr "mode" "SF")])
13108 (define_insn "*fop_df_5_i387"
13109 [(set (match_operand:DF 0 "register_operand" "=f,f")
13110 (match_operator:DF 3 "binary_fp_operator"
13111 [(match_operand:DF 1 "register_operand" "0,f")
13113 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13114 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13115 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13116 "* return output_387_binary_op (insn, operands);"
13117 [(set (attr "type")
13118 (cond [(match_operand:DF 3 "mult_operator" "")
13119 (const_string "fmul")
13120 (match_operand:DF 3 "div_operator" "")
13121 (const_string "fdiv")
13123 (const_string "fop")))
13124 (set_attr "mode" "SF")])
13126 (define_insn "*fop_df_6_i387"
13127 [(set (match_operand:DF 0 "register_operand" "=f,f")
13128 (match_operator:DF 3 "binary_fp_operator"
13130 (match_operand:SF 1 "register_operand" "0,f"))
13132 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13133 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13134 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13135 "* return output_387_binary_op (insn, operands);"
13136 [(set (attr "type")
13137 (cond [(match_operand:DF 3 "mult_operator" "")
13138 (const_string "fmul")
13139 (match_operand:DF 3 "div_operator" "")
13140 (const_string "fdiv")
13142 (const_string "fop")))
13143 (set_attr "mode" "SF")])
13145 (define_insn "*fop_xf_comm_i387"
13146 [(set (match_operand:XF 0 "register_operand" "=f")
13147 (match_operator:XF 3 "binary_fp_operator"
13148 [(match_operand:XF 1 "register_operand" "%0")
13149 (match_operand:XF 2 "register_operand" "f")]))]
13151 && COMMUTATIVE_ARITH_P (operands[3])"
13152 "* return output_387_binary_op (insn, operands);"
13153 [(set (attr "type")
13154 (if_then_else (match_operand:XF 3 "mult_operator" "")
13155 (const_string "fmul")
13156 (const_string "fop")))
13157 (set_attr "mode" "XF")])
13159 (define_insn "*fop_xf_1_i387"
13160 [(set (match_operand:XF 0 "register_operand" "=f,f")
13161 (match_operator:XF 3 "binary_fp_operator"
13162 [(match_operand:XF 1 "register_operand" "0,f")
13163 (match_operand:XF 2 "register_operand" "f,0")]))]
13165 && !COMMUTATIVE_ARITH_P (operands[3])"
13166 "* return output_387_binary_op (insn, operands);"
13167 [(set (attr "type")
13168 (cond [(match_operand:XF 3 "mult_operator" "")
13169 (const_string "fmul")
13170 (match_operand:XF 3 "div_operator" "")
13171 (const_string "fdiv")
13173 (const_string "fop")))
13174 (set_attr "mode" "XF")])
13176 (define_insn "*fop_xf_2_i387"
13177 [(set (match_operand:XF 0 "register_operand" "=f,f")
13178 (match_operator:XF 3 "binary_fp_operator"
13180 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13181 (match_operand:XF 2 "register_operand" "0,0")]))]
13182 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13183 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13184 [(set (attr "type")
13185 (cond [(match_operand:XF 3 "mult_operator" "")
13186 (const_string "fmul")
13187 (match_operand:XF 3 "div_operator" "")
13188 (const_string "fdiv")
13190 (const_string "fop")))
13191 (set_attr "fp_int_src" "true")
13192 (set_attr "mode" "<MODE>")])
13194 (define_insn "*fop_xf_3_i387"
13195 [(set (match_operand:XF 0 "register_operand" "=f,f")
13196 (match_operator:XF 3 "binary_fp_operator"
13197 [(match_operand:XF 1 "register_operand" "0,0")
13199 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13200 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13201 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13202 [(set (attr "type")
13203 (cond [(match_operand:XF 3 "mult_operator" "")
13204 (const_string "fmul")
13205 (match_operand:XF 3 "div_operator" "")
13206 (const_string "fdiv")
13208 (const_string "fop")))
13209 (set_attr "fp_int_src" "true")
13210 (set_attr "mode" "<MODE>")])
13212 (define_insn "*fop_xf_4_i387"
13213 [(set (match_operand:XF 0 "register_operand" "=f,f")
13214 (match_operator:XF 3 "binary_fp_operator"
13216 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13217 (match_operand:XF 2 "register_operand" "0,f")]))]
13219 "* return output_387_binary_op (insn, operands);"
13220 [(set (attr "type")
13221 (cond [(match_operand:XF 3 "mult_operator" "")
13222 (const_string "fmul")
13223 (match_operand:XF 3 "div_operator" "")
13224 (const_string "fdiv")
13226 (const_string "fop")))
13227 (set_attr "mode" "<MODE>")])
13229 (define_insn "*fop_xf_5_i387"
13230 [(set (match_operand:XF 0 "register_operand" "=f,f")
13231 (match_operator:XF 3 "binary_fp_operator"
13232 [(match_operand:XF 1 "register_operand" "0,f")
13234 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13236 "* return output_387_binary_op (insn, operands);"
13237 [(set (attr "type")
13238 (cond [(match_operand:XF 3 "mult_operator" "")
13239 (const_string "fmul")
13240 (match_operand:XF 3 "div_operator" "")
13241 (const_string "fdiv")
13243 (const_string "fop")))
13244 (set_attr "mode" "<MODE>")])
13246 (define_insn "*fop_xf_6_i387"
13247 [(set (match_operand:XF 0 "register_operand" "=f,f")
13248 (match_operator:XF 3 "binary_fp_operator"
13250 (match_operand:MODEF 1 "register_operand" "0,f"))
13252 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13254 "* return output_387_binary_op (insn, operands);"
13255 [(set (attr "type")
13256 (cond [(match_operand:XF 3 "mult_operator" "")
13257 (const_string "fmul")
13258 (match_operand:XF 3 "div_operator" "")
13259 (const_string "fdiv")
13261 (const_string "fop")))
13262 (set_attr "mode" "<MODE>")])
13265 [(set (match_operand 0 "register_operand" "")
13266 (match_operator 3 "binary_fp_operator"
13267 [(float (match_operand:SWI24 1 "register_operand" ""))
13268 (match_operand 2 "register_operand" "")]))]
13270 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13271 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13274 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13275 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13276 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13277 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13278 GET_MODE (operands[3]),
13281 ix86_free_from_memory (GET_MODE (operands[1]));
13286 [(set (match_operand 0 "register_operand" "")
13287 (match_operator 3 "binary_fp_operator"
13288 [(match_operand 1 "register_operand" "")
13289 (float (match_operand:SWI24 2 "register_operand" ""))]))]
13291 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13292 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13295 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13296 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13297 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13298 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13299 GET_MODE (operands[3]),
13302 ix86_free_from_memory (GET_MODE (operands[2]));
13306 ;; FPU special functions.
13308 ;; This pattern implements a no-op XFmode truncation for
13309 ;; all fancy i386 XFmode math functions.
13311 (define_insn "truncxf<mode>2_i387_noop_unspec"
13312 [(set (match_operand:MODEF 0 "register_operand" "=f")
13313 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13314 UNSPEC_TRUNC_NOOP))]
13315 "TARGET_USE_FANCY_MATH_387"
13316 "* return output_387_reg_move (insn, operands);"
13317 [(set_attr "type" "fmov")
13318 (set_attr "mode" "<MODE>")])
13320 (define_insn "sqrtxf2"
13321 [(set (match_operand:XF 0 "register_operand" "=f")
13322 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13323 "TARGET_USE_FANCY_MATH_387"
13325 [(set_attr "type" "fpspc")
13326 (set_attr "mode" "XF")
13327 (set_attr "athlon_decode" "direct")
13328 (set_attr "amdfam10_decode" "direct")
13329 (set_attr "bdver1_decode" "direct")])
13331 (define_insn "sqrt_extend<mode>xf2_i387"
13332 [(set (match_operand:XF 0 "register_operand" "=f")
13335 (match_operand:MODEF 1 "register_operand" "0"))))]
13336 "TARGET_USE_FANCY_MATH_387"
13338 [(set_attr "type" "fpspc")
13339 (set_attr "mode" "XF")
13340 (set_attr "athlon_decode" "direct")
13341 (set_attr "amdfam10_decode" "direct")
13342 (set_attr "bdver1_decode" "direct")])
13344 (define_insn "*rsqrtsf2_sse"
13345 [(set (match_operand:SF 0 "register_operand" "=x")
13346 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13349 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13350 [(set_attr "type" "sse")
13351 (set_attr "atom_sse_attr" "rcp")
13352 (set_attr "prefix" "maybe_vex")
13353 (set_attr "mode" "SF")])
13355 (define_expand "rsqrtsf2"
13356 [(set (match_operand:SF 0 "register_operand" "")
13357 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13361 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13365 (define_insn "*sqrt<mode>2_sse"
13366 [(set (match_operand:MODEF 0 "register_operand" "=x")
13368 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13369 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13370 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13371 [(set_attr "type" "sse")
13372 (set_attr "atom_sse_attr" "sqrt")
13373 (set_attr "prefix" "maybe_vex")
13374 (set_attr "mode" "<MODE>")
13375 (set_attr "athlon_decode" "*")
13376 (set_attr "amdfam10_decode" "*")
13377 (set_attr "bdver1_decode" "*")])
13379 (define_expand "sqrt<mode>2"
13380 [(set (match_operand:MODEF 0 "register_operand" "")
13382 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13383 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13384 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13386 if (<MODE>mode == SFmode
13388 && TARGET_RECIP_SQRT
13389 && !optimize_function_for_size_p (cfun)
13390 && flag_finite_math_only && !flag_trapping_math
13391 && flag_unsafe_math_optimizations)
13393 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13397 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13399 rtx op0 = gen_reg_rtx (XFmode);
13400 rtx op1 = force_reg (<MODE>mode, operands[1]);
13402 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13403 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13408 (define_insn "fpremxf4_i387"
13409 [(set (match_operand:XF 0 "register_operand" "=f")
13410 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13411 (match_operand:XF 3 "register_operand" "1")]
13413 (set (match_operand:XF 1 "register_operand" "=u")
13414 (unspec:XF [(match_dup 2) (match_dup 3)]
13416 (set (reg:CCFP FPSR_REG)
13417 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13419 "TARGET_USE_FANCY_MATH_387"
13421 [(set_attr "type" "fpspc")
13422 (set_attr "mode" "XF")])
13424 (define_expand "fmodxf3"
13425 [(use (match_operand:XF 0 "register_operand" ""))
13426 (use (match_operand:XF 1 "general_operand" ""))
13427 (use (match_operand:XF 2 "general_operand" ""))]
13428 "TARGET_USE_FANCY_MATH_387"
13430 rtx label = gen_label_rtx ();
13432 rtx op1 = gen_reg_rtx (XFmode);
13433 rtx op2 = gen_reg_rtx (XFmode);
13435 emit_move_insn (op2, operands[2]);
13436 emit_move_insn (op1, operands[1]);
13438 emit_label (label);
13439 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13440 ix86_emit_fp_unordered_jump (label);
13441 LABEL_NUSES (label) = 1;
13443 emit_move_insn (operands[0], op1);
13447 (define_expand "fmod<mode>3"
13448 [(use (match_operand:MODEF 0 "register_operand" ""))
13449 (use (match_operand:MODEF 1 "general_operand" ""))
13450 (use (match_operand:MODEF 2 "general_operand" ""))]
13451 "TARGET_USE_FANCY_MATH_387"
13453 rtx (*gen_truncxf) (rtx, rtx);
13455 rtx label = gen_label_rtx ();
13457 rtx op1 = gen_reg_rtx (XFmode);
13458 rtx op2 = gen_reg_rtx (XFmode);
13460 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13461 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13463 emit_label (label);
13464 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13465 ix86_emit_fp_unordered_jump (label);
13466 LABEL_NUSES (label) = 1;
13468 /* Truncate the result properly for strict SSE math. */
13469 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13470 && !TARGET_MIX_SSE_I387)
13471 gen_truncxf = gen_truncxf<mode>2;
13473 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13475 emit_insn (gen_truncxf (operands[0], op1));
13479 (define_insn "fprem1xf4_i387"
13480 [(set (match_operand:XF 0 "register_operand" "=f")
13481 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13482 (match_operand:XF 3 "register_operand" "1")]
13484 (set (match_operand:XF 1 "register_operand" "=u")
13485 (unspec:XF [(match_dup 2) (match_dup 3)]
13487 (set (reg:CCFP FPSR_REG)
13488 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13490 "TARGET_USE_FANCY_MATH_387"
13492 [(set_attr "type" "fpspc")
13493 (set_attr "mode" "XF")])
13495 (define_expand "remainderxf3"
13496 [(use (match_operand:XF 0 "register_operand" ""))
13497 (use (match_operand:XF 1 "general_operand" ""))
13498 (use (match_operand:XF 2 "general_operand" ""))]
13499 "TARGET_USE_FANCY_MATH_387"
13501 rtx label = gen_label_rtx ();
13503 rtx op1 = gen_reg_rtx (XFmode);
13504 rtx op2 = gen_reg_rtx (XFmode);
13506 emit_move_insn (op2, operands[2]);
13507 emit_move_insn (op1, operands[1]);
13509 emit_label (label);
13510 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13511 ix86_emit_fp_unordered_jump (label);
13512 LABEL_NUSES (label) = 1;
13514 emit_move_insn (operands[0], op1);
13518 (define_expand "remainder<mode>3"
13519 [(use (match_operand:MODEF 0 "register_operand" ""))
13520 (use (match_operand:MODEF 1 "general_operand" ""))
13521 (use (match_operand:MODEF 2 "general_operand" ""))]
13522 "TARGET_USE_FANCY_MATH_387"
13524 rtx (*gen_truncxf) (rtx, rtx);
13526 rtx label = gen_label_rtx ();
13528 rtx op1 = gen_reg_rtx (XFmode);
13529 rtx op2 = gen_reg_rtx (XFmode);
13531 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13532 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13534 emit_label (label);
13536 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13537 ix86_emit_fp_unordered_jump (label);
13538 LABEL_NUSES (label) = 1;
13540 /* Truncate the result properly for strict SSE math. */
13541 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13542 && !TARGET_MIX_SSE_I387)
13543 gen_truncxf = gen_truncxf<mode>2;
13545 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13547 emit_insn (gen_truncxf (operands[0], op1));
13551 (define_insn "*sinxf2_i387"
13552 [(set (match_operand:XF 0 "register_operand" "=f")
13553 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13554 "TARGET_USE_FANCY_MATH_387
13555 && flag_unsafe_math_optimizations"
13557 [(set_attr "type" "fpspc")
13558 (set_attr "mode" "XF")])
13560 (define_insn "*sin_extend<mode>xf2_i387"
13561 [(set (match_operand:XF 0 "register_operand" "=f")
13562 (unspec:XF [(float_extend:XF
13563 (match_operand:MODEF 1 "register_operand" "0"))]
13565 "TARGET_USE_FANCY_MATH_387
13566 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13567 || TARGET_MIX_SSE_I387)
13568 && flag_unsafe_math_optimizations"
13570 [(set_attr "type" "fpspc")
13571 (set_attr "mode" "XF")])
13573 (define_insn "*cosxf2_i387"
13574 [(set (match_operand:XF 0 "register_operand" "=f")
13575 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13576 "TARGET_USE_FANCY_MATH_387
13577 && flag_unsafe_math_optimizations"
13579 [(set_attr "type" "fpspc")
13580 (set_attr "mode" "XF")])
13582 (define_insn "*cos_extend<mode>xf2_i387"
13583 [(set (match_operand:XF 0 "register_operand" "=f")
13584 (unspec:XF [(float_extend:XF
13585 (match_operand:MODEF 1 "register_operand" "0"))]
13587 "TARGET_USE_FANCY_MATH_387
13588 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13589 || TARGET_MIX_SSE_I387)
13590 && flag_unsafe_math_optimizations"
13592 [(set_attr "type" "fpspc")
13593 (set_attr "mode" "XF")])
13595 ;; When sincos pattern is defined, sin and cos builtin functions will be
13596 ;; expanded to sincos pattern with one of its outputs left unused.
13597 ;; CSE pass will figure out if two sincos patterns can be combined,
13598 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13599 ;; depending on the unused output.
13601 (define_insn "sincosxf3"
13602 [(set (match_operand:XF 0 "register_operand" "=f")
13603 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13604 UNSPEC_SINCOS_COS))
13605 (set (match_operand:XF 1 "register_operand" "=u")
13606 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13607 "TARGET_USE_FANCY_MATH_387
13608 && flag_unsafe_math_optimizations"
13610 [(set_attr "type" "fpspc")
13611 (set_attr "mode" "XF")])
13614 [(set (match_operand:XF 0 "register_operand" "")
13615 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13616 UNSPEC_SINCOS_COS))
13617 (set (match_operand:XF 1 "register_operand" "")
13618 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13619 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13620 && can_create_pseudo_p ()"
13621 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13624 [(set (match_operand:XF 0 "register_operand" "")
13625 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13626 UNSPEC_SINCOS_COS))
13627 (set (match_operand:XF 1 "register_operand" "")
13628 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13629 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13630 && can_create_pseudo_p ()"
13631 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13633 (define_insn "sincos_extend<mode>xf3_i387"
13634 [(set (match_operand:XF 0 "register_operand" "=f")
13635 (unspec:XF [(float_extend:XF
13636 (match_operand:MODEF 2 "register_operand" "0"))]
13637 UNSPEC_SINCOS_COS))
13638 (set (match_operand:XF 1 "register_operand" "=u")
13639 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13640 "TARGET_USE_FANCY_MATH_387
13641 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13642 || TARGET_MIX_SSE_I387)
13643 && flag_unsafe_math_optimizations"
13645 [(set_attr "type" "fpspc")
13646 (set_attr "mode" "XF")])
13649 [(set (match_operand:XF 0 "register_operand" "")
13650 (unspec:XF [(float_extend:XF
13651 (match_operand:MODEF 2 "register_operand" ""))]
13652 UNSPEC_SINCOS_COS))
13653 (set (match_operand:XF 1 "register_operand" "")
13654 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13655 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13656 && can_create_pseudo_p ()"
13657 [(set (match_dup 1)
13658 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13661 [(set (match_operand:XF 0 "register_operand" "")
13662 (unspec:XF [(float_extend:XF
13663 (match_operand:MODEF 2 "register_operand" ""))]
13664 UNSPEC_SINCOS_COS))
13665 (set (match_operand:XF 1 "register_operand" "")
13666 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13667 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13668 && can_create_pseudo_p ()"
13669 [(set (match_dup 0)
13670 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13672 (define_expand "sincos<mode>3"
13673 [(use (match_operand:MODEF 0 "register_operand" ""))
13674 (use (match_operand:MODEF 1 "register_operand" ""))
13675 (use (match_operand:MODEF 2 "register_operand" ""))]
13676 "TARGET_USE_FANCY_MATH_387
13677 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13678 || TARGET_MIX_SSE_I387)
13679 && flag_unsafe_math_optimizations"
13681 rtx op0 = gen_reg_rtx (XFmode);
13682 rtx op1 = gen_reg_rtx (XFmode);
13684 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13685 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13686 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13690 (define_insn "fptanxf4_i387"
13691 [(set (match_operand:XF 0 "register_operand" "=f")
13692 (match_operand:XF 3 "const_double_operand" "F"))
13693 (set (match_operand:XF 1 "register_operand" "=u")
13694 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13696 "TARGET_USE_FANCY_MATH_387
13697 && flag_unsafe_math_optimizations
13698 && standard_80387_constant_p (operands[3]) == 2"
13700 [(set_attr "type" "fpspc")
13701 (set_attr "mode" "XF")])
13703 (define_insn "fptan_extend<mode>xf4_i387"
13704 [(set (match_operand:MODEF 0 "register_operand" "=f")
13705 (match_operand:MODEF 3 "const_double_operand" "F"))
13706 (set (match_operand:XF 1 "register_operand" "=u")
13707 (unspec:XF [(float_extend:XF
13708 (match_operand:MODEF 2 "register_operand" "0"))]
13710 "TARGET_USE_FANCY_MATH_387
13711 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13712 || TARGET_MIX_SSE_I387)
13713 && flag_unsafe_math_optimizations
13714 && standard_80387_constant_p (operands[3]) == 2"
13716 [(set_attr "type" "fpspc")
13717 (set_attr "mode" "XF")])
13719 (define_expand "tanxf2"
13720 [(use (match_operand:XF 0 "register_operand" ""))
13721 (use (match_operand:XF 1 "register_operand" ""))]
13722 "TARGET_USE_FANCY_MATH_387
13723 && flag_unsafe_math_optimizations"
13725 rtx one = gen_reg_rtx (XFmode);
13726 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13728 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13732 (define_expand "tan<mode>2"
13733 [(use (match_operand:MODEF 0 "register_operand" ""))
13734 (use (match_operand:MODEF 1 "register_operand" ""))]
13735 "TARGET_USE_FANCY_MATH_387
13736 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13737 || TARGET_MIX_SSE_I387)
13738 && flag_unsafe_math_optimizations"
13740 rtx op0 = gen_reg_rtx (XFmode);
13742 rtx one = gen_reg_rtx (<MODE>mode);
13743 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13745 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13746 operands[1], op2));
13747 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13751 (define_insn "*fpatanxf3_i387"
13752 [(set (match_operand:XF 0 "register_operand" "=f")
13753 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13754 (match_operand:XF 2 "register_operand" "u")]
13756 (clobber (match_scratch:XF 3 "=2"))]
13757 "TARGET_USE_FANCY_MATH_387
13758 && flag_unsafe_math_optimizations"
13760 [(set_attr "type" "fpspc")
13761 (set_attr "mode" "XF")])
13763 (define_insn "fpatan_extend<mode>xf3_i387"
13764 [(set (match_operand:XF 0 "register_operand" "=f")
13765 (unspec:XF [(float_extend:XF
13766 (match_operand:MODEF 1 "register_operand" "0"))
13768 (match_operand:MODEF 2 "register_operand" "u"))]
13770 (clobber (match_scratch:XF 3 "=2"))]
13771 "TARGET_USE_FANCY_MATH_387
13772 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13773 || TARGET_MIX_SSE_I387)
13774 && flag_unsafe_math_optimizations"
13776 [(set_attr "type" "fpspc")
13777 (set_attr "mode" "XF")])
13779 (define_expand "atan2xf3"
13780 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13781 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13782 (match_operand:XF 1 "register_operand" "")]
13784 (clobber (match_scratch:XF 3 ""))])]
13785 "TARGET_USE_FANCY_MATH_387
13786 && flag_unsafe_math_optimizations")
13788 (define_expand "atan2<mode>3"
13789 [(use (match_operand:MODEF 0 "register_operand" ""))
13790 (use (match_operand:MODEF 1 "register_operand" ""))
13791 (use (match_operand:MODEF 2 "register_operand" ""))]
13792 "TARGET_USE_FANCY_MATH_387
13793 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13794 || TARGET_MIX_SSE_I387)
13795 && flag_unsafe_math_optimizations"
13797 rtx op0 = gen_reg_rtx (XFmode);
13799 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13800 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13804 (define_expand "atanxf2"
13805 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13806 (unspec:XF [(match_dup 2)
13807 (match_operand:XF 1 "register_operand" "")]
13809 (clobber (match_scratch:XF 3 ""))])]
13810 "TARGET_USE_FANCY_MATH_387
13811 && flag_unsafe_math_optimizations"
13813 operands[2] = gen_reg_rtx (XFmode);
13814 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13817 (define_expand "atan<mode>2"
13818 [(use (match_operand:MODEF 0 "register_operand" ""))
13819 (use (match_operand:MODEF 1 "register_operand" ""))]
13820 "TARGET_USE_FANCY_MATH_387
13821 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13822 || TARGET_MIX_SSE_I387)
13823 && flag_unsafe_math_optimizations"
13825 rtx op0 = gen_reg_rtx (XFmode);
13827 rtx op2 = gen_reg_rtx (<MODE>mode);
13828 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13830 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13831 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13835 (define_expand "asinxf2"
13836 [(set (match_dup 2)
13837 (mult:XF (match_operand:XF 1 "register_operand" "")
13839 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13840 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13841 (parallel [(set (match_operand:XF 0 "register_operand" "")
13842 (unspec:XF [(match_dup 5) (match_dup 1)]
13844 (clobber (match_scratch:XF 6 ""))])]
13845 "TARGET_USE_FANCY_MATH_387
13846 && flag_unsafe_math_optimizations"
13850 if (optimize_insn_for_size_p ())
13853 for (i = 2; i < 6; i++)
13854 operands[i] = gen_reg_rtx (XFmode);
13856 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13859 (define_expand "asin<mode>2"
13860 [(use (match_operand:MODEF 0 "register_operand" ""))
13861 (use (match_operand:MODEF 1 "general_operand" ""))]
13862 "TARGET_USE_FANCY_MATH_387
13863 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13864 || TARGET_MIX_SSE_I387)
13865 && flag_unsafe_math_optimizations"
13867 rtx op0 = gen_reg_rtx (XFmode);
13868 rtx op1 = gen_reg_rtx (XFmode);
13870 if (optimize_insn_for_size_p ())
13873 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13874 emit_insn (gen_asinxf2 (op0, op1));
13875 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13879 (define_expand "acosxf2"
13880 [(set (match_dup 2)
13881 (mult:XF (match_operand:XF 1 "register_operand" "")
13883 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13884 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13885 (parallel [(set (match_operand:XF 0 "register_operand" "")
13886 (unspec:XF [(match_dup 1) (match_dup 5)]
13888 (clobber (match_scratch:XF 6 ""))])]
13889 "TARGET_USE_FANCY_MATH_387
13890 && flag_unsafe_math_optimizations"
13894 if (optimize_insn_for_size_p ())
13897 for (i = 2; i < 6; i++)
13898 operands[i] = gen_reg_rtx (XFmode);
13900 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13903 (define_expand "acos<mode>2"
13904 [(use (match_operand:MODEF 0 "register_operand" ""))
13905 (use (match_operand:MODEF 1 "general_operand" ""))]
13906 "TARGET_USE_FANCY_MATH_387
13907 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13908 || TARGET_MIX_SSE_I387)
13909 && flag_unsafe_math_optimizations"
13911 rtx op0 = gen_reg_rtx (XFmode);
13912 rtx op1 = gen_reg_rtx (XFmode);
13914 if (optimize_insn_for_size_p ())
13917 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13918 emit_insn (gen_acosxf2 (op0, op1));
13919 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13923 (define_insn "fyl2xxf3_i387"
13924 [(set (match_operand:XF 0 "register_operand" "=f")
13925 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13926 (match_operand:XF 2 "register_operand" "u")]
13928 (clobber (match_scratch:XF 3 "=2"))]
13929 "TARGET_USE_FANCY_MATH_387
13930 && flag_unsafe_math_optimizations"
13932 [(set_attr "type" "fpspc")
13933 (set_attr "mode" "XF")])
13935 (define_insn "fyl2x_extend<mode>xf3_i387"
13936 [(set (match_operand:XF 0 "register_operand" "=f")
13937 (unspec:XF [(float_extend:XF
13938 (match_operand:MODEF 1 "register_operand" "0"))
13939 (match_operand:XF 2 "register_operand" "u")]
13941 (clobber (match_scratch:XF 3 "=2"))]
13942 "TARGET_USE_FANCY_MATH_387
13943 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13944 || TARGET_MIX_SSE_I387)
13945 && flag_unsafe_math_optimizations"
13947 [(set_attr "type" "fpspc")
13948 (set_attr "mode" "XF")])
13950 (define_expand "logxf2"
13951 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13952 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13953 (match_dup 2)] UNSPEC_FYL2X))
13954 (clobber (match_scratch:XF 3 ""))])]
13955 "TARGET_USE_FANCY_MATH_387
13956 && flag_unsafe_math_optimizations"
13958 operands[2] = gen_reg_rtx (XFmode);
13959 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13962 (define_expand "log<mode>2"
13963 [(use (match_operand:MODEF 0 "register_operand" ""))
13964 (use (match_operand:MODEF 1 "register_operand" ""))]
13965 "TARGET_USE_FANCY_MATH_387
13966 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13967 || TARGET_MIX_SSE_I387)
13968 && flag_unsafe_math_optimizations"
13970 rtx op0 = gen_reg_rtx (XFmode);
13972 rtx op2 = gen_reg_rtx (XFmode);
13973 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13975 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13976 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13980 (define_expand "log10xf2"
13981 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13982 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13983 (match_dup 2)] UNSPEC_FYL2X))
13984 (clobber (match_scratch:XF 3 ""))])]
13985 "TARGET_USE_FANCY_MATH_387
13986 && flag_unsafe_math_optimizations"
13988 operands[2] = gen_reg_rtx (XFmode);
13989 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13992 (define_expand "log10<mode>2"
13993 [(use (match_operand:MODEF 0 "register_operand" ""))
13994 (use (match_operand:MODEF 1 "register_operand" ""))]
13995 "TARGET_USE_FANCY_MATH_387
13996 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13997 || TARGET_MIX_SSE_I387)
13998 && flag_unsafe_math_optimizations"
14000 rtx op0 = gen_reg_rtx (XFmode);
14002 rtx op2 = gen_reg_rtx (XFmode);
14003 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14005 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14006 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14010 (define_expand "log2xf2"
14011 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14012 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14013 (match_dup 2)] UNSPEC_FYL2X))
14014 (clobber (match_scratch:XF 3 ""))])]
14015 "TARGET_USE_FANCY_MATH_387
14016 && flag_unsafe_math_optimizations"
14018 operands[2] = gen_reg_rtx (XFmode);
14019 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14022 (define_expand "log2<mode>2"
14023 [(use (match_operand:MODEF 0 "register_operand" ""))
14024 (use (match_operand:MODEF 1 "register_operand" ""))]
14025 "TARGET_USE_FANCY_MATH_387
14026 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14027 || TARGET_MIX_SSE_I387)
14028 && flag_unsafe_math_optimizations"
14030 rtx op0 = gen_reg_rtx (XFmode);
14032 rtx op2 = gen_reg_rtx (XFmode);
14033 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14035 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14036 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14040 (define_insn "fyl2xp1xf3_i387"
14041 [(set (match_operand:XF 0 "register_operand" "=f")
14042 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14043 (match_operand:XF 2 "register_operand" "u")]
14045 (clobber (match_scratch:XF 3 "=2"))]
14046 "TARGET_USE_FANCY_MATH_387
14047 && flag_unsafe_math_optimizations"
14049 [(set_attr "type" "fpspc")
14050 (set_attr "mode" "XF")])
14052 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14053 [(set (match_operand:XF 0 "register_operand" "=f")
14054 (unspec:XF [(float_extend:XF
14055 (match_operand:MODEF 1 "register_operand" "0"))
14056 (match_operand:XF 2 "register_operand" "u")]
14058 (clobber (match_scratch:XF 3 "=2"))]
14059 "TARGET_USE_FANCY_MATH_387
14060 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14061 || TARGET_MIX_SSE_I387)
14062 && flag_unsafe_math_optimizations"
14064 [(set_attr "type" "fpspc")
14065 (set_attr "mode" "XF")])
14067 (define_expand "log1pxf2"
14068 [(use (match_operand:XF 0 "register_operand" ""))
14069 (use (match_operand:XF 1 "register_operand" ""))]
14070 "TARGET_USE_FANCY_MATH_387
14071 && flag_unsafe_math_optimizations"
14073 if (optimize_insn_for_size_p ())
14076 ix86_emit_i387_log1p (operands[0], operands[1]);
14080 (define_expand "log1p<mode>2"
14081 [(use (match_operand:MODEF 0 "register_operand" ""))
14082 (use (match_operand:MODEF 1 "register_operand" ""))]
14083 "TARGET_USE_FANCY_MATH_387
14084 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14085 || TARGET_MIX_SSE_I387)
14086 && flag_unsafe_math_optimizations"
14090 if (optimize_insn_for_size_p ())
14093 op0 = gen_reg_rtx (XFmode);
14095 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14097 ix86_emit_i387_log1p (op0, operands[1]);
14098 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14102 (define_insn "fxtractxf3_i387"
14103 [(set (match_operand:XF 0 "register_operand" "=f")
14104 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14105 UNSPEC_XTRACT_FRACT))
14106 (set (match_operand:XF 1 "register_operand" "=u")
14107 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14108 "TARGET_USE_FANCY_MATH_387
14109 && flag_unsafe_math_optimizations"
14111 [(set_attr "type" "fpspc")
14112 (set_attr "mode" "XF")])
14114 (define_insn "fxtract_extend<mode>xf3_i387"
14115 [(set (match_operand:XF 0 "register_operand" "=f")
14116 (unspec:XF [(float_extend:XF
14117 (match_operand:MODEF 2 "register_operand" "0"))]
14118 UNSPEC_XTRACT_FRACT))
14119 (set (match_operand:XF 1 "register_operand" "=u")
14120 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14121 "TARGET_USE_FANCY_MATH_387
14122 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14123 || TARGET_MIX_SSE_I387)
14124 && flag_unsafe_math_optimizations"
14126 [(set_attr "type" "fpspc")
14127 (set_attr "mode" "XF")])
14129 (define_expand "logbxf2"
14130 [(parallel [(set (match_dup 2)
14131 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14132 UNSPEC_XTRACT_FRACT))
14133 (set (match_operand:XF 0 "register_operand" "")
14134 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14135 "TARGET_USE_FANCY_MATH_387
14136 && flag_unsafe_math_optimizations"
14137 "operands[2] = gen_reg_rtx (XFmode);")
14139 (define_expand "logb<mode>2"
14140 [(use (match_operand:MODEF 0 "register_operand" ""))
14141 (use (match_operand:MODEF 1 "register_operand" ""))]
14142 "TARGET_USE_FANCY_MATH_387
14143 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14144 || TARGET_MIX_SSE_I387)
14145 && flag_unsafe_math_optimizations"
14147 rtx op0 = gen_reg_rtx (XFmode);
14148 rtx op1 = gen_reg_rtx (XFmode);
14150 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14151 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14155 (define_expand "ilogbxf2"
14156 [(use (match_operand:SI 0 "register_operand" ""))
14157 (use (match_operand:XF 1 "register_operand" ""))]
14158 "TARGET_USE_FANCY_MATH_387
14159 && flag_unsafe_math_optimizations"
14163 if (optimize_insn_for_size_p ())
14166 op0 = gen_reg_rtx (XFmode);
14167 op1 = gen_reg_rtx (XFmode);
14169 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14170 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14174 (define_expand "ilogb<mode>2"
14175 [(use (match_operand:SI 0 "register_operand" ""))
14176 (use (match_operand:MODEF 1 "register_operand" ""))]
14177 "TARGET_USE_FANCY_MATH_387
14178 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14179 || TARGET_MIX_SSE_I387)
14180 && flag_unsafe_math_optimizations"
14184 if (optimize_insn_for_size_p ())
14187 op0 = gen_reg_rtx (XFmode);
14188 op1 = gen_reg_rtx (XFmode);
14190 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14191 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14195 (define_insn "*f2xm1xf2_i387"
14196 [(set (match_operand:XF 0 "register_operand" "=f")
14197 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14199 "TARGET_USE_FANCY_MATH_387
14200 && flag_unsafe_math_optimizations"
14202 [(set_attr "type" "fpspc")
14203 (set_attr "mode" "XF")])
14205 (define_insn "*fscalexf4_i387"
14206 [(set (match_operand:XF 0 "register_operand" "=f")
14207 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14208 (match_operand:XF 3 "register_operand" "1")]
14209 UNSPEC_FSCALE_FRACT))
14210 (set (match_operand:XF 1 "register_operand" "=u")
14211 (unspec:XF [(match_dup 2) (match_dup 3)]
14212 UNSPEC_FSCALE_EXP))]
14213 "TARGET_USE_FANCY_MATH_387
14214 && flag_unsafe_math_optimizations"
14216 [(set_attr "type" "fpspc")
14217 (set_attr "mode" "XF")])
14219 (define_expand "expNcorexf3"
14220 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14221 (match_operand:XF 2 "register_operand" "")))
14222 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14223 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14224 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14225 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14226 (parallel [(set (match_operand:XF 0 "register_operand" "")
14227 (unspec:XF [(match_dup 8) (match_dup 4)]
14228 UNSPEC_FSCALE_FRACT))
14230 (unspec:XF [(match_dup 8) (match_dup 4)]
14231 UNSPEC_FSCALE_EXP))])]
14232 "TARGET_USE_FANCY_MATH_387
14233 && flag_unsafe_math_optimizations"
14237 if (optimize_insn_for_size_p ())
14240 for (i = 3; i < 10; i++)
14241 operands[i] = gen_reg_rtx (XFmode);
14243 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14246 (define_expand "expxf2"
14247 [(use (match_operand:XF 0 "register_operand" ""))
14248 (use (match_operand:XF 1 "register_operand" ""))]
14249 "TARGET_USE_FANCY_MATH_387
14250 && flag_unsafe_math_optimizations"
14254 if (optimize_insn_for_size_p ())
14257 op2 = gen_reg_rtx (XFmode);
14258 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14260 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14264 (define_expand "exp<mode>2"
14265 [(use (match_operand:MODEF 0 "register_operand" ""))
14266 (use (match_operand:MODEF 1 "general_operand" ""))]
14267 "TARGET_USE_FANCY_MATH_387
14268 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14269 || TARGET_MIX_SSE_I387)
14270 && flag_unsafe_math_optimizations"
14274 if (optimize_insn_for_size_p ())
14277 op0 = gen_reg_rtx (XFmode);
14278 op1 = gen_reg_rtx (XFmode);
14280 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14281 emit_insn (gen_expxf2 (op0, op1));
14282 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14286 (define_expand "exp10xf2"
14287 [(use (match_operand:XF 0 "register_operand" ""))
14288 (use (match_operand:XF 1 "register_operand" ""))]
14289 "TARGET_USE_FANCY_MATH_387
14290 && flag_unsafe_math_optimizations"
14294 if (optimize_insn_for_size_p ())
14297 op2 = gen_reg_rtx (XFmode);
14298 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14300 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14304 (define_expand "exp10<mode>2"
14305 [(use (match_operand:MODEF 0 "register_operand" ""))
14306 (use (match_operand:MODEF 1 "general_operand" ""))]
14307 "TARGET_USE_FANCY_MATH_387
14308 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14309 || TARGET_MIX_SSE_I387)
14310 && flag_unsafe_math_optimizations"
14314 if (optimize_insn_for_size_p ())
14317 op0 = gen_reg_rtx (XFmode);
14318 op1 = gen_reg_rtx (XFmode);
14320 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14321 emit_insn (gen_exp10xf2 (op0, op1));
14322 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14326 (define_expand "exp2xf2"
14327 [(use (match_operand:XF 0 "register_operand" ""))
14328 (use (match_operand:XF 1 "register_operand" ""))]
14329 "TARGET_USE_FANCY_MATH_387
14330 && flag_unsafe_math_optimizations"
14334 if (optimize_insn_for_size_p ())
14337 op2 = gen_reg_rtx (XFmode);
14338 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14340 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14344 (define_expand "exp2<mode>2"
14345 [(use (match_operand:MODEF 0 "register_operand" ""))
14346 (use (match_operand:MODEF 1 "general_operand" ""))]
14347 "TARGET_USE_FANCY_MATH_387
14348 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14349 || TARGET_MIX_SSE_I387)
14350 && flag_unsafe_math_optimizations"
14354 if (optimize_insn_for_size_p ())
14357 op0 = gen_reg_rtx (XFmode);
14358 op1 = gen_reg_rtx (XFmode);
14360 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14361 emit_insn (gen_exp2xf2 (op0, op1));
14362 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14366 (define_expand "expm1xf2"
14367 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14369 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14370 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14371 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14372 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14373 (parallel [(set (match_dup 7)
14374 (unspec:XF [(match_dup 6) (match_dup 4)]
14375 UNSPEC_FSCALE_FRACT))
14377 (unspec:XF [(match_dup 6) (match_dup 4)]
14378 UNSPEC_FSCALE_EXP))])
14379 (parallel [(set (match_dup 10)
14380 (unspec:XF [(match_dup 9) (match_dup 8)]
14381 UNSPEC_FSCALE_FRACT))
14382 (set (match_dup 11)
14383 (unspec:XF [(match_dup 9) (match_dup 8)]
14384 UNSPEC_FSCALE_EXP))])
14385 (set (match_dup 12) (minus:XF (match_dup 10)
14386 (float_extend:XF (match_dup 13))))
14387 (set (match_operand:XF 0 "register_operand" "")
14388 (plus:XF (match_dup 12) (match_dup 7)))]
14389 "TARGET_USE_FANCY_MATH_387
14390 && flag_unsafe_math_optimizations"
14394 if (optimize_insn_for_size_p ())
14397 for (i = 2; i < 13; i++)
14398 operands[i] = gen_reg_rtx (XFmode);
14401 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14403 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14406 (define_expand "expm1<mode>2"
14407 [(use (match_operand:MODEF 0 "register_operand" ""))
14408 (use (match_operand:MODEF 1 "general_operand" ""))]
14409 "TARGET_USE_FANCY_MATH_387
14410 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14411 || TARGET_MIX_SSE_I387)
14412 && flag_unsafe_math_optimizations"
14416 if (optimize_insn_for_size_p ())
14419 op0 = gen_reg_rtx (XFmode);
14420 op1 = gen_reg_rtx (XFmode);
14422 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14423 emit_insn (gen_expm1xf2 (op0, op1));
14424 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14428 (define_expand "ldexpxf3"
14429 [(set (match_dup 3)
14430 (float:XF (match_operand:SI 2 "register_operand" "")))
14431 (parallel [(set (match_operand:XF 0 " register_operand" "")
14432 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14434 UNSPEC_FSCALE_FRACT))
14436 (unspec:XF [(match_dup 1) (match_dup 3)]
14437 UNSPEC_FSCALE_EXP))])]
14438 "TARGET_USE_FANCY_MATH_387
14439 && flag_unsafe_math_optimizations"
14441 if (optimize_insn_for_size_p ())
14444 operands[3] = gen_reg_rtx (XFmode);
14445 operands[4] = gen_reg_rtx (XFmode);
14448 (define_expand "ldexp<mode>3"
14449 [(use (match_operand:MODEF 0 "register_operand" ""))
14450 (use (match_operand:MODEF 1 "general_operand" ""))
14451 (use (match_operand:SI 2 "register_operand" ""))]
14452 "TARGET_USE_FANCY_MATH_387
14453 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14454 || TARGET_MIX_SSE_I387)
14455 && flag_unsafe_math_optimizations"
14459 if (optimize_insn_for_size_p ())
14462 op0 = gen_reg_rtx (XFmode);
14463 op1 = gen_reg_rtx (XFmode);
14465 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14466 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14467 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14471 (define_expand "scalbxf3"
14472 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14473 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14474 (match_operand:XF 2 "register_operand" "")]
14475 UNSPEC_FSCALE_FRACT))
14477 (unspec:XF [(match_dup 1) (match_dup 2)]
14478 UNSPEC_FSCALE_EXP))])]
14479 "TARGET_USE_FANCY_MATH_387
14480 && flag_unsafe_math_optimizations"
14482 if (optimize_insn_for_size_p ())
14485 operands[3] = gen_reg_rtx (XFmode);
14488 (define_expand "scalb<mode>3"
14489 [(use (match_operand:MODEF 0 "register_operand" ""))
14490 (use (match_operand:MODEF 1 "general_operand" ""))
14491 (use (match_operand:MODEF 2 "general_operand" ""))]
14492 "TARGET_USE_FANCY_MATH_387
14493 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14494 || TARGET_MIX_SSE_I387)
14495 && flag_unsafe_math_optimizations"
14499 if (optimize_insn_for_size_p ())
14502 op0 = gen_reg_rtx (XFmode);
14503 op1 = gen_reg_rtx (XFmode);
14504 op2 = gen_reg_rtx (XFmode);
14506 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14507 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14508 emit_insn (gen_scalbxf3 (op0, op1, op2));
14509 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14513 (define_expand "significandxf2"
14514 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14515 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14516 UNSPEC_XTRACT_FRACT))
14518 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14519 "TARGET_USE_FANCY_MATH_387
14520 && flag_unsafe_math_optimizations"
14521 "operands[2] = gen_reg_rtx (XFmode);")
14523 (define_expand "significand<mode>2"
14524 [(use (match_operand:MODEF 0 "register_operand" ""))
14525 (use (match_operand:MODEF 1 "register_operand" ""))]
14526 "TARGET_USE_FANCY_MATH_387
14527 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14528 || TARGET_MIX_SSE_I387)
14529 && flag_unsafe_math_optimizations"
14531 rtx op0 = gen_reg_rtx (XFmode);
14532 rtx op1 = gen_reg_rtx (XFmode);
14534 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14535 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14540 (define_insn "sse4_1_round<mode>2"
14541 [(set (match_operand:MODEF 0 "register_operand" "=x")
14542 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14543 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14546 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14547 [(set_attr "type" "ssecvt")
14548 (set_attr "prefix_extra" "1")
14549 (set_attr "prefix" "maybe_vex")
14550 (set_attr "mode" "<MODE>")])
14552 (define_insn "rintxf2"
14553 [(set (match_operand:XF 0 "register_operand" "=f")
14554 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14556 "TARGET_USE_FANCY_MATH_387
14557 && flag_unsafe_math_optimizations"
14559 [(set_attr "type" "fpspc")
14560 (set_attr "mode" "XF")])
14562 (define_expand "rint<mode>2"
14563 [(use (match_operand:MODEF 0 "register_operand" ""))
14564 (use (match_operand:MODEF 1 "register_operand" ""))]
14565 "(TARGET_USE_FANCY_MATH_387
14566 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14567 || TARGET_MIX_SSE_I387)
14568 && flag_unsafe_math_optimizations)
14569 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14570 && !flag_trapping_math)"
14572 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14573 && !flag_trapping_math)
14576 emit_insn (gen_sse4_1_round<mode>2
14577 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14578 else if (optimize_insn_for_size_p ())
14581 ix86_expand_rint (operands[0], operands[1]);
14585 rtx op0 = gen_reg_rtx (XFmode);
14586 rtx op1 = gen_reg_rtx (XFmode);
14588 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14589 emit_insn (gen_rintxf2 (op0, op1));
14591 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14596 (define_expand "round<mode>2"
14597 [(match_operand:X87MODEF 0 "register_operand" "")
14598 (match_operand:X87MODEF 1 "nonimmediate_operand" "")]
14599 "(TARGET_USE_FANCY_MATH_387
14600 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14601 || TARGET_MIX_SSE_I387)
14602 && flag_unsafe_math_optimizations)
14603 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14604 && !flag_trapping_math && !flag_rounding_math)"
14606 if (optimize_insn_for_size_p ())
14609 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14610 && !flag_trapping_math && !flag_rounding_math)
14614 operands[1] = force_reg (<MODE>mode, operands[1]);
14615 ix86_expand_round_sse4 (operands[0], operands[1]);
14617 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14618 ix86_expand_round (operands[0], operands[1]);
14620 ix86_expand_rounddf_32 (operands[0], operands[1]);
14624 operands[1] = force_reg (<MODE>mode, operands[1]);
14625 ix86_emit_i387_round (operands[0], operands[1]);
14630 (define_insn_and_split "*fistdi2_1"
14631 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14632 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14634 "TARGET_USE_FANCY_MATH_387
14635 && can_create_pseudo_p ()"
14640 if (memory_operand (operands[0], VOIDmode))
14641 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14644 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14645 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14650 [(set_attr "type" "fpspc")
14651 (set_attr "mode" "DI")])
14653 (define_insn "fistdi2"
14654 [(set (match_operand:DI 0 "memory_operand" "=m")
14655 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14657 (clobber (match_scratch:XF 2 "=&1f"))]
14658 "TARGET_USE_FANCY_MATH_387"
14659 "* return output_fix_trunc (insn, operands, false);"
14660 [(set_attr "type" "fpspc")
14661 (set_attr "mode" "DI")])
14663 (define_insn "fistdi2_with_temp"
14664 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14665 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14667 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14668 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14669 "TARGET_USE_FANCY_MATH_387"
14671 [(set_attr "type" "fpspc")
14672 (set_attr "mode" "DI")])
14675 [(set (match_operand:DI 0 "register_operand" "")
14676 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14678 (clobber (match_operand:DI 2 "memory_operand" ""))
14679 (clobber (match_scratch 3 ""))]
14681 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14682 (clobber (match_dup 3))])
14683 (set (match_dup 0) (match_dup 2))])
14686 [(set (match_operand:DI 0 "memory_operand" "")
14687 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14689 (clobber (match_operand:DI 2 "memory_operand" ""))
14690 (clobber (match_scratch 3 ""))]
14692 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14693 (clobber (match_dup 3))])])
14695 (define_insn_and_split "*fist<mode>2_1"
14696 [(set (match_operand:SWI24 0 "register_operand" "")
14697 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14699 "TARGET_USE_FANCY_MATH_387
14700 && can_create_pseudo_p ()"
14705 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14706 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14710 [(set_attr "type" "fpspc")
14711 (set_attr "mode" "<MODE>")])
14713 (define_insn "fist<mode>2"
14714 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14715 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14717 "TARGET_USE_FANCY_MATH_387"
14718 "* return output_fix_trunc (insn, operands, false);"
14719 [(set_attr "type" "fpspc")
14720 (set_attr "mode" "<MODE>")])
14722 (define_insn "fist<mode>2_with_temp"
14723 [(set (match_operand:SWI24 0 "register_operand" "=r")
14724 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14726 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14727 "TARGET_USE_FANCY_MATH_387"
14729 [(set_attr "type" "fpspc")
14730 (set_attr "mode" "<MODE>")])
14733 [(set (match_operand:SWI24 0 "register_operand" "")
14734 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14736 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14738 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14739 (set (match_dup 0) (match_dup 2))])
14742 [(set (match_operand:SWI24 0 "memory_operand" "")
14743 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14745 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14747 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14749 (define_expand "lrintxf<mode>2"
14750 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14751 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14753 "TARGET_USE_FANCY_MATH_387")
14755 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14756 [(set (match_operand:SWI48x 0 "nonimmediate_operand" "")
14757 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")]
14758 UNSPEC_FIX_NOTRUNC))]
14759 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14760 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14762 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14763 [(match_operand:SWI248x 0 "nonimmediate_operand" "")
14764 (match_operand:X87MODEF 1 "register_operand" "")]
14765 "(TARGET_USE_FANCY_MATH_387
14766 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14767 || TARGET_MIX_SSE_I387)
14768 && flag_unsafe_math_optimizations)
14769 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14770 && <SWI248x:MODE>mode != HImode
14771 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14772 && !flag_trapping_math && !flag_rounding_math)"
14774 if (optimize_insn_for_size_p ())
14777 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14778 && <SWI248x:MODE>mode != HImode
14779 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14780 && !flag_trapping_math && !flag_rounding_math)
14781 ix86_expand_lround (operands[0], operands[1]);
14783 ix86_emit_i387_round (operands[0], operands[1]);
14787 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14788 (define_insn_and_split "frndintxf2_floor"
14789 [(set (match_operand:XF 0 "register_operand" "")
14790 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14791 UNSPEC_FRNDINT_FLOOR))
14792 (clobber (reg:CC FLAGS_REG))]
14793 "TARGET_USE_FANCY_MATH_387
14794 && flag_unsafe_math_optimizations
14795 && can_create_pseudo_p ()"
14800 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14802 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14803 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14805 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14806 operands[2], operands[3]));
14809 [(set_attr "type" "frndint")
14810 (set_attr "i387_cw" "floor")
14811 (set_attr "mode" "XF")])
14813 (define_insn "frndintxf2_floor_i387"
14814 [(set (match_operand:XF 0 "register_operand" "=f")
14815 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14816 UNSPEC_FRNDINT_FLOOR))
14817 (use (match_operand:HI 2 "memory_operand" "m"))
14818 (use (match_operand:HI 3 "memory_operand" "m"))]
14819 "TARGET_USE_FANCY_MATH_387
14820 && flag_unsafe_math_optimizations"
14821 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14822 [(set_attr "type" "frndint")
14823 (set_attr "i387_cw" "floor")
14824 (set_attr "mode" "XF")])
14826 (define_expand "floorxf2"
14827 [(use (match_operand:XF 0 "register_operand" ""))
14828 (use (match_operand:XF 1 "register_operand" ""))]
14829 "TARGET_USE_FANCY_MATH_387
14830 && flag_unsafe_math_optimizations"
14832 if (optimize_insn_for_size_p ())
14834 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14838 (define_expand "floor<mode>2"
14839 [(use (match_operand:MODEF 0 "register_operand" ""))
14840 (use (match_operand:MODEF 1 "register_operand" ""))]
14841 "(TARGET_USE_FANCY_MATH_387
14842 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14843 || TARGET_MIX_SSE_I387)
14844 && flag_unsafe_math_optimizations)
14845 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14846 && !flag_trapping_math)"
14848 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14849 && !flag_trapping_math)
14852 emit_insn (gen_sse4_1_round<mode>2
14853 (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14854 else if (optimize_insn_for_size_p ())
14856 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14857 ix86_expand_floorceil (operands[0], operands[1], true);
14859 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
14865 if (optimize_insn_for_size_p ())
14868 op0 = gen_reg_rtx (XFmode);
14869 op1 = gen_reg_rtx (XFmode);
14870 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14871 emit_insn (gen_frndintxf2_floor (op0, op1));
14873 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14878 (define_insn_and_split "*fist<mode>2_floor_1"
14879 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14880 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14881 UNSPEC_FIST_FLOOR))
14882 (clobber (reg:CC FLAGS_REG))]
14883 "TARGET_USE_FANCY_MATH_387
14884 && flag_unsafe_math_optimizations
14885 && can_create_pseudo_p ()"
14890 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14892 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14893 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14894 if (memory_operand (operands[0], VOIDmode))
14895 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14896 operands[2], operands[3]));
14899 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14900 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14901 operands[2], operands[3],
14906 [(set_attr "type" "fistp")
14907 (set_attr "i387_cw" "floor")
14908 (set_attr "mode" "<MODE>")])
14910 (define_insn "fistdi2_floor"
14911 [(set (match_operand:DI 0 "memory_operand" "=m")
14912 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14913 UNSPEC_FIST_FLOOR))
14914 (use (match_operand:HI 2 "memory_operand" "m"))
14915 (use (match_operand:HI 3 "memory_operand" "m"))
14916 (clobber (match_scratch:XF 4 "=&1f"))]
14917 "TARGET_USE_FANCY_MATH_387
14918 && flag_unsafe_math_optimizations"
14919 "* return output_fix_trunc (insn, operands, false);"
14920 [(set_attr "type" "fistp")
14921 (set_attr "i387_cw" "floor")
14922 (set_attr "mode" "DI")])
14924 (define_insn "fistdi2_floor_with_temp"
14925 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14926 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14927 UNSPEC_FIST_FLOOR))
14928 (use (match_operand:HI 2 "memory_operand" "m,m"))
14929 (use (match_operand:HI 3 "memory_operand" "m,m"))
14930 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14931 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14932 "TARGET_USE_FANCY_MATH_387
14933 && flag_unsafe_math_optimizations"
14935 [(set_attr "type" "fistp")
14936 (set_attr "i387_cw" "floor")
14937 (set_attr "mode" "DI")])
14940 [(set (match_operand:DI 0 "register_operand" "")
14941 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14942 UNSPEC_FIST_FLOOR))
14943 (use (match_operand:HI 2 "memory_operand" ""))
14944 (use (match_operand:HI 3 "memory_operand" ""))
14945 (clobber (match_operand:DI 4 "memory_operand" ""))
14946 (clobber (match_scratch 5 ""))]
14948 [(parallel [(set (match_dup 4)
14949 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14950 (use (match_dup 2))
14951 (use (match_dup 3))
14952 (clobber (match_dup 5))])
14953 (set (match_dup 0) (match_dup 4))])
14956 [(set (match_operand:DI 0 "memory_operand" "")
14957 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14958 UNSPEC_FIST_FLOOR))
14959 (use (match_operand:HI 2 "memory_operand" ""))
14960 (use (match_operand:HI 3 "memory_operand" ""))
14961 (clobber (match_operand:DI 4 "memory_operand" ""))
14962 (clobber (match_scratch 5 ""))]
14964 [(parallel [(set (match_dup 0)
14965 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14966 (use (match_dup 2))
14967 (use (match_dup 3))
14968 (clobber (match_dup 5))])])
14970 (define_insn "fist<mode>2_floor"
14971 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14972 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14973 UNSPEC_FIST_FLOOR))
14974 (use (match_operand:HI 2 "memory_operand" "m"))
14975 (use (match_operand:HI 3 "memory_operand" "m"))]
14976 "TARGET_USE_FANCY_MATH_387
14977 && flag_unsafe_math_optimizations"
14978 "* return output_fix_trunc (insn, operands, false);"
14979 [(set_attr "type" "fistp")
14980 (set_attr "i387_cw" "floor")
14981 (set_attr "mode" "<MODE>")])
14983 (define_insn "fist<mode>2_floor_with_temp"
14984 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
14985 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
14986 UNSPEC_FIST_FLOOR))
14987 (use (match_operand:HI 2 "memory_operand" "m,m"))
14988 (use (match_operand:HI 3 "memory_operand" "m,m"))
14989 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
14990 "TARGET_USE_FANCY_MATH_387
14991 && flag_unsafe_math_optimizations"
14993 [(set_attr "type" "fistp")
14994 (set_attr "i387_cw" "floor")
14995 (set_attr "mode" "<MODE>")])
14998 [(set (match_operand:SWI24 0 "register_operand" "")
14999 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15000 UNSPEC_FIST_FLOOR))
15001 (use (match_operand:HI 2 "memory_operand" ""))
15002 (use (match_operand:HI 3 "memory_operand" ""))
15003 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15005 [(parallel [(set (match_dup 4)
15006 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15007 (use (match_dup 2))
15008 (use (match_dup 3))])
15009 (set (match_dup 0) (match_dup 4))])
15012 [(set (match_operand:SWI24 0 "memory_operand" "")
15013 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15014 UNSPEC_FIST_FLOOR))
15015 (use (match_operand:HI 2 "memory_operand" ""))
15016 (use (match_operand:HI 3 "memory_operand" ""))
15017 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15019 [(parallel [(set (match_dup 0)
15020 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15021 (use (match_dup 2))
15022 (use (match_dup 3))])])
15024 (define_expand "lfloorxf<mode>2"
15025 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15026 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15027 UNSPEC_FIST_FLOOR))
15028 (clobber (reg:CC FLAGS_REG))])]
15029 "TARGET_USE_FANCY_MATH_387
15030 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15031 && flag_unsafe_math_optimizations")
15033 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15034 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15035 (match_operand:MODEF 1 "register_operand" "")]
15036 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15037 && !flag_trapping_math"
15039 if (TARGET_64BIT && optimize_insn_for_size_p ())
15041 ix86_expand_lfloorceil (operands[0], operands[1], true);
15045 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15046 (define_insn_and_split "frndintxf2_ceil"
15047 [(set (match_operand:XF 0 "register_operand" "")
15048 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15049 UNSPEC_FRNDINT_CEIL))
15050 (clobber (reg:CC FLAGS_REG))]
15051 "TARGET_USE_FANCY_MATH_387
15052 && flag_unsafe_math_optimizations
15053 && can_create_pseudo_p ()"
15058 ix86_optimize_mode_switching[I387_CEIL] = 1;
15060 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15061 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15063 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15064 operands[2], operands[3]));
15067 [(set_attr "type" "frndint")
15068 (set_attr "i387_cw" "ceil")
15069 (set_attr "mode" "XF")])
15071 (define_insn "frndintxf2_ceil_i387"
15072 [(set (match_operand:XF 0 "register_operand" "=f")
15073 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15074 UNSPEC_FRNDINT_CEIL))
15075 (use (match_operand:HI 2 "memory_operand" "m"))
15076 (use (match_operand:HI 3 "memory_operand" "m"))]
15077 "TARGET_USE_FANCY_MATH_387
15078 && flag_unsafe_math_optimizations"
15079 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15080 [(set_attr "type" "frndint")
15081 (set_attr "i387_cw" "ceil")
15082 (set_attr "mode" "XF")])
15084 (define_expand "ceilxf2"
15085 [(use (match_operand:XF 0 "register_operand" ""))
15086 (use (match_operand:XF 1 "register_operand" ""))]
15087 "TARGET_USE_FANCY_MATH_387
15088 && flag_unsafe_math_optimizations"
15090 if (optimize_insn_for_size_p ())
15092 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15096 (define_expand "ceil<mode>2"
15097 [(use (match_operand:MODEF 0 "register_operand" ""))
15098 (use (match_operand:MODEF 1 "register_operand" ""))]
15099 "(TARGET_USE_FANCY_MATH_387
15100 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15101 || TARGET_MIX_SSE_I387)
15102 && flag_unsafe_math_optimizations)
15103 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15104 && !flag_trapping_math)"
15106 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15107 && !flag_trapping_math)
15110 emit_insn (gen_sse4_1_round<mode>2
15111 (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
15112 else if (optimize_insn_for_size_p ())
15114 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15115 ix86_expand_floorceil (operands[0], operands[1], false);
15117 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15123 if (optimize_insn_for_size_p ())
15126 op0 = gen_reg_rtx (XFmode);
15127 op1 = gen_reg_rtx (XFmode);
15128 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15129 emit_insn (gen_frndintxf2_ceil (op0, op1));
15131 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15136 (define_insn_and_split "*fist<mode>2_ceil_1"
15137 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15138 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15140 (clobber (reg:CC FLAGS_REG))]
15141 "TARGET_USE_FANCY_MATH_387
15142 && flag_unsafe_math_optimizations
15143 && can_create_pseudo_p ()"
15148 ix86_optimize_mode_switching[I387_CEIL] = 1;
15150 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15151 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15152 if (memory_operand (operands[0], VOIDmode))
15153 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15154 operands[2], operands[3]));
15157 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15158 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15159 operands[2], operands[3],
15164 [(set_attr "type" "fistp")
15165 (set_attr "i387_cw" "ceil")
15166 (set_attr "mode" "<MODE>")])
15168 (define_insn "fistdi2_ceil"
15169 [(set (match_operand:DI 0 "memory_operand" "=m")
15170 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15172 (use (match_operand:HI 2 "memory_operand" "m"))
15173 (use (match_operand:HI 3 "memory_operand" "m"))
15174 (clobber (match_scratch:XF 4 "=&1f"))]
15175 "TARGET_USE_FANCY_MATH_387
15176 && flag_unsafe_math_optimizations"
15177 "* return output_fix_trunc (insn, operands, false);"
15178 [(set_attr "type" "fistp")
15179 (set_attr "i387_cw" "ceil")
15180 (set_attr "mode" "DI")])
15182 (define_insn "fistdi2_ceil_with_temp"
15183 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15184 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15186 (use (match_operand:HI 2 "memory_operand" "m,m"))
15187 (use (match_operand:HI 3 "memory_operand" "m,m"))
15188 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15189 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15190 "TARGET_USE_FANCY_MATH_387
15191 && flag_unsafe_math_optimizations"
15193 [(set_attr "type" "fistp")
15194 (set_attr "i387_cw" "ceil")
15195 (set_attr "mode" "DI")])
15198 [(set (match_operand:DI 0 "register_operand" "")
15199 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15201 (use (match_operand:HI 2 "memory_operand" ""))
15202 (use (match_operand:HI 3 "memory_operand" ""))
15203 (clobber (match_operand:DI 4 "memory_operand" ""))
15204 (clobber (match_scratch 5 ""))]
15206 [(parallel [(set (match_dup 4)
15207 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15208 (use (match_dup 2))
15209 (use (match_dup 3))
15210 (clobber (match_dup 5))])
15211 (set (match_dup 0) (match_dup 4))])
15214 [(set (match_operand:DI 0 "memory_operand" "")
15215 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15217 (use (match_operand:HI 2 "memory_operand" ""))
15218 (use (match_operand:HI 3 "memory_operand" ""))
15219 (clobber (match_operand:DI 4 "memory_operand" ""))
15220 (clobber (match_scratch 5 ""))]
15222 [(parallel [(set (match_dup 0)
15223 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15224 (use (match_dup 2))
15225 (use (match_dup 3))
15226 (clobber (match_dup 5))])])
15228 (define_insn "fist<mode>2_ceil"
15229 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15230 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15232 (use (match_operand:HI 2 "memory_operand" "m"))
15233 (use (match_operand:HI 3 "memory_operand" "m"))]
15234 "TARGET_USE_FANCY_MATH_387
15235 && flag_unsafe_math_optimizations"
15236 "* return output_fix_trunc (insn, operands, false);"
15237 [(set_attr "type" "fistp")
15238 (set_attr "i387_cw" "ceil")
15239 (set_attr "mode" "<MODE>")])
15241 (define_insn "fist<mode>2_ceil_with_temp"
15242 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15243 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15245 (use (match_operand:HI 2 "memory_operand" "m,m"))
15246 (use (match_operand:HI 3 "memory_operand" "m,m"))
15247 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15248 "TARGET_USE_FANCY_MATH_387
15249 && flag_unsafe_math_optimizations"
15251 [(set_attr "type" "fistp")
15252 (set_attr "i387_cw" "ceil")
15253 (set_attr "mode" "<MODE>")])
15256 [(set (match_operand:SWI24 0 "register_operand" "")
15257 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15259 (use (match_operand:HI 2 "memory_operand" ""))
15260 (use (match_operand:HI 3 "memory_operand" ""))
15261 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15263 [(parallel [(set (match_dup 4)
15264 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15265 (use (match_dup 2))
15266 (use (match_dup 3))])
15267 (set (match_dup 0) (match_dup 4))])
15270 [(set (match_operand:SWI24 0 "memory_operand" "")
15271 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15273 (use (match_operand:HI 2 "memory_operand" ""))
15274 (use (match_operand:HI 3 "memory_operand" ""))
15275 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15277 [(parallel [(set (match_dup 0)
15278 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15279 (use (match_dup 2))
15280 (use (match_dup 3))])])
15282 (define_expand "lceilxf<mode>2"
15283 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15284 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15286 (clobber (reg:CC FLAGS_REG))])]
15287 "TARGET_USE_FANCY_MATH_387
15288 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15289 && flag_unsafe_math_optimizations")
15291 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15292 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15293 (match_operand:MODEF 1 "register_operand" "")]
15294 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15295 && !flag_trapping_math"
15297 ix86_expand_lfloorceil (operands[0], operands[1], false);
15301 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15302 (define_insn_and_split "frndintxf2_trunc"
15303 [(set (match_operand:XF 0 "register_operand" "")
15304 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15305 UNSPEC_FRNDINT_TRUNC))
15306 (clobber (reg:CC FLAGS_REG))]
15307 "TARGET_USE_FANCY_MATH_387
15308 && flag_unsafe_math_optimizations
15309 && can_create_pseudo_p ()"
15314 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15316 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15317 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15319 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15320 operands[2], operands[3]));
15323 [(set_attr "type" "frndint")
15324 (set_attr "i387_cw" "trunc")
15325 (set_attr "mode" "XF")])
15327 (define_insn "frndintxf2_trunc_i387"
15328 [(set (match_operand:XF 0 "register_operand" "=f")
15329 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15330 UNSPEC_FRNDINT_TRUNC))
15331 (use (match_operand:HI 2 "memory_operand" "m"))
15332 (use (match_operand:HI 3 "memory_operand" "m"))]
15333 "TARGET_USE_FANCY_MATH_387
15334 && flag_unsafe_math_optimizations"
15335 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15336 [(set_attr "type" "frndint")
15337 (set_attr "i387_cw" "trunc")
15338 (set_attr "mode" "XF")])
15340 (define_expand "btruncxf2"
15341 [(use (match_operand:XF 0 "register_operand" ""))
15342 (use (match_operand:XF 1 "register_operand" ""))]
15343 "TARGET_USE_FANCY_MATH_387
15344 && flag_unsafe_math_optimizations"
15346 if (optimize_insn_for_size_p ())
15348 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15352 (define_expand "btrunc<mode>2"
15353 [(use (match_operand:MODEF 0 "register_operand" ""))
15354 (use (match_operand:MODEF 1 "register_operand" ""))]
15355 "(TARGET_USE_FANCY_MATH_387
15356 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15357 || TARGET_MIX_SSE_I387)
15358 && flag_unsafe_math_optimizations)
15359 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15360 && !flag_trapping_math)"
15362 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15363 && !flag_trapping_math)
15366 emit_insn (gen_sse4_1_round<mode>2
15367 (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15368 else if (optimize_insn_for_size_p ())
15370 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15371 ix86_expand_trunc (operands[0], operands[1]);
15373 ix86_expand_truncdf_32 (operands[0], operands[1]);
15379 if (optimize_insn_for_size_p ())
15382 op0 = gen_reg_rtx (XFmode);
15383 op1 = gen_reg_rtx (XFmode);
15384 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15385 emit_insn (gen_frndintxf2_trunc (op0, op1));
15387 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15392 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15393 (define_insn_and_split "frndintxf2_mask_pm"
15394 [(set (match_operand:XF 0 "register_operand" "")
15395 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15396 UNSPEC_FRNDINT_MASK_PM))
15397 (clobber (reg:CC FLAGS_REG))]
15398 "TARGET_USE_FANCY_MATH_387
15399 && flag_unsafe_math_optimizations
15400 && can_create_pseudo_p ()"
15405 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15407 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15408 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15410 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15411 operands[2], operands[3]));
15414 [(set_attr "type" "frndint")
15415 (set_attr "i387_cw" "mask_pm")
15416 (set_attr "mode" "XF")])
15418 (define_insn "frndintxf2_mask_pm_i387"
15419 [(set (match_operand:XF 0 "register_operand" "=f")
15420 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15421 UNSPEC_FRNDINT_MASK_PM))
15422 (use (match_operand:HI 2 "memory_operand" "m"))
15423 (use (match_operand:HI 3 "memory_operand" "m"))]
15424 "TARGET_USE_FANCY_MATH_387
15425 && flag_unsafe_math_optimizations"
15426 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15427 [(set_attr "type" "frndint")
15428 (set_attr "i387_cw" "mask_pm")
15429 (set_attr "mode" "XF")])
15431 (define_expand "nearbyintxf2"
15432 [(use (match_operand:XF 0 "register_operand" ""))
15433 (use (match_operand:XF 1 "register_operand" ""))]
15434 "TARGET_USE_FANCY_MATH_387
15435 && flag_unsafe_math_optimizations"
15437 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15441 (define_expand "nearbyint<mode>2"
15442 [(use (match_operand:MODEF 0 "register_operand" ""))
15443 (use (match_operand:MODEF 1 "register_operand" ""))]
15444 "TARGET_USE_FANCY_MATH_387
15445 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15446 || TARGET_MIX_SSE_I387)
15447 && flag_unsafe_math_optimizations"
15449 rtx op0 = gen_reg_rtx (XFmode);
15450 rtx op1 = gen_reg_rtx (XFmode);
15452 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15453 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15455 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15459 (define_insn "fxam<mode>2_i387"
15460 [(set (match_operand:HI 0 "register_operand" "=a")
15462 [(match_operand:X87MODEF 1 "register_operand" "f")]
15464 "TARGET_USE_FANCY_MATH_387"
15465 "fxam\n\tfnstsw\t%0"
15466 [(set_attr "type" "multi")
15467 (set_attr "length" "4")
15468 (set_attr "unit" "i387")
15469 (set_attr "mode" "<MODE>")])
15471 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15472 [(set (match_operand:HI 0 "register_operand" "")
15474 [(match_operand:MODEF 1 "memory_operand" "")]
15476 "TARGET_USE_FANCY_MATH_387
15477 && can_create_pseudo_p ()"
15480 [(set (match_dup 2)(match_dup 1))
15482 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15484 operands[2] = gen_reg_rtx (<MODE>mode);
15486 MEM_VOLATILE_P (operands[1]) = 1;
15488 [(set_attr "type" "multi")
15489 (set_attr "unit" "i387")
15490 (set_attr "mode" "<MODE>")])
15492 (define_expand "isinfxf2"
15493 [(use (match_operand:SI 0 "register_operand" ""))
15494 (use (match_operand:XF 1 "register_operand" ""))]
15495 "TARGET_USE_FANCY_MATH_387
15496 && TARGET_C99_FUNCTIONS"
15498 rtx mask = GEN_INT (0x45);
15499 rtx val = GEN_INT (0x05);
15503 rtx scratch = gen_reg_rtx (HImode);
15504 rtx res = gen_reg_rtx (QImode);
15506 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15508 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15509 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15510 cond = gen_rtx_fmt_ee (EQ, QImode,
15511 gen_rtx_REG (CCmode, FLAGS_REG),
15513 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15514 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15518 (define_expand "isinf<mode>2"
15519 [(use (match_operand:SI 0 "register_operand" ""))
15520 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15521 "TARGET_USE_FANCY_MATH_387
15522 && TARGET_C99_FUNCTIONS
15523 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15525 rtx mask = GEN_INT (0x45);
15526 rtx val = GEN_INT (0x05);
15530 rtx scratch = gen_reg_rtx (HImode);
15531 rtx res = gen_reg_rtx (QImode);
15533 /* Remove excess precision by forcing value through memory. */
15534 if (memory_operand (operands[1], VOIDmode))
15535 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15538 enum ix86_stack_slot slot = (virtuals_instantiated
15541 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15543 emit_move_insn (temp, operands[1]);
15544 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15547 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15548 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15549 cond = gen_rtx_fmt_ee (EQ, QImode,
15550 gen_rtx_REG (CCmode, FLAGS_REG),
15552 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15553 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15557 (define_expand "signbitxf2"
15558 [(use (match_operand:SI 0 "register_operand" ""))
15559 (use (match_operand:XF 1 "register_operand" ""))]
15560 "TARGET_USE_FANCY_MATH_387"
15562 rtx scratch = gen_reg_rtx (HImode);
15564 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15565 emit_insn (gen_andsi3 (operands[0],
15566 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15570 (define_insn "movmsk_df"
15571 [(set (match_operand:SI 0 "register_operand" "=r")
15573 [(match_operand:DF 1 "register_operand" "x")]
15575 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15576 "%vmovmskpd\t{%1, %0|%0, %1}"
15577 [(set_attr "type" "ssemov")
15578 (set_attr "prefix" "maybe_vex")
15579 (set_attr "mode" "DF")])
15581 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15582 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15583 (define_expand "signbitdf2"
15584 [(use (match_operand:SI 0 "register_operand" ""))
15585 (use (match_operand:DF 1 "register_operand" ""))]
15586 "TARGET_USE_FANCY_MATH_387
15587 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15589 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15591 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15592 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15596 rtx scratch = gen_reg_rtx (HImode);
15598 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15599 emit_insn (gen_andsi3 (operands[0],
15600 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15605 (define_expand "signbitsf2"
15606 [(use (match_operand:SI 0 "register_operand" ""))
15607 (use (match_operand:SF 1 "register_operand" ""))]
15608 "TARGET_USE_FANCY_MATH_387
15609 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15611 rtx scratch = gen_reg_rtx (HImode);
15613 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15614 emit_insn (gen_andsi3 (operands[0],
15615 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15619 ;; Block operation instructions
15622 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15625 [(set_attr "length" "1")
15626 (set_attr "length_immediate" "0")
15627 (set_attr "modrm" "0")])
15629 (define_expand "movmem<mode>"
15630 [(use (match_operand:BLK 0 "memory_operand" ""))
15631 (use (match_operand:BLK 1 "memory_operand" ""))
15632 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15633 (use (match_operand:SWI48 3 "const_int_operand" ""))
15634 (use (match_operand:SI 4 "const_int_operand" ""))
15635 (use (match_operand:SI 5 "const_int_operand" ""))]
15638 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15639 operands[4], operands[5]))
15645 ;; Most CPUs don't like single string operations
15646 ;; Handle this case here to simplify previous expander.
15648 (define_expand "strmov"
15649 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15650 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15651 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15652 (clobber (reg:CC FLAGS_REG))])
15653 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15654 (clobber (reg:CC FLAGS_REG))])]
15657 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15659 /* If .md ever supports :P for Pmode, these can be directly
15660 in the pattern above. */
15661 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15662 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15664 /* Can't use this if the user has appropriated esi or edi. */
15665 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15666 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15668 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15669 operands[2], operands[3],
15670 operands[5], operands[6]));
15674 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15677 (define_expand "strmov_singleop"
15678 [(parallel [(set (match_operand 1 "memory_operand" "")
15679 (match_operand 3 "memory_operand" ""))
15680 (set (match_operand 0 "register_operand" "")
15681 (match_operand 4 "" ""))
15682 (set (match_operand 2 "register_operand" "")
15683 (match_operand 5 "" ""))])]
15685 "ix86_current_function_needs_cld = 1;")
15687 (define_insn "*strmovdi_rex_1"
15688 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15689 (mem:DI (match_operand:P 3 "register_operand" "1")))
15690 (set (match_operand:P 0 "register_operand" "=D")
15691 (plus:P (match_dup 2)
15693 (set (match_operand:P 1 "register_operand" "=S")
15694 (plus:P (match_dup 3)
15697 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15699 [(set_attr "type" "str")
15700 (set_attr "memory" "both")
15701 (set_attr "mode" "DI")])
15703 (define_insn "*strmovsi_1"
15704 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15705 (mem:SI (match_operand:P 3 "register_operand" "1")))
15706 (set (match_operand:P 0 "register_operand" "=D")
15707 (plus:P (match_dup 2)
15709 (set (match_operand:P 1 "register_operand" "=S")
15710 (plus:P (match_dup 3)
15712 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15714 [(set_attr "type" "str")
15715 (set_attr "memory" "both")
15716 (set_attr "mode" "SI")])
15718 (define_insn "*strmovhi_1"
15719 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15720 (mem:HI (match_operand:P 3 "register_operand" "1")))
15721 (set (match_operand:P 0 "register_operand" "=D")
15722 (plus:P (match_dup 2)
15724 (set (match_operand:P 1 "register_operand" "=S")
15725 (plus:P (match_dup 3)
15727 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15729 [(set_attr "type" "str")
15730 (set_attr "memory" "both")
15731 (set_attr "mode" "HI")])
15733 (define_insn "*strmovqi_1"
15734 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15735 (mem:QI (match_operand:P 3 "register_operand" "1")))
15736 (set (match_operand:P 0 "register_operand" "=D")
15737 (plus:P (match_dup 2)
15739 (set (match_operand:P 1 "register_operand" "=S")
15740 (plus:P (match_dup 3)
15742 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15744 [(set_attr "type" "str")
15745 (set_attr "memory" "both")
15746 (set (attr "prefix_rex")
15748 (match_test "<P:MODE>mode == DImode")
15750 (const_string "*")))
15751 (set_attr "mode" "QI")])
15753 (define_expand "rep_mov"
15754 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15755 (set (match_operand 0 "register_operand" "")
15756 (match_operand 5 "" ""))
15757 (set (match_operand 2 "register_operand" "")
15758 (match_operand 6 "" ""))
15759 (set (match_operand 1 "memory_operand" "")
15760 (match_operand 3 "memory_operand" ""))
15761 (use (match_dup 4))])]
15763 "ix86_current_function_needs_cld = 1;")
15765 (define_insn "*rep_movdi_rex64"
15766 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15767 (set (match_operand:P 0 "register_operand" "=D")
15768 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15770 (match_operand:P 3 "register_operand" "0")))
15771 (set (match_operand:P 1 "register_operand" "=S")
15772 (plus:P (ashift:P (match_dup 5) (const_int 3))
15773 (match_operand:P 4 "register_operand" "1")))
15774 (set (mem:BLK (match_dup 3))
15775 (mem:BLK (match_dup 4)))
15776 (use (match_dup 5))]
15778 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15780 [(set_attr "type" "str")
15781 (set_attr "prefix_rep" "1")
15782 (set_attr "memory" "both")
15783 (set_attr "mode" "DI")])
15785 (define_insn "*rep_movsi"
15786 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15787 (set (match_operand:P 0 "register_operand" "=D")
15788 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15790 (match_operand:P 3 "register_operand" "0")))
15791 (set (match_operand:P 1 "register_operand" "=S")
15792 (plus:P (ashift:P (match_dup 5) (const_int 2))
15793 (match_operand:P 4 "register_operand" "1")))
15794 (set (mem:BLK (match_dup 3))
15795 (mem:BLK (match_dup 4)))
15796 (use (match_dup 5))]
15797 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15798 "%^rep{%;} movs{l|d}"
15799 [(set_attr "type" "str")
15800 (set_attr "prefix_rep" "1")
15801 (set_attr "memory" "both")
15802 (set_attr "mode" "SI")])
15804 (define_insn "*rep_movqi"
15805 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15806 (set (match_operand:P 0 "register_operand" "=D")
15807 (plus:P (match_operand:P 3 "register_operand" "0")
15808 (match_operand:P 5 "register_operand" "2")))
15809 (set (match_operand:P 1 "register_operand" "=S")
15810 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15811 (set (mem:BLK (match_dup 3))
15812 (mem:BLK (match_dup 4)))
15813 (use (match_dup 5))]
15814 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15816 [(set_attr "type" "str")
15817 (set_attr "prefix_rep" "1")
15818 (set_attr "memory" "both")
15819 (set_attr "mode" "QI")])
15821 (define_expand "setmem<mode>"
15822 [(use (match_operand:BLK 0 "memory_operand" ""))
15823 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15824 (use (match_operand:QI 2 "nonmemory_operand" ""))
15825 (use (match_operand 3 "const_int_operand" ""))
15826 (use (match_operand:SI 4 "const_int_operand" ""))
15827 (use (match_operand:SI 5 "const_int_operand" ""))]
15830 if (ix86_expand_setmem (operands[0], operands[1],
15831 operands[2], operands[3],
15832 operands[4], operands[5]))
15838 ;; Most CPUs don't like single string operations
15839 ;; Handle this case here to simplify previous expander.
15841 (define_expand "strset"
15842 [(set (match_operand 1 "memory_operand" "")
15843 (match_operand 2 "register_operand" ""))
15844 (parallel [(set (match_operand 0 "register_operand" "")
15846 (clobber (reg:CC FLAGS_REG))])]
15849 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15850 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15852 /* If .md ever supports :P for Pmode, this can be directly
15853 in the pattern above. */
15854 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15855 GEN_INT (GET_MODE_SIZE (GET_MODE
15857 /* Can't use this if the user has appropriated eax or edi. */
15858 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15859 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15861 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15867 (define_expand "strset_singleop"
15868 [(parallel [(set (match_operand 1 "memory_operand" "")
15869 (match_operand 2 "register_operand" ""))
15870 (set (match_operand 0 "register_operand" "")
15871 (match_operand 3 "" ""))])]
15873 "ix86_current_function_needs_cld = 1;")
15875 (define_insn "*strsetdi_rex_1"
15876 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
15877 (match_operand:DI 2 "register_operand" "a"))
15878 (set (match_operand:P 0 "register_operand" "=D")
15879 (plus:P (match_dup 1)
15882 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15884 [(set_attr "type" "str")
15885 (set_attr "memory" "store")
15886 (set_attr "mode" "DI")])
15888 (define_insn "*strsetsi_1"
15889 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15890 (match_operand:SI 2 "register_operand" "a"))
15891 (set (match_operand:P 0 "register_operand" "=D")
15892 (plus:P (match_dup 1)
15894 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15896 [(set_attr "type" "str")
15897 (set_attr "memory" "store")
15898 (set_attr "mode" "SI")])
15900 (define_insn "*strsethi_1"
15901 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15902 (match_operand:HI 2 "register_operand" "a"))
15903 (set (match_operand:P 0 "register_operand" "=D")
15904 (plus:P (match_dup 1)
15906 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15908 [(set_attr "type" "str")
15909 (set_attr "memory" "store")
15910 (set_attr "mode" "HI")])
15912 (define_insn "*strsetqi_1"
15913 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15914 (match_operand:QI 2 "register_operand" "a"))
15915 (set (match_operand:P 0 "register_operand" "=D")
15916 (plus:P (match_dup 1)
15918 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15920 [(set_attr "type" "str")
15921 (set_attr "memory" "store")
15922 (set (attr "prefix_rex")
15924 (match_test "<P:MODE>mode == DImode")
15926 (const_string "*")))
15927 (set_attr "mode" "QI")])
15929 (define_expand "rep_stos"
15930 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15931 (set (match_operand 0 "register_operand" "")
15932 (match_operand 4 "" ""))
15933 (set (match_operand 2 "memory_operand" "") (const_int 0))
15934 (use (match_operand 3 "register_operand" ""))
15935 (use (match_dup 1))])]
15937 "ix86_current_function_needs_cld = 1;")
15939 (define_insn "*rep_stosdi_rex64"
15940 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15941 (set (match_operand:P 0 "register_operand" "=D")
15942 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15944 (match_operand:P 3 "register_operand" "0")))
15945 (set (mem:BLK (match_dup 3))
15947 (use (match_operand:DI 2 "register_operand" "a"))
15948 (use (match_dup 4))]
15950 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15952 [(set_attr "type" "str")
15953 (set_attr "prefix_rep" "1")
15954 (set_attr "memory" "store")
15955 (set_attr "mode" "DI")])
15957 (define_insn "*rep_stossi"
15958 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15959 (set (match_operand:P 0 "register_operand" "=D")
15960 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15962 (match_operand:P 3 "register_operand" "0")))
15963 (set (mem:BLK (match_dup 3))
15965 (use (match_operand:SI 2 "register_operand" "a"))
15966 (use (match_dup 4))]
15967 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15968 "%^rep{%;} stos{l|d}"
15969 [(set_attr "type" "str")
15970 (set_attr "prefix_rep" "1")
15971 (set_attr "memory" "store")
15972 (set_attr "mode" "SI")])
15974 (define_insn "*rep_stosqi"
15975 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15976 (set (match_operand:P 0 "register_operand" "=D")
15977 (plus:P (match_operand:P 3 "register_operand" "0")
15978 (match_operand:P 4 "register_operand" "1")))
15979 (set (mem:BLK (match_dup 3))
15981 (use (match_operand:QI 2 "register_operand" "a"))
15982 (use (match_dup 4))]
15983 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15985 [(set_attr "type" "str")
15986 (set_attr "prefix_rep" "1")
15987 (set_attr "memory" "store")
15988 (set (attr "prefix_rex")
15990 (match_test "<P:MODE>mode == DImode")
15992 (const_string "*")))
15993 (set_attr "mode" "QI")])
15995 (define_expand "cmpstrnsi"
15996 [(set (match_operand:SI 0 "register_operand" "")
15997 (compare:SI (match_operand:BLK 1 "general_operand" "")
15998 (match_operand:BLK 2 "general_operand" "")))
15999 (use (match_operand 3 "general_operand" ""))
16000 (use (match_operand 4 "immediate_operand" ""))]
16003 rtx addr1, addr2, out, outlow, count, countreg, align;
16005 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16008 /* Can't use this if the user has appropriated ecx, esi or edi. */
16009 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16014 out = gen_reg_rtx (SImode);
16016 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16017 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16018 if (addr1 != XEXP (operands[1], 0))
16019 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16020 if (addr2 != XEXP (operands[2], 0))
16021 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16023 count = operands[3];
16024 countreg = ix86_zero_extend_to_Pmode (count);
16026 /* %%% Iff we are testing strict equality, we can use known alignment
16027 to good advantage. This may be possible with combine, particularly
16028 once cc0 is dead. */
16029 align = operands[4];
16031 if (CONST_INT_P (count))
16033 if (INTVAL (count) == 0)
16035 emit_move_insn (operands[0], const0_rtx);
16038 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16039 operands[1], operands[2]));
16043 rtx (*gen_cmp) (rtx, rtx);
16045 gen_cmp = (TARGET_64BIT
16046 ? gen_cmpdi_1 : gen_cmpsi_1);
16048 emit_insn (gen_cmp (countreg, countreg));
16049 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16050 operands[1], operands[2]));
16053 outlow = gen_lowpart (QImode, out);
16054 emit_insn (gen_cmpintqi (outlow));
16055 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16057 if (operands[0] != out)
16058 emit_move_insn (operands[0], out);
16063 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16065 (define_expand "cmpintqi"
16066 [(set (match_dup 1)
16067 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16069 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16070 (parallel [(set (match_operand:QI 0 "register_operand" "")
16071 (minus:QI (match_dup 1)
16073 (clobber (reg:CC FLAGS_REG))])]
16076 operands[1] = gen_reg_rtx (QImode);
16077 operands[2] = gen_reg_rtx (QImode);
16080 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16081 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16083 (define_expand "cmpstrnqi_nz_1"
16084 [(parallel [(set (reg:CC FLAGS_REG)
16085 (compare:CC (match_operand 4 "memory_operand" "")
16086 (match_operand 5 "memory_operand" "")))
16087 (use (match_operand 2 "register_operand" ""))
16088 (use (match_operand:SI 3 "immediate_operand" ""))
16089 (clobber (match_operand 0 "register_operand" ""))
16090 (clobber (match_operand 1 "register_operand" ""))
16091 (clobber (match_dup 2))])]
16093 "ix86_current_function_needs_cld = 1;")
16095 (define_insn "*cmpstrnqi_nz_1"
16096 [(set (reg:CC FLAGS_REG)
16097 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16098 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16099 (use (match_operand:P 6 "register_operand" "2"))
16100 (use (match_operand:SI 3 "immediate_operand" "i"))
16101 (clobber (match_operand:P 0 "register_operand" "=S"))
16102 (clobber (match_operand:P 1 "register_operand" "=D"))
16103 (clobber (match_operand:P 2 "register_operand" "=c"))]
16104 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16106 [(set_attr "type" "str")
16107 (set_attr "mode" "QI")
16108 (set (attr "prefix_rex")
16110 (match_test "<P:MODE>mode == DImode")
16112 (const_string "*")))
16113 (set_attr "prefix_rep" "1")])
16115 ;; The same, but the count is not known to not be zero.
16117 (define_expand "cmpstrnqi_1"
16118 [(parallel [(set (reg:CC FLAGS_REG)
16119 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16121 (compare:CC (match_operand 4 "memory_operand" "")
16122 (match_operand 5 "memory_operand" ""))
16124 (use (match_operand:SI 3 "immediate_operand" ""))
16125 (use (reg:CC FLAGS_REG))
16126 (clobber (match_operand 0 "register_operand" ""))
16127 (clobber (match_operand 1 "register_operand" ""))
16128 (clobber (match_dup 2))])]
16130 "ix86_current_function_needs_cld = 1;")
16132 (define_insn "*cmpstrnqi_1"
16133 [(set (reg:CC FLAGS_REG)
16134 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16136 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16137 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16139 (use (match_operand:SI 3 "immediate_operand" "i"))
16140 (use (reg:CC FLAGS_REG))
16141 (clobber (match_operand:P 0 "register_operand" "=S"))
16142 (clobber (match_operand:P 1 "register_operand" "=D"))
16143 (clobber (match_operand:P 2 "register_operand" "=c"))]
16144 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16146 [(set_attr "type" "str")
16147 (set_attr "mode" "QI")
16148 (set (attr "prefix_rex")
16150 (match_test "<P:MODE>mode == DImode")
16152 (const_string "*")))
16153 (set_attr "prefix_rep" "1")])
16155 (define_expand "strlen<mode>"
16156 [(set (match_operand:P 0 "register_operand" "")
16157 (unspec:P [(match_operand:BLK 1 "general_operand" "")
16158 (match_operand:QI 2 "immediate_operand" "")
16159 (match_operand 3 "immediate_operand" "")]
16163 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16169 (define_expand "strlenqi_1"
16170 [(parallel [(set (match_operand 0 "register_operand" "")
16171 (match_operand 2 "" ""))
16172 (clobber (match_operand 1 "register_operand" ""))
16173 (clobber (reg:CC FLAGS_REG))])]
16175 "ix86_current_function_needs_cld = 1;")
16177 (define_insn "*strlenqi_1"
16178 [(set (match_operand:P 0 "register_operand" "=&c")
16179 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16180 (match_operand:QI 2 "register_operand" "a")
16181 (match_operand:P 3 "immediate_operand" "i")
16182 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16183 (clobber (match_operand:P 1 "register_operand" "=D"))
16184 (clobber (reg:CC FLAGS_REG))]
16185 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16186 "%^repnz{%;} scasb"
16187 [(set_attr "type" "str")
16188 (set_attr "mode" "QI")
16189 (set (attr "prefix_rex")
16191 (match_test "<P:MODE>mode == DImode")
16193 (const_string "*")))
16194 (set_attr "prefix_rep" "1")])
16196 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16197 ;; handled in combine, but it is not currently up to the task.
16198 ;; When used for their truth value, the cmpstrn* expanders generate
16207 ;; The intermediate three instructions are unnecessary.
16209 ;; This one handles cmpstrn*_nz_1...
16212 (set (reg:CC FLAGS_REG)
16213 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16214 (mem:BLK (match_operand 5 "register_operand" ""))))
16215 (use (match_operand 6 "register_operand" ""))
16216 (use (match_operand:SI 3 "immediate_operand" ""))
16217 (clobber (match_operand 0 "register_operand" ""))
16218 (clobber (match_operand 1 "register_operand" ""))
16219 (clobber (match_operand 2 "register_operand" ""))])
16220 (set (match_operand:QI 7 "register_operand" "")
16221 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16222 (set (match_operand:QI 8 "register_operand" "")
16223 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16224 (set (reg FLAGS_REG)
16225 (compare (match_dup 7) (match_dup 8)))
16227 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16229 (set (reg:CC FLAGS_REG)
16230 (compare:CC (mem:BLK (match_dup 4))
16231 (mem:BLK (match_dup 5))))
16232 (use (match_dup 6))
16233 (use (match_dup 3))
16234 (clobber (match_dup 0))
16235 (clobber (match_dup 1))
16236 (clobber (match_dup 2))])])
16238 ;; ...and this one handles cmpstrn*_1.
16241 (set (reg:CC FLAGS_REG)
16242 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16244 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16245 (mem:BLK (match_operand 5 "register_operand" "")))
16247 (use (match_operand:SI 3 "immediate_operand" ""))
16248 (use (reg:CC FLAGS_REG))
16249 (clobber (match_operand 0 "register_operand" ""))
16250 (clobber (match_operand 1 "register_operand" ""))
16251 (clobber (match_operand 2 "register_operand" ""))])
16252 (set (match_operand:QI 7 "register_operand" "")
16253 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16254 (set (match_operand:QI 8 "register_operand" "")
16255 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16256 (set (reg FLAGS_REG)
16257 (compare (match_dup 7) (match_dup 8)))
16259 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16261 (set (reg:CC FLAGS_REG)
16262 (if_then_else:CC (ne (match_dup 6)
16264 (compare:CC (mem:BLK (match_dup 4))
16265 (mem:BLK (match_dup 5)))
16267 (use (match_dup 3))
16268 (use (reg:CC FLAGS_REG))
16269 (clobber (match_dup 0))
16270 (clobber (match_dup 1))
16271 (clobber (match_dup 2))])])
16273 ;; Conditional move instructions.
16275 (define_expand "mov<mode>cc"
16276 [(set (match_operand:SWIM 0 "register_operand" "")
16277 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16278 (match_operand:SWIM 2 "<general_operand>" "")
16279 (match_operand:SWIM 3 "<general_operand>" "")))]
16281 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16283 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16284 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16285 ;; So just document what we're doing explicitly.
16287 (define_expand "x86_mov<mode>cc_0_m1"
16289 [(set (match_operand:SWI48 0 "register_operand" "")
16290 (if_then_else:SWI48
16291 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16292 [(match_operand 1 "flags_reg_operand" "")
16296 (clobber (reg:CC FLAGS_REG))])])
16298 (define_insn "*x86_mov<mode>cc_0_m1"
16299 [(set (match_operand:SWI48 0 "register_operand" "=r")
16300 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16301 [(reg FLAGS_REG) (const_int 0)])
16304 (clobber (reg:CC FLAGS_REG))]
16306 "sbb{<imodesuffix>}\t%0, %0"
16307 ; Since we don't have the proper number of operands for an alu insn,
16308 ; fill in all the blanks.
16309 [(set_attr "type" "alu")
16310 (set_attr "use_carry" "1")
16311 (set_attr "pent_pair" "pu")
16312 (set_attr "memory" "none")
16313 (set_attr "imm_disp" "false")
16314 (set_attr "mode" "<MODE>")
16315 (set_attr "length_immediate" "0")])
16317 (define_insn "*x86_mov<mode>cc_0_m1_se"
16318 [(set (match_operand:SWI48 0 "register_operand" "=r")
16319 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16320 [(reg FLAGS_REG) (const_int 0)])
16323 (clobber (reg:CC FLAGS_REG))]
16325 "sbb{<imodesuffix>}\t%0, %0"
16326 [(set_attr "type" "alu")
16327 (set_attr "use_carry" "1")
16328 (set_attr "pent_pair" "pu")
16329 (set_attr "memory" "none")
16330 (set_attr "imm_disp" "false")
16331 (set_attr "mode" "<MODE>")
16332 (set_attr "length_immediate" "0")])
16334 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16335 [(set (match_operand:SWI48 0 "register_operand" "=r")
16336 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16337 [(reg FLAGS_REG) (const_int 0)])))]
16339 "sbb{<imodesuffix>}\t%0, %0"
16340 [(set_attr "type" "alu")
16341 (set_attr "use_carry" "1")
16342 (set_attr "pent_pair" "pu")
16343 (set_attr "memory" "none")
16344 (set_attr "imm_disp" "false")
16345 (set_attr "mode" "<MODE>")
16346 (set_attr "length_immediate" "0")])
16348 (define_insn "*mov<mode>cc_noc"
16349 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16350 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16351 [(reg FLAGS_REG) (const_int 0)])
16352 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16353 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16354 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16356 cmov%O2%C1\t{%2, %0|%0, %2}
16357 cmov%O2%c1\t{%3, %0|%0, %3}"
16358 [(set_attr "type" "icmov")
16359 (set_attr "mode" "<MODE>")])
16361 (define_insn_and_split "*movqicc_noc"
16362 [(set (match_operand:QI 0 "register_operand" "=r,r")
16363 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16364 [(match_operand 4 "flags_reg_operand" "")
16366 (match_operand:QI 2 "register_operand" "r,0")
16367 (match_operand:QI 3 "register_operand" "0,r")))]
16368 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16370 "&& reload_completed"
16371 [(set (match_dup 0)
16372 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16375 "operands[0] = gen_lowpart (SImode, operands[0]);
16376 operands[2] = gen_lowpart (SImode, operands[2]);
16377 operands[3] = gen_lowpart (SImode, operands[3]);"
16378 [(set_attr "type" "icmov")
16379 (set_attr "mode" "SI")])
16381 (define_expand "mov<mode>cc"
16382 [(set (match_operand:X87MODEF 0 "register_operand" "")
16383 (if_then_else:X87MODEF
16384 (match_operand 1 "ix86_fp_comparison_operator" "")
16385 (match_operand:X87MODEF 2 "register_operand" "")
16386 (match_operand:X87MODEF 3 "register_operand" "")))]
16387 "(TARGET_80387 && TARGET_CMOVE)
16388 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16389 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16391 (define_insn "*movxfcc_1"
16392 [(set (match_operand:XF 0 "register_operand" "=f,f")
16393 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16394 [(reg FLAGS_REG) (const_int 0)])
16395 (match_operand:XF 2 "register_operand" "f,0")
16396 (match_operand:XF 3 "register_operand" "0,f")))]
16397 "TARGET_80387 && TARGET_CMOVE"
16399 fcmov%F1\t{%2, %0|%0, %2}
16400 fcmov%f1\t{%3, %0|%0, %3}"
16401 [(set_attr "type" "fcmov")
16402 (set_attr "mode" "XF")])
16404 (define_insn "*movdfcc_1_rex64"
16405 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16406 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16407 [(reg FLAGS_REG) (const_int 0)])
16408 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16409 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16410 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16411 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16413 fcmov%F1\t{%2, %0|%0, %2}
16414 fcmov%f1\t{%3, %0|%0, %3}
16415 cmov%O2%C1\t{%2, %0|%0, %2}
16416 cmov%O2%c1\t{%3, %0|%0, %3}"
16417 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16418 (set_attr "mode" "DF,DF,DI,DI")])
16420 (define_insn "*movdfcc_1"
16421 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16422 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16423 [(reg FLAGS_REG) (const_int 0)])
16424 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16425 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16426 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16427 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16429 fcmov%F1\t{%2, %0|%0, %2}
16430 fcmov%f1\t{%3, %0|%0, %3}
16433 [(set_attr "type" "fcmov,fcmov,multi,multi")
16434 (set_attr "mode" "DF,DF,DI,DI")])
16437 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16438 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16439 [(match_operand 4 "flags_reg_operand" "")
16441 (match_operand:DF 2 "nonimmediate_operand" "")
16442 (match_operand:DF 3 "nonimmediate_operand" "")))]
16443 "!TARGET_64BIT && reload_completed"
16444 [(set (match_dup 2)
16445 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16449 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16453 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16454 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16457 (define_insn "*movsfcc_1_387"
16458 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16459 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16460 [(reg FLAGS_REG) (const_int 0)])
16461 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16462 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16463 "TARGET_80387 && TARGET_CMOVE
16464 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16466 fcmov%F1\t{%2, %0|%0, %2}
16467 fcmov%f1\t{%3, %0|%0, %3}
16468 cmov%O2%C1\t{%2, %0|%0, %2}
16469 cmov%O2%c1\t{%3, %0|%0, %3}"
16470 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16471 (set_attr "mode" "SF,SF,SI,SI")])
16473 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16474 ;; the scalar versions to have only XMM registers as operands.
16476 ;; XOP conditional move
16477 (define_insn "*xop_pcmov_<mode>"
16478 [(set (match_operand:MODEF 0 "register_operand" "=x")
16479 (if_then_else:MODEF
16480 (match_operand:MODEF 1 "register_operand" "x")
16481 (match_operand:MODEF 2 "register_operand" "x")
16482 (match_operand:MODEF 3 "register_operand" "x")))]
16484 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16485 [(set_attr "type" "sse4arg")])
16487 ;; These versions of the min/max patterns are intentionally ignorant of
16488 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16489 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16490 ;; are undefined in this condition, we're certain this is correct.
16492 (define_insn "<code><mode>3"
16493 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16495 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16496 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16497 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16499 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16500 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16501 [(set_attr "isa" "noavx,avx")
16502 (set_attr "prefix" "orig,vex")
16503 (set_attr "type" "sseadd")
16504 (set_attr "mode" "<MODE>")])
16506 ;; These versions of the min/max patterns implement exactly the operations
16507 ;; min = (op1 < op2 ? op1 : op2)
16508 ;; max = (!(op1 < op2) ? op1 : op2)
16509 ;; Their operands are not commutative, and thus they may be used in the
16510 ;; presence of -0.0 and NaN.
16512 (define_insn "*ieee_smin<mode>3"
16513 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16515 [(match_operand:MODEF 1 "register_operand" "0,x")
16516 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16518 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16520 min<ssemodesuffix>\t{%2, %0|%0, %2}
16521 vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16522 [(set_attr "isa" "noavx,avx")
16523 (set_attr "prefix" "orig,vex")
16524 (set_attr "type" "sseadd")
16525 (set_attr "mode" "<MODE>")])
16527 (define_insn "*ieee_smax<mode>3"
16528 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16530 [(match_operand:MODEF 1 "register_operand" "0,x")
16531 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16533 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16535 max<ssemodesuffix>\t{%2, %0|%0, %2}
16536 vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16537 [(set_attr "isa" "noavx,avx")
16538 (set_attr "prefix" "orig,vex")
16539 (set_attr "type" "sseadd")
16540 (set_attr "mode" "<MODE>")])
16542 ;; Make two stack loads independent:
16544 ;; fld %st(0) -> fld bb
16545 ;; fmul bb fmul %st(1), %st
16547 ;; Actually we only match the last two instructions for simplicity.
16549 [(set (match_operand 0 "fp_register_operand" "")
16550 (match_operand 1 "fp_register_operand" ""))
16552 (match_operator 2 "binary_fp_operator"
16554 (match_operand 3 "memory_operand" "")]))]
16555 "REGNO (operands[0]) != REGNO (operands[1])"
16556 [(set (match_dup 0) (match_dup 3))
16557 (set (match_dup 0) (match_dup 4))]
16559 ;; The % modifier is not operational anymore in peephole2's, so we have to
16560 ;; swap the operands manually in the case of addition and multiplication.
16564 if (COMMUTATIVE_ARITH_P (operands[2]))
16565 op0 = operands[0], op1 = operands[1];
16567 op0 = operands[1], op1 = operands[0];
16569 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16570 GET_MODE (operands[2]),
16574 ;; Conditional addition patterns
16575 (define_expand "add<mode>cc"
16576 [(match_operand:SWI 0 "register_operand" "")
16577 (match_operand 1 "ordered_comparison_operator" "")
16578 (match_operand:SWI 2 "register_operand" "")
16579 (match_operand:SWI 3 "const_int_operand" "")]
16581 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16583 ;; Misc patterns (?)
16585 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16586 ;; Otherwise there will be nothing to keep
16588 ;; [(set (reg ebp) (reg esp))]
16589 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16590 ;; (clobber (eflags)]
16591 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16593 ;; in proper program order.
16595 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16596 [(set (match_operand:P 0 "register_operand" "=r,r")
16597 (plus:P (match_operand:P 1 "register_operand" "0,r")
16598 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16599 (clobber (reg:CC FLAGS_REG))
16600 (clobber (mem:BLK (scratch)))]
16603 switch (get_attr_type (insn))
16606 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16609 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16610 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16611 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16613 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16616 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16617 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16620 [(set (attr "type")
16621 (cond [(and (eq_attr "alternative" "0")
16622 (not (match_test "TARGET_OPT_AGU")))
16623 (const_string "alu")
16624 (match_operand:<MODE> 2 "const0_operand" "")
16625 (const_string "imov")
16627 (const_string "lea")))
16628 (set (attr "length_immediate")
16629 (cond [(eq_attr "type" "imov")
16631 (and (eq_attr "type" "alu")
16632 (match_operand 2 "const128_operand" ""))
16635 (const_string "*")))
16636 (set_attr "mode" "<MODE>")])
16638 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16639 [(set (match_operand:P 0 "register_operand" "=r")
16640 (minus:P (match_operand:P 1 "register_operand" "0")
16641 (match_operand:P 2 "register_operand" "r")))
16642 (clobber (reg:CC FLAGS_REG))
16643 (clobber (mem:BLK (scratch)))]
16645 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16646 [(set_attr "type" "alu")
16647 (set_attr "mode" "<MODE>")])
16649 (define_insn "allocate_stack_worker_probe_<mode>"
16650 [(set (match_operand:P 0 "register_operand" "=a")
16651 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16652 UNSPECV_STACK_PROBE))
16653 (clobber (reg:CC FLAGS_REG))]
16654 "ix86_target_stack_probe ()"
16655 "call\t___chkstk_ms"
16656 [(set_attr "type" "multi")
16657 (set_attr "length" "5")])
16659 (define_expand "allocate_stack"
16660 [(match_operand 0 "register_operand" "")
16661 (match_operand 1 "general_operand" "")]
16662 "ix86_target_stack_probe ()"
16666 #ifndef CHECK_STACK_LIMIT
16667 #define CHECK_STACK_LIMIT 0
16670 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16671 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16673 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16674 stack_pointer_rtx, 0, OPTAB_DIRECT);
16675 if (x != stack_pointer_rtx)
16676 emit_move_insn (stack_pointer_rtx, x);
16680 x = copy_to_mode_reg (Pmode, operands[1]);
16682 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16684 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16685 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16686 stack_pointer_rtx, 0, OPTAB_DIRECT);
16687 if (x != stack_pointer_rtx)
16688 emit_move_insn (stack_pointer_rtx, x);
16691 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16695 ;; Use IOR for stack probes, this is shorter.
16696 (define_expand "probe_stack"
16697 [(match_operand 0 "memory_operand" "")]
16700 rtx (*gen_ior3) (rtx, rtx, rtx);
16702 gen_ior3 = (GET_MODE (operands[0]) == DImode
16703 ? gen_iordi3 : gen_iorsi3);
16705 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16709 (define_insn "adjust_stack_and_probe<mode>"
16710 [(set (match_operand:P 0 "register_operand" "=r")
16711 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16712 UNSPECV_PROBE_STACK_RANGE))
16713 (set (reg:P SP_REG)
16714 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16715 (clobber (reg:CC FLAGS_REG))
16716 (clobber (mem:BLK (scratch)))]
16718 "* return output_adjust_stack_and_probe (operands[0]);"
16719 [(set_attr "type" "multi")])
16721 (define_insn "probe_stack_range<mode>"
16722 [(set (match_operand:P 0 "register_operand" "=r")
16723 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16724 (match_operand:P 2 "const_int_operand" "n")]
16725 UNSPECV_PROBE_STACK_RANGE))
16726 (clobber (reg:CC FLAGS_REG))]
16728 "* return output_probe_stack_range (operands[0], operands[2]);"
16729 [(set_attr "type" "multi")])
16731 (define_expand "builtin_setjmp_receiver"
16732 [(label_ref (match_operand 0 "" ""))]
16733 "!TARGET_64BIT && flag_pic"
16739 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16740 rtx label_rtx = gen_label_rtx ();
16741 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16742 xops[0] = xops[1] = picreg;
16743 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16744 ix86_expand_binary_operator (MINUS, SImode, xops);
16748 emit_insn (gen_set_got (pic_offset_table_rtx));
16752 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16755 [(set (match_operand 0 "register_operand" "")
16756 (match_operator 3 "promotable_binary_operator"
16757 [(match_operand 1 "register_operand" "")
16758 (match_operand 2 "aligned_operand" "")]))
16759 (clobber (reg:CC FLAGS_REG))]
16760 "! TARGET_PARTIAL_REG_STALL && reload_completed
16761 && ((GET_MODE (operands[0]) == HImode
16762 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16763 /* ??? next two lines just !satisfies_constraint_K (...) */
16764 || !CONST_INT_P (operands[2])
16765 || satisfies_constraint_K (operands[2])))
16766 || (GET_MODE (operands[0]) == QImode
16767 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16768 [(parallel [(set (match_dup 0)
16769 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16770 (clobber (reg:CC FLAGS_REG))])]
16772 operands[0] = gen_lowpart (SImode, operands[0]);
16773 operands[1] = gen_lowpart (SImode, operands[1]);
16774 if (GET_CODE (operands[3]) != ASHIFT)
16775 operands[2] = gen_lowpart (SImode, operands[2]);
16776 PUT_MODE (operands[3], SImode);
16779 ; Promote the QImode tests, as i386 has encoding of the AND
16780 ; instruction with 32-bit sign-extended immediate and thus the
16781 ; instruction size is unchanged, except in the %eax case for
16782 ; which it is increased by one byte, hence the ! optimize_size.
16784 [(set (match_operand 0 "flags_reg_operand" "")
16785 (match_operator 2 "compare_operator"
16786 [(and (match_operand 3 "aligned_operand" "")
16787 (match_operand 4 "const_int_operand" ""))
16789 (set (match_operand 1 "register_operand" "")
16790 (and (match_dup 3) (match_dup 4)))]
16791 "! TARGET_PARTIAL_REG_STALL && reload_completed
16792 && optimize_insn_for_speed_p ()
16793 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16794 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16795 /* Ensure that the operand will remain sign-extended immediate. */
16796 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16797 [(parallel [(set (match_dup 0)
16798 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16801 (and:SI (match_dup 3) (match_dup 4)))])]
16804 = gen_int_mode (INTVAL (operands[4])
16805 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16806 operands[1] = gen_lowpart (SImode, operands[1]);
16807 operands[3] = gen_lowpart (SImode, operands[3]);
16810 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16811 ; the TEST instruction with 32-bit sign-extended immediate and thus
16812 ; the instruction size would at least double, which is not what we
16813 ; want even with ! optimize_size.
16815 [(set (match_operand 0 "flags_reg_operand" "")
16816 (match_operator 1 "compare_operator"
16817 [(and (match_operand:HI 2 "aligned_operand" "")
16818 (match_operand:HI 3 "const_int_operand" ""))
16820 "! TARGET_PARTIAL_REG_STALL && reload_completed
16821 && ! TARGET_FAST_PREFIX
16822 && optimize_insn_for_speed_p ()
16823 /* Ensure that the operand will remain sign-extended immediate. */
16824 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16825 [(set (match_dup 0)
16826 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16830 = gen_int_mode (INTVAL (operands[3])
16831 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16832 operands[2] = gen_lowpart (SImode, operands[2]);
16836 [(set (match_operand 0 "register_operand" "")
16837 (neg (match_operand 1 "register_operand" "")))
16838 (clobber (reg:CC FLAGS_REG))]
16839 "! TARGET_PARTIAL_REG_STALL && reload_completed
16840 && (GET_MODE (operands[0]) == HImode
16841 || (GET_MODE (operands[0]) == QImode
16842 && (TARGET_PROMOTE_QImode
16843 || optimize_insn_for_size_p ())))"
16844 [(parallel [(set (match_dup 0)
16845 (neg:SI (match_dup 1)))
16846 (clobber (reg:CC FLAGS_REG))])]
16848 operands[0] = gen_lowpart (SImode, operands[0]);
16849 operands[1] = gen_lowpart (SImode, operands[1]);
16853 [(set (match_operand 0 "register_operand" "")
16854 (not (match_operand 1 "register_operand" "")))]
16855 "! TARGET_PARTIAL_REG_STALL && reload_completed
16856 && (GET_MODE (operands[0]) == HImode
16857 || (GET_MODE (operands[0]) == QImode
16858 && (TARGET_PROMOTE_QImode
16859 || optimize_insn_for_size_p ())))"
16860 [(set (match_dup 0)
16861 (not:SI (match_dup 1)))]
16863 operands[0] = gen_lowpart (SImode, operands[0]);
16864 operands[1] = gen_lowpart (SImode, operands[1]);
16868 [(set (match_operand 0 "register_operand" "")
16869 (if_then_else (match_operator 1 "ordered_comparison_operator"
16870 [(reg FLAGS_REG) (const_int 0)])
16871 (match_operand 2 "register_operand" "")
16872 (match_operand 3 "register_operand" "")))]
16873 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16874 && (GET_MODE (operands[0]) == HImode
16875 || (GET_MODE (operands[0]) == QImode
16876 && (TARGET_PROMOTE_QImode
16877 || optimize_insn_for_size_p ())))"
16878 [(set (match_dup 0)
16879 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16881 operands[0] = gen_lowpart (SImode, operands[0]);
16882 operands[2] = gen_lowpart (SImode, operands[2]);
16883 operands[3] = gen_lowpart (SImode, operands[3]);
16886 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16887 ;; transform a complex memory operation into two memory to register operations.
16889 ;; Don't push memory operands
16891 [(set (match_operand:SWI 0 "push_operand" "")
16892 (match_operand:SWI 1 "memory_operand" ""))
16893 (match_scratch:SWI 2 "<r>")]
16894 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16895 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16896 [(set (match_dup 2) (match_dup 1))
16897 (set (match_dup 0) (match_dup 2))])
16899 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16902 [(set (match_operand:SF 0 "push_operand" "")
16903 (match_operand:SF 1 "memory_operand" ""))
16904 (match_scratch:SF 2 "r")]
16905 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16906 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16907 [(set (match_dup 2) (match_dup 1))
16908 (set (match_dup 0) (match_dup 2))])
16910 ;; Don't move an immediate directly to memory when the instruction
16913 [(match_scratch:SWI124 1 "<r>")
16914 (set (match_operand:SWI124 0 "memory_operand" "")
16916 "optimize_insn_for_speed_p ()
16917 && !TARGET_USE_MOV0
16918 && TARGET_SPLIT_LONG_MOVES
16919 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16920 && peep2_regno_dead_p (0, FLAGS_REG)"
16921 [(parallel [(set (match_dup 2) (const_int 0))
16922 (clobber (reg:CC FLAGS_REG))])
16923 (set (match_dup 0) (match_dup 1))]
16924 "operands[2] = gen_lowpart (SImode, operands[1]);")
16927 [(match_scratch:SWI124 2 "<r>")
16928 (set (match_operand:SWI124 0 "memory_operand" "")
16929 (match_operand:SWI124 1 "immediate_operand" ""))]
16930 "optimize_insn_for_speed_p ()
16931 && TARGET_SPLIT_LONG_MOVES
16932 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16933 [(set (match_dup 2) (match_dup 1))
16934 (set (match_dup 0) (match_dup 2))])
16936 ;; Don't compare memory with zero, load and use a test instead.
16938 [(set (match_operand 0 "flags_reg_operand" "")
16939 (match_operator 1 "compare_operator"
16940 [(match_operand:SI 2 "memory_operand" "")
16942 (match_scratch:SI 3 "r")]
16943 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16944 [(set (match_dup 3) (match_dup 2))
16945 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16947 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16948 ;; Don't split NOTs with a displacement operand, because resulting XOR
16949 ;; will not be pairable anyway.
16951 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16952 ;; represented using a modRM byte. The XOR replacement is long decoded,
16953 ;; so this split helps here as well.
16955 ;; Note: Can't do this as a regular split because we can't get proper
16956 ;; lifetime information then.
16959 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16960 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16961 "optimize_insn_for_speed_p ()
16962 && ((TARGET_NOT_UNPAIRABLE
16963 && (!MEM_P (operands[0])
16964 || !memory_displacement_operand (operands[0], <MODE>mode)))
16965 || (TARGET_NOT_VECTORMODE
16966 && long_memory_operand (operands[0], <MODE>mode)))
16967 && peep2_regno_dead_p (0, FLAGS_REG)"
16968 [(parallel [(set (match_dup 0)
16969 (xor:SWI124 (match_dup 1) (const_int -1)))
16970 (clobber (reg:CC FLAGS_REG))])])
16972 ;; Non pairable "test imm, reg" instructions can be translated to
16973 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16974 ;; byte opcode instead of two, have a short form for byte operands),
16975 ;; so do it for other CPUs as well. Given that the value was dead,
16976 ;; this should not create any new dependencies. Pass on the sub-word
16977 ;; versions if we're concerned about partial register stalls.
16980 [(set (match_operand 0 "flags_reg_operand" "")
16981 (match_operator 1 "compare_operator"
16982 [(and:SI (match_operand:SI 2 "register_operand" "")
16983 (match_operand:SI 3 "immediate_operand" ""))
16985 "ix86_match_ccmode (insn, CCNOmode)
16986 && (true_regnum (operands[2]) != AX_REG
16987 || satisfies_constraint_K (operands[3]))
16988 && peep2_reg_dead_p (1, operands[2])"
16990 [(set (match_dup 0)
16991 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16994 (and:SI (match_dup 2) (match_dup 3)))])])
16996 ;; We don't need to handle HImode case, because it will be promoted to SImode
16997 ;; on ! TARGET_PARTIAL_REG_STALL
17000 [(set (match_operand 0 "flags_reg_operand" "")
17001 (match_operator 1 "compare_operator"
17002 [(and:QI (match_operand:QI 2 "register_operand" "")
17003 (match_operand:QI 3 "immediate_operand" ""))
17005 "! TARGET_PARTIAL_REG_STALL
17006 && ix86_match_ccmode (insn, CCNOmode)
17007 && true_regnum (operands[2]) != AX_REG
17008 && peep2_reg_dead_p (1, operands[2])"
17010 [(set (match_dup 0)
17011 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17014 (and:QI (match_dup 2) (match_dup 3)))])])
17017 [(set (match_operand 0 "flags_reg_operand" "")
17018 (match_operator 1 "compare_operator"
17021 (match_operand 2 "ext_register_operand" "")
17024 (match_operand 3 "const_int_operand" ""))
17026 "! TARGET_PARTIAL_REG_STALL
17027 && ix86_match_ccmode (insn, CCNOmode)
17028 && true_regnum (operands[2]) != AX_REG
17029 && peep2_reg_dead_p (1, operands[2])"
17030 [(parallel [(set (match_dup 0)
17039 (set (zero_extract:SI (match_dup 2)
17047 (match_dup 3)))])])
17049 ;; Don't do logical operations with memory inputs.
17051 [(match_scratch:SI 2 "r")
17052 (parallel [(set (match_operand:SI 0 "register_operand" "")
17053 (match_operator:SI 3 "arith_or_logical_operator"
17055 (match_operand:SI 1 "memory_operand" "")]))
17056 (clobber (reg:CC FLAGS_REG))])]
17057 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17058 [(set (match_dup 2) (match_dup 1))
17059 (parallel [(set (match_dup 0)
17060 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17061 (clobber (reg:CC FLAGS_REG))])])
17064 [(match_scratch:SI 2 "r")
17065 (parallel [(set (match_operand:SI 0 "register_operand" "")
17066 (match_operator:SI 3 "arith_or_logical_operator"
17067 [(match_operand:SI 1 "memory_operand" "")
17069 (clobber (reg:CC FLAGS_REG))])]
17070 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17071 [(set (match_dup 2) (match_dup 1))
17072 (parallel [(set (match_dup 0)
17073 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17074 (clobber (reg:CC FLAGS_REG))])])
17076 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17077 ;; refers to the destination of the load!
17080 [(set (match_operand:SI 0 "register_operand" "")
17081 (match_operand:SI 1 "register_operand" ""))
17082 (parallel [(set (match_dup 0)
17083 (match_operator:SI 3 "commutative_operator"
17085 (match_operand:SI 2 "memory_operand" "")]))
17086 (clobber (reg:CC FLAGS_REG))])]
17087 "REGNO (operands[0]) != REGNO (operands[1])
17088 && GENERAL_REGNO_P (REGNO (operands[0]))
17089 && GENERAL_REGNO_P (REGNO (operands[1]))"
17090 [(set (match_dup 0) (match_dup 4))
17091 (parallel [(set (match_dup 0)
17092 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17093 (clobber (reg:CC FLAGS_REG))])]
17094 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17097 [(set (match_operand 0 "register_operand" "")
17098 (match_operand 1 "register_operand" ""))
17100 (match_operator 3 "commutative_operator"
17102 (match_operand 2 "memory_operand" "")]))]
17103 "REGNO (operands[0]) != REGNO (operands[1])
17104 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17105 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17106 [(set (match_dup 0) (match_dup 2))
17108 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17110 ; Don't do logical operations with memory outputs
17112 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17113 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17114 ; the same decoder scheduling characteristics as the original.
17117 [(match_scratch:SI 2 "r")
17118 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17119 (match_operator:SI 3 "arith_or_logical_operator"
17121 (match_operand:SI 1 "nonmemory_operand" "")]))
17122 (clobber (reg:CC FLAGS_REG))])]
17123 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17124 /* Do not split stack checking probes. */
17125 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17126 [(set (match_dup 2) (match_dup 0))
17127 (parallel [(set (match_dup 2)
17128 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17129 (clobber (reg:CC FLAGS_REG))])
17130 (set (match_dup 0) (match_dup 2))])
17133 [(match_scratch:SI 2 "r")
17134 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17135 (match_operator:SI 3 "arith_or_logical_operator"
17136 [(match_operand:SI 1 "nonmemory_operand" "")
17138 (clobber (reg:CC FLAGS_REG))])]
17139 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17140 /* Do not split stack checking probes. */
17141 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17142 [(set (match_dup 2) (match_dup 0))
17143 (parallel [(set (match_dup 2)
17144 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17145 (clobber (reg:CC FLAGS_REG))])
17146 (set (match_dup 0) (match_dup 2))])
17148 ;; Attempt to use arith or logical operations with memory outputs with
17149 ;; setting of flags.
17151 [(set (match_operand:SWI 0 "register_operand" "")
17152 (match_operand:SWI 1 "memory_operand" ""))
17153 (parallel [(set (match_dup 0)
17154 (match_operator:SWI 3 "plusminuslogic_operator"
17156 (match_operand:SWI 2 "<nonmemory_operand>" "")]))
17157 (clobber (reg:CC FLAGS_REG))])
17158 (set (match_dup 1) (match_dup 0))
17159 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17160 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17161 && peep2_reg_dead_p (4, operands[0])
17162 && !reg_overlap_mentioned_p (operands[0], operands[1])
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:SI 0 "register_operand" "")
17290 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17291 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17293 && peep2_regno_dead_p (0, FLAGS_REG)
17294 && REGNO (operands[0]) == REGNO (operands[1])"
17295 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17296 (clobber (reg:CC FLAGS_REG))])]
17297 "operands[2] = gen_lowpart (SImode, operands[2]);")
17300 [(set (match_operand:SWI48 0 "register_operand" "")
17301 (mult:SWI48 (match_dup 0)
17302 (match_operand:SWI48 1 "const_int_operand" "")))]
17303 "exact_log2 (INTVAL (operands[1])) >= 0
17304 && peep2_regno_dead_p (0, FLAGS_REG)"
17305 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17306 (clobber (reg:CC FLAGS_REG))])]
17307 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17310 [(set (match_operand:SI 0 "register_operand" "")
17311 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17312 (match_operand:DI 2 "const_int_operand" "")) 0))]
17314 && exact_log2 (INTVAL (operands[2])) >= 0
17315 && REGNO (operands[0]) == REGNO (operands[1])
17316 && peep2_regno_dead_p (0, FLAGS_REG)"
17317 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17318 (clobber (reg:CC FLAGS_REG))])]
17319 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17321 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17322 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17323 ;; On many CPUs it is also faster, since special hardware to avoid esp
17324 ;; dependencies is present.
17326 ;; While some of these conversions may be done using splitters, we use
17327 ;; peepholes in order to allow combine_stack_adjustments pass to see
17328 ;; nonobfuscated RTL.
17330 ;; Convert prologue esp subtractions to push.
17331 ;; We need register to push. In order to keep verify_flow_info happy we have
17333 ;; - use scratch and clobber it in order to avoid dependencies
17334 ;; - use already live register
17335 ;; We can't use the second way right now, since there is no reliable way how to
17336 ;; verify that given register is live. First choice will also most likely in
17337 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17338 ;; call clobbered registers are dead. We may want to use base pointer as an
17339 ;; alternative when no register is available later.
17342 [(match_scratch:W 1 "r")
17343 (parallel [(set (reg:P SP_REG)
17344 (plus:P (reg:P SP_REG)
17345 (match_operand:P 0 "const_int_operand" "")))
17346 (clobber (reg:CC FLAGS_REG))
17347 (clobber (mem:BLK (scratch)))])]
17348 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17349 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17350 [(clobber (match_dup 1))
17351 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17352 (clobber (mem:BLK (scratch)))])])
17355 [(match_scratch:W 1 "r")
17356 (parallel [(set (reg:P SP_REG)
17357 (plus:P (reg:P SP_REG)
17358 (match_operand:P 0 "const_int_operand" "")))
17359 (clobber (reg:CC FLAGS_REG))
17360 (clobber (mem:BLK (scratch)))])]
17361 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17362 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17363 [(clobber (match_dup 1))
17364 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17365 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17366 (clobber (mem:BLK (scratch)))])])
17368 ;; Convert esp subtractions to push.
17370 [(match_scratch:W 1 "r")
17371 (parallel [(set (reg:P SP_REG)
17372 (plus:P (reg:P SP_REG)
17373 (match_operand:P 0 "const_int_operand" "")))
17374 (clobber (reg:CC FLAGS_REG))])]
17375 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17376 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17377 [(clobber (match_dup 1))
17378 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17381 [(match_scratch:W 1 "r")
17382 (parallel [(set (reg:P SP_REG)
17383 (plus:P (reg:P SP_REG)
17384 (match_operand:P 0 "const_int_operand" "")))
17385 (clobber (reg:CC FLAGS_REG))])]
17386 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17387 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17388 [(clobber (match_dup 1))
17389 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17390 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17392 ;; Convert epilogue deallocator to pop.
17394 [(match_scratch:W 1 "r")
17395 (parallel [(set (reg:P SP_REG)
17396 (plus:P (reg:P SP_REG)
17397 (match_operand:P 0 "const_int_operand" "")))
17398 (clobber (reg:CC FLAGS_REG))
17399 (clobber (mem:BLK (scratch)))])]
17400 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17401 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17402 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17403 (clobber (mem:BLK (scratch)))])])
17405 ;; Two pops case is tricky, since pop causes dependency
17406 ;; on destination register. We use two registers if available.
17408 [(match_scratch:W 1 "r")
17409 (match_scratch:W 2 "r")
17410 (parallel [(set (reg:P SP_REG)
17411 (plus:P (reg:P SP_REG)
17412 (match_operand:P 0 "const_int_operand" "")))
17413 (clobber (reg:CC FLAGS_REG))
17414 (clobber (mem:BLK (scratch)))])]
17415 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17416 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17417 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17418 (clobber (mem:BLK (scratch)))])
17419 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17422 [(match_scratch:W 1 "r")
17423 (parallel [(set (reg:P SP_REG)
17424 (plus:P (reg:P SP_REG)
17425 (match_operand:P 0 "const_int_operand" "")))
17426 (clobber (reg:CC FLAGS_REG))
17427 (clobber (mem:BLK (scratch)))])]
17428 "optimize_insn_for_size_p ()
17429 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17430 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17431 (clobber (mem:BLK (scratch)))])
17432 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17434 ;; Convert esp additions to pop.
17436 [(match_scratch:W 1 "r")
17437 (parallel [(set (reg:P SP_REG)
17438 (plus:P (reg:P SP_REG)
17439 (match_operand:P 0 "const_int_operand" "")))
17440 (clobber (reg:CC FLAGS_REG))])]
17441 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17442 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17444 ;; Two pops case is tricky, since pop causes dependency
17445 ;; on destination register. We use two registers if available.
17447 [(match_scratch:W 1 "r")
17448 (match_scratch:W 2 "r")
17449 (parallel [(set (reg:P SP_REG)
17450 (plus:P (reg:P SP_REG)
17451 (match_operand:P 0 "const_int_operand" "")))
17452 (clobber (reg:CC FLAGS_REG))])]
17453 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17454 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17455 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17458 [(match_scratch:W 1 "r")
17459 (parallel [(set (reg:P SP_REG)
17460 (plus:P (reg:P SP_REG)
17461 (match_operand:P 0 "const_int_operand" "")))
17462 (clobber (reg:CC FLAGS_REG))])]
17463 "optimize_insn_for_size_p ()
17464 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17465 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17466 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17468 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17469 ;; required and register dies. Similarly for 128 to -128.
17471 [(set (match_operand 0 "flags_reg_operand" "")
17472 (match_operator 1 "compare_operator"
17473 [(match_operand 2 "register_operand" "")
17474 (match_operand 3 "const_int_operand" "")]))]
17475 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17476 && incdec_operand (operands[3], GET_MODE (operands[3])))
17477 || (!TARGET_FUSE_CMP_AND_BRANCH
17478 && INTVAL (operands[3]) == 128))
17479 && ix86_match_ccmode (insn, CCGCmode)
17480 && peep2_reg_dead_p (1, operands[2])"
17481 [(parallel [(set (match_dup 0)
17482 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17483 (clobber (match_dup 2))])])
17485 ;; Convert imul by three, five and nine into lea
17488 [(set (match_operand:SWI48 0 "register_operand" "")
17489 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17490 (match_operand:SWI48 2 "const359_operand" "")))
17491 (clobber (reg:CC FLAGS_REG))])]
17492 "!TARGET_PARTIAL_REG_STALL
17493 || <MODE>mode == SImode
17494 || optimize_function_for_size_p (cfun)"
17495 [(set (match_dup 0)
17496 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17498 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17502 [(set (match_operand:SWI48 0 "register_operand" "")
17503 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17504 (match_operand:SWI48 2 "const359_operand" "")))
17505 (clobber (reg:CC FLAGS_REG))])]
17506 "optimize_insn_for_speed_p ()
17507 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17508 [(set (match_dup 0) (match_dup 1))
17510 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17512 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17514 ;; imul $32bit_imm, mem, reg is vector decoded, while
17515 ;; imul $32bit_imm, reg, reg is direct decoded.
17517 [(match_scratch:SWI48 3 "r")
17518 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17519 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17520 (match_operand:SWI48 2 "immediate_operand" "")))
17521 (clobber (reg:CC FLAGS_REG))])]
17522 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17523 && !satisfies_constraint_K (operands[2])"
17524 [(set (match_dup 3) (match_dup 1))
17525 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17526 (clobber (reg:CC FLAGS_REG))])])
17529 [(match_scratch:SI 3 "r")
17530 (parallel [(set (match_operand:DI 0 "register_operand" "")
17532 (mult:SI (match_operand:SI 1 "memory_operand" "")
17533 (match_operand:SI 2 "immediate_operand" ""))))
17534 (clobber (reg:CC FLAGS_REG))])]
17536 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17537 && !satisfies_constraint_K (operands[2])"
17538 [(set (match_dup 3) (match_dup 1))
17539 (parallel [(set (match_dup 0)
17540 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17541 (clobber (reg:CC FLAGS_REG))])])
17543 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17544 ;; Convert it into imul reg, reg
17545 ;; It would be better to force assembler to encode instruction using long
17546 ;; immediate, but there is apparently no way to do so.
17548 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17550 (match_operand:SWI248 1 "nonimmediate_operand" "")
17551 (match_operand:SWI248 2 "const_int_operand" "")))
17552 (clobber (reg:CC FLAGS_REG))])
17553 (match_scratch:SWI248 3 "r")]
17554 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17555 && satisfies_constraint_K (operands[2])"
17556 [(set (match_dup 3) (match_dup 2))
17557 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17558 (clobber (reg:CC FLAGS_REG))])]
17560 if (!rtx_equal_p (operands[0], operands[1]))
17561 emit_move_insn (operands[0], operands[1]);
17564 ;; After splitting up read-modify operations, array accesses with memory
17565 ;; operands might end up in form:
17567 ;; movl 4(%esp), %edx
17569 ;; instead of pre-splitting:
17571 ;; addl 4(%esp), %eax
17573 ;; movl 4(%esp), %edx
17574 ;; leal (%edx,%eax,4), %eax
17577 [(match_scratch:W 5 "r")
17578 (parallel [(set (match_operand 0 "register_operand" "")
17579 (ashift (match_operand 1 "register_operand" "")
17580 (match_operand 2 "const_int_operand" "")))
17581 (clobber (reg:CC FLAGS_REG))])
17582 (parallel [(set (match_operand 3 "register_operand" "")
17583 (plus (match_dup 0)
17584 (match_operand 4 "x86_64_general_operand" "")))
17585 (clobber (reg:CC FLAGS_REG))])]
17586 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17587 /* Validate MODE for lea. */
17588 && ((!TARGET_PARTIAL_REG_STALL
17589 && (GET_MODE (operands[0]) == QImode
17590 || GET_MODE (operands[0]) == HImode))
17591 || GET_MODE (operands[0]) == SImode
17592 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17593 && (rtx_equal_p (operands[0], operands[3])
17594 || peep2_reg_dead_p (2, operands[0]))
17595 /* We reorder load and the shift. */
17596 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17597 [(set (match_dup 5) (match_dup 4))
17598 (set (match_dup 0) (match_dup 1))]
17600 enum machine_mode op1mode = GET_MODE (operands[1]);
17601 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17602 int scale = 1 << INTVAL (operands[2]);
17603 rtx index = gen_lowpart (word_mode, operands[1]);
17604 rtx base = gen_lowpart (word_mode, operands[5]);
17605 rtx dest = gen_lowpart (mode, operands[3]);
17607 operands[1] = gen_rtx_PLUS (word_mode, base,
17608 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
17609 operands[5] = base;
17610 if (mode != word_mode)
17611 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17612 if (op1mode != word_mode)
17613 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17614 operands[0] = dest;
17617 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17618 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17619 ;; caught for use by garbage collectors and the like. Using an insn that
17620 ;; maps to SIGILL makes it more likely the program will rightfully die.
17621 ;; Keeping with tradition, "6" is in honor of #UD.
17622 (define_insn "trap"
17623 [(trap_if (const_int 1) (const_int 6))]
17625 { return ASM_SHORT "0x0b0f"; }
17626 [(set_attr "length" "2")])
17628 (define_expand "prefetch"
17629 [(prefetch (match_operand 0 "address_operand" "")
17630 (match_operand:SI 1 "const_int_operand" "")
17631 (match_operand:SI 2 "const_int_operand" ""))]
17632 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17634 int rw = INTVAL (operands[1]);
17635 int locality = INTVAL (operands[2]);
17637 gcc_assert (rw == 0 || rw == 1);
17638 gcc_assert (locality >= 0 && locality <= 3);
17639 gcc_assert (GET_MODE (operands[0]) == Pmode
17640 || GET_MODE (operands[0]) == VOIDmode);
17642 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17643 supported by SSE counterpart or the SSE prefetch is not available
17644 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17646 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17647 operands[2] = GEN_INT (3);
17649 operands[1] = const0_rtx;
17652 (define_insn "*prefetch_sse_<mode>"
17653 [(prefetch (match_operand:P 0 "address_operand" "p")
17655 (match_operand:SI 1 "const_int_operand" ""))]
17656 "TARGET_PREFETCH_SSE"
17658 static const char * const patterns[4] = {
17659 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17662 int locality = INTVAL (operands[1]);
17663 gcc_assert (locality >= 0 && locality <= 3);
17665 return patterns[locality];
17667 [(set_attr "type" "sse")
17668 (set_attr "atom_sse_attr" "prefetch")
17669 (set (attr "length_address")
17670 (symbol_ref "memory_address_length (operands[0])"))
17671 (set_attr "memory" "none")])
17673 (define_insn "*prefetch_3dnow_<mode>"
17674 [(prefetch (match_operand:P 0 "address_operand" "p")
17675 (match_operand:SI 1 "const_int_operand" "n")
17679 if (INTVAL (operands[1]) == 0)
17680 return "prefetch\t%a0";
17682 return "prefetchw\t%a0";
17684 [(set_attr "type" "mmx")
17685 (set (attr "length_address")
17686 (symbol_ref "memory_address_length (operands[0])"))
17687 (set_attr "memory" "none")])
17689 (define_expand "stack_protect_set"
17690 [(match_operand 0 "memory_operand" "")
17691 (match_operand 1 "memory_operand" "")]
17694 rtx (*insn)(rtx, rtx);
17696 #ifdef TARGET_THREAD_SSP_OFFSET
17697 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17698 insn = (TARGET_LP64
17699 ? gen_stack_tls_protect_set_di
17700 : gen_stack_tls_protect_set_si);
17702 insn = (TARGET_LP64
17703 ? gen_stack_protect_set_di
17704 : gen_stack_protect_set_si);
17707 emit_insn (insn (operands[0], operands[1]));
17711 (define_insn "stack_protect_set_<mode>"
17712 [(set (match_operand:PTR 0 "memory_operand" "=m")
17713 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17715 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17716 (clobber (reg:CC FLAGS_REG))]
17718 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17719 [(set_attr "type" "multi")])
17721 (define_insn "stack_tls_protect_set_<mode>"
17722 [(set (match_operand:PTR 0 "memory_operand" "=m")
17723 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17724 UNSPEC_SP_TLS_SET))
17725 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17726 (clobber (reg:CC FLAGS_REG))]
17728 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17729 [(set_attr "type" "multi")])
17731 (define_expand "stack_protect_test"
17732 [(match_operand 0 "memory_operand" "")
17733 (match_operand 1 "memory_operand" "")
17734 (match_operand 2 "" "")]
17737 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17739 rtx (*insn)(rtx, rtx, rtx);
17741 #ifdef TARGET_THREAD_SSP_OFFSET
17742 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17743 insn = (TARGET_LP64
17744 ? gen_stack_tls_protect_test_di
17745 : gen_stack_tls_protect_test_si);
17747 insn = (TARGET_LP64
17748 ? gen_stack_protect_test_di
17749 : gen_stack_protect_test_si);
17752 emit_insn (insn (flags, operands[0], operands[1]));
17754 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17755 flags, const0_rtx, operands[2]));
17759 (define_insn "stack_protect_test_<mode>"
17760 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17761 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17762 (match_operand:PTR 2 "memory_operand" "m")]
17764 (clobber (match_scratch:PTR 3 "=&r"))]
17766 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17767 [(set_attr "type" "multi")])
17769 (define_insn "stack_tls_protect_test_<mode>"
17770 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17771 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17772 (match_operand:PTR 2 "const_int_operand" "i")]
17773 UNSPEC_SP_TLS_TEST))
17774 (clobber (match_scratch:PTR 3 "=r"))]
17776 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17777 [(set_attr "type" "multi")])
17779 (define_insn "sse4_2_crc32<mode>"
17780 [(set (match_operand:SI 0 "register_operand" "=r")
17782 [(match_operand:SI 1 "register_operand" "0")
17783 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17785 "TARGET_SSE4_2 || TARGET_CRC32"
17786 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17787 [(set_attr "type" "sselog1")
17788 (set_attr "prefix_rep" "1")
17789 (set_attr "prefix_extra" "1")
17790 (set (attr "prefix_data16")
17791 (if_then_else (match_operand:HI 2 "" "")
17793 (const_string "*")))
17794 (set (attr "prefix_rex")
17795 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17797 (const_string "*")))
17798 (set_attr "mode" "SI")])
17800 (define_insn "sse4_2_crc32di"
17801 [(set (match_operand:DI 0 "register_operand" "=r")
17803 [(match_operand:DI 1 "register_operand" "0")
17804 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17806 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17807 "crc32{q}\t{%2, %0|%0, %2}"
17808 [(set_attr "type" "sselog1")
17809 (set_attr "prefix_rep" "1")
17810 (set_attr "prefix_extra" "1")
17811 (set_attr "mode" "DI")])
17813 (define_expand "rdpmc"
17814 [(match_operand:DI 0 "register_operand" "")
17815 (match_operand:SI 1 "register_operand" "")]
17818 rtx reg = gen_reg_rtx (DImode);
17821 /* Force operand 1 into ECX. */
17822 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17823 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17824 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17829 rtvec vec = rtvec_alloc (2);
17830 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17831 rtx upper = gen_reg_rtx (DImode);
17832 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17833 gen_rtvec (1, const0_rtx),
17835 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17836 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17838 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17839 NULL, 1, OPTAB_DIRECT);
17840 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17844 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17845 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17849 (define_insn "*rdpmc"
17850 [(set (match_operand:DI 0 "register_operand" "=A")
17851 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17855 [(set_attr "type" "other")
17856 (set_attr "length" "2")])
17858 (define_insn "*rdpmc_rex64"
17859 [(set (match_operand:DI 0 "register_operand" "=a")
17860 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17862 (set (match_operand:DI 1 "register_operand" "=d")
17863 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17866 [(set_attr "type" "other")
17867 (set_attr "length" "2")])
17869 (define_expand "rdtsc"
17870 [(set (match_operand:DI 0 "register_operand" "")
17871 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17876 rtvec vec = rtvec_alloc (2);
17877 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17878 rtx upper = gen_reg_rtx (DImode);
17879 rtx lower = gen_reg_rtx (DImode);
17880 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17881 gen_rtvec (1, const0_rtx),
17883 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17884 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17886 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17887 NULL, 1, OPTAB_DIRECT);
17888 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17890 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17895 (define_insn "*rdtsc"
17896 [(set (match_operand:DI 0 "register_operand" "=A")
17897 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17900 [(set_attr "type" "other")
17901 (set_attr "length" "2")])
17903 (define_insn "*rdtsc_rex64"
17904 [(set (match_operand:DI 0 "register_operand" "=a")
17905 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17906 (set (match_operand:DI 1 "register_operand" "=d")
17907 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17910 [(set_attr "type" "other")
17911 (set_attr "length" "2")])
17913 (define_expand "rdtscp"
17914 [(match_operand:DI 0 "register_operand" "")
17915 (match_operand:SI 1 "memory_operand" "")]
17918 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17919 gen_rtvec (1, const0_rtx),
17921 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17922 gen_rtvec (1, const0_rtx),
17924 rtx reg = gen_reg_rtx (DImode);
17925 rtx tmp = gen_reg_rtx (SImode);
17929 rtvec vec = rtvec_alloc (3);
17930 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17931 rtx upper = gen_reg_rtx (DImode);
17932 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17933 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17934 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17936 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17937 NULL, 1, OPTAB_DIRECT);
17938 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17943 rtvec vec = rtvec_alloc (2);
17944 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17945 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17946 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17949 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17950 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17954 (define_insn "*rdtscp"
17955 [(set (match_operand:DI 0 "register_operand" "=A")
17956 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17957 (set (match_operand:SI 1 "register_operand" "=c")
17958 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17961 [(set_attr "type" "other")
17962 (set_attr "length" "3")])
17964 (define_insn "*rdtscp_rex64"
17965 [(set (match_operand:DI 0 "register_operand" "=a")
17966 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17967 (set (match_operand:DI 1 "register_operand" "=d")
17968 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17969 (set (match_operand:SI 2 "register_operand" "=c")
17970 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17973 [(set_attr "type" "other")
17974 (set_attr "length" "3")])
17976 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17978 ;; LWP instructions
17980 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17982 (define_expand "lwp_llwpcb"
17983 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17984 UNSPECV_LLWP_INTRINSIC)]
17987 (define_insn "*lwp_llwpcb<mode>1"
17988 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17989 UNSPECV_LLWP_INTRINSIC)]
17992 [(set_attr "type" "lwp")
17993 (set_attr "mode" "<MODE>")
17994 (set_attr "length" "5")])
17996 (define_expand "lwp_slwpcb"
17997 [(set (match_operand 0 "register_operand" "=r")
17998 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18003 insn = (TARGET_64BIT
18005 : gen_lwp_slwpcbsi);
18007 emit_insn (insn (operands[0]));
18011 (define_insn "lwp_slwpcb<mode>"
18012 [(set (match_operand:P 0 "register_operand" "=r")
18013 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18016 [(set_attr "type" "lwp")
18017 (set_attr "mode" "<MODE>")
18018 (set_attr "length" "5")])
18020 (define_expand "lwp_lwpval<mode>3"
18021 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18022 (match_operand:SI 2 "nonimmediate_operand" "rm")
18023 (match_operand:SI 3 "const_int_operand" "i")]
18024 UNSPECV_LWPVAL_INTRINSIC)]
18026 ;; Avoid unused variable warning.
18027 "(void) operands[0];")
18029 (define_insn "*lwp_lwpval<mode>3_1"
18030 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18031 (match_operand:SI 1 "nonimmediate_operand" "rm")
18032 (match_operand:SI 2 "const_int_operand" "i")]
18033 UNSPECV_LWPVAL_INTRINSIC)]
18035 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18036 [(set_attr "type" "lwp")
18037 (set_attr "mode" "<MODE>")
18038 (set (attr "length")
18039 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18041 (define_expand "lwp_lwpins<mode>3"
18042 [(set (reg:CCC FLAGS_REG)
18043 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18044 (match_operand:SI 2 "nonimmediate_operand" "rm")
18045 (match_operand:SI 3 "const_int_operand" "i")]
18046 UNSPECV_LWPINS_INTRINSIC))
18047 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18048 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18051 (define_insn "*lwp_lwpins<mode>3_1"
18052 [(set (reg:CCC FLAGS_REG)
18053 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18054 (match_operand:SI 1 "nonimmediate_operand" "rm")
18055 (match_operand:SI 2 "const_int_operand" "i")]
18056 UNSPECV_LWPINS_INTRINSIC))]
18058 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18059 [(set_attr "type" "lwp")
18060 (set_attr "mode" "<MODE>")
18061 (set (attr "length")
18062 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18064 (define_insn "rdfsbase<mode>"
18065 [(set (match_operand:SWI48 0 "register_operand" "=r")
18066 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18067 "TARGET_64BIT && TARGET_FSGSBASE"
18069 [(set_attr "type" "other")
18070 (set_attr "prefix_extra" "2")])
18072 (define_insn "rdgsbase<mode>"
18073 [(set (match_operand:SWI48 0 "register_operand" "=r")
18074 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18075 "TARGET_64BIT && TARGET_FSGSBASE"
18077 [(set_attr "type" "other")
18078 (set_attr "prefix_extra" "2")])
18080 (define_insn "wrfsbase<mode>"
18081 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18083 "TARGET_64BIT && TARGET_FSGSBASE"
18085 [(set_attr "type" "other")
18086 (set_attr "prefix_extra" "2")])
18088 (define_insn "wrgsbase<mode>"
18089 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18091 "TARGET_64BIT && TARGET_FSGSBASE"
18093 [(set_attr "type" "other")
18094 (set_attr "prefix_extra" "2")])
18096 (define_insn "rdrand<mode>_1"
18097 [(set (match_operand:SWI248 0 "register_operand" "=r")
18098 (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
18099 (set (reg:CCC FLAGS_REG)
18100 (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
18103 [(set_attr "type" "other")
18104 (set_attr "prefix_extra" "1")])
18106 (define_expand "pause"
18107 [(set (match_dup 0)
18108 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18111 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18112 MEM_VOLATILE_P (operands[0]) = 1;
18115 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18116 ;; They have the same encoding.
18117 (define_insn "*pause"
18118 [(set (match_operand:BLK 0 "" "")
18119 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18122 [(set_attr "length" "2")
18123 (set_attr "memory" "unknown")])
18127 (include "sync.md")