1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988-2013 Free Software Foundation, Inc.
3 ;; Mostly by William Schelter.
4 ;; x86_64 support added by Jan Hubicka
6 ;; This file is part of GCC.
8 ;; GCC is free software; you can redistribute it and/or modify
9 ;; it under the terms of the GNU General Public License as published by
10 ;; the Free Software Foundation; either version 3, or (at your option)
13 ;; GCC is distributed in the hope that it will be useful,
14 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 ;; GNU General Public License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING3. If not see
20 ;; <http://www.gnu.org/licenses/>. */
22 ;; The original PO technology requires these to be ordered by speed,
23 ;; so that assigner will pick the fastest.
25 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
27 ;; The special asm out single letter directives following a '%' are:
28 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
29 ;; C -- print opcode suffix for set/cmov insn.
30 ;; c -- like C, but print reversed condition
31 ;; F,f -- likewise, but for floating-point.
32 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
34 ;; R -- print the prefix for register names.
35 ;; z -- print the opcode suffix for the size of the current operand.
36 ;; Z -- likewise, with special suffixes for x87 instructions.
37 ;; * -- print a star (in certain assembler syntax)
38 ;; A -- print an absolute memory reference.
39 ;; E -- print address with DImode register names if TARGET_64BIT.
40 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
41 ;; s -- print a shift double count, followed by the assemblers argument
43 ;; b -- print the QImode name of the register for the indicated operand.
44 ;; %b0 would print %al if operands[0] is reg 0.
45 ;; w -- likewise, print the HImode name of the register.
46 ;; k -- likewise, print the SImode name of the register.
47 ;; q -- likewise, print the DImode name of the register.
48 ;; x -- likewise, print the V4SFmode name of the register.
49 ;; t -- likewise, print the V8SFmode name of the register.
50 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
51 ;; y -- print "st(0)" instead of "st" as a register.
52 ;; d -- print duplicated register operand for AVX instruction.
53 ;; D -- print condition for SSE cmp instruction.
54 ;; P -- if PIC, print an @PLT suffix.
55 ;; p -- print raw symbol name.
56 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; K -- print HLE lock prefix
60 ;; Y -- print condition for XOP pcom* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
63 ;; ~ -- print "i" if TARGET_AVX2, "f" otherwise.
64 ;; @ -- print a segment register of thread base pointer load
65 ;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
67 (define_c_enum "unspec" [
68 ;; Relocation specifiers
79 UNSPEC_MACHOPIC_OFFSET
87 UNSPEC_MEMORY_BLOCKAGE
97 ;; Other random patterns
106 UNSPEC_LD_MPIC ; load_macho_picbase
108 UNSPEC_DIV_ALREADY_SPLIT
109 UNSPEC_MS_TO_SYSV_CALL
115 ;; For SSE/MMX support:
123 ;; Generic math support
125 UNSPEC_IEEE_MIN ; not commutative
126 UNSPEC_IEEE_MAX ; not commutative
128 ;; x87 Floating point
144 UNSPEC_FRNDINT_MASK_PM
148 ;; x87 Double output FP
183 (define_c_enum "unspecv" [
186 UNSPECV_PROBE_STACK_RANGE
189 UNSPECV_SPLIT_STACK_RETURN
195 UNSPECV_LLWP_INTRINSIC
196 UNSPECV_SLWP_INTRINSIC
197 UNSPECV_LWPVAL_INTRINSIC
198 UNSPECV_LWPINS_INTRINSIC
214 ;; For RDRAND support
217 ;; For RDSEED support
229 ;; Constants to represent rounding modes in the ROUND instruction
238 ;; Constants to represent pcomtrue/pcomfalse variants
248 ;; Constants used in the XOP pperm instruction
250 [(PPERM_SRC 0x00) /* copy source */
251 (PPERM_INVERT 0x20) /* invert source */
252 (PPERM_REVERSE 0x40) /* bit reverse source */
253 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
254 (PPERM_ZERO 0x80) /* all 0's */
255 (PPERM_ONES 0xa0) /* all 1's */
256 (PPERM_SIGN 0xc0) /* propagate sign bit */
257 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
258 (PPERM_SRC1 0x00) /* use first source byte */
259 (PPERM_SRC2 0x10) /* use second source byte */
262 ;; Registers by name.
317 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
320 ;; In C guard expressions, put expressions which may be compile-time
321 ;; constants first. This allows for better optimization. For
322 ;; example, write "TARGET_64BIT && reload_completed", not
323 ;; "reload_completed && TARGET_64BIT".
327 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
328 atom,generic64,amdfam10,bdver1,bdver2,bdver3,btver1,btver2"
329 (const (symbol_ref "ix86_schedule")))
331 ;; A basic instruction type. Refinements due to arguments to be
332 ;; provided in other attributes.
335 alu,alu1,negnot,imov,imovx,lea,
336 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,imul,imulx,idiv,
337 icmp,test,ibr,setcc,icmov,
338 push,pop,call,callv,leave,
340 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
341 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
342 sse,ssemov,sseadd,sseadd1,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,
343 sseshuf,sseshuf1,ssediv,sseins,ssemuladd,sse4arg,lwp,
344 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
345 (const_string "other"))
347 ;; Main data type used by the insn
349 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
350 (const_string "unknown"))
352 ;; The CPU unit operations uses.
353 (define_attr "unit" "integer,i387,sse,mmx,unknown"
354 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
355 (const_string "i387")
356 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
357 sse,ssemov,sseadd,sseadd1,ssemul,ssecmp,ssecomi,ssecvt,
358 sseshuf,sseshuf1,ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
360 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
362 (eq_attr "type" "other")
363 (const_string "unknown")]
364 (const_string "integer")))
366 ;; The minimum required alignment of vector mode memory operands of the SSE
367 ;; (non-VEX/EVEX) instruction in bits, if it is different from
368 ;; GET_MODE_ALIGNMENT of the operand, otherwise 0. If an instruction has
369 ;; multiple alternatives, this should be conservative maximum of those minimum
370 ;; required alignments.
371 (define_attr "ssememalign" "" (const_int 0))
373 ;; The (bounding maximum) length of an instruction immediate.
374 (define_attr "length_immediate" ""
375 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
378 (eq_attr "unit" "i387,sse,mmx")
380 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
381 rotate,rotatex,rotate1,imul,icmp,push,pop")
382 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
383 (eq_attr "type" "imov,test")
384 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
385 (eq_attr "type" "call")
386 (if_then_else (match_operand 0 "constant_call_address_operand")
389 (eq_attr "type" "callv")
390 (if_then_else (match_operand 1 "constant_call_address_operand")
393 ;; We don't know the size before shorten_branches. Expect
394 ;; the instruction to fit for better scheduling.
395 (eq_attr "type" "ibr")
398 (symbol_ref "/* Update immediate_length and other attributes! */
399 gcc_unreachable (),1")))
401 ;; The (bounding maximum) length of an instruction address.
402 (define_attr "length_address" ""
403 (cond [(eq_attr "type" "str,other,multi,fxch")
405 (and (eq_attr "type" "call")
406 (match_operand 0 "constant_call_address_operand"))
408 (and (eq_attr "type" "callv")
409 (match_operand 1 "constant_call_address_operand"))
412 (symbol_ref "ix86_attr_length_address_default (insn)")))
414 ;; Set when length prefix is used.
415 (define_attr "prefix_data16" ""
416 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
418 (eq_attr "mode" "HI")
420 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
425 ;; Set when string REP prefix is used.
426 (define_attr "prefix_rep" ""
427 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
429 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
434 ;; Set when 0f opcode prefix is used.
435 (define_attr "prefix_0f" ""
437 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
438 (eq_attr "unit" "sse,mmx"))
442 ;; Set when REX opcode prefix is used.
443 (define_attr "prefix_rex" ""
444 (cond [(not (match_test "TARGET_64BIT"))
446 (and (eq_attr "mode" "DI")
447 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
448 (eq_attr "unit" "!mmx")))
450 (and (eq_attr "mode" "QI")
451 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
453 (match_test "x86_extended_reg_mentioned_p (insn)")
455 (and (eq_attr "type" "imovx")
456 (match_operand:QI 1 "ext_QIreg_operand"))
461 ;; There are also additional prefixes in 3DNOW, SSSE3.
462 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
463 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
464 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
465 (define_attr "prefix_extra" ""
466 (cond [(eq_attr "type" "ssemuladd,sse4arg")
468 (eq_attr "type" "sseiadd1,ssecvt1")
473 ;; Prefix used: original, VEX or maybe VEX.
474 (define_attr "prefix" "orig,vex,maybe_vex"
475 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
477 (const_string "orig")))
479 ;; VEX W bit is used.
480 (define_attr "prefix_vex_w" "" (const_int 0))
482 ;; The length of VEX prefix
483 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
484 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
485 ;; still prefix_0f 1, with prefix_extra 1.
486 (define_attr "length_vex" ""
487 (if_then_else (and (eq_attr "prefix_0f" "1")
488 (eq_attr "prefix_extra" "0"))
489 (if_then_else (eq_attr "prefix_vex_w" "1")
490 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
491 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
492 (if_then_else (eq_attr "prefix_vex_w" "1")
493 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
494 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
496 ;; Set when modrm byte is used.
497 (define_attr "modrm" ""
498 (cond [(eq_attr "type" "str,leave")
500 (eq_attr "unit" "i387")
502 (and (eq_attr "type" "incdec")
503 (and (not (match_test "TARGET_64BIT"))
504 (ior (match_operand:SI 1 "register_operand")
505 (match_operand:HI 1 "register_operand"))))
507 (and (eq_attr "type" "push")
508 (not (match_operand 1 "memory_operand")))
510 (and (eq_attr "type" "pop")
511 (not (match_operand 0 "memory_operand")))
513 (and (eq_attr "type" "imov")
514 (and (not (eq_attr "mode" "DI"))
515 (ior (and (match_operand 0 "register_operand")
516 (match_operand 1 "immediate_operand"))
517 (ior (and (match_operand 0 "ax_reg_operand")
518 (match_operand 1 "memory_displacement_only_operand"))
519 (and (match_operand 0 "memory_displacement_only_operand")
520 (match_operand 1 "ax_reg_operand"))))))
522 (and (eq_attr "type" "call")
523 (match_operand 0 "constant_call_address_operand"))
525 (and (eq_attr "type" "callv")
526 (match_operand 1 "constant_call_address_operand"))
528 (and (eq_attr "type" "alu,alu1,icmp,test")
529 (match_operand 0 "ax_reg_operand"))
530 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
534 ;; The (bounding maximum) length of an instruction in bytes.
535 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
536 ;; Later we may want to split them and compute proper length as for
538 (define_attr "length" ""
539 (cond [(eq_attr "type" "other,multi,fistp,frndint")
541 (eq_attr "type" "fcmp")
543 (eq_attr "unit" "i387")
545 (plus (attr "prefix_data16")
546 (attr "length_address")))
547 (ior (eq_attr "prefix" "vex")
548 (and (eq_attr "prefix" "maybe_vex")
549 (match_test "TARGET_AVX")))
550 (plus (attr "length_vex")
551 (plus (attr "length_immediate")
553 (attr "length_address"))))]
554 (plus (plus (attr "modrm")
555 (plus (attr "prefix_0f")
556 (plus (attr "prefix_rex")
557 (plus (attr "prefix_extra")
559 (plus (attr "prefix_rep")
560 (plus (attr "prefix_data16")
561 (plus (attr "length_immediate")
562 (attr "length_address")))))))
564 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
565 ;; `store' if there is a simple memory reference therein, or `unknown'
566 ;; if the instruction is complex.
568 (define_attr "memory" "none,load,store,both,unknown"
569 (cond [(eq_attr "type" "other,multi,str,lwp")
570 (const_string "unknown")
571 (eq_attr "type" "lea,fcmov,fpspc")
572 (const_string "none")
573 (eq_attr "type" "fistp,leave")
574 (const_string "both")
575 (eq_attr "type" "frndint")
576 (const_string "load")
577 (eq_attr "type" "push")
578 (if_then_else (match_operand 1 "memory_operand")
579 (const_string "both")
580 (const_string "store"))
581 (eq_attr "type" "pop")
582 (if_then_else (match_operand 0 "memory_operand")
583 (const_string "both")
584 (const_string "load"))
585 (eq_attr "type" "setcc")
586 (if_then_else (match_operand 0 "memory_operand")
587 (const_string "store")
588 (const_string "none"))
589 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
590 (if_then_else (ior (match_operand 0 "memory_operand")
591 (match_operand 1 "memory_operand"))
592 (const_string "load")
593 (const_string "none"))
594 (eq_attr "type" "ibr")
595 (if_then_else (match_operand 0 "memory_operand")
596 (const_string "load")
597 (const_string "none"))
598 (eq_attr "type" "call")
599 (if_then_else (match_operand 0 "constant_call_address_operand")
600 (const_string "none")
601 (const_string "load"))
602 (eq_attr "type" "callv")
603 (if_then_else (match_operand 1 "constant_call_address_operand")
604 (const_string "none")
605 (const_string "load"))
606 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1,sseshuf1")
607 (match_operand 1 "memory_operand"))
608 (const_string "both")
609 (and (match_operand 0 "memory_operand")
610 (match_operand 1 "memory_operand"))
611 (const_string "both")
612 (match_operand 0 "memory_operand")
613 (const_string "store")
614 (match_operand 1 "memory_operand")
615 (const_string "load")
617 "!alu1,negnot,ishift1,
618 imov,imovx,icmp,test,bitmanip,
620 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
621 sseshuf1,sseadd1,sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
622 (match_operand 2 "memory_operand"))
623 (const_string "load")
624 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
625 (match_operand 3 "memory_operand"))
626 (const_string "load")
628 (const_string "none")))
630 ;; Indicates if an instruction has both an immediate and a displacement.
632 (define_attr "imm_disp" "false,true,unknown"
633 (cond [(eq_attr "type" "other,multi")
634 (const_string "unknown")
635 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
636 (and (match_operand 0 "memory_displacement_operand")
637 (match_operand 1 "immediate_operand")))
638 (const_string "true")
639 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
640 (and (match_operand 0 "memory_displacement_operand")
641 (match_operand 2 "immediate_operand")))
642 (const_string "true")
644 (const_string "false")))
646 ;; Indicates if an FP operation has an integer source.
648 (define_attr "fp_int_src" "false,true"
649 (const_string "false"))
651 ;; Defines rounding mode of an FP operation.
653 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
654 (const_string "any"))
656 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
657 (define_attr "use_carry" "0,1" (const_string "0"))
659 ;; Define attribute to indicate unaligned ssemov insns
660 (define_attr "movu" "0,1" (const_string "0"))
662 ;; Used to control the "enabled" attribute on a per-instruction basis.
663 (define_attr "isa" "base,sse2,sse2_noavx,sse3,sse4,sse4_noavx,noavx,avx,
664 avx2,noavx2,bmi2,fma4,fma"
665 (const_string "base"))
667 (define_attr "enabled" ""
668 (cond [(eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
669 (eq_attr "isa" "sse2_noavx")
670 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
671 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
672 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
673 (eq_attr "isa" "sse4_noavx")
674 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
675 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
676 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
677 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
678 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
679 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
680 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
681 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
685 ;; Describe a user's asm statement.
686 (define_asm_attributes
687 [(set_attr "length" "128")
688 (set_attr "type" "multi")])
690 (define_code_iterator plusminus [plus minus])
692 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
694 ;; Base name for define_insn
695 (define_code_attr plusminus_insn
696 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
697 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
699 ;; Base name for insn mnemonic.
700 (define_code_attr plusminus_mnemonic
701 [(plus "add") (ss_plus "adds") (us_plus "addus")
702 (minus "sub") (ss_minus "subs") (us_minus "subus")])
703 (define_code_attr plusminus_carry_mnemonic
704 [(plus "adc") (minus "sbb")])
706 ;; Mark commutative operators as such in constraints.
707 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
708 (minus "") (ss_minus "") (us_minus "")])
710 ;; Mapping of max and min
711 (define_code_iterator maxmin [smax smin umax umin])
713 ;; Mapping of signed max and min
714 (define_code_iterator smaxmin [smax smin])
716 ;; Mapping of unsigned max and min
717 (define_code_iterator umaxmin [umax umin])
719 ;; Base name for integer and FP insn mnemonic
720 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
721 (umax "maxu") (umin "minu")])
722 (define_code_attr maxmin_float [(smax "max") (smin "min")])
724 ;; Mapping of logic operators
725 (define_code_iterator any_logic [and ior xor])
726 (define_code_iterator any_or [ior xor])
728 ;; Base name for insn mnemonic.
729 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
731 ;; Mapping of logic-shift operators
732 (define_code_iterator any_lshift [ashift lshiftrt])
734 ;; Mapping of shift-right operators
735 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
737 ;; Mapping of all shift operators
738 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
740 ;; Base name for define_insn
741 (define_code_attr shift_insn
742 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
744 ;; Base name for insn mnemonic.
745 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
746 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
748 ;; Mapping of rotate operators
749 (define_code_iterator any_rotate [rotate rotatert])
751 ;; Base name for define_insn
752 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
754 ;; Base name for insn mnemonic.
755 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
757 ;; Mapping of abs neg operators
758 (define_code_iterator absneg [abs neg])
760 ;; Base name for x87 insn mnemonic.
761 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
763 ;; Used in signed and unsigned widening multiplications.
764 (define_code_iterator any_extend [sign_extend zero_extend])
766 ;; Prefix for insn menmonic.
767 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
769 ;; Prefix for define_insn
770 (define_code_attr u [(sign_extend "") (zero_extend "u")])
771 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
772 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
774 ;; All integer modes.
775 (define_mode_iterator SWI1248x [QI HI SI DI])
777 ;; All integer modes without QImode.
778 (define_mode_iterator SWI248x [HI SI DI])
780 ;; All integer modes without QImode and HImode.
781 (define_mode_iterator SWI48x [SI DI])
783 ;; All integer modes without SImode and DImode.
784 (define_mode_iterator SWI12 [QI HI])
786 ;; All integer modes without DImode.
787 (define_mode_iterator SWI124 [QI HI SI])
789 ;; All integer modes without QImode and DImode.
790 (define_mode_iterator SWI24 [HI SI])
792 ;; Single word integer modes.
793 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
795 ;; Single word integer modes without QImode.
796 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
798 ;; Single word integer modes without QImode and HImode.
799 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
801 ;; All math-dependant single and double word integer modes.
802 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
803 (HI "TARGET_HIMODE_MATH")
804 SI DI (TI "TARGET_64BIT")])
806 ;; Math-dependant single word integer modes.
807 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
808 (HI "TARGET_HIMODE_MATH")
809 SI (DI "TARGET_64BIT")])
811 ;; Math-dependant integer modes without DImode.
812 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
813 (HI "TARGET_HIMODE_MATH")
816 ;; Math-dependant single word integer modes without QImode.
817 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
818 SI (DI "TARGET_64BIT")])
820 ;; Double word integer modes.
821 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
822 (TI "TARGET_64BIT")])
824 ;; Double word integer modes as mode attribute.
825 (define_mode_attr DWI [(SI "DI") (DI "TI")])
826 (define_mode_attr dwi [(SI "di") (DI "ti")])
828 ;; Half mode for double word integer modes.
829 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
830 (DI "TARGET_64BIT")])
832 ;; Instruction suffix for integer modes.
833 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
835 ;; Pointer size prefix for integer modes (Intel asm dialect)
836 (define_mode_attr iptrsize [(QI "BYTE")
841 ;; Register class for integer modes.
842 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
844 ;; Immediate operand constraint for integer modes.
845 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
847 ;; General operand constraint for word modes.
848 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
850 ;; Immediate operand constraint for double integer modes.
851 (define_mode_attr di [(SI "nF") (DI "e")])
853 ;; Immediate operand constraint for shifts.
854 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
856 ;; General operand predicate for integer modes.
857 (define_mode_attr general_operand
858 [(QI "general_operand")
859 (HI "general_operand")
860 (SI "x86_64_general_operand")
861 (DI "x86_64_general_operand")
862 (TI "x86_64_general_operand")])
864 ;; General sign/zero extend operand predicate for integer modes.
865 (define_mode_attr general_szext_operand
866 [(QI "general_operand")
867 (HI "general_operand")
868 (SI "x86_64_szext_general_operand")
869 (DI "x86_64_szext_general_operand")])
871 ;; Immediate operand predicate for integer modes.
872 (define_mode_attr immediate_operand
873 [(QI "immediate_operand")
874 (HI "immediate_operand")
875 (SI "x86_64_immediate_operand")
876 (DI "x86_64_immediate_operand")])
878 ;; Nonmemory operand predicate for integer modes.
879 (define_mode_attr nonmemory_operand
880 [(QI "nonmemory_operand")
881 (HI "nonmemory_operand")
882 (SI "x86_64_nonmemory_operand")
883 (DI "x86_64_nonmemory_operand")])
885 ;; Operand predicate for shifts.
886 (define_mode_attr shift_operand
887 [(QI "nonimmediate_operand")
888 (HI "nonimmediate_operand")
889 (SI "nonimmediate_operand")
890 (DI "shiftdi_operand")
891 (TI "register_operand")])
893 ;; Operand predicate for shift argument.
894 (define_mode_attr shift_immediate_operand
895 [(QI "const_1_to_31_operand")
896 (HI "const_1_to_31_operand")
897 (SI "const_1_to_31_operand")
898 (DI "const_1_to_63_operand")])
900 ;; Input operand predicate for arithmetic left shifts.
901 (define_mode_attr ashl_input_operand
902 [(QI "nonimmediate_operand")
903 (HI "nonimmediate_operand")
904 (SI "nonimmediate_operand")
905 (DI "ashldi_input_operand")
906 (TI "reg_or_pm1_operand")])
908 ;; SSE and x87 SFmode and DFmode floating point modes
909 (define_mode_iterator MODEF [SF DF])
911 ;; All x87 floating point modes
912 (define_mode_iterator X87MODEF [SF DF XF])
914 ;; SSE instruction suffix for various modes
915 (define_mode_attr ssemodesuffix
917 (V8SF "ps") (V4DF "pd")
918 (V4SF "ps") (V2DF "pd")
919 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
920 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
922 ;; SSE vector suffix for floating point modes
923 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
925 ;; SSE vector mode corresponding to a scalar mode
926 (define_mode_attr ssevecmode
927 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
929 ;; Instruction suffix for REX 64bit operators.
930 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
932 ;; This mode iterator allows :P to be used for patterns that operate on
933 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
934 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
936 ;; This mode iterator allows :W to be used for patterns that operate on
937 ;; word_mode sized quantities.
938 (define_mode_iterator W
939 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
941 ;; This mode iterator allows :PTR to be used for patterns that operate on
942 ;; ptr_mode sized quantities.
943 (define_mode_iterator PTR
944 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
946 ;; Scheduling descriptions
948 (include "pentium.md")
951 (include "athlon.md")
952 (include "bdver1.md")
953 (include "bdver3.md")
954 (include "btver2.md")
960 ;; Operand and operator predicates and constraints
962 (include "predicates.md")
963 (include "constraints.md")
966 ;; Compare and branch/compare and store instructions.
968 (define_expand "cbranch<mode>4"
969 [(set (reg:CC FLAGS_REG)
970 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
971 (match_operand:SDWIM 2 "<general_operand>")))
972 (set (pc) (if_then_else
973 (match_operator 0 "ordered_comparison_operator"
974 [(reg:CC FLAGS_REG) (const_int 0)])
975 (label_ref (match_operand 3))
979 if (MEM_P (operands[1]) && MEM_P (operands[2]))
980 operands[1] = force_reg (<MODE>mode, operands[1]);
981 ix86_expand_branch (GET_CODE (operands[0]),
982 operands[1], operands[2], operands[3]);
986 (define_expand "cstore<mode>4"
987 [(set (reg:CC FLAGS_REG)
988 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
989 (match_operand:SWIM 3 "<general_operand>")))
990 (set (match_operand:QI 0 "register_operand")
991 (match_operator 1 "ordered_comparison_operator"
992 [(reg:CC FLAGS_REG) (const_int 0)]))]
995 if (MEM_P (operands[2]) && MEM_P (operands[3]))
996 operands[2] = force_reg (<MODE>mode, operands[2]);
997 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
998 operands[2], operands[3]);
1002 (define_expand "cmp<mode>_1"
1003 [(set (reg:CC FLAGS_REG)
1004 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1005 (match_operand:SWI48 1 "<general_operand>")))])
1007 (define_insn "*cmp<mode>_ccno_1"
1008 [(set (reg FLAGS_REG)
1009 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1010 (match_operand:SWI 1 "const0_operand")))]
1011 "ix86_match_ccmode (insn, CCNOmode)"
1013 test{<imodesuffix>}\t%0, %0
1014 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1015 [(set_attr "type" "test,icmp")
1016 (set_attr "length_immediate" "0,1")
1017 (set_attr "mode" "<MODE>")])
1019 (define_insn "*cmp<mode>_1"
1020 [(set (reg FLAGS_REG)
1021 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1022 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1023 "ix86_match_ccmode (insn, CCmode)"
1024 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1025 [(set_attr "type" "icmp")
1026 (set_attr "mode" "<MODE>")])
1028 (define_insn "*cmp<mode>_minus_1"
1029 [(set (reg FLAGS_REG)
1031 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1032 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1034 "ix86_match_ccmode (insn, CCGOCmode)"
1035 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1036 [(set_attr "type" "icmp")
1037 (set_attr "mode" "<MODE>")])
1039 (define_insn "*cmpqi_ext_1"
1040 [(set (reg FLAGS_REG)
1042 (match_operand:QI 0 "general_operand" "Qm")
1045 (match_operand 1 "ext_register_operand" "Q")
1047 (const_int 8)) 0)))]
1048 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1049 "cmp{b}\t{%h1, %0|%0, %h1}"
1050 [(set_attr "type" "icmp")
1051 (set_attr "mode" "QI")])
1053 (define_insn "*cmpqi_ext_1_rex64"
1054 [(set (reg FLAGS_REG)
1056 (match_operand:QI 0 "register_operand" "Q")
1059 (match_operand 1 "ext_register_operand" "Q")
1061 (const_int 8)) 0)))]
1062 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1063 "cmp{b}\t{%h1, %0|%0, %h1}"
1064 [(set_attr "type" "icmp")
1065 (set_attr "mode" "QI")])
1067 (define_insn "*cmpqi_ext_2"
1068 [(set (reg FLAGS_REG)
1072 (match_operand 0 "ext_register_operand" "Q")
1075 (match_operand:QI 1 "const0_operand")))]
1076 "ix86_match_ccmode (insn, CCNOmode)"
1078 [(set_attr "type" "test")
1079 (set_attr "length_immediate" "0")
1080 (set_attr "mode" "QI")])
1082 (define_expand "cmpqi_ext_3"
1083 [(set (reg:CC FLAGS_REG)
1087 (match_operand 0 "ext_register_operand")
1090 (match_operand:QI 1 "immediate_operand")))])
1092 (define_insn "*cmpqi_ext_3_insn"
1093 [(set (reg FLAGS_REG)
1097 (match_operand 0 "ext_register_operand" "Q")
1100 (match_operand:QI 1 "general_operand" "Qmn")))]
1101 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1102 "cmp{b}\t{%1, %h0|%h0, %1}"
1103 [(set_attr "type" "icmp")
1104 (set_attr "modrm" "1")
1105 (set_attr "mode" "QI")])
1107 (define_insn "*cmpqi_ext_3_insn_rex64"
1108 [(set (reg FLAGS_REG)
1112 (match_operand 0 "ext_register_operand" "Q")
1115 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1116 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1117 "cmp{b}\t{%1, %h0|%h0, %1}"
1118 [(set_attr "type" "icmp")
1119 (set_attr "modrm" "1")
1120 (set_attr "mode" "QI")])
1122 (define_insn "*cmpqi_ext_4"
1123 [(set (reg FLAGS_REG)
1127 (match_operand 0 "ext_register_operand" "Q")
1132 (match_operand 1 "ext_register_operand" "Q")
1134 (const_int 8)) 0)))]
1135 "ix86_match_ccmode (insn, CCmode)"
1136 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1137 [(set_attr "type" "icmp")
1138 (set_attr "mode" "QI")])
1140 ;; These implement float point compares.
1141 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1142 ;; which would allow mix and match FP modes on the compares. Which is what
1143 ;; the old patterns did, but with many more of them.
1145 (define_expand "cbranchxf4"
1146 [(set (reg:CC FLAGS_REG)
1147 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1148 (match_operand:XF 2 "nonmemory_operand")))
1149 (set (pc) (if_then_else
1150 (match_operator 0 "ix86_fp_comparison_operator"
1153 (label_ref (match_operand 3))
1157 ix86_expand_branch (GET_CODE (operands[0]),
1158 operands[1], operands[2], operands[3]);
1162 (define_expand "cstorexf4"
1163 [(set (reg:CC FLAGS_REG)
1164 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1165 (match_operand:XF 3 "nonmemory_operand")))
1166 (set (match_operand:QI 0 "register_operand")
1167 (match_operator 1 "ix86_fp_comparison_operator"
1172 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1173 operands[2], operands[3]);
1177 (define_expand "cbranch<mode>4"
1178 [(set (reg:CC FLAGS_REG)
1179 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1180 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1181 (set (pc) (if_then_else
1182 (match_operator 0 "ix86_fp_comparison_operator"
1185 (label_ref (match_operand 3))
1187 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1189 ix86_expand_branch (GET_CODE (operands[0]),
1190 operands[1], operands[2], operands[3]);
1194 (define_expand "cstore<mode>4"
1195 [(set (reg:CC FLAGS_REG)
1196 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1197 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1198 (set (match_operand:QI 0 "register_operand")
1199 (match_operator 1 "ix86_fp_comparison_operator"
1202 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1204 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1205 operands[2], operands[3]);
1209 (define_expand "cbranchcc4"
1210 [(set (pc) (if_then_else
1211 (match_operator 0 "comparison_operator"
1212 [(match_operand 1 "flags_reg_operand")
1213 (match_operand 2 "const0_operand")])
1214 (label_ref (match_operand 3))
1218 ix86_expand_branch (GET_CODE (operands[0]),
1219 operands[1], operands[2], operands[3]);
1223 (define_expand "cstorecc4"
1224 [(set (match_operand:QI 0 "register_operand")
1225 (match_operator 1 "comparison_operator"
1226 [(match_operand 2 "flags_reg_operand")
1227 (match_operand 3 "const0_operand")]))]
1230 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1231 operands[2], operands[3]);
1236 ;; FP compares, step 1:
1237 ;; Set the FP condition codes.
1239 ;; CCFPmode compare with exceptions
1240 ;; CCFPUmode compare with no exceptions
1242 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1243 ;; used to manage the reg stack popping would not be preserved.
1245 (define_insn "*cmp<mode>_0_i387"
1246 [(set (match_operand:HI 0 "register_operand" "=a")
1249 (match_operand:X87MODEF 1 "register_operand" "f")
1250 (match_operand:X87MODEF 2 "const0_operand"))]
1253 "* return output_fp_compare (insn, operands, false, false);"
1254 [(set_attr "type" "multi")
1255 (set_attr "unit" "i387")
1256 (set_attr "mode" "<MODE>")])
1258 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1259 [(set (reg:CCFP FLAGS_REG)
1261 (match_operand:X87MODEF 1 "register_operand" "f")
1262 (match_operand:X87MODEF 2 "const0_operand")))
1263 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1264 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1266 "&& reload_completed"
1269 [(compare:CCFP (match_dup 1)(match_dup 2))]
1271 (set (reg:CC FLAGS_REG)
1272 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1274 [(set_attr "type" "multi")
1275 (set_attr "unit" "i387")
1276 (set_attr "mode" "<MODE>")])
1278 (define_insn "*cmpxf_i387"
1279 [(set (match_operand:HI 0 "register_operand" "=a")
1282 (match_operand:XF 1 "register_operand" "f")
1283 (match_operand:XF 2 "register_operand" "f"))]
1286 "* return output_fp_compare (insn, operands, false, false);"
1287 [(set_attr "type" "multi")
1288 (set_attr "unit" "i387")
1289 (set_attr "mode" "XF")])
1291 (define_insn_and_split "*cmpxf_cc_i387"
1292 [(set (reg:CCFP FLAGS_REG)
1294 (match_operand:XF 1 "register_operand" "f")
1295 (match_operand:XF 2 "register_operand" "f")))
1296 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1297 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1299 "&& reload_completed"
1302 [(compare:CCFP (match_dup 1)(match_dup 2))]
1304 (set (reg:CC FLAGS_REG)
1305 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1307 [(set_attr "type" "multi")
1308 (set_attr "unit" "i387")
1309 (set_attr "mode" "XF")])
1311 (define_insn "*cmp<mode>_i387"
1312 [(set (match_operand:HI 0 "register_operand" "=a")
1315 (match_operand:MODEF 1 "register_operand" "f")
1316 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1319 "* return output_fp_compare (insn, operands, false, false);"
1320 [(set_attr "type" "multi")
1321 (set_attr "unit" "i387")
1322 (set_attr "mode" "<MODE>")])
1324 (define_insn_and_split "*cmp<mode>_cc_i387"
1325 [(set (reg:CCFP FLAGS_REG)
1327 (match_operand:MODEF 1 "register_operand" "f")
1328 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1329 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1330 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1332 "&& reload_completed"
1335 [(compare:CCFP (match_dup 1)(match_dup 2))]
1337 (set (reg:CC FLAGS_REG)
1338 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1340 [(set_attr "type" "multi")
1341 (set_attr "unit" "i387")
1342 (set_attr "mode" "<MODE>")])
1344 (define_insn "*cmpu<mode>_i387"
1345 [(set (match_operand:HI 0 "register_operand" "=a")
1348 (match_operand:X87MODEF 1 "register_operand" "f")
1349 (match_operand:X87MODEF 2 "register_operand" "f"))]
1352 "* return output_fp_compare (insn, operands, false, true);"
1353 [(set_attr "type" "multi")
1354 (set_attr "unit" "i387")
1355 (set_attr "mode" "<MODE>")])
1357 (define_insn_and_split "*cmpu<mode>_cc_i387"
1358 [(set (reg:CCFPU FLAGS_REG)
1360 (match_operand:X87MODEF 1 "register_operand" "f")
1361 (match_operand:X87MODEF 2 "register_operand" "f")))
1362 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1363 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1365 "&& reload_completed"
1368 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1370 (set (reg:CC FLAGS_REG)
1371 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1373 [(set_attr "type" "multi")
1374 (set_attr "unit" "i387")
1375 (set_attr "mode" "<MODE>")])
1377 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1378 [(set (match_operand:HI 0 "register_operand" "=a")
1381 (match_operand:X87MODEF 1 "register_operand" "f")
1382 (match_operator:X87MODEF 3 "float_operator"
1383 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1386 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1387 || optimize_function_for_size_p (cfun))"
1388 "* return output_fp_compare (insn, operands, false, false);"
1389 [(set_attr "type" "multi")
1390 (set_attr "unit" "i387")
1391 (set_attr "fp_int_src" "true")
1392 (set_attr "mode" "<SWI24:MODE>")])
1394 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1395 [(set (reg:CCFP FLAGS_REG)
1397 (match_operand:X87MODEF 1 "register_operand" "f")
1398 (match_operator:X87MODEF 3 "float_operator"
1399 [(match_operand:SWI24 2 "memory_operand" "m")])))
1400 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1401 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1402 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1403 || optimize_function_for_size_p (cfun))"
1405 "&& reload_completed"
1410 (match_op_dup 3 [(match_dup 2)]))]
1412 (set (reg:CC FLAGS_REG)
1413 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1415 [(set_attr "type" "multi")
1416 (set_attr "unit" "i387")
1417 (set_attr "fp_int_src" "true")
1418 (set_attr "mode" "<SWI24:MODE>")])
1420 ;; FP compares, step 2
1421 ;; Move the fpsw to ax.
1423 (define_insn "x86_fnstsw_1"
1424 [(set (match_operand:HI 0 "register_operand" "=a")
1425 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1428 [(set (attr "length")
1429 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1430 (set_attr "mode" "SI")
1431 (set_attr "unit" "i387")])
1433 ;; FP compares, step 3
1434 ;; Get ax into flags, general case.
1436 (define_insn "x86_sahf_1"
1437 [(set (reg:CC FLAGS_REG)
1438 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1442 #ifndef HAVE_AS_IX86_SAHF
1444 return ASM_BYTE "0x9e";
1449 [(set_attr "length" "1")
1450 (set_attr "athlon_decode" "vector")
1451 (set_attr "amdfam10_decode" "direct")
1452 (set_attr "bdver1_decode" "direct")
1453 (set_attr "mode" "SI")])
1455 ;; Pentium Pro can do steps 1 through 3 in one go.
1456 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1457 ;; (these i387 instructions set flags directly)
1459 (define_mode_iterator FPCMP [CCFP CCFPU])
1460 (define_mode_attr unord [(CCFP "") (CCFPU "u")])
1462 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_mixed"
1463 [(set (reg:FPCMP FLAGS_REG)
1465 (match_operand:MODEF 0 "register_operand" "f,x")
1466 (match_operand:MODEF 1 "nonimmediate_operand" "f,xm")))]
1467 "TARGET_MIX_SSE_I387
1468 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1469 "* return output_fp_compare (insn, operands, true,
1470 <FPCMP:MODE>mode == CCFPUmode);"
1471 [(set_attr "type" "fcmp,ssecomi")
1472 (set_attr "prefix" "orig,maybe_vex")
1473 (set_attr "mode" "<MODEF:MODE>")
1474 (set (attr "prefix_rep")
1475 (if_then_else (eq_attr "type" "ssecomi")
1477 (const_string "*")))
1478 (set (attr "prefix_data16")
1479 (cond [(eq_attr "type" "fcmp")
1481 (eq_attr "mode" "DF")
1484 (const_string "0")))
1485 (set_attr "athlon_decode" "vector")
1486 (set_attr "amdfam10_decode" "direct")
1487 (set_attr "bdver1_decode" "double")])
1489 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_sse"
1490 [(set (reg:FPCMP FLAGS_REG)
1492 (match_operand:MODEF 0 "register_operand" "x")
1493 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
1495 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1496 "* return output_fp_compare (insn, operands, true,
1497 <FPCMP:MODE>mode == CCFPUmode);"
1498 [(set_attr "type" "ssecomi")
1499 (set_attr "prefix" "maybe_vex")
1500 (set_attr "mode" "<MODEF:MODE>")
1501 (set_attr "prefix_rep" "0")
1502 (set (attr "prefix_data16")
1503 (if_then_else (eq_attr "mode" "DF")
1505 (const_string "0")))
1506 (set_attr "athlon_decode" "vector")
1507 (set_attr "amdfam10_decode" "direct")
1508 (set_attr "bdver1_decode" "double")])
1510 (define_insn "*cmpi<FPCMP:unord><X87MODEF:mode>_i387"
1511 [(set (reg:FPCMP FLAGS_REG)
1513 (match_operand:X87MODEF 0 "register_operand" "f")
1514 (match_operand:X87MODEF 1 "register_operand" "f")))]
1515 "TARGET_80387 && TARGET_CMOVE
1516 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
1517 "* return output_fp_compare (insn, operands, true,
1518 <FPCMP:MODE>mode == CCFPUmode);"
1519 [(set_attr "type" "fcmp")
1520 (set_attr "mode" "<X87MODEF:MODE>")
1521 (set_attr "athlon_decode" "vector")
1522 (set_attr "amdfam10_decode" "direct")
1523 (set_attr "bdver1_decode" "double")])
1525 ;; Push/pop instructions.
1527 (define_insn "*push<mode>2"
1528 [(set (match_operand:DWI 0 "push_operand" "=<")
1529 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1532 [(set_attr "type" "multi")
1533 (set_attr "mode" "<MODE>")])
1536 [(set (match_operand:TI 0 "push_operand")
1537 (match_operand:TI 1 "general_operand"))]
1538 "TARGET_64BIT && reload_completed
1539 && !SSE_REG_P (operands[1])"
1541 "ix86_split_long_move (operands); DONE;")
1543 (define_insn "*pushdi2_rex64"
1544 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1545 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1550 [(set_attr "type" "push,multi")
1551 (set_attr "mode" "DI")])
1553 ;; Convert impossible pushes of immediate to existing instructions.
1554 ;; First try to get scratch register and go through it. In case this
1555 ;; fails, push sign extended lower part first and then overwrite
1556 ;; upper part by 32bit move.
1558 [(match_scratch:DI 2 "r")
1559 (set (match_operand:DI 0 "push_operand")
1560 (match_operand:DI 1 "immediate_operand"))]
1561 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1562 && !x86_64_immediate_operand (operands[1], DImode)"
1563 [(set (match_dup 2) (match_dup 1))
1564 (set (match_dup 0) (match_dup 2))])
1566 ;; We need to define this as both peepholer and splitter for case
1567 ;; peephole2 pass is not run.
1568 ;; "&& 1" is needed to keep it from matching the previous pattern.
1570 [(set (match_operand:DI 0 "push_operand")
1571 (match_operand:DI 1 "immediate_operand"))]
1572 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1573 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1574 [(set (match_dup 0) (match_dup 1))
1575 (set (match_dup 2) (match_dup 3))]
1577 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1579 operands[1] = gen_lowpart (DImode, operands[2]);
1580 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1585 [(set (match_operand:DI 0 "push_operand")
1586 (match_operand:DI 1 "immediate_operand"))]
1587 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1588 ? epilogue_completed : reload_completed)
1589 && !symbolic_operand (operands[1], DImode)
1590 && !x86_64_immediate_operand (operands[1], DImode)"
1591 [(set (match_dup 0) (match_dup 1))
1592 (set (match_dup 2) (match_dup 3))]
1594 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1596 operands[1] = gen_lowpart (DImode, operands[2]);
1597 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1602 [(set (match_operand:DI 0 "push_operand")
1603 (match_operand:DI 1 "general_operand"))]
1604 "!TARGET_64BIT && reload_completed
1605 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1607 "ix86_split_long_move (operands); DONE;")
1609 (define_insn "*pushsi2"
1610 [(set (match_operand:SI 0 "push_operand" "=<")
1611 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1614 [(set_attr "type" "push")
1615 (set_attr "mode" "SI")])
1617 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1618 ;; "push a byte/word". But actually we use pushl, which has the effect
1619 ;; of rounding the amount pushed up to a word.
1621 ;; For TARGET_64BIT we always round up to 8 bytes.
1622 (define_insn "*push<mode>2_rex64"
1623 [(set (match_operand:SWI124 0 "push_operand" "=X")
1624 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1627 [(set_attr "type" "push")
1628 (set_attr "mode" "DI")])
1630 (define_insn "*push<mode>2"
1631 [(set (match_operand:SWI12 0 "push_operand" "=X")
1632 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1635 [(set_attr "type" "push")
1636 (set_attr "mode" "SI")])
1638 (define_insn "*push<mode>2_prologue"
1639 [(set (match_operand:W 0 "push_operand" "=<")
1640 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1641 (clobber (mem:BLK (scratch)))]
1643 "push{<imodesuffix>}\t%1"
1644 [(set_attr "type" "push")
1645 (set_attr "mode" "<MODE>")])
1647 (define_insn "*pop<mode>1"
1648 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1649 (match_operand:W 1 "pop_operand" ">"))]
1651 "pop{<imodesuffix>}\t%0"
1652 [(set_attr "type" "pop")
1653 (set_attr "mode" "<MODE>")])
1655 (define_insn "*pop<mode>1_epilogue"
1656 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1657 (match_operand:W 1 "pop_operand" ">"))
1658 (clobber (mem:BLK (scratch)))]
1660 "pop{<imodesuffix>}\t%0"
1661 [(set_attr "type" "pop")
1662 (set_attr "mode" "<MODE>")])
1664 ;; Move instructions.
1666 (define_expand "movoi"
1667 [(set (match_operand:OI 0 "nonimmediate_operand")
1668 (match_operand:OI 1 "general_operand"))]
1670 "ix86_expand_move (OImode, operands); DONE;")
1672 (define_expand "movti"
1673 [(set (match_operand:TI 0 "nonimmediate_operand")
1674 (match_operand:TI 1 "nonimmediate_operand"))]
1675 "TARGET_64BIT || TARGET_SSE"
1678 ix86_expand_move (TImode, operands);
1679 else if (push_operand (operands[0], TImode))
1680 ix86_expand_push (TImode, operands[1]);
1682 ix86_expand_vector_move (TImode, operands);
1686 ;; This expands to what emit_move_complex would generate if we didn't
1687 ;; have a movti pattern. Having this avoids problems with reload on
1688 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1689 ;; to have around all the time.
1690 (define_expand "movcdi"
1691 [(set (match_operand:CDI 0 "nonimmediate_operand")
1692 (match_operand:CDI 1 "general_operand"))]
1695 if (push_operand (operands[0], CDImode))
1696 emit_move_complex_push (CDImode, operands[0], operands[1]);
1698 emit_move_complex_parts (operands[0], operands[1]);
1702 (define_expand "mov<mode>"
1703 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1704 (match_operand:SWI1248x 1 "general_operand"))]
1706 "ix86_expand_move (<MODE>mode, operands); DONE;")
1708 (define_insn "*mov<mode>_xor"
1709 [(set (match_operand:SWI48 0 "register_operand" "=r")
1710 (match_operand:SWI48 1 "const0_operand"))
1711 (clobber (reg:CC FLAGS_REG))]
1714 [(set_attr "type" "alu1")
1715 (set_attr "mode" "SI")
1716 (set_attr "length_immediate" "0")])
1718 (define_insn "*mov<mode>_or"
1719 [(set (match_operand:SWI48 0 "register_operand" "=r")
1720 (match_operand:SWI48 1 "const_int_operand"))
1721 (clobber (reg:CC FLAGS_REG))]
1723 && operands[1] == constm1_rtx"
1724 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1725 [(set_attr "type" "alu1")
1726 (set_attr "mode" "<MODE>")
1727 (set_attr "length_immediate" "1")])
1729 (define_insn "*movoi_internal_avx"
1730 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x ,m")
1731 (match_operand:OI 1 "vector_move_operand" "C ,xm,x"))]
1732 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1734 switch (which_alternative)
1737 return standard_sse_constant_opcode (insn, operands[1]);
1740 if (misaligned_operand (operands[0], OImode)
1741 || misaligned_operand (operands[1], OImode))
1743 if (get_attr_mode (insn) == MODE_V8SF)
1744 return "vmovups\t{%1, %0|%0, %1}";
1746 return "vmovdqu\t{%1, %0|%0, %1}";
1750 if (get_attr_mode (insn) == MODE_V8SF)
1751 return "vmovaps\t{%1, %0|%0, %1}";
1753 return "vmovdqa\t{%1, %0|%0, %1}";
1759 [(set_attr "type" "sselog1,ssemov,ssemov")
1760 (set_attr "prefix" "vex")
1762 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1763 (const_string "V8SF")
1764 (and (eq_attr "alternative" "2")
1765 (match_test "TARGET_SSE_TYPELESS_STORES"))
1766 (const_string "V8SF")
1768 (const_string "OI")))])
1770 (define_insn "*movti_internal_rex64"
1771 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,x,x ,m")
1772 (match_operand:TI 1 "general_operand" "riFo,re,C,xm,x"))]
1773 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1775 switch (which_alternative)
1781 return standard_sse_constant_opcode (insn, operands[1]);
1784 /* TDmode values are passed as TImode on the stack. Moving them
1785 to stack may result in unaligned memory access. */
1786 if (misaligned_operand (operands[0], TImode)
1787 || misaligned_operand (operands[1], TImode))
1789 if (get_attr_mode (insn) == MODE_V4SF)
1790 return "%vmovups\t{%1, %0|%0, %1}";
1792 return "%vmovdqu\t{%1, %0|%0, %1}";
1796 if (get_attr_mode (insn) == MODE_V4SF)
1797 return "%vmovaps\t{%1, %0|%0, %1}";
1799 return "%vmovdqa\t{%1, %0|%0, %1}";
1805 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1806 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1808 (cond [(eq_attr "alternative" "0,1")
1810 (not (match_test "TARGET_SSE2"))
1811 (const_string "V4SF")
1812 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1813 (const_string "V4SF")
1814 (and (eq_attr "alternative" "4")
1815 (match_test "TARGET_SSE_TYPELESS_STORES"))
1816 (const_string "V4SF")
1817 (match_test "TARGET_AVX")
1819 (match_test "optimize_function_for_size_p (cfun)")
1820 (const_string "V4SF")
1822 (const_string "TI")))])
1825 [(set (match_operand:TI 0 "nonimmediate_operand")
1826 (match_operand:TI 1 "general_operand"))]
1828 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1830 "ix86_split_long_move (operands); DONE;")
1832 (define_insn "*movti_internal_sse"
1833 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x ,m")
1834 (match_operand:TI 1 "vector_move_operand" "C ,xm,x"))]
1835 "TARGET_SSE && !TARGET_64BIT
1836 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1838 switch (which_alternative)
1841 return standard_sse_constant_opcode (insn, operands[1]);
1844 /* TDmode values are passed as TImode on the stack. Moving them
1845 to stack may result in unaligned memory access. */
1846 if (misaligned_operand (operands[0], TImode)
1847 || misaligned_operand (operands[1], TImode))
1849 if (get_attr_mode (insn) == MODE_V4SF)
1850 return "%vmovups\t{%1, %0|%0, %1}";
1852 return "%vmovdqu\t{%1, %0|%0, %1}";
1856 if (get_attr_mode (insn) == MODE_V4SF)
1857 return "%vmovaps\t{%1, %0|%0, %1}";
1859 return "%vmovdqa\t{%1, %0|%0, %1}";
1865 [(set_attr "type" "sselog1,ssemov,ssemov")
1866 (set_attr "prefix" "maybe_vex")
1868 (cond [(not (match_test "TARGET_SSE2"))
1869 (const_string "V4SF")
1870 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1871 (const_string "V4SF")
1872 (and (eq_attr "alternative" "2")
1873 (match_test "TARGET_SSE_TYPELESS_STORES"))
1874 (const_string "V4SF")
1875 (match_test "TARGET_AVX")
1877 (match_test "optimize_function_for_size_p (cfun)")
1878 (const_string "V4SF")
1880 (const_string "TI")))])
1882 (define_insn "*movdi_internal_rex64"
1883 [(set (match_operand:DI 0 "nonimmediate_operand"
1884 "=r,r ,r,m ,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1885 (match_operand:DI 1 "general_operand"
1886 "Z ,rem,i,re,C ,*y ,m ,*Ym,r ,C ,*x,*x,m ,*Yi,r ,*Ym,*x"))]
1887 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1889 switch (get_attr_type (insn))
1892 if (SSE_REG_P (operands[0]))
1893 return "movq2dq\t{%1, %0|%0, %1}";
1895 return "movdq2q\t{%1, %0|%0, %1}";
1898 if (get_attr_mode (insn) == MODE_V4SF)
1899 return "%vmovaps\t{%1, %0|%0, %1}";
1900 else if (get_attr_mode (insn) == MODE_TI)
1901 return "%vmovdqa\t{%1, %0|%0, %1}";
1903 /* Handle broken assemblers that require movd instead of movq. */
1904 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1905 return "%vmovd\t{%1, %0|%0, %1}";
1907 return "%vmovq\t{%1, %0|%0, %1}";
1910 /* Handle broken assemblers that require movd instead of movq. */
1911 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1912 return "movd\t{%1, %0|%0, %1}";
1914 return "movq\t{%1, %0|%0, %1}";
1917 return standard_sse_constant_opcode (insn, operands[1]);
1920 return "pxor\t%0, %0";
1923 return "lea{q}\t{%E1, %0|%0, %E1}";
1926 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1927 if (get_attr_mode (insn) == MODE_SI)
1928 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1929 else if (which_alternative == 2)
1930 return "movabs{q}\t{%1, %0|%0, %1}";
1931 else if (ix86_use_lea_for_mov (insn, operands))
1932 return "lea{q}\t{%E1, %0|%0, %E1}";
1934 return "mov{q}\t{%1, %0|%0, %1}";
1938 (cond [(eq_attr "alternative" "4")
1939 (const_string "mmx")
1940 (eq_attr "alternative" "5,6,7,8")
1941 (const_string "mmxmov")
1942 (eq_attr "alternative" "9")
1943 (const_string "sselog1")
1944 (eq_attr "alternative" "10,11,12,13,14")
1945 (const_string "ssemov")
1946 (eq_attr "alternative" "15,16")
1947 (const_string "ssecvt")
1948 (match_operand 1 "pic_32bit_operand")
1949 (const_string "lea")
1951 (const_string "imov")))
1954 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
1956 (const_string "*")))
1957 (set (attr "length_immediate")
1959 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
1961 (const_string "*")))
1962 (set (attr "prefix_rex")
1963 (if_then_else (eq_attr "alternative" "7,8")
1965 (const_string "*")))
1966 (set (attr "prefix_data16")
1967 (if_then_else (eq_attr "alternative" "10")
1969 (const_string "*")))
1970 (set (attr "prefix")
1971 (if_then_else (eq_attr "alternative" "9,10,11,12,13,14")
1972 (const_string "maybe_vex")
1973 (const_string "orig")))
1975 (cond [(eq_attr "alternative" "0")
1977 (eq_attr "alternative" "9,11")
1978 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1979 (const_string "V4SF")
1980 (match_test "TARGET_AVX")
1982 (match_test "optimize_function_for_size_p (cfun)")
1983 (const_string "V4SF")
1985 (const_string "TI"))
1987 (const_string "DI")))])
1989 ;; Reload patterns to support multi-word load/store
1990 ;; with non-offsetable address.
1991 (define_expand "reload_noff_store"
1992 [(parallel [(match_operand 0 "memory_operand" "=m")
1993 (match_operand 1 "register_operand" "r")
1994 (match_operand:DI 2 "register_operand" "=&r")])]
1997 rtx mem = operands[0];
1998 rtx addr = XEXP (mem, 0);
2000 emit_move_insn (operands[2], addr);
2001 mem = replace_equiv_address_nv (mem, operands[2]);
2003 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
2007 (define_expand "reload_noff_load"
2008 [(parallel [(match_operand 0 "register_operand" "=r")
2009 (match_operand 1 "memory_operand" "m")
2010 (match_operand:DI 2 "register_operand" "=r")])]
2013 rtx mem = operands[1];
2014 rtx addr = XEXP (mem, 0);
2016 emit_move_insn (operands[2], addr);
2017 mem = replace_equiv_address_nv (mem, operands[2]);
2019 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
2023 (define_insn "*movdi_internal"
2024 [(set (match_operand:DI 0 "nonimmediate_operand"
2025 "=r ,o ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym")
2026 (match_operand:DI 1 "general_operand"
2027 "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))]
2028 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2030 switch (get_attr_type (insn))
2033 if (SSE_REG_P (operands[0]))
2034 return "movq2dq\t{%1, %0|%0, %1}";
2036 return "movdq2q\t{%1, %0|%0, %1}";
2039 switch (get_attr_mode (insn))
2042 return "%vmovdqa\t{%1, %0|%0, %1}";
2044 return "%vmovq\t{%1, %0|%0, %1}";
2046 return "%vmovaps\t{%1, %0|%0, %1}";
2048 return "movlps\t{%1, %0|%0, %1}";
2054 return "movq\t{%1, %0|%0, %1}";
2057 return standard_sse_constant_opcode (insn, operands[1]);
2060 return "pxor\t%0, %0";
2070 (cond [(eq_attr "alternative" "5,6,7,8,13,14")
2071 (const_string "sse2")
2072 (eq_attr "alternative" "9,10,11,12")
2073 (const_string "noavx")
2075 (const_string "*")))
2077 (cond [(eq_attr "alternative" "0,1")
2078 (const_string "multi")
2079 (eq_attr "alternative" "2")
2080 (const_string "mmx")
2081 (eq_attr "alternative" "3,4")
2082 (const_string "mmxmov")
2083 (eq_attr "alternative" "5,9")
2084 (const_string "sselog1")
2085 (eq_attr "alternative" "13,14")
2086 (const_string "ssecvt")
2088 (const_string "ssemov")))
2089 (set (attr "prefix")
2090 (if_then_else (eq_attr "alternative" "5,6,7,8")
2091 (const_string "maybe_vex")
2092 (const_string "orig")))
2094 (cond [(eq_attr "alternative" "9,11")
2095 (const_string "V4SF")
2096 (eq_attr "alternative" "10,12")
2097 (const_string "V2SF")
2098 (eq_attr "alternative" "5,7")
2099 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2100 (const_string "V4SF")
2101 (match_test "TARGET_AVX")
2103 (match_test "optimize_function_for_size_p (cfun)")
2104 (const_string "V4SF")
2106 (const_string "TI"))
2108 (const_string "DI")))])
2111 [(set (match_operand:DI 0 "nonimmediate_operand")
2112 (match_operand:DI 1 "general_operand"))]
2113 "!TARGET_64BIT && reload_completed
2114 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2115 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2117 "ix86_split_long_move (operands); DONE;")
2119 (define_insn "*movsi_internal"
2120 [(set (match_operand:SI 0 "nonimmediate_operand"
2121 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2122 (match_operand:SI 1 "general_operand"
2123 "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m"))]
2124 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2126 switch (get_attr_type (insn))
2129 return standard_sse_constant_opcode (insn, operands[1]);
2132 switch (get_attr_mode (insn))
2135 return "%vmovdqa\t{%1, %0|%0, %1}";
2137 return "%vmovaps\t{%1, %0|%0, %1}";
2139 return "%vmovd\t{%1, %0|%0, %1}";
2141 return "%vmovss\t{%1, %0|%0, %1}";
2147 return "pxor\t%0, %0";
2150 if (get_attr_mode (insn) == MODE_DI)
2151 return "movq\t{%1, %0|%0, %1}";
2152 return "movd\t{%1, %0|%0, %1}";
2155 return "lea{l}\t{%E1, %0|%0, %E1}";
2158 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2159 if (ix86_use_lea_for_mov (insn, operands))
2160 return "lea{l}\t{%E1, %0|%0, %E1}";
2162 return "mov{l}\t{%1, %0|%0, %1}";
2166 (cond [(eq_attr "alternative" "2")
2167 (const_string "mmx")
2168 (eq_attr "alternative" "3,4,5")
2169 (const_string "mmxmov")
2170 (eq_attr "alternative" "6")
2171 (const_string "sselog1")
2172 (eq_attr "alternative" "7,8,9,10,11")
2173 (const_string "ssemov")
2174 (match_operand 1 "pic_32bit_operand")
2175 (const_string "lea")
2177 (const_string "imov")))
2178 (set (attr "prefix")
2179 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2180 (const_string "orig")
2181 (const_string "maybe_vex")))
2182 (set (attr "prefix_data16")
2183 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2185 (const_string "*")))
2187 (cond [(eq_attr "alternative" "2,3")
2189 (eq_attr "alternative" "6,7")
2190 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2191 (const_string "V4SF")
2192 (match_test "TARGET_AVX")
2194 (ior (not (match_test "TARGET_SSE2"))
2195 (match_test "optimize_function_for_size_p (cfun)"))
2196 (const_string "V4SF")
2198 (const_string "TI"))
2199 (and (eq_attr "alternative" "8,9,10,11")
2200 (not (match_test "TARGET_SSE2")))
2203 (const_string "SI")))])
2205 (define_insn "*movhi_internal"
2206 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m")
2207 (match_operand:HI 1 "general_operand" "r ,rn,rm,rn"))]
2208 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2210 switch (get_attr_type (insn))
2213 /* movzwl is faster than movw on p2 due to partial word stalls,
2214 though not as fast as an aligned movl. */
2215 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2217 if (get_attr_mode (insn) == MODE_SI)
2218 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2220 return "mov{w}\t{%1, %0|%0, %1}";
2224 (cond [(match_test "optimize_function_for_size_p (cfun)")
2225 (const_string "imov")
2226 (and (eq_attr "alternative" "0")
2227 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2228 (not (match_test "TARGET_HIMODE_MATH"))))
2229 (const_string "imov")
2230 (and (eq_attr "alternative" "1,2")
2231 (match_operand:HI 1 "aligned_operand"))
2232 (const_string "imov")
2233 (and (match_test "TARGET_MOVX")
2234 (eq_attr "alternative" "0,2"))
2235 (const_string "imovx")
2237 (const_string "imov")))
2239 (cond [(eq_attr "type" "imovx")
2241 (and (eq_attr "alternative" "1,2")
2242 (match_operand:HI 1 "aligned_operand"))
2244 (and (eq_attr "alternative" "0")
2245 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2246 (not (match_test "TARGET_HIMODE_MATH"))))
2249 (const_string "HI")))])
2251 ;; Situation is quite tricky about when to choose full sized (SImode) move
2252 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2253 ;; partial register dependency machines (such as AMD Athlon), where QImode
2254 ;; moves issue extra dependency and for partial register stalls machines
2255 ;; that don't use QImode patterns (and QImode move cause stall on the next
2258 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2259 ;; register stall machines with, where we use QImode instructions, since
2260 ;; partial register stall can be caused there. Then we use movzx.
2261 (define_insn "*movqi_internal"
2262 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2263 (match_operand:QI 1 "general_operand" "q ,qn,qm,q,rn,qm,qn"))]
2264 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2266 switch (get_attr_type (insn))
2269 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2270 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2272 if (get_attr_mode (insn) == MODE_SI)
2273 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2275 return "mov{b}\t{%1, %0|%0, %1}";
2279 (cond [(and (eq_attr "alternative" "5")
2280 (not (match_operand:QI 1 "aligned_operand")))
2281 (const_string "imovx")
2282 (match_test "optimize_function_for_size_p (cfun)")
2283 (const_string "imov")
2284 (and (eq_attr "alternative" "3")
2285 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2286 (not (match_test "TARGET_QIMODE_MATH"))))
2287 (const_string "imov")
2288 (eq_attr "alternative" "3,5")
2289 (const_string "imovx")
2290 (and (match_test "TARGET_MOVX")
2291 (eq_attr "alternative" "2"))
2292 (const_string "imovx")
2294 (const_string "imov")))
2296 (cond [(eq_attr "alternative" "3,4,5")
2298 (eq_attr "alternative" "6")
2300 (eq_attr "type" "imovx")
2302 (and (eq_attr "type" "imov")
2303 (and (eq_attr "alternative" "0,1")
2304 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2305 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2306 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2308 ;; Avoid partial register stalls when not using QImode arithmetic
2309 (and (eq_attr "type" "imov")
2310 (and (eq_attr "alternative" "0,1")
2311 (and (match_test "TARGET_PARTIAL_REG_STALL")
2312 (not (match_test "TARGET_QIMODE_MATH")))))
2315 (const_string "QI")))])
2317 ;; Stores and loads of ax to arbitrary constant address.
2318 ;; We fake an second form of instruction to force reload to load address
2319 ;; into register when rax is not available
2320 (define_insn "*movabs<mode>_1"
2321 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2322 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2323 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2325 movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1}
2326 mov{<imodesuffix>}\t{%1, %a0|<iptrsize> PTR %a0, %1}"
2327 [(set_attr "type" "imov")
2328 (set_attr "modrm" "0,*")
2329 (set_attr "length_address" "8,0")
2330 (set_attr "length_immediate" "0,*")
2331 (set_attr "memory" "store")
2332 (set_attr "mode" "<MODE>")])
2334 (define_insn "*movabs<mode>_2"
2335 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2336 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2337 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2339 movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]}
2340 mov{<imodesuffix>}\t{%a1, %0|%0, <iptrsize> PTR %a1}"
2341 [(set_attr "type" "imov")
2342 (set_attr "modrm" "0,*")
2343 (set_attr "length_address" "8,0")
2344 (set_attr "length_immediate" "0")
2345 (set_attr "memory" "load")
2346 (set_attr "mode" "<MODE>")])
2348 (define_insn "swap<mode>"
2349 [(set (match_operand:SWI48 0 "register_operand" "+r")
2350 (match_operand:SWI48 1 "register_operand" "+r"))
2354 "xchg{<imodesuffix>}\t%1, %0"
2355 [(set_attr "type" "imov")
2356 (set_attr "mode" "<MODE>")
2357 (set_attr "pent_pair" "np")
2358 (set_attr "athlon_decode" "vector")
2359 (set_attr "amdfam10_decode" "double")
2360 (set_attr "bdver1_decode" "double")])
2362 (define_insn "*swap<mode>_1"
2363 [(set (match_operand:SWI12 0 "register_operand" "+r")
2364 (match_operand:SWI12 1 "register_operand" "+r"))
2367 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2369 [(set_attr "type" "imov")
2370 (set_attr "mode" "SI")
2371 (set_attr "pent_pair" "np")
2372 (set_attr "athlon_decode" "vector")
2373 (set_attr "amdfam10_decode" "double")
2374 (set_attr "bdver1_decode" "double")])
2376 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2377 ;; is disabled for AMDFAM10
2378 (define_insn "*swap<mode>_2"
2379 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2380 (match_operand:SWI12 1 "register_operand" "+<r>"))
2383 "TARGET_PARTIAL_REG_STALL"
2384 "xchg{<imodesuffix>}\t%1, %0"
2385 [(set_attr "type" "imov")
2386 (set_attr "mode" "<MODE>")
2387 (set_attr "pent_pair" "np")
2388 (set_attr "athlon_decode" "vector")])
2390 (define_expand "movstrict<mode>"
2391 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2392 (match_operand:SWI12 1 "general_operand"))]
2395 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2397 if (GET_CODE (operands[0]) == SUBREG
2398 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2400 /* Don't generate memory->memory moves, go through a register */
2401 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2402 operands[1] = force_reg (<MODE>mode, operands[1]);
2405 (define_insn "*movstrict<mode>_1"
2406 [(set (strict_low_part
2407 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2408 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2409 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2410 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2411 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2412 [(set_attr "type" "imov")
2413 (set_attr "mode" "<MODE>")])
2415 (define_insn "*movstrict<mode>_xor"
2416 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2417 (match_operand:SWI12 1 "const0_operand"))
2418 (clobber (reg:CC FLAGS_REG))]
2420 "xor{<imodesuffix>}\t%0, %0"
2421 [(set_attr "type" "alu1")
2422 (set_attr "mode" "<MODE>")
2423 (set_attr "length_immediate" "0")])
2425 (define_insn "*mov<mode>_extv_1"
2426 [(set (match_operand:SWI24 0 "register_operand" "=R")
2427 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2431 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2432 [(set_attr "type" "imovx")
2433 (set_attr "mode" "SI")])
2435 (define_insn "*movqi_extv_1_rex64"
2436 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2437 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2442 switch (get_attr_type (insn))
2445 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2447 return "mov{b}\t{%h1, %0|%0, %h1}";
2451 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand"))
2452 (match_test "TARGET_MOVX"))
2453 (const_string "imovx")
2454 (const_string "imov")))
2456 (if_then_else (eq_attr "type" "imovx")
2458 (const_string "QI")))])
2460 (define_insn "*movqi_extv_1"
2461 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2462 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2467 switch (get_attr_type (insn))
2470 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2472 return "mov{b}\t{%h1, %0|%0, %h1}";
2476 (if_then_else (and (match_operand:QI 0 "register_operand")
2477 (ior (not (match_operand:QI 0 "QIreg_operand"))
2478 (match_test "TARGET_MOVX")))
2479 (const_string "imovx")
2480 (const_string "imov")))
2482 (if_then_else (eq_attr "type" "imovx")
2484 (const_string "QI")))])
2486 (define_insn "*mov<mode>_extzv_1"
2487 [(set (match_operand:SWI48 0 "register_operand" "=R")
2488 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2492 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2493 [(set_attr "type" "imovx")
2494 (set_attr "mode" "SI")])
2496 (define_insn "*movqi_extzv_2_rex64"
2497 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2499 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2504 switch (get_attr_type (insn))
2507 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2509 return "mov{b}\t{%h1, %0|%0, %h1}";
2513 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand"))
2514 (match_test "TARGET_MOVX"))
2515 (const_string "imovx")
2516 (const_string "imov")))
2518 (if_then_else (eq_attr "type" "imovx")
2520 (const_string "QI")))])
2522 (define_insn "*movqi_extzv_2"
2523 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2525 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2530 switch (get_attr_type (insn))
2533 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2535 return "mov{b}\t{%h1, %0|%0, %h1}";
2539 (if_then_else (and (match_operand:QI 0 "register_operand")
2540 (ior (not (match_operand:QI 0 "QIreg_operand"))
2541 (match_test "TARGET_MOVX")))
2542 (const_string "imovx")
2543 (const_string "imov")))
2545 (if_then_else (eq_attr "type" "imovx")
2547 (const_string "QI")))])
2549 (define_expand "mov<mode>_insv_1"
2550 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand")
2553 (match_operand:SWI48 1 "nonmemory_operand"))])
2555 (define_insn "*mov<mode>_insv_1_rex64"
2556 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2559 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2562 if (CONST_INT_P (operands[1]))
2563 operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2564 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2566 [(set_attr "type" "imov")
2567 (set_attr "mode" "QI")])
2569 (define_insn "*movsi_insv_1"
2570 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2573 (match_operand:SI 1 "general_operand" "Qmn"))]
2576 if (CONST_INT_P (operands[1]))
2577 operands[1] = simplify_gen_subreg (QImode, operands[1], SImode, 0);
2578 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2580 [(set_attr "type" "imov")
2581 (set_attr "mode" "QI")])
2583 (define_insn "*movqi_insv_2"
2584 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2587 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2590 "mov{b}\t{%h1, %h0|%h0, %h1}"
2591 [(set_attr "type" "imov")
2592 (set_attr "mode" "QI")])
2594 ;; Floating point push instructions.
2596 (define_insn "*pushtf"
2597 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2598 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2601 /* This insn should be already split before reg-stack. */
2604 [(set_attr "type" "multi")
2605 (set_attr "unit" "sse,*,*")
2606 (set_attr "mode" "TF,SI,SI")])
2608 ;; %%% Kill this when call knows how to work this out.
2610 [(set (match_operand:TF 0 "push_operand")
2611 (match_operand:TF 1 "sse_reg_operand"))]
2612 "TARGET_SSE && reload_completed"
2613 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2614 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2616 (define_insn "*pushxf"
2617 [(set (match_operand:XF 0 "push_operand" "=<,<")
2618 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2619 "optimize_function_for_speed_p (cfun)"
2621 /* This insn should be already split before reg-stack. */
2624 [(set_attr "type" "multi")
2625 (set_attr "unit" "i387,*")
2626 (set_attr "mode" "XF,SI")])
2628 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2629 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2630 ;; Pushing using integer instructions is longer except for constants
2631 ;; and direct memory references (assuming that any given constant is pushed
2632 ;; only once, but this ought to be handled elsewhere).
2634 (define_insn "*pushxf_nointeger"
2635 [(set (match_operand:XF 0 "push_operand" "=<,<")
2636 (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2637 "optimize_function_for_size_p (cfun)"
2639 /* This insn should be already split before reg-stack. */
2642 [(set_attr "type" "multi")
2643 (set_attr "unit" "i387,*")
2644 (set_attr "mode" "XF,SI")])
2646 ;; %%% Kill this when call knows how to work this out.
2648 [(set (match_operand:XF 0 "push_operand")
2649 (match_operand:XF 1 "fp_register_operand"))]
2651 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2652 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2653 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2655 (define_insn "*pushdf_rex64"
2656 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2657 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
2660 /* This insn should be already split before reg-stack. */
2663 [(set_attr "type" "multi")
2664 (set_attr "unit" "i387,*,*")
2665 (set_attr "mode" "DF,DI,DF")])
2667 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2668 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2669 ;; On the average, pushdf using integers can be still shorter.
2671 (define_insn "*pushdf"
2672 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2673 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
2676 /* This insn should be already split before reg-stack. */
2679 [(set_attr "isa" "*,*,sse2")
2680 (set_attr "type" "multi")
2681 (set_attr "unit" "i387,*,*")
2682 (set_attr "mode" "DF,DI,DF")])
2684 ;; %%% Kill this when call knows how to work this out.
2686 [(set (match_operand:DF 0 "push_operand")
2687 (match_operand:DF 1 "any_fp_register_operand"))]
2689 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2690 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2692 (define_insn "*pushsf_rex64"
2693 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2694 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2697 /* Anything else should be already split before reg-stack. */
2698 gcc_assert (which_alternative == 1);
2699 return "push{q}\t%q1";
2701 [(set_attr "type" "multi,push,multi")
2702 (set_attr "unit" "i387,*,*")
2703 (set_attr "mode" "SF,DI,SF")])
2705 (define_insn "*pushsf"
2706 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2707 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2710 /* Anything else should be already split before reg-stack. */
2711 gcc_assert (which_alternative == 1);
2712 return "push{l}\t%1";
2714 [(set_attr "type" "multi,push,multi")
2715 (set_attr "unit" "i387,*,*")
2716 (set_attr "mode" "SF,SI,SF")])
2718 ;; %%% Kill this when call knows how to work this out.
2720 [(set (match_operand:SF 0 "push_operand")
2721 (match_operand:SF 1 "any_fp_register_operand"))]
2723 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2724 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2726 rtx op = XEXP (operands[0], 0);
2727 if (GET_CODE (op) == PRE_DEC)
2729 gcc_assert (!TARGET_64BIT);
2734 op = XEXP (XEXP (op, 1), 1);
2735 gcc_assert (CONST_INT_P (op));
2741 [(set (match_operand:SF 0 "push_operand")
2742 (match_operand:SF 1 "memory_operand"))]
2744 && (operands[2] = find_constant_src (insn))"
2745 [(set (match_dup 0) (match_dup 2))])
2748 [(set (match_operand 0 "push_operand")
2749 (match_operand 1 "general_operand"))]
2751 && (GET_MODE (operands[0]) == TFmode
2752 || GET_MODE (operands[0]) == XFmode
2753 || GET_MODE (operands[0]) == DFmode)
2754 && !ANY_FP_REG_P (operands[1])"
2756 "ix86_split_long_move (operands); DONE;")
2758 ;; Floating point move instructions.
2760 (define_expand "movtf"
2761 [(set (match_operand:TF 0 "nonimmediate_operand")
2762 (match_operand:TF 1 "nonimmediate_operand"))]
2763 "TARGET_64BIT || TARGET_SSE"
2765 ix86_expand_move (TFmode, operands);
2769 (define_expand "mov<mode>"
2770 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2771 (match_operand:X87MODEF 1 "general_operand"))]
2773 "ix86_expand_move (<MODE>mode, operands); DONE;")
2775 (define_insn "*movtf_internal_rex64"
2776 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
2777 (match_operand:TF 1 "general_operand" "C ,xm,x,*roF,*rC"))]
2778 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2779 && (!can_create_pseudo_p ()
2780 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2781 || GET_CODE (operands[1]) != CONST_DOUBLE
2782 || (optimize_function_for_size_p (cfun)
2783 && standard_sse_constant_p (operands[1])
2784 && !memory_operand (operands[0], TFmode))
2785 || (!TARGET_MEMORY_MISMATCH_STALL
2786 && memory_operand (operands[0], TFmode)))"
2788 switch (which_alternative)
2791 return standard_sse_constant_opcode (insn, operands[1]);
2794 /* Handle misaligned load/store since we
2795 don't have movmisaligntf pattern. */
2796 if (misaligned_operand (operands[0], TFmode)
2797 || misaligned_operand (operands[1], TFmode))
2799 if (get_attr_mode (insn) == MODE_V4SF)
2800 return "%vmovups\t{%1, %0|%0, %1}";
2802 return "%vmovdqu\t{%1, %0|%0, %1}";
2806 if (get_attr_mode (insn) == MODE_V4SF)
2807 return "%vmovaps\t{%1, %0|%0, %1}";
2809 return "%vmovdqa\t{%1, %0|%0, %1}";
2820 [(set_attr "type" "sselog1,ssemov,ssemov,*,*")
2821 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2823 (cond [(eq_attr "alternative" "3,4")
2825 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2826 (const_string "V4SF")
2827 (and (eq_attr "alternative" "2")
2828 (match_test "TARGET_SSE_TYPELESS_STORES"))
2829 (const_string "V4SF")
2830 (match_test "TARGET_AVX")
2832 (ior (not (match_test "TARGET_SSE2"))
2833 (match_test "optimize_function_for_size_p (cfun)"))
2834 (const_string "V4SF")
2836 (const_string "TI")))])
2838 (define_insn "*movtf_internal_sse"
2839 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m")
2840 (match_operand:TF 1 "general_operand" "C ,xm,x"))]
2841 "TARGET_SSE && !TARGET_64BIT
2842 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2843 && (!can_create_pseudo_p ()
2844 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2845 || GET_CODE (operands[1]) != CONST_DOUBLE
2846 || (optimize_function_for_size_p (cfun)
2847 && standard_sse_constant_p (operands[1])
2848 && !memory_operand (operands[0], TFmode))
2849 || (!TARGET_MEMORY_MISMATCH_STALL
2850 && memory_operand (operands[0], TFmode)))"
2852 switch (which_alternative)
2855 return standard_sse_constant_opcode (insn, operands[1]);
2858 /* Handle misaligned load/store since we
2859 don't have movmisaligntf pattern. */
2860 if (misaligned_operand (operands[0], TFmode)
2861 || misaligned_operand (operands[1], TFmode))
2863 if (get_attr_mode (insn) == MODE_V4SF)
2864 return "%vmovups\t{%1, %0|%0, %1}";
2866 return "%vmovdqu\t{%1, %0|%0, %1}";
2870 if (get_attr_mode (insn) == MODE_V4SF)
2871 return "%vmovaps\t{%1, %0|%0, %1}";
2873 return "%vmovdqa\t{%1, %0|%0, %1}";
2879 [(set_attr "type" "sselog1,ssemov,ssemov")
2880 (set_attr "prefix" "maybe_vex")
2882 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2883 (const_string "V4SF")
2884 (and (eq_attr "alternative" "2")
2885 (match_test "TARGET_SSE_TYPELESS_STORES"))
2886 (const_string "V4SF")
2887 (match_test "TARGET_AVX")
2889 (ior (not (match_test "TARGET_SSE2"))
2890 (match_test "optimize_function_for_size_p (cfun)"))
2891 (const_string "V4SF")
2893 (const_string "TI")))])
2895 (define_insn "*movxf_internal_rex64"
2896 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2897 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,Yx*rC"))]
2898 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2899 && (!can_create_pseudo_p ()
2900 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2901 || GET_CODE (operands[1]) != CONST_DOUBLE
2902 || (optimize_function_for_size_p (cfun)
2903 && standard_80387_constant_p (operands[1]) > 0
2904 && !memory_operand (operands[0], XFmode))
2905 || (!TARGET_MEMORY_MISMATCH_STALL
2906 && memory_operand (operands[0], XFmode)))"
2908 switch (which_alternative)
2912 return output_387_reg_move (insn, operands);
2915 return standard_80387_constant_opcode (operands[1]);
2925 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2926 (set_attr "mode" "XF,XF,XF,SI,SI")])
2928 ;; Possible store forwarding (partial memory) stall in alternative 4.
2929 (define_insn "*movxf_internal"
2930 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2931 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,Yx*rF"))]
2932 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2933 && (!can_create_pseudo_p ()
2934 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2935 || GET_CODE (operands[1]) != CONST_DOUBLE
2936 || (optimize_function_for_size_p (cfun)
2937 && standard_80387_constant_p (operands[1]) > 0
2938 && !memory_operand (operands[0], XFmode))
2939 || (!TARGET_MEMORY_MISMATCH_STALL
2940 && memory_operand (operands[0], XFmode)))"
2942 switch (which_alternative)
2946 return output_387_reg_move (insn, operands);
2949 return standard_80387_constant_opcode (operands[1]);
2959 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2960 (set_attr "mode" "XF,XF,XF,SI,SI")])
2962 (define_insn "*movdf_internal_rex64"
2963 [(set (match_operand:DF 0 "nonimmediate_operand"
2964 "=Yf*f,m ,Yf*f,?r,?m,?r,?r,x,x,x,m,Yi,r")
2965 (match_operand:DF 1 "general_operand"
2966 "Yf*fm,Yf*f,G ,rm,rC,C ,F ,C,x,m,x,r ,Yi"))]
2967 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2968 && (!can_create_pseudo_p ()
2969 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2970 || GET_CODE (operands[1]) != CONST_DOUBLE
2971 || (optimize_function_for_size_p (cfun)
2972 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2973 && standard_80387_constant_p (operands[1]) > 0)
2974 || (TARGET_SSE2 && TARGET_SSE_MATH
2975 && standard_sse_constant_p (operands[1]))))
2976 || memory_operand (operands[0], DFmode))"
2978 switch (which_alternative)
2982 return output_387_reg_move (insn, operands);
2985 return standard_80387_constant_opcode (operands[1]);
2989 return "mov{q}\t{%1, %0|%0, %1}";
2992 return "mov{l}\t{%1, %k0|%k0, %1}";
2995 return "movabs{q}\t{%1, %0|%0, %1}";
2998 return standard_sse_constant_opcode (insn, operands[1]);
3003 switch (get_attr_mode (insn))
3006 return "%vmovapd\t{%1, %0|%0, %1}";
3008 return "%vmovaps\t{%1, %0|%0, %1}";
3011 return "%vmovq\t{%1, %0|%0, %1}";
3013 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3014 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3015 return "%vmovsd\t{%1, %0|%0, %1}";
3017 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3019 return "%vmovlps\t{%1, %d0|%d0, %1}";
3026 /* Handle broken assemblers that require movd instead of movq. */
3027 return "%vmovd\t{%1, %0|%0, %1}";
3034 (cond [(eq_attr "alternative" "0,1,2")
3035 (const_string "fmov")
3036 (eq_attr "alternative" "3,4,5,6")
3037 (const_string "imov")
3038 (eq_attr "alternative" "7")
3039 (const_string "sselog1")
3041 (const_string "ssemov")))
3044 (and (eq_attr "alternative" "6") (eq_attr "type" "imov"))
3046 (const_string "*")))
3047 (set (attr "length_immediate")
3049 (and (eq_attr "alternative" "6") (eq_attr "type" "imov"))
3051 (const_string "*")))
3052 (set (attr "prefix")
3053 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3054 (const_string "orig")
3055 (const_string "maybe_vex")))
3056 (set (attr "prefix_data16")
3057 (if_then_else (eq_attr "mode" "V1DF")
3059 (const_string "*")))
3061 (cond [(eq_attr "alternative" "0,1,2")
3063 (eq_attr "alternative" "3,4,6,11,12")
3065 (eq_attr "alternative" "5")
3068 /* xorps is one byte shorter for !TARGET_AVX. */
3069 (eq_attr "alternative" "7")
3070 (cond [(match_test "TARGET_AVX")
3071 (const_string "V2DF")
3072 (match_test "optimize_function_for_size_p (cfun)")
3073 (const_string "V4SF")
3074 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3077 (const_string "V2DF"))
3079 /* For architectures resolving dependencies on
3080 whole SSE registers use APD move to break dependency
3081 chains, otherwise use short move to avoid extra work.
3083 movaps encodes one byte shorter for !TARGET_AVX. */
3084 (eq_attr "alternative" "8")
3085 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3086 (const_string "V4SF")
3087 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3088 (const_string "V2DF")
3089 (match_test "TARGET_AVX")
3091 (match_test "optimize_function_for_size_p (cfun)")
3092 (const_string "V4SF")
3094 (const_string "DF"))
3095 /* For architectures resolving dependencies on register
3096 parts we may avoid extra work to zero out upper part
3098 (eq_attr "alternative" "9")
3100 (match_test "TARGET_SSE_SPLIT_REGS")
3101 (const_string "V1DF")
3102 (const_string "DF"))
3104 (const_string "DF")))])
3106 ;; Possible store forwarding (partial memory) stall in alternative 4.
3107 (define_insn "*movdf_internal"
3108 [(set (match_operand:DF 0 "nonimmediate_operand"
3109 "=Yf*f,m ,Yf*f,?Yd*r ,!o ,x,x,x,m,*x,*x,*x,m")
3110 (match_operand:DF 1 "general_operand"
3111 "Yf*fm,Yf*f,G ,Yd*roF,Yd*rF,C,x,m,x,C ,*x,m ,*x"))]
3112 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3113 && (!can_create_pseudo_p ()
3114 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3115 || GET_CODE (operands[1]) != CONST_DOUBLE
3116 || (optimize_function_for_size_p (cfun)
3117 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3118 && standard_80387_constant_p (operands[1]) > 0)
3119 || (TARGET_SSE2 && TARGET_SSE_MATH
3120 && standard_sse_constant_p (operands[1])))
3121 && !memory_operand (operands[0], DFmode))
3122 || (!TARGET_MEMORY_MISMATCH_STALL
3123 && memory_operand (operands[0], DFmode)))"
3125 switch (which_alternative)
3129 return output_387_reg_move (insn, operands);
3132 return standard_80387_constant_opcode (operands[1]);
3140 return standard_sse_constant_opcode (insn, operands[1]);
3148 switch (get_attr_mode (insn))
3151 return "%vmovapd\t{%1, %0|%0, %1}";
3153 return "%vmovaps\t{%1, %0|%0, %1}";
3156 return "%vmovq\t{%1, %0|%0, %1}";
3158 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3159 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3160 return "%vmovsd\t{%1, %0|%0, %1}";
3162 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3164 return "%vmovlps\t{%1, %d0|%d0, %1}";
3174 (if_then_else (eq_attr "alternative" "5,6,7,8")
3175 (const_string "sse2")
3176 (const_string "*")))
3178 (cond [(eq_attr "alternative" "0,1,2")
3179 (const_string "fmov")
3180 (eq_attr "alternative" "3,4")
3181 (const_string "multi")
3182 (eq_attr "alternative" "5,9")
3183 (const_string "sselog1")
3185 (const_string "ssemov")))
3186 (set (attr "prefix")
3187 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3188 (const_string "orig")
3189 (const_string "maybe_vex")))
3190 (set (attr "prefix_data16")
3191 (if_then_else (eq_attr "mode" "V1DF")
3193 (const_string "*")))
3195 (cond [(eq_attr "alternative" "0,1,2")
3197 (eq_attr "alternative" "3,4")
3200 /* For SSE1, we have many fewer alternatives. */
3201 (not (match_test "TARGET_SSE2"))
3203 (eq_attr "alternative" "5,6,9,10")
3204 (const_string "V4SF")
3205 (const_string "V2SF"))
3207 /* xorps is one byte shorter for !TARGET_AVX. */
3208 (eq_attr "alternative" "5,9")
3209 (cond [(match_test "TARGET_AVX")
3210 (const_string "V2DF")
3211 (match_test "optimize_function_for_size_p (cfun)")
3212 (const_string "V4SF")
3213 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3216 (const_string "V2DF"))
3218 /* For architectures resolving dependencies on
3219 whole SSE registers use APD move to break dependency
3220 chains, otherwise use short move to avoid extra work.
3222 movaps encodes one byte shorter for !TARGET_AVX. */
3223 (eq_attr "alternative" "6,10")
3224 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
3225 (const_string "V4SF")
3226 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3227 (const_string "V2DF")
3228 (match_test "TARGET_AVX")
3230 (match_test "optimize_function_for_size_p (cfun)")
3231 (const_string "V4SF")
3233 (const_string "DF"))
3235 /* For architectures resolving dependencies on register
3236 parts we may avoid extra work to zero out upper part
3238 (eq_attr "alternative" "7,11")
3240 (match_test "TARGET_SSE_SPLIT_REGS")
3241 (const_string "V1DF")
3242 (const_string "DF"))
3244 (const_string "DF")))])
3246 (define_insn "*movsf_internal"
3247 [(set (match_operand:SF 0 "nonimmediate_operand"
3248 "=Yf*f,m ,Yf*f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3249 (match_operand:SF 1 "general_operand"
3250 "Yf*fm,Yf*f,G ,rmF,rF,C,x,m,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3251 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3252 && (!can_create_pseudo_p ()
3253 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3254 || GET_CODE (operands[1]) != CONST_DOUBLE
3255 || (optimize_function_for_size_p (cfun)
3256 && ((!TARGET_SSE_MATH
3257 && standard_80387_constant_p (operands[1]) > 0)
3259 && standard_sse_constant_p (operands[1]))))
3260 || memory_operand (operands[0], SFmode))"
3262 switch (which_alternative)
3266 return output_387_reg_move (insn, operands);
3269 return standard_80387_constant_opcode (operands[1]);
3273 return "mov{l}\t{%1, %0|%0, %1}";
3276 return standard_sse_constant_opcode (insn, operands[1]);
3279 if (get_attr_mode (insn) == MODE_V4SF)
3280 return "%vmovaps\t{%1, %0|%0, %1}";
3282 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3286 return "%vmovss\t{%1, %0|%0, %1}";
3292 return "movd\t{%1, %0|%0, %1}";
3295 return "movq\t{%1, %0|%0, %1}";
3299 return "%vmovd\t{%1, %0|%0, %1}";
3306 (cond [(eq_attr "alternative" "0,1,2")
3307 (const_string "fmov")
3308 (eq_attr "alternative" "3,4")
3309 (const_string "imov")
3310 (eq_attr "alternative" "5")
3311 (const_string "sselog1")
3312 (eq_attr "alternative" "9,10,11,14,15")
3313 (const_string "mmxmov")
3315 (const_string "ssemov")))
3316 (set (attr "prefix")
3317 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3318 (const_string "maybe_vex")
3319 (const_string "orig")))
3321 (cond [(eq_attr "alternative" "3,4,9,10")
3323 (eq_attr "alternative" "5")
3324 (cond [(match_test "TARGET_AVX")
3325 (const_string "V4SF")
3326 (ior (not (match_test "TARGET_SSE2"))
3327 (match_test "optimize_function_for_size_p (cfun)"))
3328 (const_string "V4SF")
3329 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3332 (const_string "V4SF"))
3334 /* For architectures resolving dependencies on
3335 whole SSE registers use APS move to break dependency
3336 chains, otherwise use short move to avoid extra work.
3338 Do the same for architectures resolving dependencies on
3339 the parts. While in DF mode it is better to always handle
3340 just register parts, the SF mode is different due to lack
3341 of instructions to load just part of the register. It is
3342 better to maintain the whole registers in single format
3343 to avoid problems on using packed logical operations. */
3344 (eq_attr "alternative" "6")
3346 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3347 (match_test "TARGET_SSE_SPLIT_REGS"))
3348 (const_string "V4SF")
3349 (const_string "SF"))
3350 (eq_attr "alternative" "11")
3351 (const_string "DI")]
3352 (const_string "SF")))])
3355 [(set (match_operand 0 "any_fp_register_operand")
3356 (match_operand 1 "memory_operand"))]
3358 && (GET_MODE (operands[0]) == TFmode
3359 || GET_MODE (operands[0]) == XFmode
3360 || GET_MODE (operands[0]) == DFmode
3361 || GET_MODE (operands[0]) == SFmode)
3362 && (operands[2] = find_constant_src (insn))"
3363 [(set (match_dup 0) (match_dup 2))]
3365 rtx c = operands[2];
3366 int r = REGNO (operands[0]);
3368 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3369 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3374 [(set (match_operand 0 "any_fp_register_operand")
3375 (float_extend (match_operand 1 "memory_operand")))]
3377 && (GET_MODE (operands[0]) == TFmode
3378 || GET_MODE (operands[0]) == XFmode
3379 || GET_MODE (operands[0]) == DFmode)
3380 && (operands[2] = find_constant_src (insn))"
3381 [(set (match_dup 0) (match_dup 2))]
3383 rtx c = operands[2];
3384 int r = REGNO (operands[0]);
3386 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3387 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3391 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3393 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3394 (match_operand:X87MODEF 1 "immediate_operand"))]
3396 && (standard_80387_constant_p (operands[1]) == 8
3397 || standard_80387_constant_p (operands[1]) == 9)"
3398 [(set (match_dup 0)(match_dup 1))
3400 (neg:X87MODEF (match_dup 0)))]
3404 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3405 if (real_isnegzero (&r))
3406 operands[1] = CONST0_RTX (<MODE>mode);
3408 operands[1] = CONST1_RTX (<MODE>mode);
3412 [(set (match_operand 0 "nonimmediate_operand")
3413 (match_operand 1 "general_operand"))]
3415 && (GET_MODE (operands[0]) == TFmode
3416 || GET_MODE (operands[0]) == XFmode
3417 || GET_MODE (operands[0]) == DFmode)
3418 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3420 "ix86_split_long_move (operands); DONE;")
3422 (define_insn "swapxf"
3423 [(set (match_operand:XF 0 "register_operand" "+f")
3424 (match_operand:XF 1 "register_operand" "+f"))
3429 if (STACK_TOP_P (operands[0]))
3434 [(set_attr "type" "fxch")
3435 (set_attr "mode" "XF")])
3437 (define_insn "*swap<mode>"
3438 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3439 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3442 "TARGET_80387 || reload_completed"
3444 if (STACK_TOP_P (operands[0]))
3449 [(set_attr "type" "fxch")
3450 (set_attr "mode" "<MODE>")])
3452 ;; Zero extension instructions
3454 (define_expand "zero_extendsidi2"
3455 [(set (match_operand:DI 0 "nonimmediate_operand")
3456 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3458 (define_insn "*zero_extendsidi2_rex64"
3459 [(set (match_operand:DI 0 "nonimmediate_operand"
3460 "=r ,o,?*Ym,?!*y,?*Yi,?*x")
3462 (match_operand:SI 1 "x86_64_zext_general_operand"
3463 "rmWz,0,r ,m ,r ,m")))]
3466 switch (get_attr_type (insn))
3469 if (ix86_use_lea_for_mov (insn, operands))
3470 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3472 return "mov{l}\t{%1, %k0|%k0, %1}";
3478 return "movd\t{%1, %0|%0, %1}";
3481 return "%vmovd\t{%1, %0|%0, %1}";
3487 [(set_attr "type" "imovx,multi,mmxmov,mmxmov,ssemov,ssemov")
3488 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3489 (set_attr "prefix_0f" "0,*,*,*,*,*")
3490 (set_attr "mode" "SI,SI,DI,DI,TI,TI")])
3492 (define_insn "*zero_extendsidi2"
3493 [(set (match_operand:DI 0 "nonimmediate_operand"
3494 "=ro,?r,?o,?*Ym,?!*y,?*Yi,?*x")
3495 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand"
3496 "0 ,rm,r ,r ,m ,r ,m")))]
3502 movd\t{%1, %0|%0, %1}
3503 movd\t{%1, %0|%0, %1}
3504 %vmovd\t{%1, %0|%0, %1}
3505 %vmovd\t{%1, %0|%0, %1}"
3506 [(set_attr "isa" "*,*,*,*,*,*,sse2")
3507 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3508 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3509 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3512 [(set (match_operand:DI 0 "memory_operand")
3513 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3515 [(set (match_dup 4) (const_int 0))]
3516 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3519 [(set (match_operand:DI 0 "register_operand")
3520 (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3521 "!TARGET_64BIT && reload_completed
3522 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3523 && true_regnum (operands[0]) == true_regnum (operands[1])"
3524 [(set (match_dup 4) (const_int 0))]
3525 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3528 [(set (match_operand:DI 0 "nonimmediate_operand")
3529 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3530 "!TARGET_64BIT && reload_completed
3531 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3532 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3533 [(set (match_dup 3) (match_dup 1))
3534 (set (match_dup 4) (const_int 0))]
3535 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3537 (define_insn "zero_extend<mode>di2"
3538 [(set (match_operand:DI 0 "register_operand" "=r")
3540 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3542 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3543 [(set_attr "type" "imovx")
3544 (set_attr "mode" "SI")])
3546 (define_expand "zero_extend<mode>si2"
3547 [(set (match_operand:SI 0 "register_operand")
3548 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3551 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3553 operands[1] = force_reg (<MODE>mode, operands[1]);
3554 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3559 (define_insn_and_split "zero_extend<mode>si2_and"
3560 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3562 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3563 (clobber (reg:CC FLAGS_REG))]
3564 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3566 "&& reload_completed"
3567 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3568 (clobber (reg:CC FLAGS_REG))])]
3570 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3572 ix86_expand_clear (operands[0]);
3574 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3575 emit_insn (gen_movstrict<mode>
3576 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3580 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3582 [(set_attr "type" "alu1")
3583 (set_attr "mode" "SI")])
3585 (define_insn "*zero_extend<mode>si2"
3586 [(set (match_operand:SI 0 "register_operand" "=r")
3588 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3589 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3590 "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3591 [(set_attr "type" "imovx")
3592 (set_attr "mode" "SI")])
3594 (define_expand "zero_extendqihi2"
3595 [(set (match_operand:HI 0 "register_operand")
3596 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3599 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3601 operands[1] = force_reg (QImode, operands[1]);
3602 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3607 (define_insn_and_split "zero_extendqihi2_and"
3608 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3609 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3610 (clobber (reg:CC FLAGS_REG))]
3611 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3613 "&& reload_completed"
3614 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3615 (clobber (reg:CC FLAGS_REG))])]
3617 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3619 ix86_expand_clear (operands[0]);
3621 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3622 emit_insn (gen_movstrictqi
3623 (gen_lowpart (QImode, operands[0]), operands[1]));
3627 operands[0] = gen_lowpart (SImode, operands[0]);
3629 [(set_attr "type" "alu1")
3630 (set_attr "mode" "SI")])
3632 ; zero extend to SImode to avoid partial register stalls
3633 (define_insn "*zero_extendqihi2"
3634 [(set (match_operand:HI 0 "register_operand" "=r")
3635 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3636 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3637 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3638 [(set_attr "type" "imovx")
3639 (set_attr "mode" "SI")])
3641 ;; Sign extension instructions
3643 (define_expand "extendsidi2"
3644 [(set (match_operand:DI 0 "register_operand")
3645 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3650 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3655 (define_insn "*extendsidi2_rex64"
3656 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3657 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3661 movs{lq|x}\t{%1, %0|%0, %1}"
3662 [(set_attr "type" "imovx")
3663 (set_attr "mode" "DI")
3664 (set_attr "prefix_0f" "0")
3665 (set_attr "modrm" "0,1")])
3667 (define_insn "extendsidi2_1"
3668 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3669 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3670 (clobber (reg:CC FLAGS_REG))
3671 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3675 ;; Split the memory case. If the source register doesn't die, it will stay
3676 ;; this way, if it does die, following peephole2s take care of it.
3678 [(set (match_operand:DI 0 "memory_operand")
3679 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3680 (clobber (reg:CC FLAGS_REG))
3681 (clobber (match_operand:SI 2 "register_operand"))]
3685 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3687 emit_move_insn (operands[3], operands[1]);
3689 /* Generate a cltd if possible and doing so it profitable. */
3690 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3691 && true_regnum (operands[1]) == AX_REG
3692 && true_regnum (operands[2]) == DX_REG)
3694 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3698 emit_move_insn (operands[2], operands[1]);
3699 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3701 emit_move_insn (operands[4], operands[2]);
3705 ;; Peepholes for the case where the source register does die, after
3706 ;; being split with the above splitter.
3708 [(set (match_operand:SI 0 "memory_operand")
3709 (match_operand:SI 1 "register_operand"))
3710 (set (match_operand:SI 2 "register_operand") (match_dup 1))
3711 (parallel [(set (match_dup 2)
3712 (ashiftrt:SI (match_dup 2) (const_int 31)))
3713 (clobber (reg:CC FLAGS_REG))])
3714 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3715 "REGNO (operands[1]) != REGNO (operands[2])
3716 && peep2_reg_dead_p (2, operands[1])
3717 && peep2_reg_dead_p (4, operands[2])
3718 && !reg_mentioned_p (operands[2], operands[3])"
3719 [(set (match_dup 0) (match_dup 1))
3720 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3721 (clobber (reg:CC FLAGS_REG))])
3722 (set (match_dup 3) (match_dup 1))])
3725 [(set (match_operand:SI 0 "memory_operand")
3726 (match_operand:SI 1 "register_operand"))
3727 (parallel [(set (match_operand:SI 2 "register_operand")
3728 (ashiftrt:SI (match_dup 1) (const_int 31)))
3729 (clobber (reg:CC FLAGS_REG))])
3730 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3731 "/* cltd is shorter than sarl $31, %eax */
3732 !optimize_function_for_size_p (cfun)
3733 && true_regnum (operands[1]) == AX_REG
3734 && true_regnum (operands[2]) == DX_REG
3735 && peep2_reg_dead_p (2, operands[1])
3736 && peep2_reg_dead_p (3, operands[2])
3737 && !reg_mentioned_p (operands[2], operands[3])"
3738 [(set (match_dup 0) (match_dup 1))
3739 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3740 (clobber (reg:CC FLAGS_REG))])
3741 (set (match_dup 3) (match_dup 1))])
3743 ;; Extend to register case. Optimize case where source and destination
3744 ;; registers match and cases where we can use cltd.
3746 [(set (match_operand:DI 0 "register_operand")
3747 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3748 (clobber (reg:CC FLAGS_REG))
3749 (clobber (match_scratch:SI 2))]
3753 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3755 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3756 emit_move_insn (operands[3], operands[1]);
3758 /* Generate a cltd if possible and doing so it profitable. */
3759 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3760 && true_regnum (operands[3]) == AX_REG
3761 && true_regnum (operands[4]) == DX_REG)
3763 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3767 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3768 emit_move_insn (operands[4], operands[1]);
3770 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3774 (define_insn "extend<mode>di2"
3775 [(set (match_operand:DI 0 "register_operand" "=r")
3777 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3779 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3780 [(set_attr "type" "imovx")
3781 (set_attr "mode" "DI")])
3783 (define_insn "extendhisi2"
3784 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3785 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3788 switch (get_attr_prefix_0f (insn))
3791 return "{cwtl|cwde}";
3793 return "movs{wl|x}\t{%1, %0|%0, %1}";
3796 [(set_attr "type" "imovx")
3797 (set_attr "mode" "SI")
3798 (set (attr "prefix_0f")
3799 ;; movsx is short decodable while cwtl is vector decoded.
3800 (if_then_else (and (eq_attr "cpu" "!k6")
3801 (eq_attr "alternative" "0"))
3803 (const_string "1")))
3805 (if_then_else (eq_attr "prefix_0f" "0")
3807 (const_string "1")))])
3809 (define_insn "*extendhisi2_zext"
3810 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3813 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3816 switch (get_attr_prefix_0f (insn))
3819 return "{cwtl|cwde}";
3821 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3824 [(set_attr "type" "imovx")
3825 (set_attr "mode" "SI")
3826 (set (attr "prefix_0f")
3827 ;; movsx is short decodable while cwtl is vector decoded.
3828 (if_then_else (and (eq_attr "cpu" "!k6")
3829 (eq_attr "alternative" "0"))
3831 (const_string "1")))
3833 (if_then_else (eq_attr "prefix_0f" "0")
3835 (const_string "1")))])
3837 (define_insn "extendqisi2"
3838 [(set (match_operand:SI 0 "register_operand" "=r")
3839 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3841 "movs{bl|x}\t{%1, %0|%0, %1}"
3842 [(set_attr "type" "imovx")
3843 (set_attr "mode" "SI")])
3845 (define_insn "*extendqisi2_zext"
3846 [(set (match_operand:DI 0 "register_operand" "=r")
3848 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3850 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3851 [(set_attr "type" "imovx")
3852 (set_attr "mode" "SI")])
3854 (define_insn "extendqihi2"
3855 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3856 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3859 switch (get_attr_prefix_0f (insn))
3862 return "{cbtw|cbw}";
3864 return "movs{bw|x}\t{%1, %0|%0, %1}";
3867 [(set_attr "type" "imovx")
3868 (set_attr "mode" "HI")
3869 (set (attr "prefix_0f")
3870 ;; movsx is short decodable while cwtl is vector decoded.
3871 (if_then_else (and (eq_attr "cpu" "!k6")
3872 (eq_attr "alternative" "0"))
3874 (const_string "1")))
3876 (if_then_else (eq_attr "prefix_0f" "0")
3878 (const_string "1")))])
3880 ;; Conversions between float and double.
3882 ;; These are all no-ops in the model used for the 80387.
3883 ;; So just emit moves.
3885 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3887 [(set (match_operand:DF 0 "push_operand")
3888 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3890 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3891 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3894 [(set (match_operand:XF 0 "push_operand")
3895 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3897 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3898 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3899 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3901 (define_expand "extendsfdf2"
3902 [(set (match_operand:DF 0 "nonimmediate_operand")
3903 (float_extend:DF (match_operand:SF 1 "general_operand")))]
3904 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3906 /* ??? Needed for compress_float_constant since all fp constants
3907 are TARGET_LEGITIMATE_CONSTANT_P. */
3908 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3910 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3911 && standard_80387_constant_p (operands[1]) > 0)
3913 operands[1] = simplify_const_unary_operation
3914 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3915 emit_move_insn_1 (operands[0], operands[1]);
3918 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3922 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3924 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3926 We do the conversion post reload to avoid producing of 128bit spills
3927 that might lead to ICE on 32bit target. The sequence unlikely combine
3930 [(set (match_operand:DF 0 "register_operand")
3932 (match_operand:SF 1 "nonimmediate_operand")))]
3933 "TARGET_USE_VECTOR_FP_CONVERTS
3934 && optimize_insn_for_speed_p ()
3935 && reload_completed && SSE_REG_P (operands[0])"
3940 (parallel [(const_int 0) (const_int 1)]))))]
3942 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3943 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3944 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3945 Try to avoid move when unpacking can be done in source. */
3946 if (REG_P (operands[1]))
3948 /* If it is unsafe to overwrite upper half of source, we need
3949 to move to destination and unpack there. */
3950 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3951 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3952 && true_regnum (operands[0]) != true_regnum (operands[1]))
3954 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3955 emit_move_insn (tmp, operands[1]);
3958 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3959 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3963 emit_insn (gen_vec_setv4sf_0 (operands[3],
3964 CONST0_RTX (V4SFmode), operands[1]));
3967 (define_insn "*extendsfdf2_mixed"
3968 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3970 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3971 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3973 switch (which_alternative)
3977 return output_387_reg_move (insn, operands);
3980 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3986 [(set_attr "type" "fmov,fmov,ssecvt")
3987 (set_attr "prefix" "orig,orig,maybe_vex")
3988 (set_attr "mode" "SF,XF,DF")])
3990 (define_insn "*extendsfdf2_sse"
3991 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3992 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3993 "TARGET_SSE2 && TARGET_SSE_MATH"
3994 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3995 [(set_attr "type" "ssecvt")
3996 (set_attr "prefix" "maybe_vex")
3997 (set_attr "mode" "DF")])
3999 (define_insn "*extendsfdf2_i387"
4000 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4001 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4003 "* return output_387_reg_move (insn, operands);"
4004 [(set_attr "type" "fmov")
4005 (set_attr "mode" "SF,XF")])
4007 (define_expand "extend<mode>xf2"
4008 [(set (match_operand:XF 0 "nonimmediate_operand")
4009 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
4012 /* ??? Needed for compress_float_constant since all fp constants
4013 are TARGET_LEGITIMATE_CONSTANT_P. */
4014 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4016 if (standard_80387_constant_p (operands[1]) > 0)
4018 operands[1] = simplify_const_unary_operation
4019 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4020 emit_move_insn_1 (operands[0], operands[1]);
4023 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4027 (define_insn "*extend<mode>xf2_i387"
4028 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4030 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4032 "* return output_387_reg_move (insn, operands);"
4033 [(set_attr "type" "fmov")
4034 (set_attr "mode" "<MODE>,XF")])
4036 ;; %%% This seems bad bad news.
4037 ;; This cannot output into an f-reg because there is no way to be sure
4038 ;; of truncating in that case. Otherwise this is just like a simple move
4039 ;; insn. So we pretend we can output to a reg in order to get better
4040 ;; register preferencing, but we really use a stack slot.
4042 ;; Conversion from DFmode to SFmode.
4044 (define_expand "truncdfsf2"
4045 [(set (match_operand:SF 0 "nonimmediate_operand")
4047 (match_operand:DF 1 "nonimmediate_operand")))]
4048 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4050 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4052 else if (flag_unsafe_math_optimizations)
4056 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4057 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4062 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4064 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4066 We do the conversion post reload to avoid producing of 128bit spills
4067 that might lead to ICE on 32bit target. The sequence unlikely combine
4070 [(set (match_operand:SF 0 "register_operand")
4072 (match_operand:DF 1 "nonimmediate_operand")))]
4073 "TARGET_USE_VECTOR_FP_CONVERTS
4074 && optimize_insn_for_speed_p ()
4075 && reload_completed && SSE_REG_P (operands[0])"
4078 (float_truncate:V2SF
4082 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4083 operands[3] = CONST0_RTX (V2SFmode);
4084 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4085 /* Use movsd for loading from memory, unpcklpd for registers.
4086 Try to avoid move when unpacking can be done in source, or SSE3
4087 movddup is available. */
4088 if (REG_P (operands[1]))
4091 && true_regnum (operands[0]) != true_regnum (operands[1])
4092 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4093 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4095 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4096 emit_move_insn (tmp, operands[1]);
4099 else if (!TARGET_SSE3)
4100 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4101 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4104 emit_insn (gen_sse2_loadlpd (operands[4],
4105 CONST0_RTX (V2DFmode), operands[1]));
4108 (define_expand "truncdfsf2_with_temp"
4109 [(parallel [(set (match_operand:SF 0)
4110 (float_truncate:SF (match_operand:DF 1)))
4111 (clobber (match_operand:SF 2))])])
4113 (define_insn "*truncdfsf_fast_mixed"
4114 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4116 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4117 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4119 switch (which_alternative)
4122 return output_387_reg_move (insn, operands);
4124 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4129 [(set_attr "type" "fmov,ssecvt")
4130 (set_attr "prefix" "orig,maybe_vex")
4131 (set_attr "mode" "SF")])
4133 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4134 ;; because nothing we do here is unsafe.
4135 (define_insn "*truncdfsf_fast_sse"
4136 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4138 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4139 "TARGET_SSE2 && TARGET_SSE_MATH"
4140 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4141 [(set_attr "type" "ssecvt")
4142 (set_attr "prefix" "maybe_vex")
4143 (set_attr "mode" "SF")])
4145 (define_insn "*truncdfsf_fast_i387"
4146 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4148 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4149 "TARGET_80387 && flag_unsafe_math_optimizations"
4150 "* return output_387_reg_move (insn, operands);"
4151 [(set_attr "type" "fmov")
4152 (set_attr "mode" "SF")])
4154 (define_insn "*truncdfsf_mixed"
4155 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4157 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4158 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4159 "TARGET_MIX_SSE_I387"
4161 switch (which_alternative)
4164 return output_387_reg_move (insn, operands);
4166 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4172 [(set_attr "isa" "*,sse2,*,*,*")
4173 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4174 (set_attr "unit" "*,*,i387,i387,i387")
4175 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4176 (set_attr "mode" "SF")])
4178 (define_insn "*truncdfsf_i387"
4179 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4181 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4182 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4185 switch (which_alternative)
4188 return output_387_reg_move (insn, operands);
4194 [(set_attr "type" "fmov,multi,multi,multi")
4195 (set_attr "unit" "*,i387,i387,i387")
4196 (set_attr "mode" "SF")])
4198 (define_insn "*truncdfsf2_i387_1"
4199 [(set (match_operand:SF 0 "memory_operand" "=m")
4201 (match_operand:DF 1 "register_operand" "f")))]
4203 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4204 && !TARGET_MIX_SSE_I387"
4205 "* return output_387_reg_move (insn, operands);"
4206 [(set_attr "type" "fmov")
4207 (set_attr "mode" "SF")])
4210 [(set (match_operand:SF 0 "register_operand")
4212 (match_operand:DF 1 "fp_register_operand")))
4213 (clobber (match_operand 2))]
4215 [(set (match_dup 2) (match_dup 1))
4216 (set (match_dup 0) (match_dup 2))]
4217 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4219 ;; Conversion from XFmode to {SF,DF}mode
4221 (define_expand "truncxf<mode>2"
4222 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4223 (float_truncate:MODEF
4224 (match_operand:XF 1 "register_operand")))
4225 (clobber (match_dup 2))])]
4228 if (flag_unsafe_math_optimizations)
4230 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4231 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4232 if (reg != operands[0])
4233 emit_move_insn (operands[0], reg);
4237 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4240 (define_insn "*truncxfsf2_mixed"
4241 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4243 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4244 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4247 gcc_assert (!which_alternative);
4248 return output_387_reg_move (insn, operands);
4250 [(set_attr "type" "fmov,multi,multi,multi")
4251 (set_attr "unit" "*,i387,i387,i387")
4252 (set_attr "mode" "SF")])
4254 (define_insn "*truncxfdf2_mixed"
4255 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4257 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4258 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4261 gcc_assert (!which_alternative);
4262 return output_387_reg_move (insn, operands);
4264 [(set_attr "isa" "*,*,sse2,*")
4265 (set_attr "type" "fmov,multi,multi,multi")
4266 (set_attr "unit" "*,i387,i387,i387")
4267 (set_attr "mode" "DF")])
4269 (define_insn "truncxf<mode>2_i387_noop"
4270 [(set (match_operand:MODEF 0 "register_operand" "=f")
4271 (float_truncate:MODEF
4272 (match_operand:XF 1 "register_operand" "f")))]
4273 "TARGET_80387 && flag_unsafe_math_optimizations"
4274 "* return output_387_reg_move (insn, operands);"
4275 [(set_attr "type" "fmov")
4276 (set_attr "mode" "<MODE>")])
4278 (define_insn "*truncxf<mode>2_i387"
4279 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4280 (float_truncate:MODEF
4281 (match_operand:XF 1 "register_operand" "f")))]
4283 "* return output_387_reg_move (insn, operands);"
4284 [(set_attr "type" "fmov")
4285 (set_attr "mode" "<MODE>")])
4288 [(set (match_operand:MODEF 0 "register_operand")
4289 (float_truncate:MODEF
4290 (match_operand:XF 1 "register_operand")))
4291 (clobber (match_operand:MODEF 2 "memory_operand"))]
4292 "TARGET_80387 && reload_completed"
4293 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4294 (set (match_dup 0) (match_dup 2))])
4297 [(set (match_operand:MODEF 0 "memory_operand")
4298 (float_truncate:MODEF
4299 (match_operand:XF 1 "register_operand")))
4300 (clobber (match_operand:MODEF 2 "memory_operand"))]
4302 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4304 ;; Signed conversion to DImode.
4306 (define_expand "fix_truncxfdi2"
4307 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4308 (fix:DI (match_operand:XF 1 "register_operand")))
4309 (clobber (reg:CC FLAGS_REG))])]
4314 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4319 (define_expand "fix_trunc<mode>di2"
4320 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4321 (fix:DI (match_operand:MODEF 1 "register_operand")))
4322 (clobber (reg:CC FLAGS_REG))])]
4323 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4326 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4328 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4331 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4333 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4334 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4335 if (out != operands[0])
4336 emit_move_insn (operands[0], out);
4341 ;; Signed conversion to SImode.
4343 (define_expand "fix_truncxfsi2"
4344 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4345 (fix:SI (match_operand:XF 1 "register_operand")))
4346 (clobber (reg:CC FLAGS_REG))])]
4351 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4356 (define_expand "fix_trunc<mode>si2"
4357 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4358 (fix:SI (match_operand:MODEF 1 "register_operand")))
4359 (clobber (reg:CC FLAGS_REG))])]
4360 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4363 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4365 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4368 if (SSE_FLOAT_MODE_P (<MODE>mode))
4370 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4371 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4372 if (out != operands[0])
4373 emit_move_insn (operands[0], out);
4378 ;; Signed conversion to HImode.
4380 (define_expand "fix_trunc<mode>hi2"
4381 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4382 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4383 (clobber (reg:CC FLAGS_REG))])]
4385 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4389 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4394 ;; Unsigned conversion to SImode.
4396 (define_expand "fixuns_trunc<mode>si2"
4398 [(set (match_operand:SI 0 "register_operand")
4400 (match_operand:MODEF 1 "nonimmediate_operand")))
4402 (clobber (match_scratch:<ssevecmode> 3))
4403 (clobber (match_scratch:<ssevecmode> 4))])]
4404 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4406 enum machine_mode mode = <MODE>mode;
4407 enum machine_mode vecmode = <ssevecmode>mode;
4408 REAL_VALUE_TYPE TWO31r;
4411 if (optimize_insn_for_size_p ())
4414 real_ldexp (&TWO31r, &dconst1, 31);
4415 two31 = const_double_from_real_value (TWO31r, mode);
4416 two31 = ix86_build_const_vector (vecmode, true, two31);
4417 operands[2] = force_reg (vecmode, two31);
4420 (define_insn_and_split "*fixuns_trunc<mode>_1"
4421 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4423 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4424 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4425 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4426 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4427 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4428 && optimize_function_for_speed_p (cfun)"
4430 "&& reload_completed"
4433 ix86_split_convert_uns_si_sse (operands);
4437 ;; Unsigned conversion to HImode.
4438 ;; Without these patterns, we'll try the unsigned SI conversion which
4439 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4441 (define_expand "fixuns_trunc<mode>hi2"
4443 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4444 (set (match_operand:HI 0 "nonimmediate_operand")
4445 (subreg:HI (match_dup 2) 0))]
4446 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4447 "operands[2] = gen_reg_rtx (SImode);")
4449 ;; When SSE is available, it is always faster to use it!
4450 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4451 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4452 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4453 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4454 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4455 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4456 [(set_attr "type" "sseicvt")
4457 (set_attr "prefix" "maybe_vex")
4458 (set (attr "prefix_rex")
4460 (match_test "<SWI48:MODE>mode == DImode")
4462 (const_string "*")))
4463 (set_attr "mode" "<MODEF:MODE>")
4464 (set_attr "athlon_decode" "double,vector")
4465 (set_attr "amdfam10_decode" "double,double")
4466 (set_attr "bdver1_decode" "double,double")])
4468 ;; Avoid vector decoded forms of the instruction.
4470 [(match_scratch:MODEF 2 "x")
4471 (set (match_operand:SWI48 0 "register_operand")
4472 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4473 "TARGET_AVOID_VECTOR_DECODE
4474 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4475 && optimize_insn_for_speed_p ()"
4476 [(set (match_dup 2) (match_dup 1))
4477 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4479 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4480 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4481 (fix:SWI248x (match_operand 1 "register_operand")))]
4482 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4484 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4485 && (TARGET_64BIT || <MODE>mode != DImode))
4487 && can_create_pseudo_p ()"
4492 if (memory_operand (operands[0], VOIDmode))
4493 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4496 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4497 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4503 [(set_attr "type" "fisttp")
4504 (set_attr "mode" "<MODE>")])
4506 (define_insn "fix_trunc<mode>_i387_fisttp"
4507 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4508 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4509 (clobber (match_scratch:XF 2 "=&1f"))]
4510 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4512 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4513 && (TARGET_64BIT || <MODE>mode != DImode))
4514 && TARGET_SSE_MATH)"
4515 "* return output_fix_trunc (insn, operands, true);"
4516 [(set_attr "type" "fisttp")
4517 (set_attr "mode" "<MODE>")])
4519 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4520 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4521 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4522 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4523 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4524 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4526 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4527 && (TARGET_64BIT || <MODE>mode != DImode))
4528 && TARGET_SSE_MATH)"
4530 [(set_attr "type" "fisttp")
4531 (set_attr "mode" "<MODE>")])
4534 [(set (match_operand:SWI248x 0 "register_operand")
4535 (fix:SWI248x (match_operand 1 "register_operand")))
4536 (clobber (match_operand:SWI248x 2 "memory_operand"))
4537 (clobber (match_scratch 3))]
4539 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4540 (clobber (match_dup 3))])
4541 (set (match_dup 0) (match_dup 2))])
4544 [(set (match_operand:SWI248x 0 "memory_operand")
4545 (fix:SWI248x (match_operand 1 "register_operand")))
4546 (clobber (match_operand:SWI248x 2 "memory_operand"))
4547 (clobber (match_scratch 3))]
4549 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4550 (clobber (match_dup 3))])])
4552 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4553 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4554 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4555 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4556 ;; function in i386.c.
4557 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4558 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4559 (fix:SWI248x (match_operand 1 "register_operand")))
4560 (clobber (reg:CC FLAGS_REG))]
4561 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4563 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4564 && (TARGET_64BIT || <MODE>mode != DImode))
4565 && can_create_pseudo_p ()"
4570 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4572 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4573 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4574 if (memory_operand (operands[0], VOIDmode))
4575 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4576 operands[2], operands[3]));
4579 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4580 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4581 operands[2], operands[3],
4586 [(set_attr "type" "fistp")
4587 (set_attr "i387_cw" "trunc")
4588 (set_attr "mode" "<MODE>")])
4590 (define_insn "fix_truncdi_i387"
4591 [(set (match_operand:DI 0 "memory_operand" "=m")
4592 (fix:DI (match_operand 1 "register_operand" "f")))
4593 (use (match_operand:HI 2 "memory_operand" "m"))
4594 (use (match_operand:HI 3 "memory_operand" "m"))
4595 (clobber (match_scratch:XF 4 "=&1f"))]
4596 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4598 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4599 "* return output_fix_trunc (insn, operands, false);"
4600 [(set_attr "type" "fistp")
4601 (set_attr "i387_cw" "trunc")
4602 (set_attr "mode" "DI")])
4604 (define_insn "fix_truncdi_i387_with_temp"
4605 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4606 (fix:DI (match_operand 1 "register_operand" "f,f")))
4607 (use (match_operand:HI 2 "memory_operand" "m,m"))
4608 (use (match_operand:HI 3 "memory_operand" "m,m"))
4609 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4610 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4611 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4613 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4615 [(set_attr "type" "fistp")
4616 (set_attr "i387_cw" "trunc")
4617 (set_attr "mode" "DI")])
4620 [(set (match_operand:DI 0 "register_operand")
4621 (fix:DI (match_operand 1 "register_operand")))
4622 (use (match_operand:HI 2 "memory_operand"))
4623 (use (match_operand:HI 3 "memory_operand"))
4624 (clobber (match_operand:DI 4 "memory_operand"))
4625 (clobber (match_scratch 5))]
4627 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4630 (clobber (match_dup 5))])
4631 (set (match_dup 0) (match_dup 4))])
4634 [(set (match_operand:DI 0 "memory_operand")
4635 (fix:DI (match_operand 1 "register_operand")))
4636 (use (match_operand:HI 2 "memory_operand"))
4637 (use (match_operand:HI 3 "memory_operand"))
4638 (clobber (match_operand:DI 4 "memory_operand"))
4639 (clobber (match_scratch 5))]
4641 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4644 (clobber (match_dup 5))])])
4646 (define_insn "fix_trunc<mode>_i387"
4647 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4648 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4649 (use (match_operand:HI 2 "memory_operand" "m"))
4650 (use (match_operand:HI 3 "memory_operand" "m"))]
4651 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4653 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4654 "* return output_fix_trunc (insn, operands, false);"
4655 [(set_attr "type" "fistp")
4656 (set_attr "i387_cw" "trunc")
4657 (set_attr "mode" "<MODE>")])
4659 (define_insn "fix_trunc<mode>_i387_with_temp"
4660 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4661 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4662 (use (match_operand:HI 2 "memory_operand" "m,m"))
4663 (use (match_operand:HI 3 "memory_operand" "m,m"))
4664 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4665 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4667 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4669 [(set_attr "type" "fistp")
4670 (set_attr "i387_cw" "trunc")
4671 (set_attr "mode" "<MODE>")])
4674 [(set (match_operand:SWI24 0 "register_operand")
4675 (fix:SWI24 (match_operand 1 "register_operand")))
4676 (use (match_operand:HI 2 "memory_operand"))
4677 (use (match_operand:HI 3 "memory_operand"))
4678 (clobber (match_operand:SWI24 4 "memory_operand"))]
4680 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4682 (use (match_dup 3))])
4683 (set (match_dup 0) (match_dup 4))])
4686 [(set (match_operand:SWI24 0 "memory_operand")
4687 (fix:SWI24 (match_operand 1 "register_operand")))
4688 (use (match_operand:HI 2 "memory_operand"))
4689 (use (match_operand:HI 3 "memory_operand"))
4690 (clobber (match_operand:SWI24 4 "memory_operand"))]
4692 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4694 (use (match_dup 3))])])
4696 (define_insn "x86_fnstcw_1"
4697 [(set (match_operand:HI 0 "memory_operand" "=m")
4698 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4701 [(set (attr "length")
4702 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4703 (set_attr "mode" "HI")
4704 (set_attr "unit" "i387")
4705 (set_attr "bdver1_decode" "vector")])
4707 (define_insn "x86_fldcw_1"
4708 [(set (reg:HI FPCR_REG)
4709 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4712 [(set (attr "length")
4713 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4714 (set_attr "mode" "HI")
4715 (set_attr "unit" "i387")
4716 (set_attr "athlon_decode" "vector")
4717 (set_attr "amdfam10_decode" "vector")
4718 (set_attr "bdver1_decode" "vector")])
4720 ;; Conversion between fixed point and floating point.
4722 ;; Even though we only accept memory inputs, the backend _really_
4723 ;; wants to be able to do this between registers.
4725 (define_expand "floathi<mode>2"
4726 [(set (match_operand:X87MODEF 0 "register_operand")
4727 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand")))]
4729 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4730 || TARGET_MIX_SSE_I387)")
4732 ;; Pre-reload splitter to add memory clobber to the pattern.
4733 (define_insn_and_split "*floathi<mode>2_1"
4734 [(set (match_operand:X87MODEF 0 "register_operand")
4735 (float:X87MODEF (match_operand:HI 1 "register_operand")))]
4737 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4738 || TARGET_MIX_SSE_I387)
4739 && can_create_pseudo_p ()"
4742 [(parallel [(set (match_dup 0)
4743 (float:X87MODEF (match_dup 1)))
4744 (clobber (match_dup 2))])]
4745 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4747 (define_insn "*floathi<mode>2_i387_with_temp"
4748 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4749 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4750 (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4752 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4753 || TARGET_MIX_SSE_I387)"
4755 [(set_attr "type" "fmov,multi")
4756 (set_attr "mode" "<MODE>")
4757 (set_attr "unit" "*,i387")
4758 (set_attr "fp_int_src" "true")])
4760 (define_insn "*floathi<mode>2_i387"
4761 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4762 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4764 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4765 || TARGET_MIX_SSE_I387)"
4767 [(set_attr "type" "fmov")
4768 (set_attr "mode" "<MODE>")
4769 (set_attr "fp_int_src" "true")])
4772 [(set (match_operand:X87MODEF 0 "register_operand")
4773 (float:X87MODEF (match_operand:HI 1 "register_operand")))
4774 (clobber (match_operand:HI 2 "memory_operand"))]
4776 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4777 || TARGET_MIX_SSE_I387)
4778 && reload_completed"
4779 [(set (match_dup 2) (match_dup 1))
4780 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4783 [(set (match_operand:X87MODEF 0 "register_operand")
4784 (float:X87MODEF (match_operand:HI 1 "memory_operand")))
4785 (clobber (match_operand:HI 2 "memory_operand"))]
4787 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4788 || TARGET_MIX_SSE_I387)
4789 && reload_completed"
4790 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4792 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4793 [(set (match_operand:X87MODEF 0 "register_operand")
4795 (match_operand:SWI48x 1 "nonimmediate_operand")))]
4797 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4798 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4800 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4801 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4802 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4804 rtx reg = gen_reg_rtx (XFmode);
4805 rtx (*insn)(rtx, rtx);
4807 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4809 if (<X87MODEF:MODE>mode == SFmode)
4810 insn = gen_truncxfsf2;
4811 else if (<X87MODEF:MODE>mode == DFmode)
4812 insn = gen_truncxfdf2;
4816 emit_insn (insn (operands[0], reg));
4821 ;; Pre-reload splitter to add memory clobber to the pattern.
4822 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4823 [(set (match_operand:X87MODEF 0 "register_operand")
4824 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))]
4826 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4827 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4828 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4829 || TARGET_MIX_SSE_I387))
4830 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4831 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4832 && ((<SWI48x:MODE>mode == SImode
4833 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4834 && optimize_function_for_speed_p (cfun)
4835 && flag_trapping_math)
4836 || !(TARGET_INTER_UNIT_CONVERSIONS
4837 || optimize_function_for_size_p (cfun)))))
4838 && can_create_pseudo_p ()"
4841 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4842 (clobber (match_dup 2))])]
4844 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4846 /* Avoid store forwarding (partial memory) stall penalty
4847 by passing DImode value through XMM registers. */
4848 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4849 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4850 && optimize_function_for_speed_p (cfun))
4852 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4859 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4860 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4862 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4863 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4864 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4865 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4867 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4868 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4869 (set_attr "unit" "*,i387,*,*,*")
4870 (set_attr "athlon_decode" "*,*,double,direct,double")
4871 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4872 (set_attr "bdver1_decode" "*,*,double,direct,double")
4873 (set_attr "fp_int_src" "true")])
4875 (define_insn "*floatsi<mode>2_vector_mixed"
4876 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4877 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4878 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4879 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4883 [(set_attr "type" "fmov,sseicvt")
4884 (set_attr "mode" "<MODE>,<ssevecmode>")
4885 (set_attr "unit" "i387,*")
4886 (set_attr "athlon_decode" "*,direct")
4887 (set_attr "amdfam10_decode" "*,double")
4888 (set_attr "bdver1_decode" "*,direct")
4889 (set_attr "fp_int_src" "true")])
4891 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_with_temp"
4892 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4894 (match_operand:SWI48 1 "nonimmediate_operand" "m,?r,r,m")))
4895 (clobber (match_operand:SWI48 2 "memory_operand" "=X,m,m,X"))]
4896 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4898 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4899 (set_attr "mode" "<MODEF:MODE>")
4900 (set_attr "unit" "*,i387,*,*")
4901 (set_attr "athlon_decode" "*,*,double,direct")
4902 (set_attr "amdfam10_decode" "*,*,vector,double")
4903 (set_attr "bdver1_decode" "*,*,double,direct")
4904 (set_attr "fp_int_src" "true")])
4907 [(set (match_operand:MODEF 0 "register_operand")
4908 (float:MODEF (match_operand:SWI48 1 "register_operand")))
4909 (clobber (match_operand:SWI48 2 "memory_operand"))]
4910 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4911 && TARGET_INTER_UNIT_CONVERSIONS
4913 && (SSE_REG_P (operands[0])
4914 || (GET_CODE (operands[0]) == SUBREG
4915 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4916 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4919 [(set (match_operand:MODEF 0 "register_operand")
4920 (float:MODEF (match_operand:SWI48 1 "register_operand")))
4921 (clobber (match_operand:SWI48 2 "memory_operand"))]
4922 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4923 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4925 && (SSE_REG_P (operands[0])
4926 || (GET_CODE (operands[0]) == SUBREG
4927 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4928 [(set (match_dup 2) (match_dup 1))
4929 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4931 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_interunit"
4932 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4934 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
4935 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4936 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4939 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
4940 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4941 [(set_attr "type" "fmov,sseicvt,sseicvt")
4942 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4943 (set_attr "mode" "<MODEF:MODE>")
4944 (set (attr "prefix_rex")
4946 (and (eq_attr "prefix" "maybe_vex")
4947 (match_test "<SWI48:MODE>mode == DImode"))
4949 (const_string "*")))
4950 (set_attr "unit" "i387,*,*")
4951 (set_attr "athlon_decode" "*,double,direct")
4952 (set_attr "amdfam10_decode" "*,vector,double")
4953 (set_attr "bdver1_decode" "*,double,direct")
4954 (set_attr "fp_int_src" "true")])
4956 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_nointerunit"
4957 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4959 (match_operand:SWI48 1 "memory_operand" "m,m")))]
4960 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4961 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4964 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4965 [(set_attr "type" "fmov,sseicvt")
4966 (set_attr "prefix" "orig,maybe_vex")
4967 (set_attr "mode" "<MODEF:MODE>")
4968 (set (attr "prefix_rex")
4970 (and (eq_attr "prefix" "maybe_vex")
4971 (match_test "<SWI48:MODE>mode == DImode"))
4973 (const_string "*")))
4974 (set_attr "athlon_decode" "*,direct")
4975 (set_attr "amdfam10_decode" "*,double")
4976 (set_attr "bdver1_decode" "*,direct")
4977 (set_attr "fp_int_src" "true")])
4979 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4980 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4982 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4983 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4984 "TARGET_SSE2 && TARGET_SSE_MATH
4985 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4987 [(set_attr "type" "sseicvt")
4988 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4989 (set_attr "athlon_decode" "double,direct,double")
4990 (set_attr "amdfam10_decode" "vector,double,double")
4991 (set_attr "bdver1_decode" "double,direct,double")
4992 (set_attr "fp_int_src" "true")])
4994 (define_insn "*floatsi<mode>2_vector_sse"
4995 [(set (match_operand:MODEF 0 "register_operand" "=x")
4996 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4997 "TARGET_SSE2 && TARGET_SSE_MATH
4998 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5000 [(set_attr "type" "sseicvt")
5001 (set_attr "mode" "<MODE>")
5002 (set_attr "athlon_decode" "direct")
5003 (set_attr "amdfam10_decode" "double")
5004 (set_attr "bdver1_decode" "direct")
5005 (set_attr "fp_int_src" "true")])
5008 [(set (match_operand:MODEF 0 "register_operand")
5009 (float:MODEF (match_operand:SI 1 "register_operand")))
5010 (clobber (match_operand:SI 2 "memory_operand"))]
5011 "TARGET_SSE2 && TARGET_SSE_MATH
5012 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5014 && (SSE_REG_P (operands[0])
5015 || (GET_CODE (operands[0]) == SUBREG
5016 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5019 rtx op1 = operands[1];
5021 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5023 if (GET_CODE (op1) == SUBREG)
5024 op1 = SUBREG_REG (op1);
5026 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5028 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5029 emit_insn (gen_sse2_loadld (operands[4],
5030 CONST0_RTX (V4SImode), operands[1]));
5032 /* We can ignore possible trapping value in the
5033 high part of SSE register for non-trapping math. */
5034 else if (SSE_REG_P (op1) && !flag_trapping_math)
5035 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5038 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5039 emit_move_insn (operands[2], operands[1]);
5040 emit_insn (gen_sse2_loadld (operands[4],
5041 CONST0_RTX (V4SImode), operands[2]));
5043 if (<ssevecmode>mode == V4SFmode)
5044 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5046 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5051 [(set (match_operand:MODEF 0 "register_operand")
5052 (float:MODEF (match_operand:SI 1 "memory_operand")))
5053 (clobber (match_operand:SI 2 "memory_operand"))]
5054 "TARGET_SSE2 && TARGET_SSE_MATH
5055 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5057 && (SSE_REG_P (operands[0])
5058 || (GET_CODE (operands[0]) == SUBREG
5059 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5062 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5064 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5066 emit_insn (gen_sse2_loadld (operands[4],
5067 CONST0_RTX (V4SImode), operands[1]));
5068 if (<ssevecmode>mode == V4SFmode)
5069 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5071 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5076 [(set (match_operand:MODEF 0 "register_operand")
5077 (float:MODEF (match_operand:SI 1 "register_operand")))]
5078 "TARGET_SSE2 && TARGET_SSE_MATH
5079 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5081 && (SSE_REG_P (operands[0])
5082 || (GET_CODE (operands[0]) == SUBREG
5083 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5086 rtx op1 = operands[1];
5088 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5090 if (GET_CODE (op1) == SUBREG)
5091 op1 = SUBREG_REG (op1);
5093 if (GENERAL_REG_P (op1))
5095 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5096 if (TARGET_INTER_UNIT_MOVES)
5097 emit_insn (gen_sse2_loadld (operands[4],
5098 CONST0_RTX (V4SImode), operands[1]));
5101 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5103 emit_insn (gen_sse2_loadld (operands[4],
5104 CONST0_RTX (V4SImode), operands[5]));
5105 ix86_free_from_memory (GET_MODE (operands[1]));
5108 /* We can ignore possible trapping value in the
5109 high part of SSE register for non-trapping math. */
5110 else if (SSE_REG_P (op1) && !flag_trapping_math)
5111 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5114 if (<ssevecmode>mode == V4SFmode)
5115 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5117 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5122 [(set (match_operand:MODEF 0 "register_operand")
5123 (float:MODEF (match_operand:SI 1 "memory_operand")))]
5124 "TARGET_SSE2 && TARGET_SSE_MATH
5125 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5127 && (SSE_REG_P (operands[0])
5128 || (GET_CODE (operands[0]) == SUBREG
5129 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5132 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5134 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5136 emit_insn (gen_sse2_loadld (operands[4],
5137 CONST0_RTX (V4SImode), operands[1]));
5138 if (<ssevecmode>mode == V4SFmode)
5139 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5141 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5145 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_with_temp"
5146 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5148 (match_operand:SWI48 1 "nonimmediate_operand" "r,m")))
5149 (clobber (match_operand:SWI48 2 "memory_operand" "=m,X"))]
5150 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5152 [(set_attr "type" "sseicvt")
5153 (set_attr "mode" "<MODEF:MODE>")
5154 (set_attr "athlon_decode" "double,direct")
5155 (set_attr "amdfam10_decode" "vector,double")
5156 (set_attr "bdver1_decode" "double,direct")
5157 (set_attr "btver2_decode" "double,double")
5158 (set_attr "fp_int_src" "true")])
5160 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_interunit"
5161 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5163 (match_operand:SWI48 1 "nonimmediate_operand" "r,m")))]
5164 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5165 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5166 "%vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5167 [(set_attr "type" "sseicvt")
5168 (set_attr "prefix" "maybe_vex")
5169 (set_attr "mode" "<MODEF:MODE>")
5170 (set (attr "prefix_rex")
5172 (and (eq_attr "prefix" "maybe_vex")
5173 (match_test "<SWI48:MODE>mode == DImode"))
5175 (const_string "*")))
5176 (set_attr "athlon_decode" "double,direct")
5177 (set_attr "amdfam10_decode" "vector,double")
5178 (set_attr "bdver1_decode" "double,direct")
5179 (set_attr "btver2_decode" "double,double")
5180 (set_attr "fp_int_src" "true")])
5183 [(set (match_operand:MODEF 0 "register_operand")
5184 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))
5185 (clobber (match_operand:SWI48 2 "memory_operand"))]
5186 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5187 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5189 && (SSE_REG_P (operands[0])
5190 || (GET_CODE (operands[0]) == SUBREG
5191 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5192 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5194 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_nointerunit"
5195 [(set (match_operand:MODEF 0 "register_operand" "=x")
5197 (match_operand:SWI48 1 "memory_operand" "m")))]
5198 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5199 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5200 "%vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
5201 [(set_attr "type" "sseicvt")
5202 (set_attr "prefix" "maybe_vex")
5203 (set_attr "mode" "<MODEF:MODE>")
5204 (set (attr "prefix_rex")
5206 (and (eq_attr "prefix" "maybe_vex")
5207 (match_test "<SWI48:MODE>mode == DImode"))
5209 (const_string "*")))
5210 (set_attr "athlon_decode" "direct")
5211 (set_attr "amdfam10_decode" "double")
5212 (set_attr "bdver1_decode" "direct")
5213 (set_attr "fp_int_src" "true")])
5216 [(set (match_operand:MODEF 0 "register_operand")
5217 (float:MODEF (match_operand:SWI48 1 "register_operand")))
5218 (clobber (match_operand:SWI48 2 "memory_operand"))]
5219 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5220 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5222 && (SSE_REG_P (operands[0])
5223 || (GET_CODE (operands[0]) == SUBREG
5224 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5225 [(set (match_dup 2) (match_dup 1))
5226 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5229 [(set (match_operand:MODEF 0 "register_operand")
5230 (float:MODEF (match_operand:SWI48 1 "memory_operand")))
5231 (clobber (match_operand:SWI48 2 "memory_operand"))]
5232 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5234 && (SSE_REG_P (operands[0])
5235 || (GET_CODE (operands[0]) == SUBREG
5236 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5237 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5239 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5240 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5242 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5243 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5245 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5249 [(set_attr "type" "fmov,multi")
5250 (set_attr "mode" "<X87MODEF:MODE>")
5251 (set_attr "unit" "*,i387")
5252 (set_attr "fp_int_src" "true")])
5254 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5255 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5257 (match_operand:SWI48x 1 "memory_operand" "m")))]
5259 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5261 [(set_attr "type" "fmov")
5262 (set_attr "mode" "<X87MODEF:MODE>")
5263 (set_attr "fp_int_src" "true")])
5266 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5267 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))
5268 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5270 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5271 && reload_completed"
5272 [(set (match_dup 2) (match_dup 1))
5273 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5276 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5277 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand")))
5278 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5280 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5281 && reload_completed"
5282 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5284 ;; Avoid store forwarding (partial memory) stall penalty
5285 ;; by passing DImode value through XMM registers. */
5287 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5288 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5290 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5291 (clobber (match_scratch:V4SI 3 "=X,x"))
5292 (clobber (match_scratch:V4SI 4 "=X,x"))
5293 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5294 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5295 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5296 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5298 [(set_attr "type" "multi")
5299 (set_attr "mode" "<X87MODEF:MODE>")
5300 (set_attr "unit" "i387")
5301 (set_attr "fp_int_src" "true")])
5304 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5305 (float:X87MODEF (match_operand:DI 1 "register_operand")))
5306 (clobber (match_scratch:V4SI 3))
5307 (clobber (match_scratch:V4SI 4))
5308 (clobber (match_operand:DI 2 "memory_operand"))]
5309 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5310 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5311 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5312 && reload_completed"
5313 [(set (match_dup 2) (match_dup 3))
5314 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5316 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5317 Assemble the 64-bit DImode value in an xmm register. */
5318 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5319 gen_rtx_SUBREG (SImode, operands[1], 0)));
5320 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5321 gen_rtx_SUBREG (SImode, operands[1], 4)));
5322 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5325 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5329 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5330 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5331 (clobber (match_scratch:V4SI 3))
5332 (clobber (match_scratch:V4SI 4))
5333 (clobber (match_operand:DI 2 "memory_operand"))]
5334 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5335 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5336 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5337 && reload_completed"
5338 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5340 ;; Avoid store forwarding (partial memory) stall penalty by extending
5341 ;; SImode value to DImode through XMM register instead of pushing two
5342 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5343 ;; targets benefit from this optimization. Also note that fild
5344 ;; loads from memory only.
5346 (define_insn "*floatunssi<mode>2_1"
5347 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5348 (unsigned_float:X87MODEF
5349 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5350 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5351 (clobber (match_scratch:SI 3 "=X,x"))]
5353 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5356 [(set_attr "type" "multi")
5357 (set_attr "mode" "<MODE>")])
5360 [(set (match_operand:X87MODEF 0 "register_operand")
5361 (unsigned_float:X87MODEF
5362 (match_operand:SI 1 "register_operand")))
5363 (clobber (match_operand:DI 2 "memory_operand"))
5364 (clobber (match_scratch:SI 3))]
5366 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5368 && reload_completed"
5369 [(set (match_dup 2) (match_dup 1))
5371 (float:X87MODEF (match_dup 2)))]
5372 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5375 [(set (match_operand:X87MODEF 0 "register_operand")
5376 (unsigned_float:X87MODEF
5377 (match_operand:SI 1 "memory_operand")))
5378 (clobber (match_operand:DI 2 "memory_operand"))
5379 (clobber (match_scratch:SI 3))]
5381 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5383 && reload_completed"
5384 [(set (match_dup 2) (match_dup 3))
5386 (float:X87MODEF (match_dup 2)))]
5388 emit_move_insn (operands[3], operands[1]);
5389 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5392 (define_expand "floatunssi<mode>2"
5394 [(set (match_operand:X87MODEF 0 "register_operand")
5395 (unsigned_float:X87MODEF
5396 (match_operand:SI 1 "nonimmediate_operand")))
5397 (clobber (match_dup 2))
5398 (clobber (match_scratch:SI 3))])]
5400 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5402 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5404 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5406 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5410 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5413 (define_expand "floatunsdisf2"
5414 [(use (match_operand:SF 0 "register_operand"))
5415 (use (match_operand:DI 1 "nonimmediate_operand"))]
5416 "TARGET_64BIT && TARGET_SSE_MATH"
5417 "x86_emit_floatuns (operands); DONE;")
5419 (define_expand "floatunsdidf2"
5420 [(use (match_operand:DF 0 "register_operand"))
5421 (use (match_operand:DI 1 "nonimmediate_operand"))]
5422 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5423 && TARGET_SSE2 && TARGET_SSE_MATH"
5426 x86_emit_floatuns (operands);
5428 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5432 ;; Load effective address instructions
5434 (define_insn_and_split "*lea<mode>"
5435 [(set (match_operand:SWI48 0 "register_operand" "=r")
5436 (match_operand:SWI48 1 "lea_address_operand" "p"))]
5439 if (SImode_address_operand (operands[1], VOIDmode))
5441 gcc_assert (TARGET_64BIT);
5442 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5445 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5447 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5450 enum machine_mode mode = <MODE>mode;
5453 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5454 change operands[] array behind our back. */
5455 pat = PATTERN (curr_insn);
5457 operands[0] = SET_DEST (pat);
5458 operands[1] = SET_SRC (pat);
5460 /* Emit all operations in SImode for zero-extended addresses. Recall
5461 that x86_64 inheretly zero-extends SImode operations to DImode. */
5462 if (SImode_address_operand (operands[1], VOIDmode))
5465 ix86_split_lea_for_addr (curr_insn, operands, mode);
5467 /* Zero-extend return register to DImode for zero-extended addresses. */
5468 if (mode != <MODE>mode)
5469 emit_insn (gen_zero_extendsidi2
5470 (operands[0], gen_lowpart (mode, operands[0])));
5474 [(set_attr "type" "lea")
5477 (match_operand 1 "SImode_address_operand")
5479 (const_string "<MODE>")))])
5483 (define_expand "add<mode>3"
5484 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5485 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5486 (match_operand:SDWIM 2 "<general_operand>")))]
5488 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5490 (define_insn_and_split "*add<dwi>3_doubleword"
5491 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5493 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5494 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5495 (clobber (reg:CC FLAGS_REG))]
5496 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5499 [(parallel [(set (reg:CC FLAGS_REG)
5500 (unspec:CC [(match_dup 1) (match_dup 2)]
5503 (plus:DWIH (match_dup 1) (match_dup 2)))])
5504 (parallel [(set (match_dup 3)
5508 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5510 (clobber (reg:CC FLAGS_REG))])]
5511 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5513 (define_insn "*add<mode>3_cc"
5514 [(set (reg:CC FLAGS_REG)
5516 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5517 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5519 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5520 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5521 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5522 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5523 [(set_attr "type" "alu")
5524 (set_attr "mode" "<MODE>")])
5526 (define_insn "addqi3_cc"
5527 [(set (reg:CC FLAGS_REG)
5529 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5530 (match_operand:QI 2 "general_operand" "qn,qm")]
5532 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5533 (plus:QI (match_dup 1) (match_dup 2)))]
5534 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5535 "add{b}\t{%2, %0|%0, %2}"
5536 [(set_attr "type" "alu")
5537 (set_attr "mode" "QI")])
5539 (define_insn "*add<mode>_1"
5540 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5542 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5543 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5544 (clobber (reg:CC FLAGS_REG))]
5545 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5547 switch (get_attr_type (insn))
5553 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5554 if (operands[2] == const1_rtx)
5555 return "inc{<imodesuffix>}\t%0";
5558 gcc_assert (operands[2] == constm1_rtx);
5559 return "dec{<imodesuffix>}\t%0";
5563 /* For most processors, ADD is faster than LEA. This alternative
5564 was added to use ADD as much as possible. */
5565 if (which_alternative == 2)
5568 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5571 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5572 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5573 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5575 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5579 (cond [(eq_attr "alternative" "3")
5580 (const_string "lea")
5581 (match_operand:SWI48 2 "incdec_operand")
5582 (const_string "incdec")
5584 (const_string "alu")))
5585 (set (attr "length_immediate")
5587 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5589 (const_string "*")))
5590 (set_attr "mode" "<MODE>")])
5592 ;; It may seem that nonimmediate operand is proper one for operand 1.
5593 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5594 ;; we take care in ix86_binary_operator_ok to not allow two memory
5595 ;; operands so proper swapping will be done in reload. This allow
5596 ;; patterns constructed from addsi_1 to match.
5598 (define_insn "addsi_1_zext"
5599 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5601 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5602 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5603 (clobber (reg:CC FLAGS_REG))]
5604 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5606 switch (get_attr_type (insn))
5612 if (operands[2] == const1_rtx)
5613 return "inc{l}\t%k0";
5616 gcc_assert (operands[2] == constm1_rtx);
5617 return "dec{l}\t%k0";
5621 /* For most processors, ADD is faster than LEA. This alternative
5622 was added to use ADD as much as possible. */
5623 if (which_alternative == 1)
5626 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5629 if (x86_maybe_negate_const_int (&operands[2], SImode))
5630 return "sub{l}\t{%2, %k0|%k0, %2}";
5632 return "add{l}\t{%2, %k0|%k0, %2}";
5636 (cond [(eq_attr "alternative" "2")
5637 (const_string "lea")
5638 (match_operand:SI 2 "incdec_operand")
5639 (const_string "incdec")
5641 (const_string "alu")))
5642 (set (attr "length_immediate")
5644 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5646 (const_string "*")))
5647 (set_attr "mode" "SI")])
5649 (define_insn "*addhi_1"
5650 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5651 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5652 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5653 (clobber (reg:CC FLAGS_REG))]
5654 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5656 switch (get_attr_type (insn))
5662 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5663 if (operands[2] == const1_rtx)
5664 return "inc{w}\t%0";
5667 gcc_assert (operands[2] == constm1_rtx);
5668 return "dec{w}\t%0";
5672 /* For most processors, ADD is faster than LEA. This alternative
5673 was added to use ADD as much as possible. */
5674 if (which_alternative == 2)
5677 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5680 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5681 if (x86_maybe_negate_const_int (&operands[2], HImode))
5682 return "sub{w}\t{%2, %0|%0, %2}";
5684 return "add{w}\t{%2, %0|%0, %2}";
5688 (cond [(eq_attr "alternative" "3")
5689 (const_string "lea")
5690 (match_operand:HI 2 "incdec_operand")
5691 (const_string "incdec")
5693 (const_string "alu")))
5694 (set (attr "length_immediate")
5696 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5698 (const_string "*")))
5699 (set_attr "mode" "HI,HI,HI,SI")])
5701 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5702 (define_insn "*addqi_1"
5703 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5704 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5705 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5706 (clobber (reg:CC FLAGS_REG))]
5707 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5709 bool widen = (which_alternative == 3 || which_alternative == 4);
5711 switch (get_attr_type (insn))
5717 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5718 if (operands[2] == const1_rtx)
5719 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5722 gcc_assert (operands[2] == constm1_rtx);
5723 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5727 /* For most processors, ADD is faster than LEA. These alternatives
5728 were added to use ADD as much as possible. */
5729 if (which_alternative == 2 || which_alternative == 4)
5732 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5735 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5736 if (x86_maybe_negate_const_int (&operands[2], QImode))
5739 return "sub{l}\t{%2, %k0|%k0, %2}";
5741 return "sub{b}\t{%2, %0|%0, %2}";
5744 return "add{l}\t{%k2, %k0|%k0, %k2}";
5746 return "add{b}\t{%2, %0|%0, %2}";
5750 (cond [(eq_attr "alternative" "5")
5751 (const_string "lea")
5752 (match_operand:QI 2 "incdec_operand")
5753 (const_string "incdec")
5755 (const_string "alu")))
5756 (set (attr "length_immediate")
5758 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5760 (const_string "*")))
5761 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5763 (define_insn "*addqi_1_slp"
5764 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5765 (plus:QI (match_dup 0)
5766 (match_operand:QI 1 "general_operand" "qn,qm")))
5767 (clobber (reg:CC FLAGS_REG))]
5768 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5769 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5771 switch (get_attr_type (insn))
5774 if (operands[1] == const1_rtx)
5775 return "inc{b}\t%0";
5778 gcc_assert (operands[1] == constm1_rtx);
5779 return "dec{b}\t%0";
5783 if (x86_maybe_negate_const_int (&operands[1], QImode))
5784 return "sub{b}\t{%1, %0|%0, %1}";
5786 return "add{b}\t{%1, %0|%0, %1}";
5790 (if_then_else (match_operand:QI 1 "incdec_operand")
5791 (const_string "incdec")
5792 (const_string "alu1")))
5793 (set (attr "memory")
5794 (if_then_else (match_operand 1 "memory_operand")
5795 (const_string "load")
5796 (const_string "none")))
5797 (set_attr "mode" "QI")])
5799 ;; Split non destructive adds if we cannot use lea.
5801 [(set (match_operand:SWI48 0 "register_operand")
5802 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5803 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5804 (clobber (reg:CC FLAGS_REG))]
5805 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5806 [(set (match_dup 0) (match_dup 1))
5807 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5808 (clobber (reg:CC FLAGS_REG))])])
5810 ;; Convert add to the lea pattern to avoid flags dependency.
5812 [(set (match_operand:SWI 0 "register_operand")
5813 (plus:SWI (match_operand:SWI 1 "register_operand")
5814 (match_operand:SWI 2 "<nonmemory_operand>")))
5815 (clobber (reg:CC FLAGS_REG))]
5816 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5819 enum machine_mode mode = <MODE>mode;
5822 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5825 operands[0] = gen_lowpart (mode, operands[0]);
5826 operands[1] = gen_lowpart (mode, operands[1]);
5827 operands[2] = gen_lowpart (mode, operands[2]);
5830 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5832 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5836 ;; Split non destructive adds if we cannot use lea.
5838 [(set (match_operand:DI 0 "register_operand")
5840 (plus:SI (match_operand:SI 1 "register_operand")
5841 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5842 (clobber (reg:CC FLAGS_REG))]
5844 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5845 [(set (match_dup 3) (match_dup 1))
5846 (parallel [(set (match_dup 0)
5847 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5848 (clobber (reg:CC FLAGS_REG))])]
5849 "operands[3] = gen_lowpart (SImode, operands[0]);")
5851 ;; Convert add to the lea pattern to avoid flags dependency.
5853 [(set (match_operand:DI 0 "register_operand")
5855 (plus:SI (match_operand:SI 1 "register_operand")
5856 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5857 (clobber (reg:CC FLAGS_REG))]
5858 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5860 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5862 (define_insn "*add<mode>_2"
5863 [(set (reg FLAGS_REG)
5866 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5867 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5869 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5870 (plus:SWI (match_dup 1) (match_dup 2)))]
5871 "ix86_match_ccmode (insn, CCGOCmode)
5872 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5874 switch (get_attr_type (insn))
5877 if (operands[2] == const1_rtx)
5878 return "inc{<imodesuffix>}\t%0";
5881 gcc_assert (operands[2] == constm1_rtx);
5882 return "dec{<imodesuffix>}\t%0";
5886 if (which_alternative == 2)
5889 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5892 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5893 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5894 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5896 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5900 (if_then_else (match_operand:SWI 2 "incdec_operand")
5901 (const_string "incdec")
5902 (const_string "alu")))
5903 (set (attr "length_immediate")
5905 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5907 (const_string "*")))
5908 (set_attr "mode" "<MODE>")])
5910 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5911 (define_insn "*addsi_2_zext"
5912 [(set (reg FLAGS_REG)
5914 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5915 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5917 (set (match_operand:DI 0 "register_operand" "=r,r")
5918 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5919 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5920 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5922 switch (get_attr_type (insn))
5925 if (operands[2] == const1_rtx)
5926 return "inc{l}\t%k0";
5929 gcc_assert (operands[2] == constm1_rtx);
5930 return "dec{l}\t%k0";
5934 if (which_alternative == 1)
5937 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5940 if (x86_maybe_negate_const_int (&operands[2], SImode))
5941 return "sub{l}\t{%2, %k0|%k0, %2}";
5943 return "add{l}\t{%2, %k0|%k0, %2}";
5947 (if_then_else (match_operand:SI 2 "incdec_operand")
5948 (const_string "incdec")
5949 (const_string "alu")))
5950 (set (attr "length_immediate")
5952 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5954 (const_string "*")))
5955 (set_attr "mode" "SI")])
5957 (define_insn "*add<mode>_3"
5958 [(set (reg FLAGS_REG)
5960 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5961 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5962 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5963 "ix86_match_ccmode (insn, CCZmode)
5964 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5966 switch (get_attr_type (insn))
5969 if (operands[2] == const1_rtx)
5970 return "inc{<imodesuffix>}\t%0";
5973 gcc_assert (operands[2] == constm1_rtx);
5974 return "dec{<imodesuffix>}\t%0";
5978 if (which_alternative == 1)
5981 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5984 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5985 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5986 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5988 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5992 (if_then_else (match_operand:SWI 2 "incdec_operand")
5993 (const_string "incdec")
5994 (const_string "alu")))
5995 (set (attr "length_immediate")
5997 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5999 (const_string "*")))
6000 (set_attr "mode" "<MODE>")])
6002 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6003 (define_insn "*addsi_3_zext"
6004 [(set (reg FLAGS_REG)
6006 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
6007 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
6008 (set (match_operand:DI 0 "register_operand" "=r,r")
6009 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6010 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6011 && ix86_binary_operator_ok (PLUS, SImode, operands)"
6013 switch (get_attr_type (insn))
6016 if (operands[2] == const1_rtx)
6017 return "inc{l}\t%k0";
6020 gcc_assert (operands[2] == constm1_rtx);
6021 return "dec{l}\t%k0";
6025 if (which_alternative == 1)
6028 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6031 if (x86_maybe_negate_const_int (&operands[2], SImode))
6032 return "sub{l}\t{%2, %k0|%k0, %2}";
6034 return "add{l}\t{%2, %k0|%k0, %2}";
6038 (if_then_else (match_operand:SI 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" "SI")])
6048 ; For comparisons against 1, -1 and 128, we may generate better code
6049 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6050 ; is matched then. We can't accept general immediate, because for
6051 ; case of overflows, the result is messed up.
6052 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6053 ; only for comparisons not depending on it.
6055 (define_insn "*adddi_4"
6056 [(set (reg FLAGS_REG)
6058 (match_operand:DI 1 "nonimmediate_operand" "0")
6059 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6060 (clobber (match_scratch:DI 0 "=rm"))]
6062 && ix86_match_ccmode (insn, CCGCmode)"
6064 switch (get_attr_type (insn))
6067 if (operands[2] == constm1_rtx)
6068 return "inc{q}\t%0";
6071 gcc_assert (operands[2] == const1_rtx);
6072 return "dec{q}\t%0";
6076 if (x86_maybe_negate_const_int (&operands[2], DImode))
6077 return "add{q}\t{%2, %0|%0, %2}";
6079 return "sub{q}\t{%2, %0|%0, %2}";
6083 (if_then_else (match_operand:DI 2 "incdec_operand")
6084 (const_string "incdec")
6085 (const_string "alu")))
6086 (set (attr "length_immediate")
6088 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6090 (const_string "*")))
6091 (set_attr "mode" "DI")])
6093 ; For comparisons against 1, -1 and 128, we may generate better code
6094 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6095 ; is matched then. We can't accept general immediate, because for
6096 ; case of overflows, the result is messed up.
6097 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6098 ; only for comparisons not depending on it.
6100 (define_insn "*add<mode>_4"
6101 [(set (reg FLAGS_REG)
6103 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6104 (match_operand:SWI124 2 "const_int_operand" "n")))
6105 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6106 "ix86_match_ccmode (insn, CCGCmode)"
6108 switch (get_attr_type (insn))
6111 if (operands[2] == constm1_rtx)
6112 return "inc{<imodesuffix>}\t%0";
6115 gcc_assert (operands[2] == const1_rtx);
6116 return "dec{<imodesuffix>}\t%0";
6120 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6121 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6123 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6127 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6128 (const_string "incdec")
6129 (const_string "alu")))
6130 (set (attr "length_immediate")
6132 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6134 (const_string "*")))
6135 (set_attr "mode" "<MODE>")])
6137 (define_insn "*add<mode>_5"
6138 [(set (reg FLAGS_REG)
6141 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6142 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6144 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6145 "ix86_match_ccmode (insn, CCGOCmode)
6146 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6148 switch (get_attr_type (insn))
6151 if (operands[2] == const1_rtx)
6152 return "inc{<imodesuffix>}\t%0";
6155 gcc_assert (operands[2] == constm1_rtx);
6156 return "dec{<imodesuffix>}\t%0";
6160 if (which_alternative == 1)
6163 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6166 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6167 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6168 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6170 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6174 (if_then_else (match_operand:SWI 2 "incdec_operand")
6175 (const_string "incdec")
6176 (const_string "alu")))
6177 (set (attr "length_immediate")
6179 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6181 (const_string "*")))
6182 (set_attr "mode" "<MODE>")])
6184 (define_insn "*addqi_ext_1_rex64"
6185 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6190 (match_operand 1 "ext_register_operand" "0")
6193 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6194 (clobber (reg:CC FLAGS_REG))]
6197 switch (get_attr_type (insn))
6200 if (operands[2] == const1_rtx)
6201 return "inc{b}\t%h0";
6204 gcc_assert (operands[2] == constm1_rtx);
6205 return "dec{b}\t%h0";
6209 return "add{b}\t{%2, %h0|%h0, %2}";
6213 (if_then_else (match_operand:QI 2 "incdec_operand")
6214 (const_string "incdec")
6215 (const_string "alu")))
6216 (set_attr "modrm" "1")
6217 (set_attr "mode" "QI")])
6219 (define_insn "addqi_ext_1"
6220 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6225 (match_operand 1 "ext_register_operand" "0")
6228 (match_operand:QI 2 "general_operand" "Qmn")))
6229 (clobber (reg:CC FLAGS_REG))]
6232 switch (get_attr_type (insn))
6235 if (operands[2] == const1_rtx)
6236 return "inc{b}\t%h0";
6239 gcc_assert (operands[2] == constm1_rtx);
6240 return "dec{b}\t%h0";
6244 return "add{b}\t{%2, %h0|%h0, %2}";
6248 (if_then_else (match_operand:QI 2 "incdec_operand")
6249 (const_string "incdec")
6250 (const_string "alu")))
6251 (set_attr "modrm" "1")
6252 (set_attr "mode" "QI")])
6254 (define_insn "*addqi_ext_2"
6255 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6260 (match_operand 1 "ext_register_operand" "%0")
6264 (match_operand 2 "ext_register_operand" "Q")
6267 (clobber (reg:CC FLAGS_REG))]
6269 "add{b}\t{%h2, %h0|%h0, %h2}"
6270 [(set_attr "type" "alu")
6271 (set_attr "mode" "QI")])
6273 ;; The lea patterns for modes less than 32 bits need to be matched by
6274 ;; several insns converted to real lea by splitters.
6276 (define_insn_and_split "*lea_general_1"
6277 [(set (match_operand 0 "register_operand" "=r")
6278 (plus (plus (match_operand 1 "index_register_operand" "l")
6279 (match_operand 2 "register_operand" "r"))
6280 (match_operand 3 "immediate_operand" "i")))]
6281 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6282 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6283 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6284 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6285 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6286 || GET_MODE (operands[3]) == VOIDmode)"
6288 "&& reload_completed"
6291 enum machine_mode mode = SImode;
6294 operands[0] = gen_lowpart (mode, operands[0]);
6295 operands[1] = gen_lowpart (mode, operands[1]);
6296 operands[2] = gen_lowpart (mode, operands[2]);
6297 operands[3] = gen_lowpart (mode, operands[3]);
6299 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6302 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6305 [(set_attr "type" "lea")
6306 (set_attr "mode" "SI")])
6308 (define_insn_and_split "*lea_general_2"
6309 [(set (match_operand 0 "register_operand" "=r")
6310 (plus (mult (match_operand 1 "index_register_operand" "l")
6311 (match_operand 2 "const248_operand" "n"))
6312 (match_operand 3 "nonmemory_operand" "ri")))]
6313 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6314 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6315 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6316 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6317 || GET_MODE (operands[3]) == VOIDmode)"
6319 "&& reload_completed"
6322 enum machine_mode mode = SImode;
6325 operands[0] = gen_lowpart (mode, operands[0]);
6326 operands[1] = gen_lowpart (mode, operands[1]);
6327 operands[3] = gen_lowpart (mode, operands[3]);
6329 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6332 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6335 [(set_attr "type" "lea")
6336 (set_attr "mode" "SI")])
6338 (define_insn_and_split "*lea_general_3"
6339 [(set (match_operand 0 "register_operand" "=r")
6340 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6341 (match_operand 2 "const248_operand" "n"))
6342 (match_operand 3 "register_operand" "r"))
6343 (match_operand 4 "immediate_operand" "i")))]
6344 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6345 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6346 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6347 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6349 "&& reload_completed"
6352 enum machine_mode mode = SImode;
6355 operands[0] = gen_lowpart (mode, operands[0]);
6356 operands[1] = gen_lowpart (mode, operands[1]);
6357 operands[3] = gen_lowpart (mode, operands[3]);
6358 operands[4] = gen_lowpart (mode, operands[4]);
6360 pat = gen_rtx_PLUS (mode,
6362 gen_rtx_MULT (mode, operands[1],
6367 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6370 [(set_attr "type" "lea")
6371 (set_attr "mode" "SI")])
6373 (define_insn_and_split "*lea_general_4"
6374 [(set (match_operand 0 "register_operand" "=r")
6376 (match_operand 1 "index_register_operand" "l")
6377 (match_operand 2 "const_int_operand" "n"))
6378 (match_operand 3 "const_int_operand" "n")))]
6379 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6380 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6381 || GET_MODE (operands[0]) == SImode
6382 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6383 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6384 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6385 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6386 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6388 "&& reload_completed"
6391 enum machine_mode mode = GET_MODE (operands[0]);
6394 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6397 operands[0] = gen_lowpart (mode, operands[0]);
6398 operands[1] = gen_lowpart (mode, operands[1]);
6401 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6403 pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6404 INTVAL (operands[3]));
6406 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6409 [(set_attr "type" "lea")
6411 (if_then_else (match_operand:DI 0)
6413 (const_string "SI")))])
6415 ;; Subtract instructions
6417 (define_expand "sub<mode>3"
6418 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6419 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6420 (match_operand:SDWIM 2 "<general_operand>")))]
6422 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6424 (define_insn_and_split "*sub<dwi>3_doubleword"
6425 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6427 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6428 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6429 (clobber (reg:CC FLAGS_REG))]
6430 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6433 [(parallel [(set (reg:CC FLAGS_REG)
6434 (compare:CC (match_dup 1) (match_dup 2)))
6436 (minus:DWIH (match_dup 1) (match_dup 2)))])
6437 (parallel [(set (match_dup 3)
6441 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6443 (clobber (reg:CC FLAGS_REG))])]
6444 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6446 (define_insn "*sub<mode>_1"
6447 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6449 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6450 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6451 (clobber (reg:CC FLAGS_REG))]
6452 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6453 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6454 [(set_attr "type" "alu")
6455 (set_attr "mode" "<MODE>")])
6457 (define_insn "*subsi_1_zext"
6458 [(set (match_operand:DI 0 "register_operand" "=r")
6460 (minus:SI (match_operand:SI 1 "register_operand" "0")
6461 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6462 (clobber (reg:CC FLAGS_REG))]
6463 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6464 "sub{l}\t{%2, %k0|%k0, %2}"
6465 [(set_attr "type" "alu")
6466 (set_attr "mode" "SI")])
6468 (define_insn "*subqi_1_slp"
6469 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6470 (minus:QI (match_dup 0)
6471 (match_operand:QI 1 "general_operand" "qn,qm")))
6472 (clobber (reg:CC FLAGS_REG))]
6473 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6474 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6475 "sub{b}\t{%1, %0|%0, %1}"
6476 [(set_attr "type" "alu1")
6477 (set_attr "mode" "QI")])
6479 (define_insn "*sub<mode>_2"
6480 [(set (reg FLAGS_REG)
6483 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6484 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6486 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6487 (minus:SWI (match_dup 1) (match_dup 2)))]
6488 "ix86_match_ccmode (insn, CCGOCmode)
6489 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6490 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6491 [(set_attr "type" "alu")
6492 (set_attr "mode" "<MODE>")])
6494 (define_insn "*subsi_2_zext"
6495 [(set (reg FLAGS_REG)
6497 (minus:SI (match_operand:SI 1 "register_operand" "0")
6498 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6500 (set (match_operand:DI 0 "register_operand" "=r")
6502 (minus:SI (match_dup 1)
6504 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6505 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6506 "sub{l}\t{%2, %k0|%k0, %2}"
6507 [(set_attr "type" "alu")
6508 (set_attr "mode" "SI")])
6510 (define_insn "*sub<mode>_3"
6511 [(set (reg FLAGS_REG)
6512 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6513 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6514 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6515 (minus:SWI (match_dup 1) (match_dup 2)))]
6516 "ix86_match_ccmode (insn, CCmode)
6517 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6518 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6519 [(set_attr "type" "alu")
6520 (set_attr "mode" "<MODE>")])
6522 (define_insn "*subsi_3_zext"
6523 [(set (reg FLAGS_REG)
6524 (compare (match_operand:SI 1 "register_operand" "0")
6525 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6526 (set (match_operand:DI 0 "register_operand" "=r")
6528 (minus:SI (match_dup 1)
6530 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6531 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6532 "sub{l}\t{%2, %1|%1, %2}"
6533 [(set_attr "type" "alu")
6534 (set_attr "mode" "SI")])
6536 ;; Add with carry and subtract with borrow
6538 (define_expand "<plusminus_insn><mode>3_carry"
6540 [(set (match_operand:SWI 0 "nonimmediate_operand")
6542 (match_operand:SWI 1 "nonimmediate_operand")
6543 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6544 [(match_operand 3 "flags_reg_operand")
6546 (match_operand:SWI 2 "<general_operand>"))))
6547 (clobber (reg:CC FLAGS_REG))])]
6548 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6550 (define_insn "*<plusminus_insn><mode>3_carry"
6551 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6553 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6555 (match_operator 3 "ix86_carry_flag_operator"
6556 [(reg FLAGS_REG) (const_int 0)])
6557 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6558 (clobber (reg:CC FLAGS_REG))]
6559 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6560 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6561 [(set_attr "type" "alu")
6562 (set_attr "use_carry" "1")
6563 (set_attr "pent_pair" "pu")
6564 (set_attr "mode" "<MODE>")])
6566 (define_insn "*addsi3_carry_zext"
6567 [(set (match_operand:DI 0 "register_operand" "=r")
6569 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6570 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6571 [(reg FLAGS_REG) (const_int 0)])
6572 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6573 (clobber (reg:CC FLAGS_REG))]
6574 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6575 "adc{l}\t{%2, %k0|%k0, %2}"
6576 [(set_attr "type" "alu")
6577 (set_attr "use_carry" "1")
6578 (set_attr "pent_pair" "pu")
6579 (set_attr "mode" "SI")])
6581 (define_insn "*subsi3_carry_zext"
6582 [(set (match_operand:DI 0 "register_operand" "=r")
6584 (minus:SI (match_operand:SI 1 "register_operand" "0")
6585 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6586 [(reg FLAGS_REG) (const_int 0)])
6587 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6588 (clobber (reg:CC FLAGS_REG))]
6589 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6590 "sbb{l}\t{%2, %k0|%k0, %2}"
6591 [(set_attr "type" "alu")
6592 (set_attr "pent_pair" "pu")
6593 (set_attr "mode" "SI")])
6597 (define_insn "adcx<mode>3"
6598 [(set (reg:CCC FLAGS_REG)
6601 (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6603 (match_operator 4 "ix86_carry_flag_operator"
6604 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6605 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6607 (set (match_operand:SWI48 0 "register_operand" "=r")
6608 (plus:SWI48 (match_dup 1)
6609 (plus:SWI48 (match_op_dup 4
6610 [(match_dup 3) (const_int 0)])
6612 "TARGET_ADX && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6613 "adcx\t{%2, %0|%0, %2}"
6614 [(set_attr "type" "alu")
6615 (set_attr "use_carry" "1")
6616 (set_attr "mode" "<MODE>")])
6618 ;; Overflow setting add instructions
6620 (define_insn "*add<mode>3_cconly_overflow"
6621 [(set (reg:CCC FLAGS_REG)
6624 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6625 (match_operand:SWI 2 "<general_operand>" "<g>"))
6627 (clobber (match_scratch:SWI 0 "=<r>"))]
6628 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6629 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6630 [(set_attr "type" "alu")
6631 (set_attr "mode" "<MODE>")])
6633 (define_insn "*add<mode>3_cc_overflow"
6634 [(set (reg:CCC FLAGS_REG)
6637 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6638 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6640 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6641 (plus:SWI (match_dup 1) (match_dup 2)))]
6642 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6643 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6644 [(set_attr "type" "alu")
6645 (set_attr "mode" "<MODE>")])
6647 (define_insn "*addsi3_zext_cc_overflow"
6648 [(set (reg:CCC FLAGS_REG)
6651 (match_operand:SI 1 "nonimmediate_operand" "%0")
6652 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6654 (set (match_operand:DI 0 "register_operand" "=r")
6655 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6656 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6657 "add{l}\t{%2, %k0|%k0, %2}"
6658 [(set_attr "type" "alu")
6659 (set_attr "mode" "SI")])
6661 ;; The patterns that match these are at the end of this file.
6663 (define_expand "<plusminus_insn>xf3"
6664 [(set (match_operand:XF 0 "register_operand")
6666 (match_operand:XF 1 "register_operand")
6667 (match_operand:XF 2 "register_operand")))]
6670 (define_expand "<plusminus_insn><mode>3"
6671 [(set (match_operand:MODEF 0 "register_operand")
6673 (match_operand:MODEF 1 "register_operand")
6674 (match_operand:MODEF 2 "nonimmediate_operand")))]
6675 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6676 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6678 ;; Multiply instructions
6680 (define_expand "mul<mode>3"
6681 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6683 (match_operand:SWIM248 1 "register_operand")
6684 (match_operand:SWIM248 2 "<general_operand>")))
6685 (clobber (reg:CC FLAGS_REG))])])
6687 (define_expand "mulqi3"
6688 [(parallel [(set (match_operand:QI 0 "register_operand")
6690 (match_operand:QI 1 "register_operand")
6691 (match_operand:QI 2 "nonimmediate_operand")))
6692 (clobber (reg:CC FLAGS_REG))])]
6693 "TARGET_QIMODE_MATH")
6696 ;; IMUL reg32/64, reg32/64, imm8 Direct
6697 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6698 ;; IMUL reg32/64, reg32/64, imm32 Direct
6699 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6700 ;; IMUL reg32/64, reg32/64 Direct
6701 ;; IMUL reg32/64, mem32/64 Direct
6703 ;; On BDVER1, all above IMULs use DirectPath
6705 (define_insn "*mul<mode>3_1"
6706 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6708 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6709 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6710 (clobber (reg:CC FLAGS_REG))]
6711 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6713 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6714 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6715 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6716 [(set_attr "type" "imul")
6717 (set_attr "prefix_0f" "0,0,1")
6718 (set (attr "athlon_decode")
6719 (cond [(eq_attr "cpu" "athlon")
6720 (const_string "vector")
6721 (eq_attr "alternative" "1")
6722 (const_string "vector")
6723 (and (eq_attr "alternative" "2")
6724 (match_operand 1 "memory_operand"))
6725 (const_string "vector")]
6726 (const_string "direct")))
6727 (set (attr "amdfam10_decode")
6728 (cond [(and (eq_attr "alternative" "0,1")
6729 (match_operand 1 "memory_operand"))
6730 (const_string "vector")]
6731 (const_string "direct")))
6732 (set_attr "bdver1_decode" "direct")
6733 (set_attr "mode" "<MODE>")])
6735 (define_insn "*mulsi3_1_zext"
6736 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6738 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6739 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6740 (clobber (reg:CC FLAGS_REG))]
6742 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6744 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6745 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6746 imul{l}\t{%2, %k0|%k0, %2}"
6747 [(set_attr "type" "imul")
6748 (set_attr "prefix_0f" "0,0,1")
6749 (set (attr "athlon_decode")
6750 (cond [(eq_attr "cpu" "athlon")
6751 (const_string "vector")
6752 (eq_attr "alternative" "1")
6753 (const_string "vector")
6754 (and (eq_attr "alternative" "2")
6755 (match_operand 1 "memory_operand"))
6756 (const_string "vector")]
6757 (const_string "direct")))
6758 (set (attr "amdfam10_decode")
6759 (cond [(and (eq_attr "alternative" "0,1")
6760 (match_operand 1 "memory_operand"))
6761 (const_string "vector")]
6762 (const_string "direct")))
6763 (set_attr "bdver1_decode" "direct")
6764 (set_attr "mode" "SI")])
6767 ;; IMUL reg16, reg16, imm8 VectorPath
6768 ;; IMUL reg16, mem16, imm8 VectorPath
6769 ;; IMUL reg16, reg16, imm16 VectorPath
6770 ;; IMUL reg16, mem16, imm16 VectorPath
6771 ;; IMUL reg16, reg16 Direct
6772 ;; IMUL reg16, mem16 Direct
6774 ;; On BDVER1, all HI MULs use DoublePath
6776 (define_insn "*mulhi3_1"
6777 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6778 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6779 (match_operand:HI 2 "general_operand" "K,n,mr")))
6780 (clobber (reg:CC FLAGS_REG))]
6782 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6784 imul{w}\t{%2, %1, %0|%0, %1, %2}
6785 imul{w}\t{%2, %1, %0|%0, %1, %2}
6786 imul{w}\t{%2, %0|%0, %2}"
6787 [(set_attr "type" "imul")
6788 (set_attr "prefix_0f" "0,0,1")
6789 (set (attr "athlon_decode")
6790 (cond [(eq_attr "cpu" "athlon")
6791 (const_string "vector")
6792 (eq_attr "alternative" "1,2")
6793 (const_string "vector")]
6794 (const_string "direct")))
6795 (set (attr "amdfam10_decode")
6796 (cond [(eq_attr "alternative" "0,1")
6797 (const_string "vector")]
6798 (const_string "direct")))
6799 (set_attr "bdver1_decode" "double")
6800 (set_attr "mode" "HI")])
6802 ;;On AMDFAM10 and BDVER1
6806 (define_insn "*mulqi3_1"
6807 [(set (match_operand:QI 0 "register_operand" "=a")
6808 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6809 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6810 (clobber (reg:CC FLAGS_REG))]
6812 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6814 [(set_attr "type" "imul")
6815 (set_attr "length_immediate" "0")
6816 (set (attr "athlon_decode")
6817 (if_then_else (eq_attr "cpu" "athlon")
6818 (const_string "vector")
6819 (const_string "direct")))
6820 (set_attr "amdfam10_decode" "direct")
6821 (set_attr "bdver1_decode" "direct")
6822 (set_attr "mode" "QI")])
6824 (define_expand "<u>mul<mode><dwi>3"
6825 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6828 (match_operand:DWIH 1 "nonimmediate_operand"))
6830 (match_operand:DWIH 2 "register_operand"))))
6831 (clobber (reg:CC FLAGS_REG))])])
6833 (define_expand "<u>mulqihi3"
6834 [(parallel [(set (match_operand:HI 0 "register_operand")
6837 (match_operand:QI 1 "nonimmediate_operand"))
6839 (match_operand:QI 2 "register_operand"))))
6840 (clobber (reg:CC FLAGS_REG))])]
6841 "TARGET_QIMODE_MATH")
6843 (define_insn "*bmi2_umulditi3_1"
6844 [(set (match_operand:DI 0 "register_operand" "=r")
6846 (match_operand:DI 2 "nonimmediate_operand" "%d")
6847 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6848 (set (match_operand:DI 1 "register_operand" "=r")
6851 (mult:TI (zero_extend:TI (match_dup 2))
6852 (zero_extend:TI (match_dup 3)))
6854 "TARGET_64BIT && TARGET_BMI2
6855 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6856 "mulx\t{%3, %0, %1|%1, %0, %3}"
6857 [(set_attr "type" "imulx")
6858 (set_attr "prefix" "vex")
6859 (set_attr "mode" "DI")])
6861 (define_insn "*bmi2_umulsidi3_1"
6862 [(set (match_operand:SI 0 "register_operand" "=r")
6864 (match_operand:SI 2 "nonimmediate_operand" "%d")
6865 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6866 (set (match_operand:SI 1 "register_operand" "=r")
6869 (mult:DI (zero_extend:DI (match_dup 2))
6870 (zero_extend:DI (match_dup 3)))
6872 "!TARGET_64BIT && TARGET_BMI2
6873 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6874 "mulx\t{%3, %0, %1|%1, %0, %3}"
6875 [(set_attr "type" "imulx")
6876 (set_attr "prefix" "vex")
6877 (set_attr "mode" "SI")])
6879 (define_insn "*umul<mode><dwi>3_1"
6880 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6883 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6885 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6886 (clobber (reg:CC FLAGS_REG))]
6887 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6890 mul{<imodesuffix>}\t%2"
6891 [(set_attr "isa" "bmi2,*")
6892 (set_attr "type" "imulx,imul")
6893 (set_attr "length_immediate" "*,0")
6894 (set (attr "athlon_decode")
6895 (cond [(eq_attr "alternative" "1")
6896 (if_then_else (eq_attr "cpu" "athlon")
6897 (const_string "vector")
6898 (const_string "double"))]
6899 (const_string "*")))
6900 (set_attr "amdfam10_decode" "*,double")
6901 (set_attr "bdver1_decode" "*,direct")
6902 (set_attr "prefix" "vex,orig")
6903 (set_attr "mode" "<MODE>")])
6905 ;; Convert mul to the mulx pattern to avoid flags dependency.
6907 [(set (match_operand:<DWI> 0 "register_operand")
6910 (match_operand:DWIH 1 "register_operand"))
6912 (match_operand:DWIH 2 "nonimmediate_operand"))))
6913 (clobber (reg:CC FLAGS_REG))]
6914 "TARGET_BMI2 && reload_completed
6915 && true_regnum (operands[1]) == DX_REG"
6916 [(parallel [(set (match_dup 3)
6917 (mult:DWIH (match_dup 1) (match_dup 2)))
6921 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6922 (zero_extend:<DWI> (match_dup 2)))
6925 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6927 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6930 (define_insn "*mul<mode><dwi>3_1"
6931 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6934 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6936 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6937 (clobber (reg:CC FLAGS_REG))]
6938 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6939 "imul{<imodesuffix>}\t%2"
6940 [(set_attr "type" "imul")
6941 (set_attr "length_immediate" "0")
6942 (set (attr "athlon_decode")
6943 (if_then_else (eq_attr "cpu" "athlon")
6944 (const_string "vector")
6945 (const_string "double")))
6946 (set_attr "amdfam10_decode" "double")
6947 (set_attr "bdver1_decode" "direct")
6948 (set_attr "mode" "<MODE>")])
6950 (define_insn "*<u>mulqihi3_1"
6951 [(set (match_operand:HI 0 "register_operand" "=a")
6954 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6956 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6957 (clobber (reg:CC FLAGS_REG))]
6959 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6960 "<sgnprefix>mul{b}\t%2"
6961 [(set_attr "type" "imul")
6962 (set_attr "length_immediate" "0")
6963 (set (attr "athlon_decode")
6964 (if_then_else (eq_attr "cpu" "athlon")
6965 (const_string "vector")
6966 (const_string "direct")))
6967 (set_attr "amdfam10_decode" "direct")
6968 (set_attr "bdver1_decode" "direct")
6969 (set_attr "mode" "QI")])
6971 (define_expand "<s>mul<mode>3_highpart"
6972 [(parallel [(set (match_operand:SWI48 0 "register_operand")
6977 (match_operand:SWI48 1 "nonimmediate_operand"))
6979 (match_operand:SWI48 2 "register_operand")))
6981 (clobber (match_scratch:SWI48 3))
6982 (clobber (reg:CC FLAGS_REG))])]
6984 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6986 (define_insn "*<s>muldi3_highpart_1"
6987 [(set (match_operand:DI 0 "register_operand" "=d")
6992 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6994 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6996 (clobber (match_scratch:DI 3 "=1"))
6997 (clobber (reg:CC FLAGS_REG))]
6999 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7000 "<sgnprefix>mul{q}\t%2"
7001 [(set_attr "type" "imul")
7002 (set_attr "length_immediate" "0")
7003 (set (attr "athlon_decode")
7004 (if_then_else (eq_attr "cpu" "athlon")
7005 (const_string "vector")
7006 (const_string "double")))
7007 (set_attr "amdfam10_decode" "double")
7008 (set_attr "bdver1_decode" "direct")
7009 (set_attr "mode" "DI")])
7011 (define_insn "*<s>mulsi3_highpart_1"
7012 [(set (match_operand:SI 0 "register_operand" "=d")
7017 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7019 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7021 (clobber (match_scratch:SI 3 "=1"))
7022 (clobber (reg:CC FLAGS_REG))]
7023 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7024 "<sgnprefix>mul{l}\t%2"
7025 [(set_attr "type" "imul")
7026 (set_attr "length_immediate" "0")
7027 (set (attr "athlon_decode")
7028 (if_then_else (eq_attr "cpu" "athlon")
7029 (const_string "vector")
7030 (const_string "double")))
7031 (set_attr "amdfam10_decode" "double")
7032 (set_attr "bdver1_decode" "direct")
7033 (set_attr "mode" "SI")])
7035 (define_insn "*<s>mulsi3_highpart_zext"
7036 [(set (match_operand:DI 0 "register_operand" "=d")
7037 (zero_extend:DI (truncate:SI
7039 (mult:DI (any_extend:DI
7040 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7042 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7044 (clobber (match_scratch:SI 3 "=1"))
7045 (clobber (reg:CC FLAGS_REG))]
7047 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7048 "<sgnprefix>mul{l}\t%2"
7049 [(set_attr "type" "imul")
7050 (set_attr "length_immediate" "0")
7051 (set (attr "athlon_decode")
7052 (if_then_else (eq_attr "cpu" "athlon")
7053 (const_string "vector")
7054 (const_string "double")))
7055 (set_attr "amdfam10_decode" "double")
7056 (set_attr "bdver1_decode" "direct")
7057 (set_attr "mode" "SI")])
7059 ;; The patterns that match these are at the end of this file.
7061 (define_expand "mulxf3"
7062 [(set (match_operand:XF 0 "register_operand")
7063 (mult:XF (match_operand:XF 1 "register_operand")
7064 (match_operand:XF 2 "register_operand")))]
7067 (define_expand "mul<mode>3"
7068 [(set (match_operand:MODEF 0 "register_operand")
7069 (mult:MODEF (match_operand:MODEF 1 "register_operand")
7070 (match_operand:MODEF 2 "nonimmediate_operand")))]
7071 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7072 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7074 ;; Divide instructions
7076 ;; The patterns that match these are at the end of this file.
7078 (define_expand "divxf3"
7079 [(set (match_operand:XF 0 "register_operand")
7080 (div:XF (match_operand:XF 1 "register_operand")
7081 (match_operand:XF 2 "register_operand")))]
7084 (define_expand "divdf3"
7085 [(set (match_operand:DF 0 "register_operand")
7086 (div:DF (match_operand:DF 1 "register_operand")
7087 (match_operand:DF 2 "nonimmediate_operand")))]
7088 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7089 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7091 (define_expand "divsf3"
7092 [(set (match_operand:SF 0 "register_operand")
7093 (div:SF (match_operand:SF 1 "register_operand")
7094 (match_operand:SF 2 "nonimmediate_operand")))]
7095 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7100 && optimize_insn_for_speed_p ()
7101 && flag_finite_math_only && !flag_trapping_math
7102 && flag_unsafe_math_optimizations)
7104 ix86_emit_swdivsf (operands[0], operands[1],
7105 operands[2], SFmode);
7110 ;; Divmod instructions.
7112 (define_expand "divmod<mode>4"
7113 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7115 (match_operand:SWIM248 1 "register_operand")
7116 (match_operand:SWIM248 2 "nonimmediate_operand")))
7117 (set (match_operand:SWIM248 3 "register_operand")
7118 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7119 (clobber (reg:CC FLAGS_REG))])])
7121 ;; Split with 8bit unsigned divide:
7122 ;; if (dividend an divisor are in [0-255])
7123 ;; use 8bit unsigned integer divide
7125 ;; use original integer divide
7127 [(set (match_operand:SWI48 0 "register_operand")
7128 (div:SWI48 (match_operand:SWI48 2 "register_operand")
7129 (match_operand:SWI48 3 "nonimmediate_operand")))
7130 (set (match_operand:SWI48 1 "register_operand")
7131 (mod:SWI48 (match_dup 2) (match_dup 3)))
7132 (clobber (reg:CC FLAGS_REG))]
7133 "TARGET_USE_8BIT_IDIV
7134 && TARGET_QIMODE_MATH
7135 && can_create_pseudo_p ()
7136 && !optimize_insn_for_size_p ()"
7138 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7140 (define_insn_and_split "divmod<mode>4_1"
7141 [(set (match_operand:SWI48 0 "register_operand" "=a")
7142 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7143 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7144 (set (match_operand:SWI48 1 "register_operand" "=&d")
7145 (mod:SWI48 (match_dup 2) (match_dup 3)))
7146 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7147 (clobber (reg:CC FLAGS_REG))]
7151 [(parallel [(set (match_dup 1)
7152 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7153 (clobber (reg:CC FLAGS_REG))])
7154 (parallel [(set (match_dup 0)
7155 (div:SWI48 (match_dup 2) (match_dup 3)))
7157 (mod:SWI48 (match_dup 2) (match_dup 3)))
7159 (clobber (reg:CC FLAGS_REG))])]
7161 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7163 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7164 operands[4] = operands[2];
7167 /* Avoid use of cltd in favor of a mov+shift. */
7168 emit_move_insn (operands[1], operands[2]);
7169 operands[4] = operands[1];
7172 [(set_attr "type" "multi")
7173 (set_attr "mode" "<MODE>")])
7175 (define_insn_and_split "*divmod<mode>4"
7176 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7177 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7178 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7179 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7180 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7181 (clobber (reg:CC FLAGS_REG))]
7185 [(parallel [(set (match_dup 1)
7186 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7187 (clobber (reg:CC FLAGS_REG))])
7188 (parallel [(set (match_dup 0)
7189 (div:SWIM248 (match_dup 2) (match_dup 3)))
7191 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7193 (clobber (reg:CC FLAGS_REG))])]
7195 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7197 if (<MODE>mode != HImode
7198 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7199 operands[4] = operands[2];
7202 /* Avoid use of cltd in favor of a mov+shift. */
7203 emit_move_insn (operands[1], operands[2]);
7204 operands[4] = operands[1];
7207 [(set_attr "type" "multi")
7208 (set_attr "mode" "<MODE>")])
7210 (define_insn "*divmod<mode>4_noext"
7211 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7212 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7213 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7214 (set (match_operand:SWIM248 1 "register_operand" "=d")
7215 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7216 (use (match_operand:SWIM248 4 "register_operand" "1"))
7217 (clobber (reg:CC FLAGS_REG))]
7219 "idiv{<imodesuffix>}\t%3"
7220 [(set_attr "type" "idiv")
7221 (set_attr "mode" "<MODE>")])
7223 (define_expand "divmodqi4"
7224 [(parallel [(set (match_operand:QI 0 "register_operand")
7226 (match_operand:QI 1 "register_operand")
7227 (match_operand:QI 2 "nonimmediate_operand")))
7228 (set (match_operand:QI 3 "register_operand")
7229 (mod:QI (match_dup 1) (match_dup 2)))
7230 (clobber (reg:CC FLAGS_REG))])]
7231 "TARGET_QIMODE_MATH"
7236 tmp0 = gen_reg_rtx (HImode);
7237 tmp1 = gen_reg_rtx (HImode);
7239 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7241 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7242 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7244 /* Extract remainder from AH. */
7245 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7246 insn = emit_move_insn (operands[3], tmp1);
7248 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7249 set_unique_reg_note (insn, REG_EQUAL, mod);
7251 /* Extract quotient from AL. */
7252 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7254 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7255 set_unique_reg_note (insn, REG_EQUAL, div);
7260 ;; Divide AX by r/m8, with result stored in
7263 ;; Change div/mod to HImode and extend the second argument to HImode
7264 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7265 ;; combine may fail.
7266 (define_insn "divmodhiqi3"
7267 [(set (match_operand:HI 0 "register_operand" "=a")
7272 (mod:HI (match_operand:HI 1 "register_operand" "0")
7274 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7278 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7279 (clobber (reg:CC FLAGS_REG))]
7280 "TARGET_QIMODE_MATH"
7282 [(set_attr "type" "idiv")
7283 (set_attr "mode" "QI")])
7285 (define_expand "udivmod<mode>4"
7286 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7288 (match_operand:SWIM248 1 "register_operand")
7289 (match_operand:SWIM248 2 "nonimmediate_operand")))
7290 (set (match_operand:SWIM248 3 "register_operand")
7291 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7292 (clobber (reg:CC FLAGS_REG))])])
7294 ;; Split with 8bit unsigned divide:
7295 ;; if (dividend an divisor are in [0-255])
7296 ;; use 8bit unsigned integer divide
7298 ;; use original integer divide
7300 [(set (match_operand:SWI48 0 "register_operand")
7301 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7302 (match_operand:SWI48 3 "nonimmediate_operand")))
7303 (set (match_operand:SWI48 1 "register_operand")
7304 (umod:SWI48 (match_dup 2) (match_dup 3)))
7305 (clobber (reg:CC FLAGS_REG))]
7306 "TARGET_USE_8BIT_IDIV
7307 && TARGET_QIMODE_MATH
7308 && can_create_pseudo_p ()
7309 && !optimize_insn_for_size_p ()"
7311 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7313 (define_insn_and_split "udivmod<mode>4_1"
7314 [(set (match_operand:SWI48 0 "register_operand" "=a")
7315 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7316 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7317 (set (match_operand:SWI48 1 "register_operand" "=&d")
7318 (umod:SWI48 (match_dup 2) (match_dup 3)))
7319 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7320 (clobber (reg:CC FLAGS_REG))]
7324 [(set (match_dup 1) (const_int 0))
7325 (parallel [(set (match_dup 0)
7326 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7328 (umod:SWI48 (match_dup 2) (match_dup 3)))
7330 (clobber (reg:CC FLAGS_REG))])]
7332 [(set_attr "type" "multi")
7333 (set_attr "mode" "<MODE>")])
7335 (define_insn_and_split "*udivmod<mode>4"
7336 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7337 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7338 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7339 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7340 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7341 (clobber (reg:CC FLAGS_REG))]
7345 [(set (match_dup 1) (const_int 0))
7346 (parallel [(set (match_dup 0)
7347 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7349 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7351 (clobber (reg:CC FLAGS_REG))])]
7353 [(set_attr "type" "multi")
7354 (set_attr "mode" "<MODE>")])
7356 (define_insn "*udivmod<mode>4_noext"
7357 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7358 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7359 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7360 (set (match_operand:SWIM248 1 "register_operand" "=d")
7361 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7362 (use (match_operand:SWIM248 4 "register_operand" "1"))
7363 (clobber (reg:CC FLAGS_REG))]
7365 "div{<imodesuffix>}\t%3"
7366 [(set_attr "type" "idiv")
7367 (set_attr "mode" "<MODE>")])
7369 (define_expand "udivmodqi4"
7370 [(parallel [(set (match_operand:QI 0 "register_operand")
7372 (match_operand:QI 1 "register_operand")
7373 (match_operand:QI 2 "nonimmediate_operand")))
7374 (set (match_operand:QI 3 "register_operand")
7375 (umod:QI (match_dup 1) (match_dup 2)))
7376 (clobber (reg:CC FLAGS_REG))])]
7377 "TARGET_QIMODE_MATH"
7382 tmp0 = gen_reg_rtx (HImode);
7383 tmp1 = gen_reg_rtx (HImode);
7385 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7387 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7388 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7390 /* Extract remainder from AH. */
7391 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7392 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7393 insn = emit_move_insn (operands[3], tmp1);
7395 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7396 set_unique_reg_note (insn, REG_EQUAL, mod);
7398 /* Extract quotient from AL. */
7399 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7401 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7402 set_unique_reg_note (insn, REG_EQUAL, div);
7407 (define_insn "udivmodhiqi3"
7408 [(set (match_operand:HI 0 "register_operand" "=a")
7413 (mod:HI (match_operand:HI 1 "register_operand" "0")
7415 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7419 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7420 (clobber (reg:CC FLAGS_REG))]
7421 "TARGET_QIMODE_MATH"
7423 [(set_attr "type" "idiv")
7424 (set_attr "mode" "QI")])
7426 ;; We cannot use div/idiv for double division, because it causes
7427 ;; "division by zero" on the overflow and that's not what we expect
7428 ;; from truncate. Because true (non truncating) double division is
7429 ;; never generated, we can't create this insn anyway.
7432 ; [(set (match_operand:SI 0 "register_operand" "=a")
7434 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7436 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7437 ; (set (match_operand:SI 3 "register_operand" "=d")
7439 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7440 ; (clobber (reg:CC FLAGS_REG))]
7442 ; "div{l}\t{%2, %0|%0, %2}"
7443 ; [(set_attr "type" "idiv")])
7445 ;;- Logical AND instructions
7447 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7448 ;; Note that this excludes ah.
7450 (define_expand "testsi_ccno_1"
7451 [(set (reg:CCNO FLAGS_REG)
7453 (and:SI (match_operand:SI 0 "nonimmediate_operand")
7454 (match_operand:SI 1 "x86_64_nonmemory_operand"))
7457 (define_expand "testqi_ccz_1"
7458 [(set (reg:CCZ FLAGS_REG)
7459 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7460 (match_operand:QI 1 "nonmemory_operand"))
7463 (define_expand "testdi_ccno_1"
7464 [(set (reg:CCNO FLAGS_REG)
7466 (and:DI (match_operand:DI 0 "nonimmediate_operand")
7467 (match_operand:DI 1 "x86_64_szext_general_operand"))
7469 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7471 (define_insn "*testdi_1"
7472 [(set (reg FLAGS_REG)
7475 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7476 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7478 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7479 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7481 test{l}\t{%k1, %k0|%k0, %k1}
7482 test{l}\t{%k1, %k0|%k0, %k1}
7483 test{q}\t{%1, %0|%0, %1}
7484 test{q}\t{%1, %0|%0, %1}
7485 test{q}\t{%1, %0|%0, %1}"
7486 [(set_attr "type" "test")
7487 (set_attr "modrm" "0,1,0,1,1")
7488 (set_attr "mode" "SI,SI,DI,DI,DI")])
7490 (define_insn "*testqi_1_maybe_si"
7491 [(set (reg FLAGS_REG)
7494 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7495 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7497 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7498 && ix86_match_ccmode (insn,
7499 CONST_INT_P (operands[1])
7500 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7502 if (which_alternative == 3)
7504 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7505 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7506 return "test{l}\t{%1, %k0|%k0, %1}";
7508 return "test{b}\t{%1, %0|%0, %1}";
7510 [(set_attr "type" "test")
7511 (set_attr "modrm" "0,1,1,1")
7512 (set_attr "mode" "QI,QI,QI,SI")
7513 (set_attr "pent_pair" "uv,np,uv,np")])
7515 (define_insn "*test<mode>_1"
7516 [(set (reg FLAGS_REG)
7519 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7520 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7522 "ix86_match_ccmode (insn, CCNOmode)
7523 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7524 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7525 [(set_attr "type" "test")
7526 (set_attr "modrm" "0,1,1")
7527 (set_attr "mode" "<MODE>")
7528 (set_attr "pent_pair" "uv,np,uv")])
7530 (define_expand "testqi_ext_ccno_0"
7531 [(set (reg:CCNO FLAGS_REG)
7535 (match_operand 0 "ext_register_operand")
7538 (match_operand 1 "const_int_operand"))
7541 (define_insn "*testqi_ext_0"
7542 [(set (reg FLAGS_REG)
7546 (match_operand 0 "ext_register_operand" "Q")
7549 (match_operand 1 "const_int_operand" "n"))
7551 "ix86_match_ccmode (insn, CCNOmode)"
7552 "test{b}\t{%1, %h0|%h0, %1}"
7553 [(set_attr "type" "test")
7554 (set_attr "mode" "QI")
7555 (set_attr "length_immediate" "1")
7556 (set_attr "modrm" "1")
7557 (set_attr "pent_pair" "np")])
7559 (define_insn "*testqi_ext_1_rex64"
7560 [(set (reg FLAGS_REG)
7564 (match_operand 0 "ext_register_operand" "Q")
7568 (match_operand:QI 1 "register_operand" "Q")))
7570 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7571 "test{b}\t{%1, %h0|%h0, %1}"
7572 [(set_attr "type" "test")
7573 (set_attr "mode" "QI")])
7575 (define_insn "*testqi_ext_1"
7576 [(set (reg FLAGS_REG)
7580 (match_operand 0 "ext_register_operand" "Q")
7584 (match_operand:QI 1 "general_operand" "Qm")))
7586 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7587 "test{b}\t{%1, %h0|%h0, %1}"
7588 [(set_attr "type" "test")
7589 (set_attr "mode" "QI")])
7591 (define_insn "*testqi_ext_2"
7592 [(set (reg FLAGS_REG)
7596 (match_operand 0 "ext_register_operand" "Q")
7600 (match_operand 1 "ext_register_operand" "Q")
7604 "ix86_match_ccmode (insn, CCNOmode)"
7605 "test{b}\t{%h1, %h0|%h0, %h1}"
7606 [(set_attr "type" "test")
7607 (set_attr "mode" "QI")])
7609 (define_insn "*testqi_ext_3_rex64"
7610 [(set (reg FLAGS_REG)
7611 (compare (zero_extract:DI
7612 (match_operand 0 "nonimmediate_operand" "rm")
7613 (match_operand:DI 1 "const_int_operand")
7614 (match_operand:DI 2 "const_int_operand"))
7617 && ix86_match_ccmode (insn, CCNOmode)
7618 && INTVAL (operands[1]) > 0
7619 && INTVAL (operands[2]) >= 0
7620 /* Ensure that resulting mask is zero or sign extended operand. */
7621 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7622 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7623 && INTVAL (operands[1]) > 32))
7624 && (GET_MODE (operands[0]) == SImode
7625 || GET_MODE (operands[0]) == DImode
7626 || GET_MODE (operands[0]) == HImode
7627 || GET_MODE (operands[0]) == QImode)"
7630 ;; Combine likes to form bit extractions for some tests. Humor it.
7631 (define_insn "*testqi_ext_3"
7632 [(set (reg FLAGS_REG)
7633 (compare (zero_extract:SI
7634 (match_operand 0 "nonimmediate_operand" "rm")
7635 (match_operand:SI 1 "const_int_operand")
7636 (match_operand:SI 2 "const_int_operand"))
7638 "ix86_match_ccmode (insn, CCNOmode)
7639 && INTVAL (operands[1]) > 0
7640 && INTVAL (operands[2]) >= 0
7641 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7642 && (GET_MODE (operands[0]) == SImode
7643 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7644 || GET_MODE (operands[0]) == HImode
7645 || GET_MODE (operands[0]) == QImode)"
7649 [(set (match_operand 0 "flags_reg_operand")
7650 (match_operator 1 "compare_operator"
7652 (match_operand 2 "nonimmediate_operand")
7653 (match_operand 3 "const_int_operand")
7654 (match_operand 4 "const_int_operand"))
7656 "ix86_match_ccmode (insn, CCNOmode)"
7657 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7659 rtx val = operands[2];
7660 HOST_WIDE_INT len = INTVAL (operands[3]);
7661 HOST_WIDE_INT pos = INTVAL (operands[4]);
7663 enum machine_mode mode, submode;
7665 mode = GET_MODE (val);
7668 /* ??? Combine likes to put non-volatile mem extractions in QImode
7669 no matter the size of the test. So find a mode that works. */
7670 if (! MEM_VOLATILE_P (val))
7672 mode = smallest_mode_for_size (pos + len, MODE_INT);
7673 val = adjust_address (val, mode, 0);
7676 else if (GET_CODE (val) == SUBREG
7677 && (submode = GET_MODE (SUBREG_REG (val)),
7678 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7679 && pos + len <= GET_MODE_BITSIZE (submode)
7680 && GET_MODE_CLASS (submode) == MODE_INT)
7682 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7684 val = SUBREG_REG (val);
7686 else if (mode == HImode && pos + len <= 8)
7688 /* Small HImode tests can be converted to QImode. */
7690 val = gen_lowpart (QImode, val);
7693 if (len == HOST_BITS_PER_WIDE_INT)
7696 mask = ((HOST_WIDE_INT)1 << len) - 1;
7699 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7702 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7703 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7704 ;; this is relatively important trick.
7705 ;; Do the conversion only post-reload to avoid limiting of the register class
7708 [(set (match_operand 0 "flags_reg_operand")
7709 (match_operator 1 "compare_operator"
7710 [(and (match_operand 2 "register_operand")
7711 (match_operand 3 "const_int_operand"))
7714 && QI_REG_P (operands[2])
7715 && GET_MODE (operands[2]) != QImode
7716 && ((ix86_match_ccmode (insn, CCZmode)
7717 && !(INTVAL (operands[3]) & ~(255 << 8)))
7718 || (ix86_match_ccmode (insn, CCNOmode)
7719 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7722 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7726 operands[2] = gen_lowpart (SImode, operands[2]);
7727 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7731 [(set (match_operand 0 "flags_reg_operand")
7732 (match_operator 1 "compare_operator"
7733 [(and (match_operand 2 "nonimmediate_operand")
7734 (match_operand 3 "const_int_operand"))
7737 && GET_MODE (operands[2]) != QImode
7738 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7739 && ((ix86_match_ccmode (insn, CCZmode)
7740 && !(INTVAL (operands[3]) & ~255))
7741 || (ix86_match_ccmode (insn, CCNOmode)
7742 && !(INTVAL (operands[3]) & ~127)))"
7744 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7747 operands[2] = gen_lowpart (QImode, operands[2]);
7748 operands[3] = gen_lowpart (QImode, operands[3]);
7751 ;; %%% This used to optimize known byte-wide and operations to memory,
7752 ;; and sometimes to QImode registers. If this is considered useful,
7753 ;; it should be done with splitters.
7755 (define_expand "and<mode>3"
7756 [(set (match_operand:SWIM 0 "nonimmediate_operand")
7757 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7758 (match_operand:SWIM 2 "<general_szext_operand>")))]
7761 enum machine_mode mode = <MODE>mode;
7762 rtx (*insn) (rtx, rtx);
7764 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7766 HOST_WIDE_INT ival = INTVAL (operands[2]);
7768 if (ival == (HOST_WIDE_INT) 0xffffffff)
7770 else if (ival == 0xffff)
7772 else if (ival == 0xff)
7776 if (mode == <MODE>mode)
7778 ix86_expand_binary_operator (AND, <MODE>mode, operands);
7782 if (<MODE>mode == DImode)
7783 insn = (mode == SImode)
7784 ? gen_zero_extendsidi2
7786 ? gen_zero_extendhidi2
7787 : gen_zero_extendqidi2;
7788 else if (<MODE>mode == SImode)
7789 insn = (mode == HImode)
7790 ? gen_zero_extendhisi2
7791 : gen_zero_extendqisi2;
7792 else if (<MODE>mode == HImode)
7793 insn = gen_zero_extendqihi2;
7797 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7801 (define_insn "*anddi_1"
7802 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7804 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7805 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7806 (clobber (reg:CC FLAGS_REG))]
7807 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7809 switch (get_attr_type (insn))
7815 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7816 if (get_attr_mode (insn) == MODE_SI)
7817 return "and{l}\t{%k2, %k0|%k0, %k2}";
7819 return "and{q}\t{%2, %0|%0, %2}";
7822 [(set_attr "type" "alu,alu,alu,imovx")
7823 (set_attr "length_immediate" "*,*,*,0")
7824 (set (attr "prefix_rex")
7826 (and (eq_attr "type" "imovx")
7827 (and (match_test "INTVAL (operands[2]) == 0xff")
7828 (match_operand 1 "ext_QIreg_operand")))
7830 (const_string "*")))
7831 (set_attr "mode" "SI,DI,DI,SI")])
7833 (define_insn "*andsi_1"
7834 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya")
7835 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7836 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7837 (clobber (reg:CC FLAGS_REG))]
7838 "ix86_binary_operator_ok (AND, SImode, operands)"
7840 switch (get_attr_type (insn))
7846 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7847 return "and{l}\t{%2, %0|%0, %2}";
7850 [(set_attr "type" "alu,alu,imovx")
7851 (set (attr "prefix_rex")
7853 (and (eq_attr "type" "imovx")
7854 (and (match_test "INTVAL (operands[2]) == 0xff")
7855 (match_operand 1 "ext_QIreg_operand")))
7857 (const_string "*")))
7858 (set_attr "length_immediate" "*,*,0")
7859 (set_attr "mode" "SI")])
7861 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7862 (define_insn "*andsi_1_zext"
7863 [(set (match_operand:DI 0 "register_operand" "=r")
7865 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7866 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7867 (clobber (reg:CC FLAGS_REG))]
7868 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7869 "and{l}\t{%2, %k0|%k0, %2}"
7870 [(set_attr "type" "alu")
7871 (set_attr "mode" "SI")])
7873 (define_insn "*andhi_1"
7874 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya")
7875 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7876 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7877 (clobber (reg:CC FLAGS_REG))]
7878 "ix86_binary_operator_ok (AND, HImode, operands)"
7880 switch (get_attr_type (insn))
7886 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7887 return "and{w}\t{%2, %0|%0, %2}";
7890 [(set_attr "type" "alu,alu,imovx")
7891 (set_attr "length_immediate" "*,*,0")
7892 (set (attr "prefix_rex")
7894 (and (eq_attr "type" "imovx")
7895 (match_operand 1 "ext_QIreg_operand"))
7897 (const_string "*")))
7898 (set_attr "mode" "HI,HI,SI")])
7900 ;; %%% Potential partial reg stall on alternative 2. What to do?
7901 (define_insn "*andqi_1"
7902 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7903 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7904 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7905 (clobber (reg:CC FLAGS_REG))]
7906 "ix86_binary_operator_ok (AND, QImode, operands)"
7908 and{b}\t{%2, %0|%0, %2}
7909 and{b}\t{%2, %0|%0, %2}
7910 and{l}\t{%k2, %k0|%k0, %k2}"
7911 [(set_attr "type" "alu")
7912 (set_attr "mode" "QI,QI,SI")])
7914 (define_insn "*andqi_1_slp"
7915 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7916 (and:QI (match_dup 0)
7917 (match_operand:QI 1 "general_operand" "qn,qmn")))
7918 (clobber (reg:CC FLAGS_REG))]
7919 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7920 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7921 "and{b}\t{%1, %0|%0, %1}"
7922 [(set_attr "type" "alu1")
7923 (set_attr "mode" "QI")])
7925 ;; Turn *anddi_1 into *andsi_1_zext if possible.
7927 [(set (match_operand:DI 0 "register_operand")
7928 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
7929 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
7930 (clobber (reg:CC FLAGS_REG))]
7932 [(parallel [(set (match_dup 0)
7933 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
7934 (clobber (reg:CC FLAGS_REG))])]
7935 "operands[2] = gen_lowpart (SImode, operands[2]);")
7938 [(set (match_operand:SWI248 0 "register_operand")
7939 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
7940 (match_operand:SWI248 2 "const_int_operand")))
7941 (clobber (reg:CC FLAGS_REG))]
7943 && true_regnum (operands[0]) != true_regnum (operands[1])"
7946 HOST_WIDE_INT ival = INTVAL (operands[2]);
7947 enum machine_mode mode;
7948 rtx (*insn) (rtx, rtx);
7950 if (ival == (HOST_WIDE_INT) 0xffffffff)
7952 else if (ival == 0xffff)
7956 gcc_assert (ival == 0xff);
7960 if (<MODE>mode == DImode)
7961 insn = (mode == SImode)
7962 ? gen_zero_extendsidi2
7964 ? gen_zero_extendhidi2
7965 : gen_zero_extendqidi2;
7968 if (<MODE>mode != SImode)
7969 /* Zero extend to SImode to avoid partial register stalls. */
7970 operands[0] = gen_lowpart (SImode, operands[0]);
7972 insn = (mode == HImode)
7973 ? gen_zero_extendhisi2
7974 : gen_zero_extendqisi2;
7976 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7981 [(set (match_operand 0 "register_operand")
7983 (const_int -65536)))
7984 (clobber (reg:CC FLAGS_REG))]
7985 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7986 || optimize_function_for_size_p (cfun)"
7987 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7988 "operands[1] = gen_lowpart (HImode, operands[0]);")
7991 [(set (match_operand 0 "ext_register_operand")
7994 (clobber (reg:CC FLAGS_REG))]
7995 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7996 && reload_completed"
7997 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7998 "operands[1] = gen_lowpart (QImode, operands[0]);")
8001 [(set (match_operand 0 "ext_register_operand")
8003 (const_int -65281)))
8004 (clobber (reg:CC FLAGS_REG))]
8005 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8006 && reload_completed"
8007 [(parallel [(set (zero_extract:SI (match_dup 0)
8011 (zero_extract:SI (match_dup 0)
8014 (zero_extract:SI (match_dup 0)
8017 (clobber (reg:CC FLAGS_REG))])]
8018 "operands[0] = gen_lowpart (SImode, operands[0]);")
8020 (define_insn "*anddi_2"
8021 [(set (reg FLAGS_REG)
8024 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8025 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8027 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8028 (and:DI (match_dup 1) (match_dup 2)))]
8030 && ix86_match_ccmode
8032 /* If we are going to emit andl instead of andq, and the operands[2]
8033 constant might have the SImode sign bit set, make sure the sign
8034 flag isn't tested, because the instruction will set the sign flag
8035 based on bit 31 rather than bit 63. If it isn't CONST_INT,
8036 conservatively assume it might have bit 31 set. */
8037 (satisfies_constraint_Z (operands[2])
8038 && (!CONST_INT_P (operands[2])
8039 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
8040 ? CCZmode : CCNOmode)
8041 && ix86_binary_operator_ok (AND, DImode, operands)"
8043 and{l}\t{%k2, %k0|%k0, %k2}
8044 and{q}\t{%2, %0|%0, %2}
8045 and{q}\t{%2, %0|%0, %2}"
8046 [(set_attr "type" "alu")
8047 (set_attr "mode" "SI,DI,DI")])
8049 (define_insn "*andqi_2_maybe_si"
8050 [(set (reg FLAGS_REG)
8052 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8053 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8055 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8056 (and:QI (match_dup 1) (match_dup 2)))]
8057 "ix86_binary_operator_ok (AND, QImode, operands)
8058 && ix86_match_ccmode (insn,
8059 CONST_INT_P (operands[2])
8060 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8062 if (which_alternative == 2)
8064 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8065 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8066 return "and{l}\t{%2, %k0|%k0, %2}";
8068 return "and{b}\t{%2, %0|%0, %2}";
8070 [(set_attr "type" "alu")
8071 (set_attr "mode" "QI,QI,SI")])
8073 (define_insn "*and<mode>_2"
8074 [(set (reg FLAGS_REG)
8075 (compare (and:SWI124
8076 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8077 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
8079 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8080 (and:SWI124 (match_dup 1) (match_dup 2)))]
8081 "ix86_match_ccmode (insn, CCNOmode)
8082 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8083 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8084 [(set_attr "type" "alu")
8085 (set_attr "mode" "<MODE>")])
8087 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8088 (define_insn "*andsi_2_zext"
8089 [(set (reg FLAGS_REG)
8091 (match_operand:SI 1 "nonimmediate_operand" "%0")
8092 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8094 (set (match_operand:DI 0 "register_operand" "=r")
8095 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8096 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8097 && ix86_binary_operator_ok (AND, SImode, operands)"
8098 "and{l}\t{%2, %k0|%k0, %2}"
8099 [(set_attr "type" "alu")
8100 (set_attr "mode" "SI")])
8102 (define_insn "*andqi_2_slp"
8103 [(set (reg FLAGS_REG)
8105 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8106 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8108 (set (strict_low_part (match_dup 0))
8109 (and:QI (match_dup 0) (match_dup 1)))]
8110 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8111 && ix86_match_ccmode (insn, CCNOmode)
8112 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8113 "and{b}\t{%1, %0|%0, %1}"
8114 [(set_attr "type" "alu1")
8115 (set_attr "mode" "QI")])
8117 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8118 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8119 ;; for a QImode operand, which of course failed.
8120 (define_insn "andqi_ext_0"
8121 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8126 (match_operand 1 "ext_register_operand" "0")
8129 (match_operand 2 "const_int_operand" "n")))
8130 (clobber (reg:CC FLAGS_REG))]
8132 "and{b}\t{%2, %h0|%h0, %2}"
8133 [(set_attr "type" "alu")
8134 (set_attr "length_immediate" "1")
8135 (set_attr "modrm" "1")
8136 (set_attr "mode" "QI")])
8138 ;; Generated by peephole translating test to and. This shows up
8139 ;; often in fp comparisons.
8140 (define_insn "*andqi_ext_0_cc"
8141 [(set (reg FLAGS_REG)
8145 (match_operand 1 "ext_register_operand" "0")
8148 (match_operand 2 "const_int_operand" "n"))
8150 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8159 "ix86_match_ccmode (insn, CCNOmode)"
8160 "and{b}\t{%2, %h0|%h0, %2}"
8161 [(set_attr "type" "alu")
8162 (set_attr "length_immediate" "1")
8163 (set_attr "modrm" "1")
8164 (set_attr "mode" "QI")])
8166 (define_insn "*andqi_ext_1_rex64"
8167 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8172 (match_operand 1 "ext_register_operand" "0")
8176 (match_operand 2 "ext_register_operand" "Q"))))
8177 (clobber (reg:CC FLAGS_REG))]
8179 "and{b}\t{%2, %h0|%h0, %2}"
8180 [(set_attr "type" "alu")
8181 (set_attr "length_immediate" "0")
8182 (set_attr "mode" "QI")])
8184 (define_insn "*andqi_ext_1"
8185 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8190 (match_operand 1 "ext_register_operand" "0")
8194 (match_operand:QI 2 "general_operand" "Qm"))))
8195 (clobber (reg:CC FLAGS_REG))]
8197 "and{b}\t{%2, %h0|%h0, %2}"
8198 [(set_attr "type" "alu")
8199 (set_attr "length_immediate" "0")
8200 (set_attr "mode" "QI")])
8202 (define_insn "*andqi_ext_2"
8203 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8208 (match_operand 1 "ext_register_operand" "%0")
8212 (match_operand 2 "ext_register_operand" "Q")
8215 (clobber (reg:CC FLAGS_REG))]
8217 "and{b}\t{%h2, %h0|%h0, %h2}"
8218 [(set_attr "type" "alu")
8219 (set_attr "length_immediate" "0")
8220 (set_attr "mode" "QI")])
8222 ;; Convert wide AND instructions with immediate operand to shorter QImode
8223 ;; equivalents when possible.
8224 ;; Don't do the splitting with memory operands, since it introduces risk
8225 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8226 ;; for size, but that can (should?) be handled by generic code instead.
8228 [(set (match_operand 0 "register_operand")
8229 (and (match_operand 1 "register_operand")
8230 (match_operand 2 "const_int_operand")))
8231 (clobber (reg:CC FLAGS_REG))]
8233 && QI_REG_P (operands[0])
8234 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8235 && !(~INTVAL (operands[2]) & ~(255 << 8))
8236 && GET_MODE (operands[0]) != QImode"
8237 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8238 (and:SI (zero_extract:SI (match_dup 1)
8239 (const_int 8) (const_int 8))
8241 (clobber (reg:CC FLAGS_REG))])]
8243 operands[0] = gen_lowpart (SImode, operands[0]);
8244 operands[1] = gen_lowpart (SImode, operands[1]);
8245 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8248 ;; Since AND can be encoded with sign extended immediate, this is only
8249 ;; profitable when 7th bit is not set.
8251 [(set (match_operand 0 "register_operand")
8252 (and (match_operand 1 "general_operand")
8253 (match_operand 2 "const_int_operand")))
8254 (clobber (reg:CC FLAGS_REG))]
8256 && ANY_QI_REG_P (operands[0])
8257 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8258 && !(~INTVAL (operands[2]) & ~255)
8259 && !(INTVAL (operands[2]) & 128)
8260 && GET_MODE (operands[0]) != QImode"
8261 [(parallel [(set (strict_low_part (match_dup 0))
8262 (and:QI (match_dup 1)
8264 (clobber (reg:CC FLAGS_REG))])]
8266 operands[0] = gen_lowpart (QImode, operands[0]);
8267 operands[1] = gen_lowpart (QImode, operands[1]);
8268 operands[2] = gen_lowpart (QImode, operands[2]);
8271 ;; Logical inclusive and exclusive OR instructions
8273 ;; %%% This used to optimize known byte-wide and operations to memory.
8274 ;; If this is considered useful, it should be done with splitters.
8276 (define_expand "<code><mode>3"
8277 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8278 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
8279 (match_operand:SWIM 2 "<general_operand>")))]
8281 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8283 (define_insn "*<code><mode>_1"
8284 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8286 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8287 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8288 (clobber (reg:CC FLAGS_REG))]
8289 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8290 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8291 [(set_attr "type" "alu")
8292 (set_attr "mode" "<MODE>")])
8294 ;; %%% Potential partial reg stall on alternative 2. What to do?
8295 (define_insn "*<code>qi_1"
8296 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8297 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8298 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8299 (clobber (reg:CC FLAGS_REG))]
8300 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8302 <logic>{b}\t{%2, %0|%0, %2}
8303 <logic>{b}\t{%2, %0|%0, %2}
8304 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8305 [(set_attr "type" "alu")
8306 (set_attr "mode" "QI,QI,SI")])
8308 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8309 (define_insn "*<code>si_1_zext"
8310 [(set (match_operand:DI 0 "register_operand" "=r")
8312 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8313 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8314 (clobber (reg:CC FLAGS_REG))]
8315 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8316 "<logic>{l}\t{%2, %k0|%k0, %2}"
8317 [(set_attr "type" "alu")
8318 (set_attr "mode" "SI")])
8320 (define_insn "*<code>si_1_zext_imm"
8321 [(set (match_operand:DI 0 "register_operand" "=r")
8323 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8324 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8325 (clobber (reg:CC FLAGS_REG))]
8326 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8327 "<logic>{l}\t{%2, %k0|%k0, %2}"
8328 [(set_attr "type" "alu")
8329 (set_attr "mode" "SI")])
8331 (define_insn "*<code>qi_1_slp"
8332 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8333 (any_or:QI (match_dup 0)
8334 (match_operand:QI 1 "general_operand" "qmn,qn")))
8335 (clobber (reg:CC FLAGS_REG))]
8336 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8337 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8338 "<logic>{b}\t{%1, %0|%0, %1}"
8339 [(set_attr "type" "alu1")
8340 (set_attr "mode" "QI")])
8342 (define_insn "*<code><mode>_2"
8343 [(set (reg FLAGS_REG)
8344 (compare (any_or:SWI
8345 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8346 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8348 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8349 (any_or:SWI (match_dup 1) (match_dup 2)))]
8350 "ix86_match_ccmode (insn, CCNOmode)
8351 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8352 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8353 [(set_attr "type" "alu")
8354 (set_attr "mode" "<MODE>")])
8356 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8357 ;; ??? Special case for immediate operand is missing - it is tricky.
8358 (define_insn "*<code>si_2_zext"
8359 [(set (reg FLAGS_REG)
8360 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8361 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8363 (set (match_operand:DI 0 "register_operand" "=r")
8364 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8365 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8366 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8367 "<logic>{l}\t{%2, %k0|%k0, %2}"
8368 [(set_attr "type" "alu")
8369 (set_attr "mode" "SI")])
8371 (define_insn "*<code>si_2_zext_imm"
8372 [(set (reg FLAGS_REG)
8374 (match_operand:SI 1 "nonimmediate_operand" "%0")
8375 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8377 (set (match_operand:DI 0 "register_operand" "=r")
8378 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8379 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8380 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8381 "<logic>{l}\t{%2, %k0|%k0, %2}"
8382 [(set_attr "type" "alu")
8383 (set_attr "mode" "SI")])
8385 (define_insn "*<code>qi_2_slp"
8386 [(set (reg FLAGS_REG)
8387 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8388 (match_operand:QI 1 "general_operand" "qmn,qn"))
8390 (set (strict_low_part (match_dup 0))
8391 (any_or:QI (match_dup 0) (match_dup 1)))]
8392 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8393 && ix86_match_ccmode (insn, CCNOmode)
8394 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8395 "<logic>{b}\t{%1, %0|%0, %1}"
8396 [(set_attr "type" "alu1")
8397 (set_attr "mode" "QI")])
8399 (define_insn "*<code><mode>_3"
8400 [(set (reg FLAGS_REG)
8401 (compare (any_or:SWI
8402 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8403 (match_operand:SWI 2 "<general_operand>" "<g>"))
8405 (clobber (match_scratch:SWI 0 "=<r>"))]
8406 "ix86_match_ccmode (insn, CCNOmode)
8407 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8408 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8409 [(set_attr "type" "alu")
8410 (set_attr "mode" "<MODE>")])
8412 (define_insn "*<code>qi_ext_0"
8413 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8418 (match_operand 1 "ext_register_operand" "0")
8421 (match_operand 2 "const_int_operand" "n")))
8422 (clobber (reg:CC FLAGS_REG))]
8423 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8424 "<logic>{b}\t{%2, %h0|%h0, %2}"
8425 [(set_attr "type" "alu")
8426 (set_attr "length_immediate" "1")
8427 (set_attr "modrm" "1")
8428 (set_attr "mode" "QI")])
8430 (define_insn "*<code>qi_ext_1_rex64"
8431 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8436 (match_operand 1 "ext_register_operand" "0")
8440 (match_operand 2 "ext_register_operand" "Q"))))
8441 (clobber (reg:CC FLAGS_REG))]
8443 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8444 "<logic>{b}\t{%2, %h0|%h0, %2}"
8445 [(set_attr "type" "alu")
8446 (set_attr "length_immediate" "0")
8447 (set_attr "mode" "QI")])
8449 (define_insn "*<code>qi_ext_1"
8450 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8455 (match_operand 1 "ext_register_operand" "0")
8459 (match_operand:QI 2 "general_operand" "Qm"))))
8460 (clobber (reg:CC FLAGS_REG))]
8462 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8463 "<logic>{b}\t{%2, %h0|%h0, %2}"
8464 [(set_attr "type" "alu")
8465 (set_attr "length_immediate" "0")
8466 (set_attr "mode" "QI")])
8468 (define_insn "*<code>qi_ext_2"
8469 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8473 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8476 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8479 (clobber (reg:CC FLAGS_REG))]
8480 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8481 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8482 [(set_attr "type" "alu")
8483 (set_attr "length_immediate" "0")
8484 (set_attr "mode" "QI")])
8487 [(set (match_operand 0 "register_operand")
8488 (any_or (match_operand 1 "register_operand")
8489 (match_operand 2 "const_int_operand")))
8490 (clobber (reg:CC FLAGS_REG))]
8492 && QI_REG_P (operands[0])
8493 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8494 && !(INTVAL (operands[2]) & ~(255 << 8))
8495 && GET_MODE (operands[0]) != QImode"
8496 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8497 (any_or:SI (zero_extract:SI (match_dup 1)
8498 (const_int 8) (const_int 8))
8500 (clobber (reg:CC FLAGS_REG))])]
8502 operands[0] = gen_lowpart (SImode, operands[0]);
8503 operands[1] = gen_lowpart (SImode, operands[1]);
8504 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8507 ;; Since OR can be encoded with sign extended immediate, this is only
8508 ;; profitable when 7th bit is set.
8510 [(set (match_operand 0 "register_operand")
8511 (any_or (match_operand 1 "general_operand")
8512 (match_operand 2 "const_int_operand")))
8513 (clobber (reg:CC FLAGS_REG))]
8515 && ANY_QI_REG_P (operands[0])
8516 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8517 && !(INTVAL (operands[2]) & ~255)
8518 && (INTVAL (operands[2]) & 128)
8519 && GET_MODE (operands[0]) != QImode"
8520 [(parallel [(set (strict_low_part (match_dup 0))
8521 (any_or:QI (match_dup 1)
8523 (clobber (reg:CC FLAGS_REG))])]
8525 operands[0] = gen_lowpart (QImode, operands[0]);
8526 operands[1] = gen_lowpart (QImode, operands[1]);
8527 operands[2] = gen_lowpart (QImode, operands[2]);
8530 (define_expand "xorqi_cc_ext_1"
8532 (set (reg:CCNO FLAGS_REG)
8536 (match_operand 1 "ext_register_operand")
8539 (match_operand:QI 2 "general_operand"))
8541 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8551 (define_insn "*xorqi_cc_ext_1_rex64"
8552 [(set (reg FLAGS_REG)
8556 (match_operand 1 "ext_register_operand" "0")
8559 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8561 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8570 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8571 "xor{b}\t{%2, %h0|%h0, %2}"
8572 [(set_attr "type" "alu")
8573 (set_attr "modrm" "1")
8574 (set_attr "mode" "QI")])
8576 (define_insn "*xorqi_cc_ext_1"
8577 [(set (reg FLAGS_REG)
8581 (match_operand 1 "ext_register_operand" "0")
8584 (match_operand:QI 2 "general_operand" "qmn"))
8586 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8595 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8596 "xor{b}\t{%2, %h0|%h0, %2}"
8597 [(set_attr "type" "alu")
8598 (set_attr "modrm" "1")
8599 (set_attr "mode" "QI")])
8601 ;; Negation instructions
8603 (define_expand "neg<mode>2"
8604 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8605 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8607 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8609 (define_insn_and_split "*neg<dwi>2_doubleword"
8610 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8611 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8612 (clobber (reg:CC FLAGS_REG))]
8613 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8617 [(set (reg:CCZ FLAGS_REG)
8618 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8619 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8622 (plus:DWIH (match_dup 3)
8623 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8625 (clobber (reg:CC FLAGS_REG))])
8628 (neg:DWIH (match_dup 2)))
8629 (clobber (reg:CC FLAGS_REG))])]
8630 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8632 (define_insn "*neg<mode>2_1"
8633 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8634 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8635 (clobber (reg:CC FLAGS_REG))]
8636 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8637 "neg{<imodesuffix>}\t%0"
8638 [(set_attr "type" "negnot")
8639 (set_attr "mode" "<MODE>")])
8641 ;; Combine is quite creative about this pattern.
8642 (define_insn "*negsi2_1_zext"
8643 [(set (match_operand:DI 0 "register_operand" "=r")
8645 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8648 (clobber (reg:CC FLAGS_REG))]
8649 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8651 [(set_attr "type" "negnot")
8652 (set_attr "mode" "SI")])
8654 ;; The problem with neg is that it does not perform (compare x 0),
8655 ;; it really performs (compare 0 x), which leaves us with the zero
8656 ;; flag being the only useful item.
8658 (define_insn "*neg<mode>2_cmpz"
8659 [(set (reg:CCZ FLAGS_REG)
8661 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8663 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8664 (neg:SWI (match_dup 1)))]
8665 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8666 "neg{<imodesuffix>}\t%0"
8667 [(set_attr "type" "negnot")
8668 (set_attr "mode" "<MODE>")])
8670 (define_insn "*negsi2_cmpz_zext"
8671 [(set (reg:CCZ FLAGS_REG)
8675 (match_operand:DI 1 "register_operand" "0")
8679 (set (match_operand:DI 0 "register_operand" "=r")
8680 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8683 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8685 [(set_attr "type" "negnot")
8686 (set_attr "mode" "SI")])
8688 ;; Changing of sign for FP values is doable using integer unit too.
8690 (define_expand "<code><mode>2"
8691 [(set (match_operand:X87MODEF 0 "register_operand")
8692 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8693 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8694 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8696 (define_insn "*absneg<mode>2_mixed"
8697 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8698 (match_operator:MODEF 3 "absneg_operator"
8699 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8700 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8701 (clobber (reg:CC FLAGS_REG))]
8702 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8705 (define_insn "*absneg<mode>2_sse"
8706 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8707 (match_operator:MODEF 3 "absneg_operator"
8708 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8709 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8710 (clobber (reg:CC FLAGS_REG))]
8711 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8714 (define_insn "*absneg<mode>2_i387"
8715 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8716 (match_operator:X87MODEF 3 "absneg_operator"
8717 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8718 (use (match_operand 2))
8719 (clobber (reg:CC FLAGS_REG))]
8720 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8723 (define_expand "<code>tf2"
8724 [(set (match_operand:TF 0 "register_operand")
8725 (absneg:TF (match_operand:TF 1 "register_operand")))]
8727 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8729 (define_insn "*absnegtf2_sse"
8730 [(set (match_operand:TF 0 "register_operand" "=x,x")
8731 (match_operator:TF 3 "absneg_operator"
8732 [(match_operand:TF 1 "register_operand" "0,x")]))
8733 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8734 (clobber (reg:CC FLAGS_REG))]
8738 ;; Splitters for fp abs and neg.
8741 [(set (match_operand 0 "fp_register_operand")
8742 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8743 (use (match_operand 2))
8744 (clobber (reg:CC FLAGS_REG))]
8746 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8749 [(set (match_operand 0 "register_operand")
8750 (match_operator 3 "absneg_operator"
8751 [(match_operand 1 "register_operand")]))
8752 (use (match_operand 2 "nonimmediate_operand"))
8753 (clobber (reg:CC FLAGS_REG))]
8754 "reload_completed && SSE_REG_P (operands[0])"
8755 [(set (match_dup 0) (match_dup 3))]
8757 enum machine_mode mode = GET_MODE (operands[0]);
8758 enum machine_mode vmode = GET_MODE (operands[2]);
8761 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8762 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8763 if (operands_match_p (operands[0], operands[2]))
8766 operands[1] = operands[2];
8769 if (GET_CODE (operands[3]) == ABS)
8770 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8772 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8777 [(set (match_operand:SF 0 "register_operand")
8778 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8779 (use (match_operand:V4SF 2))
8780 (clobber (reg:CC FLAGS_REG))]
8782 [(parallel [(set (match_dup 0) (match_dup 1))
8783 (clobber (reg:CC FLAGS_REG))])]
8786 operands[0] = gen_lowpart (SImode, operands[0]);
8787 if (GET_CODE (operands[1]) == ABS)
8789 tmp = gen_int_mode (0x7fffffff, SImode);
8790 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8794 tmp = gen_int_mode (0x80000000, SImode);
8795 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8801 [(set (match_operand:DF 0 "register_operand")
8802 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8803 (use (match_operand 2))
8804 (clobber (reg:CC FLAGS_REG))]
8806 [(parallel [(set (match_dup 0) (match_dup 1))
8807 (clobber (reg:CC FLAGS_REG))])]
8812 tmp = gen_lowpart (DImode, operands[0]);
8813 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8816 if (GET_CODE (operands[1]) == ABS)
8819 tmp = gen_rtx_NOT (DImode, tmp);
8823 operands[0] = gen_highpart (SImode, operands[0]);
8824 if (GET_CODE (operands[1]) == ABS)
8826 tmp = gen_int_mode (0x7fffffff, SImode);
8827 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8831 tmp = gen_int_mode (0x80000000, SImode);
8832 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8839 [(set (match_operand:XF 0 "register_operand")
8840 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8841 (use (match_operand 2))
8842 (clobber (reg:CC FLAGS_REG))]
8844 [(parallel [(set (match_dup 0) (match_dup 1))
8845 (clobber (reg:CC FLAGS_REG))])]
8848 operands[0] = gen_rtx_REG (SImode,
8849 true_regnum (operands[0])
8850 + (TARGET_64BIT ? 1 : 2));
8851 if (GET_CODE (operands[1]) == ABS)
8853 tmp = GEN_INT (0x7fff);
8854 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8858 tmp = GEN_INT (0x8000);
8859 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8864 ;; Conditionalize these after reload. If they match before reload, we
8865 ;; lose the clobber and ability to use integer instructions.
8867 (define_insn "*<code><mode>2_1"
8868 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8869 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8871 && (reload_completed
8872 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8873 "f<absneg_mnemonic>"
8874 [(set_attr "type" "fsgn")
8875 (set_attr "mode" "<MODE>")])
8877 (define_insn "*<code>extendsfdf2"
8878 [(set (match_operand:DF 0 "register_operand" "=f")
8879 (absneg:DF (float_extend:DF
8880 (match_operand:SF 1 "register_operand" "0"))))]
8881 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8882 "f<absneg_mnemonic>"
8883 [(set_attr "type" "fsgn")
8884 (set_attr "mode" "DF")])
8886 (define_insn "*<code>extendsfxf2"
8887 [(set (match_operand:XF 0 "register_operand" "=f")
8888 (absneg:XF (float_extend:XF
8889 (match_operand:SF 1 "register_operand" "0"))))]
8891 "f<absneg_mnemonic>"
8892 [(set_attr "type" "fsgn")
8893 (set_attr "mode" "XF")])
8895 (define_insn "*<code>extenddfxf2"
8896 [(set (match_operand:XF 0 "register_operand" "=f")
8897 (absneg:XF (float_extend:XF
8898 (match_operand:DF 1 "register_operand" "0"))))]
8900 "f<absneg_mnemonic>"
8901 [(set_attr "type" "fsgn")
8902 (set_attr "mode" "XF")])
8904 ;; Copysign instructions
8906 (define_mode_iterator CSGNMODE [SF DF TF])
8907 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8909 (define_expand "copysign<mode>3"
8910 [(match_operand:CSGNMODE 0 "register_operand")
8911 (match_operand:CSGNMODE 1 "nonmemory_operand")
8912 (match_operand:CSGNMODE 2 "register_operand")]
8913 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8914 || (TARGET_SSE && (<MODE>mode == TFmode))"
8915 "ix86_expand_copysign (operands); DONE;")
8917 (define_insn_and_split "copysign<mode>3_const"
8918 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8920 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8921 (match_operand:CSGNMODE 2 "register_operand" "0")
8922 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8924 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8925 || (TARGET_SSE && (<MODE>mode == TFmode))"
8927 "&& reload_completed"
8929 "ix86_split_copysign_const (operands); DONE;")
8931 (define_insn "copysign<mode>3_var"
8932 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8934 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8935 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8936 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8937 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8939 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8940 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8941 || (TARGET_SSE && (<MODE>mode == TFmode))"
8945 [(set (match_operand:CSGNMODE 0 "register_operand")
8947 [(match_operand:CSGNMODE 2 "register_operand")
8948 (match_operand:CSGNMODE 3 "register_operand")
8949 (match_operand:<CSGNVMODE> 4)
8950 (match_operand:<CSGNVMODE> 5)]
8952 (clobber (match_scratch:<CSGNVMODE> 1))]
8953 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8954 || (TARGET_SSE && (<MODE>mode == TFmode)))
8955 && reload_completed"
8957 "ix86_split_copysign_var (operands); DONE;")
8959 ;; One complement instructions
8961 (define_expand "one_cmpl<mode>2"
8962 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8963 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
8965 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8967 (define_insn "*one_cmpl<mode>2_1"
8968 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8969 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8970 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8971 "not{<imodesuffix>}\t%0"
8972 [(set_attr "type" "negnot")
8973 (set_attr "mode" "<MODE>")])
8975 ;; %%% Potential partial reg stall on alternative 1. What to do?
8976 (define_insn "*one_cmplqi2_1"
8977 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8978 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8979 "ix86_unary_operator_ok (NOT, QImode, operands)"
8983 [(set_attr "type" "negnot")
8984 (set_attr "mode" "QI,SI")])
8986 ;; ??? Currently never generated - xor is used instead.
8987 (define_insn "*one_cmplsi2_1_zext"
8988 [(set (match_operand:DI 0 "register_operand" "=r")
8990 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8991 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8993 [(set_attr "type" "negnot")
8994 (set_attr "mode" "SI")])
8996 (define_insn "*one_cmpl<mode>2_2"
8997 [(set (reg FLAGS_REG)
8998 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9000 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9001 (not:SWI (match_dup 1)))]
9002 "ix86_match_ccmode (insn, CCNOmode)
9003 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9005 [(set_attr "type" "alu1")
9006 (set_attr "mode" "<MODE>")])
9009 [(set (match_operand 0 "flags_reg_operand")
9010 (match_operator 2 "compare_operator"
9011 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
9013 (set (match_operand:SWI 1 "nonimmediate_operand")
9014 (not:SWI (match_dup 3)))]
9015 "ix86_match_ccmode (insn, CCNOmode)"
9016 [(parallel [(set (match_dup 0)
9017 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9020 (xor:SWI (match_dup 3) (const_int -1)))])])
9022 ;; ??? Currently never generated - xor is used instead.
9023 (define_insn "*one_cmplsi2_2_zext"
9024 [(set (reg FLAGS_REG)
9025 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9027 (set (match_operand:DI 0 "register_operand" "=r")
9028 (zero_extend:DI (not:SI (match_dup 1))))]
9029 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9030 && ix86_unary_operator_ok (NOT, SImode, operands)"
9032 [(set_attr "type" "alu1")
9033 (set_attr "mode" "SI")])
9036 [(set (match_operand 0 "flags_reg_operand")
9037 (match_operator 2 "compare_operator"
9038 [(not:SI (match_operand:SI 3 "register_operand"))
9040 (set (match_operand:DI 1 "register_operand")
9041 (zero_extend:DI (not:SI (match_dup 3))))]
9042 "ix86_match_ccmode (insn, CCNOmode)"
9043 [(parallel [(set (match_dup 0)
9044 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9047 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
9049 ;; Shift instructions
9051 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9052 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9053 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9054 ;; from the assembler input.
9056 ;; This instruction shifts the target reg/mem as usual, but instead of
9057 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9058 ;; is a left shift double, bits are taken from the high order bits of
9059 ;; reg, else if the insn is a shift right double, bits are taken from the
9060 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9061 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9063 ;; Since sh[lr]d does not change the `reg' operand, that is done
9064 ;; separately, making all shifts emit pairs of shift double and normal
9065 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9066 ;; support a 63 bit shift, each shift where the count is in a reg expands
9067 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9069 ;; If the shift count is a constant, we need never emit more than one
9070 ;; shift pair, instead using moves and sign extension for counts greater
9073 (define_expand "ashl<mode>3"
9074 [(set (match_operand:SDWIM 0 "<shift_operand>")
9075 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
9076 (match_operand:QI 2 "nonmemory_operand")))]
9078 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
9080 (define_insn "*ashl<mode>3_doubleword"
9081 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
9082 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
9083 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
9084 (clobber (reg:CC FLAGS_REG))]
9087 [(set_attr "type" "multi")])
9090 [(set (match_operand:DWI 0 "register_operand")
9091 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
9092 (match_operand:QI 2 "nonmemory_operand")))
9093 (clobber (reg:CC FLAGS_REG))]
9094 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9096 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
9098 ;; By default we don't ask for a scratch register, because when DWImode
9099 ;; values are manipulated, registers are already at a premium. But if
9100 ;; we have one handy, we won't turn it away.
9103 [(match_scratch:DWIH 3 "r")
9104 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9106 (match_operand:<DWI> 1 "nonmemory_operand")
9107 (match_operand:QI 2 "nonmemory_operand")))
9108 (clobber (reg:CC FLAGS_REG))])
9112 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9114 (define_insn "x86_64_shld"
9115 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9116 (ior:DI (ashift:DI (match_dup 0)
9117 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9118 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9119 (minus:QI (const_int 64) (match_dup 2)))))
9120 (clobber (reg:CC FLAGS_REG))]
9122 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9123 [(set_attr "type" "ishift")
9124 (set_attr "prefix_0f" "1")
9125 (set_attr "mode" "DI")
9126 (set_attr "athlon_decode" "vector")
9127 (set_attr "amdfam10_decode" "vector")
9128 (set_attr "bdver1_decode" "vector")])
9130 (define_insn "x86_shld"
9131 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9132 (ior:SI (ashift:SI (match_dup 0)
9133 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9134 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9135 (minus:QI (const_int 32) (match_dup 2)))))
9136 (clobber (reg:CC FLAGS_REG))]
9138 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9139 [(set_attr "type" "ishift")
9140 (set_attr "prefix_0f" "1")
9141 (set_attr "mode" "SI")
9142 (set_attr "pent_pair" "np")
9143 (set_attr "athlon_decode" "vector")
9144 (set_attr "amdfam10_decode" "vector")
9145 (set_attr "bdver1_decode" "vector")])
9147 (define_expand "x86_shift<mode>_adj_1"
9148 [(set (reg:CCZ FLAGS_REG)
9149 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
9152 (set (match_operand:SWI48 0 "register_operand")
9153 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9154 (match_operand:SWI48 1 "register_operand")
9157 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9158 (match_operand:SWI48 3 "register_operand")
9161 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9163 (define_expand "x86_shift<mode>_adj_2"
9164 [(use (match_operand:SWI48 0 "register_operand"))
9165 (use (match_operand:SWI48 1 "register_operand"))
9166 (use (match_operand:QI 2 "register_operand"))]
9169 rtx label = gen_label_rtx ();
9172 emit_insn (gen_testqi_ccz_1 (operands[2],
9173 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9175 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9176 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9177 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9178 gen_rtx_LABEL_REF (VOIDmode, label),
9180 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9181 JUMP_LABEL (tmp) = label;
9183 emit_move_insn (operands[0], operands[1]);
9184 ix86_expand_clear (operands[1]);
9187 LABEL_NUSES (label) = 1;
9192 ;; Avoid useless masking of count operand.
9193 (define_insn "*ashl<mode>3_mask"
9194 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9196 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9199 (match_operand:SI 2 "register_operand" "c")
9200 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9201 (clobber (reg:CC FLAGS_REG))]
9202 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9203 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9204 == GET_MODE_BITSIZE (<MODE>mode)-1"
9206 return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9208 [(set_attr "type" "ishift")
9209 (set_attr "mode" "<MODE>")])
9211 (define_insn "*bmi2_ashl<mode>3_1"
9212 [(set (match_operand:SWI48 0 "register_operand" "=r")
9213 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9214 (match_operand:SWI48 2 "register_operand" "r")))]
9216 "shlx\t{%2, %1, %0|%0, %1, %2}"
9217 [(set_attr "type" "ishiftx")
9218 (set_attr "mode" "<MODE>")])
9220 (define_insn "*ashl<mode>3_1"
9221 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9222 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9223 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9224 (clobber (reg:CC FLAGS_REG))]
9225 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9227 switch (get_attr_type (insn))
9234 gcc_assert (operands[2] == const1_rtx);
9235 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9236 return "add{<imodesuffix>}\t%0, %0";
9239 if (operands[2] == const1_rtx
9240 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9241 return "sal{<imodesuffix>}\t%0";
9243 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9246 [(set_attr "isa" "*,*,bmi2")
9248 (cond [(eq_attr "alternative" "1")
9249 (const_string "lea")
9250 (eq_attr "alternative" "2")
9251 (const_string "ishiftx")
9252 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9253 (match_operand 0 "register_operand"))
9254 (match_operand 2 "const1_operand"))
9255 (const_string "alu")
9257 (const_string "ishift")))
9258 (set (attr "length_immediate")
9260 (ior (eq_attr "type" "alu")
9261 (and (eq_attr "type" "ishift")
9262 (and (match_operand 2 "const1_operand")
9263 (ior (match_test "TARGET_SHIFT1")
9264 (match_test "optimize_function_for_size_p (cfun)")))))
9266 (const_string "*")))
9267 (set_attr "mode" "<MODE>")])
9269 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9271 [(set (match_operand:SWI48 0 "register_operand")
9272 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9273 (match_operand:QI 2 "register_operand")))
9274 (clobber (reg:CC FLAGS_REG))]
9275 "TARGET_BMI2 && reload_completed"
9277 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9278 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9280 (define_insn "*bmi2_ashlsi3_1_zext"
9281 [(set (match_operand:DI 0 "register_operand" "=r")
9283 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9284 (match_operand:SI 2 "register_operand" "r"))))]
9285 "TARGET_64BIT && TARGET_BMI2"
9286 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9287 [(set_attr "type" "ishiftx")
9288 (set_attr "mode" "SI")])
9290 (define_insn "*ashlsi3_1_zext"
9291 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9293 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9294 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9295 (clobber (reg:CC FLAGS_REG))]
9296 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9298 switch (get_attr_type (insn))
9305 gcc_assert (operands[2] == const1_rtx);
9306 return "add{l}\t%k0, %k0";
9309 if (operands[2] == const1_rtx
9310 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9311 return "sal{l}\t%k0";
9313 return "sal{l}\t{%2, %k0|%k0, %2}";
9316 [(set_attr "isa" "*,*,bmi2")
9318 (cond [(eq_attr "alternative" "1")
9319 (const_string "lea")
9320 (eq_attr "alternative" "2")
9321 (const_string "ishiftx")
9322 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9323 (match_operand 2 "const1_operand"))
9324 (const_string "alu")
9326 (const_string "ishift")))
9327 (set (attr "length_immediate")
9329 (ior (eq_attr "type" "alu")
9330 (and (eq_attr "type" "ishift")
9331 (and (match_operand 2 "const1_operand")
9332 (ior (match_test "TARGET_SHIFT1")
9333 (match_test "optimize_function_for_size_p (cfun)")))))
9335 (const_string "*")))
9336 (set_attr "mode" "SI")])
9338 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9340 [(set (match_operand:DI 0 "register_operand")
9342 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9343 (match_operand:QI 2 "register_operand"))))
9344 (clobber (reg:CC FLAGS_REG))]
9345 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9347 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9348 "operands[2] = gen_lowpart (SImode, operands[2]);")
9350 (define_insn "*ashlhi3_1"
9351 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9352 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9353 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9354 (clobber (reg:CC FLAGS_REG))]
9355 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9357 switch (get_attr_type (insn))
9363 gcc_assert (operands[2] == const1_rtx);
9364 return "add{w}\t%0, %0";
9367 if (operands[2] == const1_rtx
9368 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9369 return "sal{w}\t%0";
9371 return "sal{w}\t{%2, %0|%0, %2}";
9375 (cond [(eq_attr "alternative" "1")
9376 (const_string "lea")
9377 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9378 (match_operand 0 "register_operand"))
9379 (match_operand 2 "const1_operand"))
9380 (const_string "alu")
9382 (const_string "ishift")))
9383 (set (attr "length_immediate")
9385 (ior (eq_attr "type" "alu")
9386 (and (eq_attr "type" "ishift")
9387 (and (match_operand 2 "const1_operand")
9388 (ior (match_test "TARGET_SHIFT1")
9389 (match_test "optimize_function_for_size_p (cfun)")))))
9391 (const_string "*")))
9392 (set_attr "mode" "HI,SI")])
9394 ;; %%% Potential partial reg stall on alternative 1. What to do?
9395 (define_insn "*ashlqi3_1"
9396 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9397 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9398 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9399 (clobber (reg:CC FLAGS_REG))]
9400 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9402 switch (get_attr_type (insn))
9408 gcc_assert (operands[2] == const1_rtx);
9409 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9410 return "add{l}\t%k0, %k0";
9412 return "add{b}\t%0, %0";
9415 if (operands[2] == const1_rtx
9416 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9418 if (get_attr_mode (insn) == MODE_SI)
9419 return "sal{l}\t%k0";
9421 return "sal{b}\t%0";
9425 if (get_attr_mode (insn) == MODE_SI)
9426 return "sal{l}\t{%2, %k0|%k0, %2}";
9428 return "sal{b}\t{%2, %0|%0, %2}";
9433 (cond [(eq_attr "alternative" "2")
9434 (const_string "lea")
9435 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9436 (match_operand 0 "register_operand"))
9437 (match_operand 2 "const1_operand"))
9438 (const_string "alu")
9440 (const_string "ishift")))
9441 (set (attr "length_immediate")
9443 (ior (eq_attr "type" "alu")
9444 (and (eq_attr "type" "ishift")
9445 (and (match_operand 2 "const1_operand")
9446 (ior (match_test "TARGET_SHIFT1")
9447 (match_test "optimize_function_for_size_p (cfun)")))))
9449 (const_string "*")))
9450 (set_attr "mode" "QI,SI,SI")])
9452 (define_insn "*ashlqi3_1_slp"
9453 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9454 (ashift:QI (match_dup 0)
9455 (match_operand:QI 1 "nonmemory_operand" "cI")))
9456 (clobber (reg:CC FLAGS_REG))]
9457 "(optimize_function_for_size_p (cfun)
9458 || !TARGET_PARTIAL_FLAG_REG_STALL
9459 || (operands[1] == const1_rtx
9461 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9463 switch (get_attr_type (insn))
9466 gcc_assert (operands[1] == const1_rtx);
9467 return "add{b}\t%0, %0";
9470 if (operands[1] == const1_rtx
9471 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9472 return "sal{b}\t%0";
9474 return "sal{b}\t{%1, %0|%0, %1}";
9478 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9479 (match_operand 0 "register_operand"))
9480 (match_operand 1 "const1_operand"))
9481 (const_string "alu")
9483 (const_string "ishift1")))
9484 (set (attr "length_immediate")
9486 (ior (eq_attr "type" "alu")
9487 (and (eq_attr "type" "ishift1")
9488 (and (match_operand 1 "const1_operand")
9489 (ior (match_test "TARGET_SHIFT1")
9490 (match_test "optimize_function_for_size_p (cfun)")))))
9492 (const_string "*")))
9493 (set_attr "mode" "QI")])
9495 ;; Convert ashift to the lea pattern to avoid flags dependency.
9497 [(set (match_operand 0 "register_operand")
9498 (ashift (match_operand 1 "index_register_operand")
9499 (match_operand:QI 2 "const_int_operand")))
9500 (clobber (reg:CC FLAGS_REG))]
9501 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9503 && true_regnum (operands[0]) != true_regnum (operands[1])"
9506 enum machine_mode mode = GET_MODE (operands[0]);
9509 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9512 operands[0] = gen_lowpart (mode, operands[0]);
9513 operands[1] = gen_lowpart (mode, operands[1]);
9516 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9518 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9520 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9524 ;; Convert ashift to the lea pattern to avoid flags dependency.
9526 [(set (match_operand:DI 0 "register_operand")
9528 (ashift:SI (match_operand:SI 1 "index_register_operand")
9529 (match_operand:QI 2 "const_int_operand"))))
9530 (clobber (reg:CC FLAGS_REG))]
9531 "TARGET_64BIT && reload_completed
9532 && true_regnum (operands[0]) != true_regnum (operands[1])"
9534 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
9536 operands[1] = gen_lowpart (SImode, operands[1]);
9537 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), SImode);
9540 ;; This pattern can't accept a variable shift count, since shifts by
9541 ;; zero don't affect the flags. We assume that shifts by constant
9542 ;; zero are optimized away.
9543 (define_insn "*ashl<mode>3_cmp"
9544 [(set (reg FLAGS_REG)
9546 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9547 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9549 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9550 (ashift:SWI (match_dup 1) (match_dup 2)))]
9551 "(optimize_function_for_size_p (cfun)
9552 || !TARGET_PARTIAL_FLAG_REG_STALL
9553 || (operands[2] == const1_rtx
9555 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9556 && ix86_match_ccmode (insn, CCGOCmode)
9557 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9559 switch (get_attr_type (insn))
9562 gcc_assert (operands[2] == const1_rtx);
9563 return "add{<imodesuffix>}\t%0, %0";
9566 if (operands[2] == const1_rtx
9567 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9568 return "sal{<imodesuffix>}\t%0";
9570 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9574 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9575 (match_operand 0 "register_operand"))
9576 (match_operand 2 "const1_operand"))
9577 (const_string "alu")
9579 (const_string "ishift")))
9580 (set (attr "length_immediate")
9582 (ior (eq_attr "type" "alu")
9583 (and (eq_attr "type" "ishift")
9584 (and (match_operand 2 "const1_operand")
9585 (ior (match_test "TARGET_SHIFT1")
9586 (match_test "optimize_function_for_size_p (cfun)")))))
9588 (const_string "*")))
9589 (set_attr "mode" "<MODE>")])
9591 (define_insn "*ashlsi3_cmp_zext"
9592 [(set (reg FLAGS_REG)
9594 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9595 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9597 (set (match_operand:DI 0 "register_operand" "=r")
9598 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9600 && (optimize_function_for_size_p (cfun)
9601 || !TARGET_PARTIAL_FLAG_REG_STALL
9602 || (operands[2] == const1_rtx
9604 || TARGET_DOUBLE_WITH_ADD)))
9605 && ix86_match_ccmode (insn, CCGOCmode)
9606 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9608 switch (get_attr_type (insn))
9611 gcc_assert (operands[2] == const1_rtx);
9612 return "add{l}\t%k0, %k0";
9615 if (operands[2] == const1_rtx
9616 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9617 return "sal{l}\t%k0";
9619 return "sal{l}\t{%2, %k0|%k0, %2}";
9623 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9624 (match_operand 2 "const1_operand"))
9625 (const_string "alu")
9627 (const_string "ishift")))
9628 (set (attr "length_immediate")
9630 (ior (eq_attr "type" "alu")
9631 (and (eq_attr "type" "ishift")
9632 (and (match_operand 2 "const1_operand")
9633 (ior (match_test "TARGET_SHIFT1")
9634 (match_test "optimize_function_for_size_p (cfun)")))))
9636 (const_string "*")))
9637 (set_attr "mode" "SI")])
9639 (define_insn "*ashl<mode>3_cconly"
9640 [(set (reg FLAGS_REG)
9642 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9643 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9645 (clobber (match_scratch:SWI 0 "=<r>"))]
9646 "(optimize_function_for_size_p (cfun)
9647 || !TARGET_PARTIAL_FLAG_REG_STALL
9648 || (operands[2] == const1_rtx
9650 || TARGET_DOUBLE_WITH_ADD)))
9651 && ix86_match_ccmode (insn, CCGOCmode)"
9653 switch (get_attr_type (insn))
9656 gcc_assert (operands[2] == const1_rtx);
9657 return "add{<imodesuffix>}\t%0, %0";
9660 if (operands[2] == const1_rtx
9661 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9662 return "sal{<imodesuffix>}\t%0";
9664 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9668 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9669 (match_operand 0 "register_operand"))
9670 (match_operand 2 "const1_operand"))
9671 (const_string "alu")
9673 (const_string "ishift")))
9674 (set (attr "length_immediate")
9676 (ior (eq_attr "type" "alu")
9677 (and (eq_attr "type" "ishift")
9678 (and (match_operand 2 "const1_operand")
9679 (ior (match_test "TARGET_SHIFT1")
9680 (match_test "optimize_function_for_size_p (cfun)")))))
9682 (const_string "*")))
9683 (set_attr "mode" "<MODE>")])
9685 ;; See comment above `ashl<mode>3' about how this works.
9687 (define_expand "<shift_insn><mode>3"
9688 [(set (match_operand:SDWIM 0 "<shift_operand>")
9689 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9690 (match_operand:QI 2 "nonmemory_operand")))]
9692 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9694 ;; Avoid useless masking of count operand.
9695 (define_insn "*<shift_insn><mode>3_mask"
9696 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9698 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9701 (match_operand:SI 2 "register_operand" "c")
9702 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9703 (clobber (reg:CC FLAGS_REG))]
9704 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9705 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9706 == GET_MODE_BITSIZE (<MODE>mode)-1"
9708 return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9710 [(set_attr "type" "ishift")
9711 (set_attr "mode" "<MODE>")])
9713 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9714 [(set (match_operand:DWI 0 "register_operand" "=r")
9715 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9716 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9717 (clobber (reg:CC FLAGS_REG))]
9720 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9722 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9723 [(set_attr "type" "multi")])
9725 ;; By default we don't ask for a scratch register, because when DWImode
9726 ;; values are manipulated, registers are already at a premium. But if
9727 ;; we have one handy, we won't turn it away.
9730 [(match_scratch:DWIH 3 "r")
9731 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9733 (match_operand:<DWI> 1 "register_operand")
9734 (match_operand:QI 2 "nonmemory_operand")))
9735 (clobber (reg:CC FLAGS_REG))])
9739 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9741 (define_insn "x86_64_shrd"
9742 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9743 (ior:DI (ashiftrt:DI (match_dup 0)
9744 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9745 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9746 (minus:QI (const_int 64) (match_dup 2)))))
9747 (clobber (reg:CC FLAGS_REG))]
9749 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9750 [(set_attr "type" "ishift")
9751 (set_attr "prefix_0f" "1")
9752 (set_attr "mode" "DI")
9753 (set_attr "athlon_decode" "vector")
9754 (set_attr "amdfam10_decode" "vector")
9755 (set_attr "bdver1_decode" "vector")])
9757 (define_insn "x86_shrd"
9758 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9759 (ior:SI (ashiftrt:SI (match_dup 0)
9760 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9761 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9762 (minus:QI (const_int 32) (match_dup 2)))))
9763 (clobber (reg:CC FLAGS_REG))]
9765 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9766 [(set_attr "type" "ishift")
9767 (set_attr "prefix_0f" "1")
9768 (set_attr "mode" "SI")
9769 (set_attr "pent_pair" "np")
9770 (set_attr "athlon_decode" "vector")
9771 (set_attr "amdfam10_decode" "vector")
9772 (set_attr "bdver1_decode" "vector")])
9774 (define_insn "ashrdi3_cvt"
9775 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9776 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9777 (match_operand:QI 2 "const_int_operand")))
9778 (clobber (reg:CC FLAGS_REG))]
9779 "TARGET_64BIT && INTVAL (operands[2]) == 63
9780 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9781 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9784 sar{q}\t{%2, %0|%0, %2}"
9785 [(set_attr "type" "imovx,ishift")
9786 (set_attr "prefix_0f" "0,*")
9787 (set_attr "length_immediate" "0,*")
9788 (set_attr "modrm" "0,1")
9789 (set_attr "mode" "DI")])
9791 (define_insn "ashrsi3_cvt"
9792 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9793 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9794 (match_operand:QI 2 "const_int_operand")))
9795 (clobber (reg:CC FLAGS_REG))]
9796 "INTVAL (operands[2]) == 31
9797 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9798 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9801 sar{l}\t{%2, %0|%0, %2}"
9802 [(set_attr "type" "imovx,ishift")
9803 (set_attr "prefix_0f" "0,*")
9804 (set_attr "length_immediate" "0,*")
9805 (set_attr "modrm" "0,1")
9806 (set_attr "mode" "SI")])
9808 (define_insn "*ashrsi3_cvt_zext"
9809 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9811 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9812 (match_operand:QI 2 "const_int_operand"))))
9813 (clobber (reg:CC FLAGS_REG))]
9814 "TARGET_64BIT && INTVAL (operands[2]) == 31
9815 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9816 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9819 sar{l}\t{%2, %k0|%k0, %2}"
9820 [(set_attr "type" "imovx,ishift")
9821 (set_attr "prefix_0f" "0,*")
9822 (set_attr "length_immediate" "0,*")
9823 (set_attr "modrm" "0,1")
9824 (set_attr "mode" "SI")])
9826 (define_expand "x86_shift<mode>_adj_3"
9827 [(use (match_operand:SWI48 0 "register_operand"))
9828 (use (match_operand:SWI48 1 "register_operand"))
9829 (use (match_operand:QI 2 "register_operand"))]
9832 rtx label = gen_label_rtx ();
9835 emit_insn (gen_testqi_ccz_1 (operands[2],
9836 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9838 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9839 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9840 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9841 gen_rtx_LABEL_REF (VOIDmode, label),
9843 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9844 JUMP_LABEL (tmp) = label;
9846 emit_move_insn (operands[0], operands[1]);
9847 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9848 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9850 LABEL_NUSES (label) = 1;
9855 (define_insn "*bmi2_<shift_insn><mode>3_1"
9856 [(set (match_operand:SWI48 0 "register_operand" "=r")
9857 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9858 (match_operand:SWI48 2 "register_operand" "r")))]
9860 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9861 [(set_attr "type" "ishiftx")
9862 (set_attr "mode" "<MODE>")])
9864 (define_insn "*<shift_insn><mode>3_1"
9865 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9867 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9868 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9869 (clobber (reg:CC FLAGS_REG))]
9870 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9872 switch (get_attr_type (insn))
9878 if (operands[2] == const1_rtx
9879 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9880 return "<shift>{<imodesuffix>}\t%0";
9882 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9885 [(set_attr "isa" "*,bmi2")
9886 (set_attr "type" "ishift,ishiftx")
9887 (set (attr "length_immediate")
9889 (and (match_operand 2 "const1_operand")
9890 (ior (match_test "TARGET_SHIFT1")
9891 (match_test "optimize_function_for_size_p (cfun)")))
9893 (const_string "*")))
9894 (set_attr "mode" "<MODE>")])
9896 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9898 [(set (match_operand:SWI48 0 "register_operand")
9899 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9900 (match_operand:QI 2 "register_operand")))
9901 (clobber (reg:CC FLAGS_REG))]
9902 "TARGET_BMI2 && reload_completed"
9904 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9905 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9907 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9908 [(set (match_operand:DI 0 "register_operand" "=r")
9910 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9911 (match_operand:SI 2 "register_operand" "r"))))]
9912 "TARGET_64BIT && TARGET_BMI2"
9913 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9914 [(set_attr "type" "ishiftx")
9915 (set_attr "mode" "SI")])
9917 (define_insn "*<shift_insn>si3_1_zext"
9918 [(set (match_operand:DI 0 "register_operand" "=r,r")
9920 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9921 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9922 (clobber (reg:CC FLAGS_REG))]
9923 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9925 switch (get_attr_type (insn))
9931 if (operands[2] == const1_rtx
9932 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9933 return "<shift>{l}\t%k0";
9935 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9938 [(set_attr "isa" "*,bmi2")
9939 (set_attr "type" "ishift,ishiftx")
9940 (set (attr "length_immediate")
9942 (and (match_operand 2 "const1_operand")
9943 (ior (match_test "TARGET_SHIFT1")
9944 (match_test "optimize_function_for_size_p (cfun)")))
9946 (const_string "*")))
9947 (set_attr "mode" "SI")])
9949 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9951 [(set (match_operand:DI 0 "register_operand")
9953 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
9954 (match_operand:QI 2 "register_operand"))))
9955 (clobber (reg:CC FLAGS_REG))]
9956 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9958 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9959 "operands[2] = gen_lowpart (SImode, operands[2]);")
9961 (define_insn "*<shift_insn><mode>3_1"
9962 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9964 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9965 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9966 (clobber (reg:CC FLAGS_REG))]
9967 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9969 if (operands[2] == const1_rtx
9970 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9971 return "<shift>{<imodesuffix>}\t%0";
9973 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9975 [(set_attr "type" "ishift")
9976 (set (attr "length_immediate")
9978 (and (match_operand 2 "const1_operand")
9979 (ior (match_test "TARGET_SHIFT1")
9980 (match_test "optimize_function_for_size_p (cfun)")))
9982 (const_string "*")))
9983 (set_attr "mode" "<MODE>")])
9985 (define_insn "*<shift_insn>qi3_1_slp"
9986 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9987 (any_shiftrt:QI (match_dup 0)
9988 (match_operand:QI 1 "nonmemory_operand" "cI")))
9989 (clobber (reg:CC FLAGS_REG))]
9990 "(optimize_function_for_size_p (cfun)
9991 || !TARGET_PARTIAL_REG_STALL
9992 || (operands[1] == const1_rtx
9995 if (operands[1] == const1_rtx
9996 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9997 return "<shift>{b}\t%0";
9999 return "<shift>{b}\t{%1, %0|%0, %1}";
10001 [(set_attr "type" "ishift1")
10002 (set (attr "length_immediate")
10004 (and (match_operand 1 "const1_operand")
10005 (ior (match_test "TARGET_SHIFT1")
10006 (match_test "optimize_function_for_size_p (cfun)")))
10008 (const_string "*")))
10009 (set_attr "mode" "QI")])
10011 ;; This pattern can't accept a variable shift count, since shifts by
10012 ;; zero don't affect the flags. We assume that shifts by constant
10013 ;; zero are optimized away.
10014 (define_insn "*<shift_insn><mode>3_cmp"
10015 [(set (reg FLAGS_REG)
10018 (match_operand:SWI 1 "nonimmediate_operand" "0")
10019 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10021 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10022 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
10023 "(optimize_function_for_size_p (cfun)
10024 || !TARGET_PARTIAL_FLAG_REG_STALL
10025 || (operands[2] == const1_rtx
10027 && ix86_match_ccmode (insn, CCGOCmode)
10028 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10030 if (operands[2] == const1_rtx
10031 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10032 return "<shift>{<imodesuffix>}\t%0";
10034 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10036 [(set_attr "type" "ishift")
10037 (set (attr "length_immediate")
10039 (and (match_operand 2 "const1_operand")
10040 (ior (match_test "TARGET_SHIFT1")
10041 (match_test "optimize_function_for_size_p (cfun)")))
10043 (const_string "*")))
10044 (set_attr "mode" "<MODE>")])
10046 (define_insn "*<shift_insn>si3_cmp_zext"
10047 [(set (reg FLAGS_REG)
10049 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
10050 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10052 (set (match_operand:DI 0 "register_operand" "=r")
10053 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
10055 && (optimize_function_for_size_p (cfun)
10056 || !TARGET_PARTIAL_FLAG_REG_STALL
10057 || (operands[2] == const1_rtx
10059 && ix86_match_ccmode (insn, CCGOCmode)
10060 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10062 if (operands[2] == const1_rtx
10063 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10064 return "<shift>{l}\t%k0";
10066 return "<shift>{l}\t{%2, %k0|%k0, %2}";
10068 [(set_attr "type" "ishift")
10069 (set (attr "length_immediate")
10071 (and (match_operand 2 "const1_operand")
10072 (ior (match_test "TARGET_SHIFT1")
10073 (match_test "optimize_function_for_size_p (cfun)")))
10075 (const_string "*")))
10076 (set_attr "mode" "SI")])
10078 (define_insn "*<shift_insn><mode>3_cconly"
10079 [(set (reg FLAGS_REG)
10082 (match_operand:SWI 1 "register_operand" "0")
10083 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
10085 (clobber (match_scratch:SWI 0 "=<r>"))]
10086 "(optimize_function_for_size_p (cfun)
10087 || !TARGET_PARTIAL_FLAG_REG_STALL
10088 || (operands[2] == const1_rtx
10090 && ix86_match_ccmode (insn, CCGOCmode)"
10092 if (operands[2] == const1_rtx
10093 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10094 return "<shift>{<imodesuffix>}\t%0";
10096 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
10098 [(set_attr "type" "ishift")
10099 (set (attr "length_immediate")
10101 (and (match_operand 2 "const1_operand")
10102 (ior (match_test "TARGET_SHIFT1")
10103 (match_test "optimize_function_for_size_p (cfun)")))
10105 (const_string "*")))
10106 (set_attr "mode" "<MODE>")])
10108 ;; Rotate instructions
10110 (define_expand "<rotate_insn>ti3"
10111 [(set (match_operand:TI 0 "register_operand")
10112 (any_rotate:TI (match_operand:TI 1 "register_operand")
10113 (match_operand:QI 2 "nonmemory_operand")))]
10116 if (const_1_to_63_operand (operands[2], VOIDmode))
10117 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10118 (operands[0], operands[1], operands[2]));
10125 (define_expand "<rotate_insn>di3"
10126 [(set (match_operand:DI 0 "shiftdi_operand")
10127 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
10128 (match_operand:QI 2 "nonmemory_operand")))]
10132 ix86_expand_binary_operator (<CODE>, DImode, operands);
10133 else if (const_1_to_31_operand (operands[2], VOIDmode))
10134 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10135 (operands[0], operands[1], operands[2]));
10142 (define_expand "<rotate_insn><mode>3"
10143 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
10144 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
10145 (match_operand:QI 2 "nonmemory_operand")))]
10147 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10149 ;; Avoid useless masking of count operand.
10150 (define_insn "*<rotate_insn><mode>3_mask"
10151 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10153 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10156 (match_operand:SI 2 "register_operand" "c")
10157 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10158 (clobber (reg:CC FLAGS_REG))]
10159 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10160 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10161 == GET_MODE_BITSIZE (<MODE>mode)-1"
10163 return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10165 [(set_attr "type" "rotate")
10166 (set_attr "mode" "<MODE>")])
10168 ;; Implement rotation using two double-precision
10169 ;; shift instructions and a scratch register.
10171 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10172 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10173 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10174 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10175 (clobber (reg:CC FLAGS_REG))
10176 (clobber (match_scratch:DWIH 3 "=&r"))]
10180 [(set (match_dup 3) (match_dup 4))
10182 [(set (match_dup 4)
10183 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10184 (lshiftrt:DWIH (match_dup 5)
10185 (minus:QI (match_dup 6) (match_dup 2)))))
10186 (clobber (reg:CC FLAGS_REG))])
10188 [(set (match_dup 5)
10189 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10190 (lshiftrt:DWIH (match_dup 3)
10191 (minus:QI (match_dup 6) (match_dup 2)))))
10192 (clobber (reg:CC FLAGS_REG))])]
10194 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10196 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10199 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10200 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10201 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10202 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10203 (clobber (reg:CC FLAGS_REG))
10204 (clobber (match_scratch:DWIH 3 "=&r"))]
10208 [(set (match_dup 3) (match_dup 4))
10210 [(set (match_dup 4)
10211 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10212 (ashift:DWIH (match_dup 5)
10213 (minus:QI (match_dup 6) (match_dup 2)))))
10214 (clobber (reg:CC FLAGS_REG))])
10216 [(set (match_dup 5)
10217 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10218 (ashift:DWIH (match_dup 3)
10219 (minus:QI (match_dup 6) (match_dup 2)))))
10220 (clobber (reg:CC FLAGS_REG))])]
10222 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10224 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10227 (define_insn "*bmi2_rorx<mode>3_1"
10228 [(set (match_operand:SWI48 0 "register_operand" "=r")
10229 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10230 (match_operand:QI 2 "immediate_operand" "<S>")))]
10232 "rorx\t{%2, %1, %0|%0, %1, %2}"
10233 [(set_attr "type" "rotatex")
10234 (set_attr "mode" "<MODE>")])
10236 (define_insn "*<rotate_insn><mode>3_1"
10237 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10239 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10240 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10241 (clobber (reg:CC FLAGS_REG))]
10242 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10244 switch (get_attr_type (insn))
10250 if (operands[2] == const1_rtx
10251 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10252 return "<rotate>{<imodesuffix>}\t%0";
10254 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10257 [(set_attr "isa" "*,bmi2")
10258 (set_attr "type" "rotate,rotatex")
10259 (set (attr "length_immediate")
10261 (and (eq_attr "type" "rotate")
10262 (and (match_operand 2 "const1_operand")
10263 (ior (match_test "TARGET_SHIFT1")
10264 (match_test "optimize_function_for_size_p (cfun)"))))
10266 (const_string "*")))
10267 (set_attr "mode" "<MODE>")])
10269 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10271 [(set (match_operand:SWI48 0 "register_operand")
10272 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10273 (match_operand:QI 2 "immediate_operand")))
10274 (clobber (reg:CC FLAGS_REG))]
10275 "TARGET_BMI2 && reload_completed"
10276 [(set (match_dup 0)
10277 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10280 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10284 [(set (match_operand:SWI48 0 "register_operand")
10285 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10286 (match_operand:QI 2 "immediate_operand")))
10287 (clobber (reg:CC FLAGS_REG))]
10288 "TARGET_BMI2 && reload_completed"
10289 [(set (match_dup 0)
10290 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10292 (define_insn "*bmi2_rorxsi3_1_zext"
10293 [(set (match_operand:DI 0 "register_operand" "=r")
10295 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10296 (match_operand:QI 2 "immediate_operand" "I"))))]
10297 "TARGET_64BIT && TARGET_BMI2"
10298 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10299 [(set_attr "type" "rotatex")
10300 (set_attr "mode" "SI")])
10302 (define_insn "*<rotate_insn>si3_1_zext"
10303 [(set (match_operand:DI 0 "register_operand" "=r,r")
10305 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10306 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10307 (clobber (reg:CC FLAGS_REG))]
10308 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10310 switch (get_attr_type (insn))
10316 if (operands[2] == const1_rtx
10317 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10318 return "<rotate>{l}\t%k0";
10320 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10323 [(set_attr "isa" "*,bmi2")
10324 (set_attr "type" "rotate,rotatex")
10325 (set (attr "length_immediate")
10327 (and (eq_attr "type" "rotate")
10328 (and (match_operand 2 "const1_operand")
10329 (ior (match_test "TARGET_SHIFT1")
10330 (match_test "optimize_function_for_size_p (cfun)"))))
10332 (const_string "*")))
10333 (set_attr "mode" "SI")])
10335 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10337 [(set (match_operand:DI 0 "register_operand")
10339 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10340 (match_operand:QI 2 "immediate_operand"))))
10341 (clobber (reg:CC FLAGS_REG))]
10342 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10343 [(set (match_dup 0)
10344 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10347 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10351 [(set (match_operand:DI 0 "register_operand")
10353 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10354 (match_operand:QI 2 "immediate_operand"))))
10355 (clobber (reg:CC FLAGS_REG))]
10356 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10357 [(set (match_dup 0)
10358 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10360 (define_insn "*<rotate_insn><mode>3_1"
10361 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10362 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10363 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10364 (clobber (reg:CC FLAGS_REG))]
10365 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10367 if (operands[2] == const1_rtx
10368 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10369 return "<rotate>{<imodesuffix>}\t%0";
10371 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10373 [(set_attr "type" "rotate")
10374 (set (attr "length_immediate")
10376 (and (match_operand 2 "const1_operand")
10377 (ior (match_test "TARGET_SHIFT1")
10378 (match_test "optimize_function_for_size_p (cfun)")))
10380 (const_string "*")))
10381 (set_attr "mode" "<MODE>")])
10383 (define_insn "*<rotate_insn>qi3_1_slp"
10384 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10385 (any_rotate:QI (match_dup 0)
10386 (match_operand:QI 1 "nonmemory_operand" "cI")))
10387 (clobber (reg:CC FLAGS_REG))]
10388 "(optimize_function_for_size_p (cfun)
10389 || !TARGET_PARTIAL_REG_STALL
10390 || (operands[1] == const1_rtx
10391 && TARGET_SHIFT1))"
10393 if (operands[1] == const1_rtx
10394 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10395 return "<rotate>{b}\t%0";
10397 return "<rotate>{b}\t{%1, %0|%0, %1}";
10399 [(set_attr "type" "rotate1")
10400 (set (attr "length_immediate")
10402 (and (match_operand 1 "const1_operand")
10403 (ior (match_test "TARGET_SHIFT1")
10404 (match_test "optimize_function_for_size_p (cfun)")))
10406 (const_string "*")))
10407 (set_attr "mode" "QI")])
10410 [(set (match_operand:HI 0 "register_operand")
10411 (any_rotate:HI (match_dup 0) (const_int 8)))
10412 (clobber (reg:CC FLAGS_REG))]
10414 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10415 [(parallel [(set (strict_low_part (match_dup 0))
10416 (bswap:HI (match_dup 0)))
10417 (clobber (reg:CC FLAGS_REG))])])
10419 ;; Bit set / bit test instructions
10421 (define_expand "extv"
10422 [(set (match_operand:SI 0 "register_operand")
10423 (sign_extract:SI (match_operand:SI 1 "register_operand")
10424 (match_operand:SI 2 "const8_operand")
10425 (match_operand:SI 3 "const8_operand")))]
10428 /* Handle extractions from %ah et al. */
10429 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10432 /* From mips.md: extract_bit_field doesn't verify that our source
10433 matches the predicate, so check it again here. */
10434 if (! ext_register_operand (operands[1], VOIDmode))
10438 (define_expand "extzv"
10439 [(set (match_operand:SI 0 "register_operand")
10440 (zero_extract:SI (match_operand 1 "ext_register_operand")
10441 (match_operand:SI 2 "const8_operand")
10442 (match_operand:SI 3 "const8_operand")))]
10445 /* Handle extractions from %ah et al. */
10446 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10449 /* From mips.md: extract_bit_field doesn't verify that our source
10450 matches the predicate, so check it again here. */
10451 if (! ext_register_operand (operands[1], VOIDmode))
10455 (define_expand "insv"
10456 [(set (zero_extract (match_operand 0 "register_operand")
10457 (match_operand 1 "const_int_operand")
10458 (match_operand 2 "const_int_operand"))
10459 (match_operand 3 "register_operand"))]
10462 rtx (*gen_mov_insv_1) (rtx, rtx);
10464 if (ix86_expand_pinsr (operands))
10467 /* Handle insertions to %ah et al. */
10468 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10471 /* From mips.md: insert_bit_field doesn't verify that our source
10472 matches the predicate, so check it again here. */
10473 if (! ext_register_operand (operands[0], VOIDmode))
10476 gen_mov_insv_1 = (TARGET_64BIT
10477 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10479 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10483 ;; %%% bts, btr, btc, bt.
10484 ;; In general these instructions are *slow* when applied to memory,
10485 ;; since they enforce atomic operation. When applied to registers,
10486 ;; it depends on the cpu implementation. They're never faster than
10487 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10488 ;; no point. But in 64-bit, we can't hold the relevant immediates
10489 ;; within the instruction itself, so operating on bits in the high
10490 ;; 32-bits of a register becomes easier.
10492 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10493 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10494 ;; negdf respectively, so they can never be disabled entirely.
10496 (define_insn "*btsq"
10497 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10499 (match_operand:DI 1 "const_0_to_63_operand"))
10501 (clobber (reg:CC FLAGS_REG))]
10502 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10503 "bts{q}\t{%1, %0|%0, %1}"
10504 [(set_attr "type" "alu1")
10505 (set_attr "prefix_0f" "1")
10506 (set_attr "mode" "DI")])
10508 (define_insn "*btrq"
10509 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10511 (match_operand:DI 1 "const_0_to_63_operand"))
10513 (clobber (reg:CC FLAGS_REG))]
10514 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10515 "btr{q}\t{%1, %0|%0, %1}"
10516 [(set_attr "type" "alu1")
10517 (set_attr "prefix_0f" "1")
10518 (set_attr "mode" "DI")])
10520 (define_insn "*btcq"
10521 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10523 (match_operand:DI 1 "const_0_to_63_operand"))
10524 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10525 (clobber (reg:CC FLAGS_REG))]
10526 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10527 "btc{q}\t{%1, %0|%0, %1}"
10528 [(set_attr "type" "alu1")
10529 (set_attr "prefix_0f" "1")
10530 (set_attr "mode" "DI")])
10532 ;; Allow Nocona to avoid these instructions if a register is available.
10535 [(match_scratch:DI 2 "r")
10536 (parallel [(set (zero_extract:DI
10537 (match_operand:DI 0 "register_operand")
10539 (match_operand:DI 1 "const_0_to_63_operand"))
10541 (clobber (reg:CC FLAGS_REG))])]
10542 "TARGET_64BIT && !TARGET_USE_BT"
10545 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10548 if (HOST_BITS_PER_WIDE_INT >= 64)
10549 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10550 else if (i < HOST_BITS_PER_WIDE_INT)
10551 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10553 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10555 op1 = immed_double_const (lo, hi, DImode);
10558 emit_move_insn (operands[2], op1);
10562 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10567 [(match_scratch:DI 2 "r")
10568 (parallel [(set (zero_extract:DI
10569 (match_operand:DI 0 "register_operand")
10571 (match_operand:DI 1 "const_0_to_63_operand"))
10573 (clobber (reg:CC FLAGS_REG))])]
10574 "TARGET_64BIT && !TARGET_USE_BT"
10577 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10580 if (HOST_BITS_PER_WIDE_INT >= 64)
10581 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10582 else if (i < HOST_BITS_PER_WIDE_INT)
10583 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10585 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10587 op1 = immed_double_const (~lo, ~hi, DImode);
10590 emit_move_insn (operands[2], op1);
10594 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10599 [(match_scratch:DI 2 "r")
10600 (parallel [(set (zero_extract:DI
10601 (match_operand:DI 0 "register_operand")
10603 (match_operand:DI 1 "const_0_to_63_operand"))
10604 (not:DI (zero_extract:DI
10605 (match_dup 0) (const_int 1) (match_dup 1))))
10606 (clobber (reg:CC FLAGS_REG))])]
10607 "TARGET_64BIT && !TARGET_USE_BT"
10610 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10613 if (HOST_BITS_PER_WIDE_INT >= 64)
10614 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10615 else if (i < HOST_BITS_PER_WIDE_INT)
10616 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10618 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10620 op1 = immed_double_const (lo, hi, DImode);
10623 emit_move_insn (operands[2], op1);
10627 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10631 (define_insn "*bt<mode>"
10632 [(set (reg:CCC FLAGS_REG)
10634 (zero_extract:SWI48
10635 (match_operand:SWI48 0 "register_operand" "r")
10637 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10639 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10640 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10641 [(set_attr "type" "alu1")
10642 (set_attr "prefix_0f" "1")
10643 (set_attr "mode" "<MODE>")])
10645 ;; Store-flag instructions.
10647 ;; For all sCOND expanders, also expand the compare or test insn that
10648 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10650 (define_insn_and_split "*setcc_di_1"
10651 [(set (match_operand:DI 0 "register_operand" "=q")
10652 (match_operator:DI 1 "ix86_comparison_operator"
10653 [(reg FLAGS_REG) (const_int 0)]))]
10654 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10656 "&& reload_completed"
10657 [(set (match_dup 2) (match_dup 1))
10658 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10660 PUT_MODE (operands[1], QImode);
10661 operands[2] = gen_lowpart (QImode, operands[0]);
10664 (define_insn_and_split "*setcc_si_1_and"
10665 [(set (match_operand:SI 0 "register_operand" "=q")
10666 (match_operator:SI 1 "ix86_comparison_operator"
10667 [(reg FLAGS_REG) (const_int 0)]))
10668 (clobber (reg:CC FLAGS_REG))]
10669 "!TARGET_PARTIAL_REG_STALL
10670 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10672 "&& reload_completed"
10673 [(set (match_dup 2) (match_dup 1))
10674 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10675 (clobber (reg:CC FLAGS_REG))])]
10677 PUT_MODE (operands[1], QImode);
10678 operands[2] = gen_lowpart (QImode, operands[0]);
10681 (define_insn_and_split "*setcc_si_1_movzbl"
10682 [(set (match_operand:SI 0 "register_operand" "=q")
10683 (match_operator:SI 1 "ix86_comparison_operator"
10684 [(reg FLAGS_REG) (const_int 0)]))]
10685 "!TARGET_PARTIAL_REG_STALL
10686 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10688 "&& reload_completed"
10689 [(set (match_dup 2) (match_dup 1))
10690 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10692 PUT_MODE (operands[1], QImode);
10693 operands[2] = gen_lowpart (QImode, operands[0]);
10696 (define_insn "*setcc_qi"
10697 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10698 (match_operator:QI 1 "ix86_comparison_operator"
10699 [(reg FLAGS_REG) (const_int 0)]))]
10702 [(set_attr "type" "setcc")
10703 (set_attr "mode" "QI")])
10705 (define_insn "*setcc_qi_slp"
10706 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10707 (match_operator:QI 1 "ix86_comparison_operator"
10708 [(reg FLAGS_REG) (const_int 0)]))]
10711 [(set_attr "type" "setcc")
10712 (set_attr "mode" "QI")])
10714 ;; In general it is not safe to assume too much about CCmode registers,
10715 ;; so simplify-rtx stops when it sees a second one. Under certain
10716 ;; conditions this is safe on x86, so help combine not create
10723 [(set (match_operand:QI 0 "nonimmediate_operand")
10724 (ne:QI (match_operator 1 "ix86_comparison_operator"
10725 [(reg FLAGS_REG) (const_int 0)])
10728 [(set (match_dup 0) (match_dup 1))]
10729 "PUT_MODE (operands[1], QImode);")
10732 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10733 (ne:QI (match_operator 1 "ix86_comparison_operator"
10734 [(reg FLAGS_REG) (const_int 0)])
10737 [(set (match_dup 0) (match_dup 1))]
10738 "PUT_MODE (operands[1], QImode);")
10741 [(set (match_operand:QI 0 "nonimmediate_operand")
10742 (eq:QI (match_operator 1 "ix86_comparison_operator"
10743 [(reg FLAGS_REG) (const_int 0)])
10746 [(set (match_dup 0) (match_dup 1))]
10748 rtx new_op1 = copy_rtx (operands[1]);
10749 operands[1] = new_op1;
10750 PUT_MODE (new_op1, QImode);
10751 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10752 GET_MODE (XEXP (new_op1, 0))));
10754 /* Make sure that (a) the CCmode we have for the flags is strong
10755 enough for the reversed compare or (b) we have a valid FP compare. */
10756 if (! ix86_comparison_operator (new_op1, VOIDmode))
10761 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10762 (eq:QI (match_operator 1 "ix86_comparison_operator"
10763 [(reg FLAGS_REG) (const_int 0)])
10766 [(set (match_dup 0) (match_dup 1))]
10768 rtx new_op1 = copy_rtx (operands[1]);
10769 operands[1] = new_op1;
10770 PUT_MODE (new_op1, QImode);
10771 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10772 GET_MODE (XEXP (new_op1, 0))));
10774 /* Make sure that (a) the CCmode we have for the flags is strong
10775 enough for the reversed compare or (b) we have a valid FP compare. */
10776 if (! ix86_comparison_operator (new_op1, VOIDmode))
10780 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10781 ;; subsequent logical operations are used to imitate conditional moves.
10782 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10785 (define_insn "setcc_<mode>_sse"
10786 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10787 (match_operator:MODEF 3 "sse_comparison_operator"
10788 [(match_operand:MODEF 1 "register_operand" "0,x")
10789 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10790 "SSE_FLOAT_MODE_P (<MODE>mode)"
10792 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10793 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10794 [(set_attr "isa" "noavx,avx")
10795 (set_attr "type" "ssecmp")
10796 (set_attr "length_immediate" "1")
10797 (set_attr "prefix" "orig,vex")
10798 (set_attr "mode" "<MODE>")])
10800 ;; Basic conditional jump instructions.
10801 ;; We ignore the overflow flag for signed branch instructions.
10803 (define_insn "*jcc_1"
10805 (if_then_else (match_operator 1 "ix86_comparison_operator"
10806 [(reg FLAGS_REG) (const_int 0)])
10807 (label_ref (match_operand 0))
10811 [(set_attr "type" "ibr")
10812 (set_attr "modrm" "0")
10813 (set (attr "length")
10814 (if_then_else (and (ge (minus (match_dup 0) (pc))
10816 (lt (minus (match_dup 0) (pc))
10821 (define_insn "*jcc_2"
10823 (if_then_else (match_operator 1 "ix86_comparison_operator"
10824 [(reg FLAGS_REG) (const_int 0)])
10826 (label_ref (match_operand 0))))]
10829 [(set_attr "type" "ibr")
10830 (set_attr "modrm" "0")
10831 (set (attr "length")
10832 (if_then_else (and (ge (minus (match_dup 0) (pc))
10834 (lt (minus (match_dup 0) (pc))
10839 ;; In general it is not safe to assume too much about CCmode registers,
10840 ;; so simplify-rtx stops when it sees a second one. Under certain
10841 ;; conditions this is safe on x86, so help combine not create
10849 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10850 [(reg FLAGS_REG) (const_int 0)])
10852 (label_ref (match_operand 1))
10856 (if_then_else (match_dup 0)
10857 (label_ref (match_dup 1))
10859 "PUT_MODE (operands[0], VOIDmode);")
10863 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10864 [(reg FLAGS_REG) (const_int 0)])
10866 (label_ref (match_operand 1))
10870 (if_then_else (match_dup 0)
10871 (label_ref (match_dup 1))
10874 rtx new_op0 = copy_rtx (operands[0]);
10875 operands[0] = new_op0;
10876 PUT_MODE (new_op0, VOIDmode);
10877 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10878 GET_MODE (XEXP (new_op0, 0))));
10880 /* Make sure that (a) the CCmode we have for the flags is strong
10881 enough for the reversed compare or (b) we have a valid FP compare. */
10882 if (! ix86_comparison_operator (new_op0, VOIDmode))
10886 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10887 ;; pass generates from shift insn with QImode operand. Actually, the mode
10888 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10889 ;; appropriate modulo of the bit offset value.
10891 (define_insn_and_split "*jcc_bt<mode>"
10893 (if_then_else (match_operator 0 "bt_comparison_operator"
10894 [(zero_extract:SWI48
10895 (match_operand:SWI48 1 "register_operand" "r")
10898 (match_operand:QI 2 "register_operand" "r")))
10900 (label_ref (match_operand 3))
10902 (clobber (reg:CC FLAGS_REG))]
10903 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10906 [(set (reg:CCC FLAGS_REG)
10908 (zero_extract:SWI48
10914 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10915 (label_ref (match_dup 3))
10918 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10920 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10923 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10924 ;; also for DImode, this is what combine produces.
10925 (define_insn_and_split "*jcc_bt<mode>_mask"
10927 (if_then_else (match_operator 0 "bt_comparison_operator"
10928 [(zero_extract:SWI48
10929 (match_operand:SWI48 1 "register_operand" "r")
10932 (match_operand:SI 2 "register_operand" "r")
10933 (match_operand:SI 3 "const_int_operand" "n")))])
10934 (label_ref (match_operand 4))
10936 (clobber (reg:CC FLAGS_REG))]
10937 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10938 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10939 == GET_MODE_BITSIZE (<MODE>mode)-1"
10942 [(set (reg:CCC FLAGS_REG)
10944 (zero_extract:SWI48
10950 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10951 (label_ref (match_dup 4))
10954 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10956 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10959 (define_insn_and_split "*jcc_btsi_1"
10961 (if_then_else (match_operator 0 "bt_comparison_operator"
10964 (match_operand:SI 1 "register_operand" "r")
10965 (match_operand:QI 2 "register_operand" "r"))
10968 (label_ref (match_operand 3))
10970 (clobber (reg:CC FLAGS_REG))]
10971 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10974 [(set (reg:CCC FLAGS_REG)
10982 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10983 (label_ref (match_dup 3))
10986 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10988 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10991 ;; avoid useless masking of bit offset operand
10992 (define_insn_and_split "*jcc_btsi_mask_1"
10995 (match_operator 0 "bt_comparison_operator"
10998 (match_operand:SI 1 "register_operand" "r")
11001 (match_operand:SI 2 "register_operand" "r")
11002 (match_operand:SI 3 "const_int_operand" "n")) 0))
11005 (label_ref (match_operand 4))
11007 (clobber (reg:CC FLAGS_REG))]
11008 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
11009 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
11012 [(set (reg:CCC FLAGS_REG)
11020 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
11021 (label_ref (match_dup 4))
11023 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
11025 ;; Define combination compare-and-branch fp compare instructions to help
11028 (define_insn "*jcc<mode>_0_i387"
11030 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11031 [(match_operand:X87MODEF 1 "register_operand" "f")
11032 (match_operand:X87MODEF 2 "const0_operand")])
11033 (label_ref (match_operand 3))
11035 (clobber (reg:CCFP FPSR_REG))
11036 (clobber (reg:CCFP FLAGS_REG))
11037 (clobber (match_scratch:HI 4 "=a"))]
11038 "TARGET_80387 && !TARGET_CMOVE"
11041 (define_insn "*jcc<mode>_0_r_i387"
11043 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11044 [(match_operand:X87MODEF 1 "register_operand" "f")
11045 (match_operand:X87MODEF 2 "const0_operand")])
11047 (label_ref (match_operand 3))))
11048 (clobber (reg:CCFP FPSR_REG))
11049 (clobber (reg:CCFP FLAGS_REG))
11050 (clobber (match_scratch:HI 4 "=a"))]
11051 "TARGET_80387 && !TARGET_CMOVE"
11054 (define_insn "*jccxf_i387"
11056 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11057 [(match_operand:XF 1 "register_operand" "f")
11058 (match_operand:XF 2 "register_operand" "f")])
11059 (label_ref (match_operand 3))
11061 (clobber (reg:CCFP FPSR_REG))
11062 (clobber (reg:CCFP FLAGS_REG))
11063 (clobber (match_scratch:HI 4 "=a"))]
11064 "TARGET_80387 && !TARGET_CMOVE"
11067 (define_insn "*jccxf_r_i387"
11069 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11070 [(match_operand:XF 1 "register_operand" "f")
11071 (match_operand:XF 2 "register_operand" "f")])
11073 (label_ref (match_operand 3))))
11074 (clobber (reg:CCFP FPSR_REG))
11075 (clobber (reg:CCFP FLAGS_REG))
11076 (clobber (match_scratch:HI 4 "=a"))]
11077 "TARGET_80387 && !TARGET_CMOVE"
11080 (define_insn "*jcc<mode>_i387"
11082 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11083 [(match_operand:MODEF 1 "register_operand" "f")
11084 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11085 (label_ref (match_operand 3))
11087 (clobber (reg:CCFP FPSR_REG))
11088 (clobber (reg:CCFP FLAGS_REG))
11089 (clobber (match_scratch:HI 4 "=a"))]
11090 "TARGET_80387 && !TARGET_CMOVE"
11093 (define_insn "*jcc<mode>_r_i387"
11095 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
11096 [(match_operand:MODEF 1 "register_operand" "f")
11097 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
11099 (label_ref (match_operand 3))))
11100 (clobber (reg:CCFP FPSR_REG))
11101 (clobber (reg:CCFP FLAGS_REG))
11102 (clobber (match_scratch:HI 4 "=a"))]
11103 "TARGET_80387 && !TARGET_CMOVE"
11106 (define_insn "*jccu<mode>_i387"
11108 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11109 [(match_operand:X87MODEF 1 "register_operand" "f")
11110 (match_operand:X87MODEF 2 "register_operand" "f")])
11111 (label_ref (match_operand 3))
11113 (clobber (reg:CCFP FPSR_REG))
11114 (clobber (reg:CCFP FLAGS_REG))
11115 (clobber (match_scratch:HI 4 "=a"))]
11116 "TARGET_80387 && !TARGET_CMOVE"
11119 (define_insn "*jccu<mode>_r_i387"
11121 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
11122 [(match_operand:X87MODEF 1 "register_operand" "f")
11123 (match_operand:X87MODEF 2 "register_operand" "f")])
11125 (label_ref (match_operand 3))))
11126 (clobber (reg:CCFP FPSR_REG))
11127 (clobber (reg:CCFP FLAGS_REG))
11128 (clobber (match_scratch:HI 4 "=a"))]
11129 "TARGET_80387 && !TARGET_CMOVE"
11134 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11135 [(match_operand:X87MODEF 1 "register_operand")
11136 (match_operand:X87MODEF 2 "nonimmediate_operand")])
11138 (match_operand 4)))
11139 (clobber (reg:CCFP FPSR_REG))
11140 (clobber (reg:CCFP FLAGS_REG))]
11141 "TARGET_80387 && !TARGET_CMOVE
11142 && reload_completed"
11145 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11146 operands[3], operands[4], NULL_RTX, NULL_RTX);
11152 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11153 [(match_operand:X87MODEF 1 "register_operand")
11154 (match_operand:X87MODEF 2 "general_operand")])
11156 (match_operand 4)))
11157 (clobber (reg:CCFP FPSR_REG))
11158 (clobber (reg:CCFP FLAGS_REG))
11159 (clobber (match_scratch:HI 5))]
11160 "TARGET_80387 && !TARGET_CMOVE
11161 && reload_completed"
11164 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11165 operands[3], operands[4], operands[5], NULL_RTX);
11169 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
11170 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11171 ;; with a precedence over other operators and is always put in the first
11172 ;; place. Swap condition and operands to match ficom instruction.
11174 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
11177 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11178 [(match_operator:X87MODEF 1 "float_operator"
11179 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11180 (match_operand:X87MODEF 3 "register_operand" "f,f")])
11181 (label_ref (match_operand 4))
11183 (clobber (reg:CCFP FPSR_REG))
11184 (clobber (reg:CCFP FLAGS_REG))
11185 (clobber (match_scratch:HI 5 "=a,a"))]
11186 "TARGET_80387 && !TARGET_CMOVE
11187 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11188 || optimize_function_for_size_p (cfun))"
11191 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
11194 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11195 [(match_operator:X87MODEF 1 "float_operator"
11196 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11197 (match_operand:X87MODEF 3 "register_operand" "f,f")])
11199 (label_ref (match_operand 4))))
11200 (clobber (reg:CCFP FPSR_REG))
11201 (clobber (reg:CCFP FLAGS_REG))
11202 (clobber (match_scratch:HI 5 "=a,a"))]
11203 "TARGET_80387 && !TARGET_CMOVE
11204 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
11205 || optimize_function_for_size_p (cfun))"
11211 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11212 [(match_operator:X87MODEF 1 "float_operator"
11213 [(match_operand:SWI24 2 "memory_operand")])
11214 (match_operand:X87MODEF 3 "register_operand")])
11216 (match_operand 5)))
11217 (clobber (reg:CCFP FPSR_REG))
11218 (clobber (reg:CCFP FLAGS_REG))
11219 (clobber (match_scratch:HI 6))]
11220 "TARGET_80387 && !TARGET_CMOVE
11221 && reload_completed"
11224 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11225 gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
11226 operands[4], operands[5], operands[6], NULL_RTX);
11230 ;; %%% Kill this when reload knows how to do it.
11234 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
11235 [(match_operator:X87MODEF 1 "float_operator"
11236 [(match_operand:SWI24 2 "register_operand")])
11237 (match_operand:X87MODEF 3 "register_operand")])
11239 (match_operand 5)))
11240 (clobber (reg:CCFP FPSR_REG))
11241 (clobber (reg:CCFP FLAGS_REG))
11242 (clobber (match_scratch:HI 6))]
11243 "TARGET_80387 && !TARGET_CMOVE
11244 && reload_completed"
11247 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11249 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
11250 gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]),
11251 operands[4], operands[5], operands[6], operands[2]);
11255 ;; Unconditional and other jump instructions
11257 (define_insn "jump"
11259 (label_ref (match_operand 0)))]
11262 [(set_attr "type" "ibr")
11263 (set (attr "length")
11264 (if_then_else (and (ge (minus (match_dup 0) (pc))
11266 (lt (minus (match_dup 0) (pc))
11270 (set_attr "modrm" "0")])
11272 (define_expand "indirect_jump"
11273 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11277 operands[0] = convert_memory_address (word_mode, operands[0]);
11280 (define_insn "*indirect_jump"
11281 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))]
11284 [(set_attr "type" "ibr")
11285 (set_attr "length_immediate" "0")])
11287 (define_expand "tablejump"
11288 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11289 (use (label_ref (match_operand 1)))])]
11292 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11293 relative. Convert the relative address to an absolute address. */
11297 enum rtx_code code;
11299 /* We can't use @GOTOFF for text labels on VxWorks;
11300 see gotoff_operand. */
11301 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11305 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11307 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11311 op1 = pic_offset_table_rtx;
11316 op0 = pic_offset_table_rtx;
11320 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11325 operands[0] = convert_memory_address (word_mode, operands[0]);
11328 (define_insn "*tablejump_1"
11329 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))
11330 (use (label_ref (match_operand 1)))]
11333 [(set_attr "type" "ibr")
11334 (set_attr "length_immediate" "0")])
11336 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11339 [(set (reg FLAGS_REG) (match_operand 0))
11340 (set (match_operand:QI 1 "register_operand")
11341 (match_operator:QI 2 "ix86_comparison_operator"
11342 [(reg FLAGS_REG) (const_int 0)]))
11343 (set (match_operand 3 "q_regs_operand")
11344 (zero_extend (match_dup 1)))]
11345 "(peep2_reg_dead_p (3, operands[1])
11346 || operands_match_p (operands[1], operands[3]))
11347 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11348 [(set (match_dup 4) (match_dup 0))
11349 (set (strict_low_part (match_dup 5))
11352 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11353 operands[5] = gen_lowpart (QImode, operands[3]);
11354 ix86_expand_clear (operands[3]);
11358 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11359 (match_operand 4)])
11360 (set (match_operand:QI 1 "register_operand")
11361 (match_operator:QI 2 "ix86_comparison_operator"
11362 [(reg FLAGS_REG) (const_int 0)]))
11363 (set (match_operand 3 "q_regs_operand")
11364 (zero_extend (match_dup 1)))]
11365 "(peep2_reg_dead_p (3, operands[1])
11366 || operands_match_p (operands[1], operands[3]))
11367 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11368 [(parallel [(set (match_dup 5) (match_dup 0))
11370 (set (strict_low_part (match_dup 6))
11373 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11374 operands[6] = gen_lowpart (QImode, operands[3]);
11375 ix86_expand_clear (operands[3]);
11378 ;; Similar, but match zero extend with andsi3.
11381 [(set (reg FLAGS_REG) (match_operand 0))
11382 (set (match_operand:QI 1 "register_operand")
11383 (match_operator:QI 2 "ix86_comparison_operator"
11384 [(reg FLAGS_REG) (const_int 0)]))
11385 (parallel [(set (match_operand:SI 3 "q_regs_operand")
11386 (and:SI (match_dup 3) (const_int 255)))
11387 (clobber (reg:CC FLAGS_REG))])]
11388 "REGNO (operands[1]) == REGNO (operands[3])
11389 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11390 [(set (match_dup 4) (match_dup 0))
11391 (set (strict_low_part (match_dup 5))
11394 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11395 operands[5] = gen_lowpart (QImode, operands[3]);
11396 ix86_expand_clear (operands[3]);
11400 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11401 (match_operand 4)])
11402 (set (match_operand:QI 1 "register_operand")
11403 (match_operator:QI 2 "ix86_comparison_operator"
11404 [(reg FLAGS_REG) (const_int 0)]))
11405 (parallel [(set (match_operand 3 "q_regs_operand")
11406 (zero_extend (match_dup 1)))
11407 (clobber (reg:CC FLAGS_REG))])]
11408 "(peep2_reg_dead_p (3, operands[1])
11409 || operands_match_p (operands[1], operands[3]))
11410 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11411 [(parallel [(set (match_dup 5) (match_dup 0))
11413 (set (strict_low_part (match_dup 6))
11416 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11417 operands[6] = gen_lowpart (QImode, operands[3]);
11418 ix86_expand_clear (operands[3]);
11421 ;; Call instructions.
11423 ;; The predicates normally associated with named expanders are not properly
11424 ;; checked for calls. This is a bug in the generic code, but it isn't that
11425 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11427 ;; P6 processors will jump to the address after the decrement when %esp
11428 ;; is used as a call operand, so they will execute return address as a code.
11429 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11431 ;; Register constraint for call instruction.
11432 (define_mode_attr c [(SI "l") (DI "r")])
11434 ;; Call subroutine returning no value.
11436 (define_expand "call"
11437 [(call (match_operand:QI 0)
11439 (use (match_operand 2))]
11442 ix86_expand_call (NULL, operands[0], operands[1],
11443 operands[2], NULL, false);
11447 (define_expand "sibcall"
11448 [(call (match_operand:QI 0)
11450 (use (match_operand 2))]
11453 ix86_expand_call (NULL, operands[0], operands[1],
11454 operands[2], NULL, true);
11458 (define_insn "*call"
11459 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11460 (match_operand 1))]
11461 "!SIBLING_CALL_P (insn)"
11462 "* return ix86_output_call_insn (insn, operands[0]);"
11463 [(set_attr "type" "call")])
11465 (define_insn "*call_rex64_ms_sysv"
11466 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11468 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11469 (clobber (reg:TI XMM6_REG))
11470 (clobber (reg:TI XMM7_REG))
11471 (clobber (reg:TI XMM8_REG))
11472 (clobber (reg:TI XMM9_REG))
11473 (clobber (reg:TI XMM10_REG))
11474 (clobber (reg:TI XMM11_REG))
11475 (clobber (reg:TI XMM12_REG))
11476 (clobber (reg:TI XMM13_REG))
11477 (clobber (reg:TI XMM14_REG))
11478 (clobber (reg:TI XMM15_REG))
11479 (clobber (reg:DI SI_REG))
11480 (clobber (reg:DI DI_REG))]
11481 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11482 "* return ix86_output_call_insn (insn, operands[0]);"
11483 [(set_attr "type" "call")])
11485 (define_insn "*sibcall"
11486 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11487 (match_operand 1))]
11488 "SIBLING_CALL_P (insn)"
11489 "* return ix86_output_call_insn (insn, operands[0]);"
11490 [(set_attr "type" "call")])
11492 (define_expand "call_pop"
11493 [(parallel [(call (match_operand:QI 0)
11494 (match_operand:SI 1))
11495 (set (reg:SI SP_REG)
11496 (plus:SI (reg:SI SP_REG)
11497 (match_operand:SI 3)))])]
11500 ix86_expand_call (NULL, operands[0], operands[1],
11501 operands[2], operands[3], false);
11505 (define_insn "*call_pop"
11506 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11508 (set (reg:SI SP_REG)
11509 (plus:SI (reg:SI SP_REG)
11510 (match_operand:SI 2 "immediate_operand" "i")))]
11511 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11512 "* return ix86_output_call_insn (insn, operands[0]);"
11513 [(set_attr "type" "call")])
11515 (define_insn "*sibcall_pop"
11516 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11518 (set (reg:SI SP_REG)
11519 (plus:SI (reg:SI SP_REG)
11520 (match_operand:SI 2 "immediate_operand" "i")))]
11521 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11522 "* return ix86_output_call_insn (insn, operands[0]);"
11523 [(set_attr "type" "call")])
11525 ;; Call subroutine, returning value in operand 0
11527 (define_expand "call_value"
11528 [(set (match_operand 0)
11529 (call (match_operand:QI 1)
11530 (match_operand 2)))
11531 (use (match_operand 3))]
11534 ix86_expand_call (operands[0], operands[1], operands[2],
11535 operands[3], NULL, false);
11539 (define_expand "sibcall_value"
11540 [(set (match_operand 0)
11541 (call (match_operand:QI 1)
11542 (match_operand 2)))
11543 (use (match_operand 3))]
11546 ix86_expand_call (operands[0], operands[1], operands[2],
11547 operands[3], NULL, true);
11551 (define_insn "*call_value"
11552 [(set (match_operand 0)
11553 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11554 (match_operand 2)))]
11555 "!SIBLING_CALL_P (insn)"
11556 "* return ix86_output_call_insn (insn, operands[1]);"
11557 [(set_attr "type" "callv")])
11559 (define_insn "*sibcall_value"
11560 [(set (match_operand 0)
11561 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11562 (match_operand 2)))]
11563 "SIBLING_CALL_P (insn)"
11564 "* return ix86_output_call_insn (insn, operands[1]);"
11565 [(set_attr "type" "callv")])
11567 (define_insn "*call_value_rex64_ms_sysv"
11568 [(set (match_operand 0)
11569 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11570 (match_operand 2)))
11571 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11572 (clobber (reg:TI XMM6_REG))
11573 (clobber (reg:TI XMM7_REG))
11574 (clobber (reg:TI XMM8_REG))
11575 (clobber (reg:TI XMM9_REG))
11576 (clobber (reg:TI XMM10_REG))
11577 (clobber (reg:TI XMM11_REG))
11578 (clobber (reg:TI XMM12_REG))
11579 (clobber (reg:TI XMM13_REG))
11580 (clobber (reg:TI XMM14_REG))
11581 (clobber (reg:TI XMM15_REG))
11582 (clobber (reg:DI SI_REG))
11583 (clobber (reg:DI DI_REG))]
11584 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11585 "* return ix86_output_call_insn (insn, operands[1]);"
11586 [(set_attr "type" "callv")])
11588 (define_expand "call_value_pop"
11589 [(parallel [(set (match_operand 0)
11590 (call (match_operand:QI 1)
11591 (match_operand:SI 2)))
11592 (set (reg:SI SP_REG)
11593 (plus:SI (reg:SI SP_REG)
11594 (match_operand:SI 4)))])]
11597 ix86_expand_call (operands[0], operands[1], operands[2],
11598 operands[3], operands[4], false);
11602 (define_insn "*call_value_pop"
11603 [(set (match_operand 0)
11604 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11605 (match_operand 2)))
11606 (set (reg:SI SP_REG)
11607 (plus:SI (reg:SI SP_REG)
11608 (match_operand:SI 3 "immediate_operand" "i")))]
11609 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11610 "* return ix86_output_call_insn (insn, operands[1]);"
11611 [(set_attr "type" "callv")])
11613 (define_insn "*sibcall_value_pop"
11614 [(set (match_operand 0)
11615 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11616 (match_operand 2)))
11617 (set (reg:SI SP_REG)
11618 (plus:SI (reg:SI SP_REG)
11619 (match_operand:SI 3 "immediate_operand" "i")))]
11620 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11621 "* return ix86_output_call_insn (insn, operands[1]);"
11622 [(set_attr "type" "callv")])
11624 ;; Call subroutine returning any type.
11626 (define_expand "untyped_call"
11627 [(parallel [(call (match_operand 0)
11630 (match_operand 2)])]
11635 /* In order to give reg-stack an easier job in validating two
11636 coprocessor registers as containing a possible return value,
11637 simply pretend the untyped call returns a complex long double
11640 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11641 and should have the default ABI. */
11643 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11644 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11645 operands[0], const0_rtx,
11646 GEN_INT ((TARGET_64BIT
11647 ? (ix86_abi == SYSV_ABI
11648 ? X86_64_SSE_REGPARM_MAX
11649 : X86_64_MS_SSE_REGPARM_MAX)
11650 : X86_32_SSE_REGPARM_MAX)
11654 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11656 rtx set = XVECEXP (operands[2], 0, i);
11657 emit_move_insn (SET_DEST (set), SET_SRC (set));
11660 /* The optimizer does not know that the call sets the function value
11661 registers we stored in the result block. We avoid problems by
11662 claiming that all hard registers are used and clobbered at this
11664 emit_insn (gen_blockage ());
11669 ;; Prologue and epilogue instructions
11671 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11672 ;; all of memory. This blocks insns from being moved across this point.
11674 (define_insn "blockage"
11675 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11678 [(set_attr "length" "0")])
11680 ;; Do not schedule instructions accessing memory across this point.
11682 (define_expand "memory_blockage"
11683 [(set (match_dup 0)
11684 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11687 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11688 MEM_VOLATILE_P (operands[0]) = 1;
11691 (define_insn "*memory_blockage"
11692 [(set (match_operand:BLK 0)
11693 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11696 [(set_attr "length" "0")])
11698 ;; As USE insns aren't meaningful after reload, this is used instead
11699 ;; to prevent deleting instructions setting registers for PIC code
11700 (define_insn "prologue_use"
11701 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
11704 [(set_attr "length" "0")])
11706 ;; Insn emitted into the body of a function to return from a function.
11707 ;; This is only done if the function's epilogue is known to be simple.
11708 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11710 (define_expand "return"
11712 "ix86_can_use_return_insn_p ()"
11714 if (crtl->args.pops_args)
11716 rtx popc = GEN_INT (crtl->args.pops_args);
11717 emit_jump_insn (gen_simple_return_pop_internal (popc));
11722 ;; We need to disable this for TARGET_SEH, as otherwise
11723 ;; shrink-wrapped prologue gets enabled too. This might exceed
11724 ;; the maximum size of prologue in unwind information.
11726 (define_expand "simple_return"
11730 if (crtl->args.pops_args)
11732 rtx popc = GEN_INT (crtl->args.pops_args);
11733 emit_jump_insn (gen_simple_return_pop_internal (popc));
11738 (define_insn "simple_return_internal"
11742 [(set_attr "length" "1")
11743 (set_attr "atom_unit" "jeu")
11744 (set_attr "length_immediate" "0")
11745 (set_attr "modrm" "0")])
11747 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11748 ;; instruction Athlon and K8 have.
11750 (define_insn "simple_return_internal_long"
11752 (unspec [(const_int 0)] UNSPEC_REP)]
11755 [(set_attr "length" "2")
11756 (set_attr "atom_unit" "jeu")
11757 (set_attr "length_immediate" "0")
11758 (set_attr "prefix_rep" "1")
11759 (set_attr "modrm" "0")])
11761 (define_insn "simple_return_pop_internal"
11763 (use (match_operand:SI 0 "const_int_operand"))]
11766 [(set_attr "length" "3")
11767 (set_attr "atom_unit" "jeu")
11768 (set_attr "length_immediate" "2")
11769 (set_attr "modrm" "0")])
11771 (define_insn "simple_return_indirect_internal"
11773 (use (match_operand:SI 0 "register_operand" "r"))]
11776 [(set_attr "type" "ibr")
11777 (set_attr "length_immediate" "0")])
11783 [(set_attr "length" "1")
11784 (set_attr "length_immediate" "0")
11785 (set_attr "modrm" "0")])
11787 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11788 (define_insn "nops"
11789 [(unspec_volatile [(match_operand 0 "const_int_operand")]
11793 int num = INTVAL (operands[0]);
11795 gcc_assert (IN_RANGE (num, 1, 8));
11798 fputs ("\tnop\n", asm_out_file);
11802 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11803 (set_attr "length_immediate" "0")
11804 (set_attr "modrm" "0")])
11806 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11807 ;; branch prediction penalty for the third jump in a 16-byte
11811 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
11814 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11815 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11817 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11818 The align insn is used to avoid 3 jump instructions in the row to improve
11819 branch prediction and the benefits hardly outweigh the cost of extra 8
11820 nops on the average inserted by full alignment pseudo operation. */
11824 [(set_attr "length" "16")])
11826 (define_expand "prologue"
11829 "ix86_expand_prologue (); DONE;")
11831 (define_insn "set_got"
11832 [(set (match_operand:SI 0 "register_operand" "=r")
11833 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11834 (clobber (reg:CC FLAGS_REG))]
11836 "* return output_set_got (operands[0], NULL_RTX);"
11837 [(set_attr "type" "multi")
11838 (set_attr "length" "12")])
11840 (define_insn "set_got_labelled"
11841 [(set (match_operand:SI 0 "register_operand" "=r")
11842 (unspec:SI [(label_ref (match_operand 1))]
11844 (clobber (reg:CC FLAGS_REG))]
11846 "* return output_set_got (operands[0], operands[1]);"
11847 [(set_attr "type" "multi")
11848 (set_attr "length" "12")])
11850 (define_insn "set_got_rex64"
11851 [(set (match_operand:DI 0 "register_operand" "=r")
11852 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11854 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11855 [(set_attr "type" "lea")
11856 (set_attr "length_address" "4")
11857 (set_attr "mode" "DI")])
11859 (define_insn "set_rip_rex64"
11860 [(set (match_operand:DI 0 "register_operand" "=r")
11861 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
11863 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11864 [(set_attr "type" "lea")
11865 (set_attr "length_address" "4")
11866 (set_attr "mode" "DI")])
11868 (define_insn "set_got_offset_rex64"
11869 [(set (match_operand:DI 0 "register_operand" "=r")
11871 [(label_ref (match_operand 1))]
11872 UNSPEC_SET_GOT_OFFSET))]
11874 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11875 [(set_attr "type" "imov")
11876 (set_attr "length_immediate" "0")
11877 (set_attr "length_address" "8")
11878 (set_attr "mode" "DI")])
11880 (define_expand "epilogue"
11883 "ix86_expand_epilogue (1); DONE;")
11885 (define_expand "sibcall_epilogue"
11888 "ix86_expand_epilogue (0); DONE;")
11890 (define_expand "eh_return"
11891 [(use (match_operand 0 "register_operand"))]
11894 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11896 /* Tricky bit: we write the address of the handler to which we will
11897 be returning into someone else's stack frame, one word below the
11898 stack address we wish to restore. */
11899 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11900 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
11901 tmp = gen_rtx_MEM (Pmode, tmp);
11902 emit_move_insn (tmp, ra);
11904 emit_jump_insn (gen_eh_return_internal ());
11909 (define_insn_and_split "eh_return_internal"
11913 "epilogue_completed"
11915 "ix86_expand_epilogue (2); DONE;")
11917 (define_insn "leave"
11918 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11919 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11920 (clobber (mem:BLK (scratch)))]
11923 [(set_attr "type" "leave")])
11925 (define_insn "leave_rex64"
11926 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11927 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11928 (clobber (mem:BLK (scratch)))]
11931 [(set_attr "type" "leave")])
11933 ;; Handle -fsplit-stack.
11935 (define_expand "split_stack_prologue"
11939 ix86_expand_split_stack_prologue ();
11943 ;; In order to support the call/return predictor, we use a return
11944 ;; instruction which the middle-end doesn't see.
11945 (define_insn "split_stack_return"
11946 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
11947 UNSPECV_SPLIT_STACK_RETURN)]
11950 if (operands[0] == const0_rtx)
11955 [(set_attr "atom_unit" "jeu")
11956 (set_attr "modrm" "0")
11957 (set (attr "length")
11958 (if_then_else (match_operand:SI 0 "const0_operand")
11961 (set (attr "length_immediate")
11962 (if_then_else (match_operand:SI 0 "const0_operand")
11966 ;; If there are operand 0 bytes available on the stack, jump to
11969 (define_expand "split_stack_space_check"
11970 [(set (pc) (if_then_else
11971 (ltu (minus (reg SP_REG)
11972 (match_operand 0 "register_operand"))
11973 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11974 (label_ref (match_operand 1))
11978 rtx reg, size, limit;
11980 reg = gen_reg_rtx (Pmode);
11981 size = force_reg (Pmode, operands[0]);
11982 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11983 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11984 UNSPEC_STACK_CHECK);
11985 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11986 ix86_expand_branch (GEU, reg, limit, operands[1]);
11991 ;; Bit manipulation instructions.
11993 (define_expand "ffs<mode>2"
11994 [(set (match_dup 2) (const_int -1))
11995 (parallel [(set (match_dup 3) (match_dup 4))
11996 (set (match_operand:SWI48 0 "register_operand")
11998 (match_operand:SWI48 1 "nonimmediate_operand")))])
11999 (set (match_dup 0) (if_then_else:SWI48
12000 (eq (match_dup 3) (const_int 0))
12003 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
12004 (clobber (reg:CC FLAGS_REG))])]
12007 enum machine_mode flags_mode;
12009 if (<MODE>mode == SImode && !TARGET_CMOVE)
12011 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12015 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12017 operands[2] = gen_reg_rtx (<MODE>mode);
12018 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
12019 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12022 (define_insn_and_split "ffssi2_no_cmove"
12023 [(set (match_operand:SI 0 "register_operand" "=r")
12024 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12025 (clobber (match_scratch:SI 2 "=&q"))
12026 (clobber (reg:CC FLAGS_REG))]
12029 "&& reload_completed"
12030 [(parallel [(set (match_dup 4) (match_dup 5))
12031 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12032 (set (strict_low_part (match_dup 3))
12033 (eq:QI (match_dup 4) (const_int 0)))
12034 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12035 (clobber (reg:CC FLAGS_REG))])
12036 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12037 (clobber (reg:CC FLAGS_REG))])
12038 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12039 (clobber (reg:CC FLAGS_REG))])]
12041 enum machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
12043 operands[3] = gen_lowpart (QImode, operands[2]);
12044 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
12045 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
12047 ix86_expand_clear (operands[2]);
12050 (define_insn "*tzcnt<mode>_1"
12051 [(set (reg:CCC FLAGS_REG)
12052 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12054 (set (match_operand:SWI48 0 "register_operand" "=r")
12055 (ctz:SWI48 (match_dup 1)))]
12057 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12058 [(set_attr "type" "alu1")
12059 (set_attr "prefix_0f" "1")
12060 (set_attr "prefix_rep" "1")
12061 (set_attr "btver2_decode" "double")
12062 (set_attr "mode" "<MODE>")])
12064 (define_insn "*bsf<mode>_1"
12065 [(set (reg:CCZ FLAGS_REG)
12066 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12068 (set (match_operand:SWI48 0 "register_operand" "=r")
12069 (ctz:SWI48 (match_dup 1)))]
12071 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12072 [(set_attr "type" "alu1")
12073 (set_attr "prefix_0f" "1")
12074 (set_attr "btver2_decode" "double")
12075 (set_attr "mode" "<MODE>")])
12077 (define_insn "ctz<mode>2"
12078 [(set (match_operand:SWI248 0 "register_operand" "=r")
12079 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12080 (clobber (reg:CC FLAGS_REG))]
12084 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12085 else if (optimize_function_for_size_p (cfun))
12087 else if (TARGET_GENERIC)
12088 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
12089 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12091 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12093 [(set_attr "type" "alu1")
12094 (set_attr "prefix_0f" "1")
12095 (set (attr "prefix_rep")
12097 (ior (match_test "TARGET_BMI")
12098 (and (not (match_test "optimize_function_for_size_p (cfun)"))
12099 (match_test "TARGET_GENERIC")))
12101 (const_string "0")))
12102 (set_attr "mode" "<MODE>")])
12104 (define_expand "clz<mode>2"
12106 [(set (match_operand:SWI248 0 "register_operand")
12109 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12110 (clobber (reg:CC FLAGS_REG))])
12112 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12113 (clobber (reg:CC FLAGS_REG))])]
12118 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12121 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12124 (define_insn "clz<mode>2_lzcnt"
12125 [(set (match_operand:SWI248 0 "register_operand" "=r")
12126 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12127 (clobber (reg:CC FLAGS_REG))]
12129 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12130 [(set_attr "prefix_rep" "1")
12131 (set_attr "type" "bitmanip")
12132 (set_attr "mode" "<MODE>")])
12134 ;; BMI instructions.
12135 (define_insn "*bmi_andn_<mode>"
12136 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12139 (match_operand:SWI48 1 "register_operand" "r,r"))
12140 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
12141 (clobber (reg:CC FLAGS_REG))]
12143 "andn\t{%2, %1, %0|%0, %1, %2}"
12144 [(set_attr "type" "bitmanip")
12145 (set_attr "btver2_decode" "direct, double")
12146 (set_attr "mode" "<MODE>")])
12148 (define_insn "bmi_bextr_<mode>"
12149 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
12150 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
12151 (match_operand:SWI48 2 "register_operand" "r,r")]
12153 (clobber (reg:CC FLAGS_REG))]
12155 "bextr\t{%2, %1, %0|%0, %1, %2}"
12156 [(set_attr "type" "bitmanip")
12157 (set_attr "btver2_decode" "direct, double")
12158 (set_attr "mode" "<MODE>")])
12160 (define_insn "*bmi_blsi_<mode>"
12161 [(set (match_operand:SWI48 0 "register_operand" "=r")
12164 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12166 (clobber (reg:CC FLAGS_REG))]
12168 "blsi\t{%1, %0|%0, %1}"
12169 [(set_attr "type" "bitmanip")
12170 (set_attr "btver2_decode" "double")
12171 (set_attr "mode" "<MODE>")])
12173 (define_insn "*bmi_blsmsk_<mode>"
12174 [(set (match_operand:SWI48 0 "register_operand" "=r")
12177 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12180 (clobber (reg:CC FLAGS_REG))]
12182 "blsmsk\t{%1, %0|%0, %1}"
12183 [(set_attr "type" "bitmanip")
12184 (set_attr "btver2_decode" "double")
12185 (set_attr "mode" "<MODE>")])
12187 (define_insn "*bmi_blsr_<mode>"
12188 [(set (match_operand:SWI48 0 "register_operand" "=r")
12191 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12194 (clobber (reg:CC FLAGS_REG))]
12196 "blsr\t{%1, %0|%0, %1}"
12197 [(set_attr "type" "bitmanip")
12198 (set_attr "btver2_decode" "double")
12199 (set_attr "mode" "<MODE>")])
12201 ;; BMI2 instructions.
12202 (define_insn "bmi2_bzhi_<mode>3"
12203 [(set (match_operand:SWI48 0 "register_operand" "=r")
12204 (and:SWI48 (lshiftrt:SWI48 (const_int -1)
12205 (match_operand:SWI48 2 "register_operand" "r"))
12206 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12207 (clobber (reg:CC FLAGS_REG))]
12209 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12210 [(set_attr "type" "bitmanip")
12211 (set_attr "prefix" "vex")
12212 (set_attr "mode" "<MODE>")])
12214 (define_insn "bmi2_pdep_<mode>3"
12215 [(set (match_operand:SWI48 0 "register_operand" "=r")
12216 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12217 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12220 "pdep\t{%2, %1, %0|%0, %1, %2}"
12221 [(set_attr "type" "bitmanip")
12222 (set_attr "prefix" "vex")
12223 (set_attr "mode" "<MODE>")])
12225 (define_insn "bmi2_pext_<mode>3"
12226 [(set (match_operand:SWI48 0 "register_operand" "=r")
12227 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12228 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12231 "pext\t{%2, %1, %0|%0, %1, %2}"
12232 [(set_attr "type" "bitmanip")
12233 (set_attr "prefix" "vex")
12234 (set_attr "mode" "<MODE>")])
12236 ;; TBM instructions.
12237 (define_insn "tbm_bextri_<mode>"
12238 [(set (match_operand:SWI48 0 "register_operand" "=r")
12239 (zero_extract:SWI48
12240 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12241 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12242 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12243 (clobber (reg:CC FLAGS_REG))]
12246 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12247 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12249 [(set_attr "type" "bitmanip")
12250 (set_attr "mode" "<MODE>")])
12252 (define_insn "*tbm_blcfill_<mode>"
12253 [(set (match_operand:SWI48 0 "register_operand" "=r")
12256 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12259 (clobber (reg:CC FLAGS_REG))]
12261 "blcfill\t{%1, %0|%0, %1}"
12262 [(set_attr "type" "bitmanip")
12263 (set_attr "mode" "<MODE>")])
12265 (define_insn "*tbm_blci_<mode>"
12266 [(set (match_operand:SWI48 0 "register_operand" "=r")
12270 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12273 (clobber (reg:CC FLAGS_REG))]
12275 "blci\t{%1, %0|%0, %1}"
12276 [(set_attr "type" "bitmanip")
12277 (set_attr "mode" "<MODE>")])
12279 (define_insn "*tbm_blcic_<mode>"
12280 [(set (match_operand:SWI48 0 "register_operand" "=r")
12283 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12287 (clobber (reg:CC FLAGS_REG))]
12289 "blcic\t{%1, %0|%0, %1}"
12290 [(set_attr "type" "bitmanip")
12291 (set_attr "mode" "<MODE>")])
12293 (define_insn "*tbm_blcmsk_<mode>"
12294 [(set (match_operand:SWI48 0 "register_operand" "=r")
12297 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12300 (clobber (reg:CC FLAGS_REG))]
12302 "blcmsk\t{%1, %0|%0, %1}"
12303 [(set_attr "type" "bitmanip")
12304 (set_attr "mode" "<MODE>")])
12306 (define_insn "*tbm_blcs_<mode>"
12307 [(set (match_operand:SWI48 0 "register_operand" "=r")
12310 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12313 (clobber (reg:CC FLAGS_REG))]
12315 "blcs\t{%1, %0|%0, %1}"
12316 [(set_attr "type" "bitmanip")
12317 (set_attr "mode" "<MODE>")])
12319 (define_insn "*tbm_blsfill_<mode>"
12320 [(set (match_operand:SWI48 0 "register_operand" "=r")
12323 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12326 (clobber (reg:CC FLAGS_REG))]
12328 "blsfill\t{%1, %0|%0, %1}"
12329 [(set_attr "type" "bitmanip")
12330 (set_attr "mode" "<MODE>")])
12332 (define_insn "*tbm_blsic_<mode>"
12333 [(set (match_operand:SWI48 0 "register_operand" "=r")
12336 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12340 (clobber (reg:CC FLAGS_REG))]
12342 "blsic\t{%1, %0|%0, %1}"
12343 [(set_attr "type" "bitmanip")
12344 (set_attr "mode" "<MODE>")])
12346 (define_insn "*tbm_t1mskc_<mode>"
12347 [(set (match_operand:SWI48 0 "register_operand" "=r")
12350 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12354 (clobber (reg:CC FLAGS_REG))]
12356 "t1mskc\t{%1, %0|%0, %1}"
12357 [(set_attr "type" "bitmanip")
12358 (set_attr "mode" "<MODE>")])
12360 (define_insn "*tbm_tzmsk_<mode>"
12361 [(set (match_operand:SWI48 0 "register_operand" "=r")
12364 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12368 (clobber (reg:CC FLAGS_REG))]
12370 "tzmsk\t{%1, %0|%0, %1}"
12371 [(set_attr "type" "bitmanip")
12372 (set_attr "mode" "<MODE>")])
12374 (define_insn "bsr_rex64"
12375 [(set (match_operand:DI 0 "register_operand" "=r")
12376 (minus:DI (const_int 63)
12377 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12378 (clobber (reg:CC FLAGS_REG))]
12380 "bsr{q}\t{%1, %0|%0, %1}"
12381 [(set_attr "type" "alu1")
12382 (set_attr "prefix_0f" "1")
12383 (set_attr "mode" "DI")])
12386 [(set (match_operand:SI 0 "register_operand" "=r")
12387 (minus:SI (const_int 31)
12388 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12389 (clobber (reg:CC FLAGS_REG))]
12391 "bsr{l}\t{%1, %0|%0, %1}"
12392 [(set_attr "type" "alu1")
12393 (set_attr "prefix_0f" "1")
12394 (set_attr "mode" "SI")])
12396 (define_insn "*bsrhi"
12397 [(set (match_operand:HI 0 "register_operand" "=r")
12398 (minus:HI (const_int 15)
12399 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12400 (clobber (reg:CC FLAGS_REG))]
12402 "bsr{w}\t{%1, %0|%0, %1}"
12403 [(set_attr "type" "alu1")
12404 (set_attr "prefix_0f" "1")
12405 (set_attr "mode" "HI")])
12407 (define_insn "popcount<mode>2"
12408 [(set (match_operand:SWI248 0 "register_operand" "=r")
12410 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12411 (clobber (reg:CC FLAGS_REG))]
12415 return "popcnt\t{%1, %0|%0, %1}";
12417 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12420 [(set_attr "prefix_rep" "1")
12421 (set_attr "type" "bitmanip")
12422 (set_attr "mode" "<MODE>")])
12424 (define_insn "*popcount<mode>2_cmp"
12425 [(set (reg FLAGS_REG)
12428 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12430 (set (match_operand:SWI248 0 "register_operand" "=r")
12431 (popcount:SWI248 (match_dup 1)))]
12432 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12435 return "popcnt\t{%1, %0|%0, %1}";
12437 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12440 [(set_attr "prefix_rep" "1")
12441 (set_attr "type" "bitmanip")
12442 (set_attr "mode" "<MODE>")])
12444 (define_insn "*popcountsi2_cmp_zext"
12445 [(set (reg FLAGS_REG)
12447 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12449 (set (match_operand:DI 0 "register_operand" "=r")
12450 (zero_extend:DI(popcount:SI (match_dup 1))))]
12451 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12454 return "popcnt\t{%1, %0|%0, %1}";
12456 return "popcnt{l}\t{%1, %0|%0, %1}";
12459 [(set_attr "prefix_rep" "1")
12460 (set_attr "type" "bitmanip")
12461 (set_attr "mode" "SI")])
12463 (define_expand "bswapdi2"
12464 [(set (match_operand:DI 0 "register_operand")
12465 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
12469 operands[1] = force_reg (DImode, operands[1]);
12472 (define_expand "bswapsi2"
12473 [(set (match_operand:SI 0 "register_operand")
12474 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
12479 else if (TARGET_BSWAP)
12480 operands[1] = force_reg (SImode, operands[1]);
12483 rtx x = operands[0];
12485 emit_move_insn (x, operands[1]);
12486 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12487 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12488 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12493 (define_insn "*bswap<mode>2_movbe"
12494 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12495 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12497 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12500 movbe\t{%1, %0|%0, %1}
12501 movbe\t{%1, %0|%0, %1}"
12502 [(set_attr "type" "bitmanip,imov,imov")
12503 (set_attr "modrm" "0,1,1")
12504 (set_attr "prefix_0f" "*,1,1")
12505 (set_attr "prefix_extra" "*,1,1")
12506 (set_attr "mode" "<MODE>")])
12508 (define_insn "*bswap<mode>2"
12509 [(set (match_operand:SWI48 0 "register_operand" "=r")
12510 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12513 [(set_attr "type" "bitmanip")
12514 (set_attr "modrm" "0")
12515 (set_attr "mode" "<MODE>")])
12517 (define_insn "*bswaphi_lowpart_1"
12518 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12519 (bswap:HI (match_dup 0)))
12520 (clobber (reg:CC FLAGS_REG))]
12521 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12523 xchg{b}\t{%h0, %b0|%b0, %h0}
12524 rol{w}\t{$8, %0|%0, 8}"
12525 [(set_attr "length" "2,4")
12526 (set_attr "mode" "QI,HI")])
12528 (define_insn "bswaphi_lowpart"
12529 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12530 (bswap:HI (match_dup 0)))
12531 (clobber (reg:CC FLAGS_REG))]
12533 "rol{w}\t{$8, %0|%0, 8}"
12534 [(set_attr "length" "4")
12535 (set_attr "mode" "HI")])
12537 (define_expand "paritydi2"
12538 [(set (match_operand:DI 0 "register_operand")
12539 (parity:DI (match_operand:DI 1 "register_operand")))]
12542 rtx scratch = gen_reg_rtx (QImode);
12545 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12546 NULL_RTX, operands[1]));
12548 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12549 gen_rtx_REG (CCmode, FLAGS_REG),
12551 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12554 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12557 rtx tmp = gen_reg_rtx (SImode);
12559 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12560 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12565 (define_expand "paritysi2"
12566 [(set (match_operand:SI 0 "register_operand")
12567 (parity:SI (match_operand:SI 1 "register_operand")))]
12570 rtx scratch = gen_reg_rtx (QImode);
12573 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12575 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12576 gen_rtx_REG (CCmode, FLAGS_REG),
12578 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12580 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12584 (define_insn_and_split "paritydi2_cmp"
12585 [(set (reg:CC FLAGS_REG)
12586 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12588 (clobber (match_scratch:DI 0 "=r"))
12589 (clobber (match_scratch:SI 1 "=&r"))
12590 (clobber (match_scratch:HI 2 "=Q"))]
12593 "&& reload_completed"
12595 [(set (match_dup 1)
12596 (xor:SI (match_dup 1) (match_dup 4)))
12597 (clobber (reg:CC FLAGS_REG))])
12599 [(set (reg:CC FLAGS_REG)
12600 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12601 (clobber (match_dup 1))
12602 (clobber (match_dup 2))])]
12604 operands[4] = gen_lowpart (SImode, operands[3]);
12608 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12609 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12612 operands[1] = gen_highpart (SImode, operands[3]);
12615 (define_insn_and_split "paritysi2_cmp"
12616 [(set (reg:CC FLAGS_REG)
12617 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12619 (clobber (match_scratch:SI 0 "=r"))
12620 (clobber (match_scratch:HI 1 "=&Q"))]
12623 "&& reload_completed"
12625 [(set (match_dup 1)
12626 (xor:HI (match_dup 1) (match_dup 3)))
12627 (clobber (reg:CC FLAGS_REG))])
12629 [(set (reg:CC FLAGS_REG)
12630 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12631 (clobber (match_dup 1))])]
12633 operands[3] = gen_lowpart (HImode, operands[2]);
12635 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12636 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12639 (define_insn "*parityhi2_cmp"
12640 [(set (reg:CC FLAGS_REG)
12641 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12643 (clobber (match_scratch:HI 0 "=Q"))]
12645 "xor{b}\t{%h0, %b0|%b0, %h0}"
12646 [(set_attr "length" "2")
12647 (set_attr "mode" "HI")])
12650 ;; Thread-local storage patterns for ELF.
12652 ;; Note that these code sequences must appear exactly as shown
12653 ;; in order to allow linker relaxation.
12655 (define_insn "*tls_global_dynamic_32_gnu"
12656 [(set (match_operand:SI 0 "register_operand" "=a")
12658 [(match_operand:SI 1 "register_operand" "b")
12659 (match_operand 2 "tls_symbolic_operand")
12660 (match_operand 3 "constant_call_address_operand" "z")]
12662 (clobber (match_scratch:SI 4 "=d"))
12663 (clobber (match_scratch:SI 5 "=c"))
12664 (clobber (reg:CC FLAGS_REG))]
12665 "!TARGET_64BIT && TARGET_GNU_TLS"
12668 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12669 if (TARGET_SUN_TLS)
12670 #ifdef HAVE_AS_IX86_TLSGDPLT
12671 return "call\t%a2@tlsgdplt";
12673 return "call\t%p3@plt";
12675 return "call\t%P3";
12677 [(set_attr "type" "multi")
12678 (set_attr "length" "12")])
12680 (define_expand "tls_global_dynamic_32"
12682 [(set (match_operand:SI 0 "register_operand")
12683 (unspec:SI [(match_operand:SI 2 "register_operand")
12684 (match_operand 1 "tls_symbolic_operand")
12685 (match_operand 3 "constant_call_address_operand")]
12687 (clobber (match_scratch:SI 4))
12688 (clobber (match_scratch:SI 5))
12689 (clobber (reg:CC FLAGS_REG))])])
12691 (define_insn "*tls_global_dynamic_64_<mode>"
12692 [(set (match_operand:P 0 "register_operand" "=a")
12694 (mem:QI (match_operand 2 "constant_call_address_operand" "z"))
12695 (match_operand 3)))
12696 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12701 fputs (ASM_BYTE "0x66\n", asm_out_file);
12703 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12704 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12705 fputs ("\trex64\n", asm_out_file);
12706 if (TARGET_SUN_TLS)
12707 return "call\t%p2@plt";
12708 return "call\t%P2";
12710 [(set_attr "type" "multi")
12711 (set (attr "length")
12712 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12714 (define_expand "tls_global_dynamic_64_<mode>"
12716 [(set (match_operand:P 0 "register_operand")
12718 (mem:QI (match_operand 2 "constant_call_address_operand"))
12720 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12724 (define_insn "*tls_local_dynamic_base_32_gnu"
12725 [(set (match_operand:SI 0 "register_operand" "=a")
12727 [(match_operand:SI 1 "register_operand" "b")
12728 (match_operand 2 "constant_call_address_operand" "z")]
12729 UNSPEC_TLS_LD_BASE))
12730 (clobber (match_scratch:SI 3 "=d"))
12731 (clobber (match_scratch:SI 4 "=c"))
12732 (clobber (reg:CC FLAGS_REG))]
12733 "!TARGET_64BIT && TARGET_GNU_TLS"
12736 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12737 if (TARGET_SUN_TLS)
12738 #ifdef HAVE_AS_IX86_TLSLDMPLT
12739 return "call\t%&@tlsldmplt";
12741 return "call\t%p2@plt";
12743 return "call\t%P2";
12745 [(set_attr "type" "multi")
12746 (set_attr "length" "11")])
12748 (define_expand "tls_local_dynamic_base_32"
12750 [(set (match_operand:SI 0 "register_operand")
12752 [(match_operand:SI 1 "register_operand")
12753 (match_operand 2 "constant_call_address_operand")]
12754 UNSPEC_TLS_LD_BASE))
12755 (clobber (match_scratch:SI 3))
12756 (clobber (match_scratch:SI 4))
12757 (clobber (reg:CC FLAGS_REG))])])
12759 (define_insn "*tls_local_dynamic_base_64_<mode>"
12760 [(set (match_operand:P 0 "register_operand" "=a")
12762 (mem:QI (match_operand 1 "constant_call_address_operand" "z"))
12763 (match_operand 2)))
12764 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12768 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12769 if (TARGET_SUN_TLS)
12770 return "call\t%p1@plt";
12771 return "call\t%P1";
12773 [(set_attr "type" "multi")
12774 (set_attr "length" "12")])
12776 (define_expand "tls_local_dynamic_base_64_<mode>"
12778 [(set (match_operand:P 0 "register_operand")
12780 (mem:QI (match_operand 1 "constant_call_address_operand"))
12782 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12785 ;; Local dynamic of a single variable is a lose. Show combine how
12786 ;; to convert that back to global dynamic.
12788 (define_insn_and_split "*tls_local_dynamic_32_once"
12789 [(set (match_operand:SI 0 "register_operand" "=a")
12791 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12792 (match_operand 2 "constant_call_address_operand" "z")]
12793 UNSPEC_TLS_LD_BASE)
12794 (const:SI (unspec:SI
12795 [(match_operand 3 "tls_symbolic_operand")]
12797 (clobber (match_scratch:SI 4 "=d"))
12798 (clobber (match_scratch:SI 5 "=c"))
12799 (clobber (reg:CC FLAGS_REG))]
12804 [(set (match_dup 0)
12805 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12807 (clobber (match_dup 4))
12808 (clobber (match_dup 5))
12809 (clobber (reg:CC FLAGS_REG))])])
12811 ;; Segment register for the thread base ptr load
12812 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12814 ;; Load and add the thread base pointer from %<tp_seg>:0.
12815 (define_insn "*load_tp_x32"
12816 [(set (match_operand:SI 0 "register_operand" "=r")
12817 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12819 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12820 [(set_attr "type" "imov")
12821 (set_attr "modrm" "0")
12822 (set_attr "length" "7")
12823 (set_attr "memory" "load")
12824 (set_attr "imm_disp" "false")])
12826 (define_insn "*load_tp_x32_zext"
12827 [(set (match_operand:DI 0 "register_operand" "=r")
12828 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12830 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12831 [(set_attr "type" "imov")
12832 (set_attr "modrm" "0")
12833 (set_attr "length" "7")
12834 (set_attr "memory" "load")
12835 (set_attr "imm_disp" "false")])
12837 (define_insn "*load_tp_<mode>"
12838 [(set (match_operand:P 0 "register_operand" "=r")
12839 (unspec:P [(const_int 0)] UNSPEC_TP))]
12841 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12842 [(set_attr "type" "imov")
12843 (set_attr "modrm" "0")
12844 (set_attr "length" "7")
12845 (set_attr "memory" "load")
12846 (set_attr "imm_disp" "false")])
12848 (define_insn "*add_tp_x32"
12849 [(set (match_operand:SI 0 "register_operand" "=r")
12850 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12851 (match_operand:SI 1 "register_operand" "0")))
12852 (clobber (reg:CC FLAGS_REG))]
12854 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12855 [(set_attr "type" "alu")
12856 (set_attr "modrm" "0")
12857 (set_attr "length" "7")
12858 (set_attr "memory" "load")
12859 (set_attr "imm_disp" "false")])
12861 (define_insn "*add_tp_x32_zext"
12862 [(set (match_operand:DI 0 "register_operand" "=r")
12864 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12865 (match_operand:SI 1 "register_operand" "0"))))
12866 (clobber (reg:CC FLAGS_REG))]
12868 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12869 [(set_attr "type" "alu")
12870 (set_attr "modrm" "0")
12871 (set_attr "length" "7")
12872 (set_attr "memory" "load")
12873 (set_attr "imm_disp" "false")])
12875 (define_insn "*add_tp_<mode>"
12876 [(set (match_operand:P 0 "register_operand" "=r")
12877 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12878 (match_operand:P 1 "register_operand" "0")))
12879 (clobber (reg:CC FLAGS_REG))]
12881 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12882 [(set_attr "type" "alu")
12883 (set_attr "modrm" "0")
12884 (set_attr "length" "7")
12885 (set_attr "memory" "load")
12886 (set_attr "imm_disp" "false")])
12888 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12889 ;; %rax as destination of the initial executable code sequence.
12890 (define_insn "tls_initial_exec_64_sun"
12891 [(set (match_operand:DI 0 "register_operand" "=a")
12893 [(match_operand 1 "tls_symbolic_operand")]
12894 UNSPEC_TLS_IE_SUN))
12895 (clobber (reg:CC FLAGS_REG))]
12896 "TARGET_64BIT && TARGET_SUN_TLS"
12899 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12900 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12902 [(set_attr "type" "multi")])
12904 ;; GNU2 TLS patterns can be split.
12906 (define_expand "tls_dynamic_gnu2_32"
12907 [(set (match_dup 3)
12908 (plus:SI (match_operand:SI 2 "register_operand")
12910 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
12913 [(set (match_operand:SI 0 "register_operand")
12914 (unspec:SI [(match_dup 1) (match_dup 3)
12915 (match_dup 2) (reg:SI SP_REG)]
12917 (clobber (reg:CC FLAGS_REG))])]
12918 "!TARGET_64BIT && TARGET_GNU2_TLS"
12920 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12921 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12924 (define_insn "*tls_dynamic_gnu2_lea_32"
12925 [(set (match_operand:SI 0 "register_operand" "=r")
12926 (plus:SI (match_operand:SI 1 "register_operand" "b")
12928 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
12929 UNSPEC_TLSDESC))))]
12930 "!TARGET_64BIT && TARGET_GNU2_TLS"
12931 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
12932 [(set_attr "type" "lea")
12933 (set_attr "mode" "SI")
12934 (set_attr "length" "6")
12935 (set_attr "length_address" "4")])
12937 (define_insn "*tls_dynamic_gnu2_call_32"
12938 [(set (match_operand:SI 0 "register_operand" "=a")
12939 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
12940 (match_operand:SI 2 "register_operand" "0")
12941 ;; we have to make sure %ebx still points to the GOT
12942 (match_operand:SI 3 "register_operand" "b")
12945 (clobber (reg:CC FLAGS_REG))]
12946 "!TARGET_64BIT && TARGET_GNU2_TLS"
12947 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12948 [(set_attr "type" "call")
12949 (set_attr "length" "2")
12950 (set_attr "length_address" "0")])
12952 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12953 [(set (match_operand:SI 0 "register_operand" "=&a")
12955 (unspec:SI [(match_operand 3 "tls_modbase_operand")
12956 (match_operand:SI 4)
12957 (match_operand:SI 2 "register_operand" "b")
12960 (const:SI (unspec:SI
12961 [(match_operand 1 "tls_symbolic_operand")]
12963 (clobber (reg:CC FLAGS_REG))]
12964 "!TARGET_64BIT && TARGET_GNU2_TLS"
12967 [(set (match_dup 0) (match_dup 5))]
12969 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12970 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12973 (define_expand "tls_dynamic_gnu2_64"
12974 [(set (match_dup 2)
12975 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
12978 [(set (match_operand:DI 0 "register_operand")
12979 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12981 (clobber (reg:CC FLAGS_REG))])]
12982 "TARGET_64BIT && TARGET_GNU2_TLS"
12984 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12985 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12988 (define_insn "*tls_dynamic_gnu2_lea_64"
12989 [(set (match_operand:DI 0 "register_operand" "=r")
12990 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
12992 "TARGET_64BIT && TARGET_GNU2_TLS"
12993 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
12994 [(set_attr "type" "lea")
12995 (set_attr "mode" "DI")
12996 (set_attr "length" "7")
12997 (set_attr "length_address" "4")])
12999 (define_insn "*tls_dynamic_gnu2_call_64"
13000 [(set (match_operand:DI 0 "register_operand" "=a")
13001 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
13002 (match_operand:DI 2 "register_operand" "0")
13005 (clobber (reg:CC FLAGS_REG))]
13006 "TARGET_64BIT && TARGET_GNU2_TLS"
13007 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
13008 [(set_attr "type" "call")
13009 (set_attr "length" "2")
13010 (set_attr "length_address" "0")])
13012 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
13013 [(set (match_operand:DI 0 "register_operand" "=&a")
13015 (unspec:DI [(match_operand 2 "tls_modbase_operand")
13016 (match_operand:DI 3)
13019 (const:DI (unspec:DI
13020 [(match_operand 1 "tls_symbolic_operand")]
13022 (clobber (reg:CC FLAGS_REG))]
13023 "TARGET_64BIT && TARGET_GNU2_TLS"
13026 [(set (match_dup 0) (match_dup 4))]
13028 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
13029 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
13032 ;; These patterns match the binary 387 instructions for addM3, subM3,
13033 ;; mulM3 and divM3. There are three patterns for each of DFmode and
13034 ;; SFmode. The first is the normal insn, the second the same insn but
13035 ;; with one operand a conversion, and the third the same insn but with
13036 ;; the other operand a conversion. The conversion may be SFmode or
13037 ;; SImode if the target mode DFmode, but only SImode if the target mode
13040 ;; Gcc is slightly more smart about handling normal two address instructions
13041 ;; so use special patterns for add and mull.
13043 (define_insn "*fop_<mode>_comm_mixed"
13044 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
13045 (match_operator:MODEF 3 "binary_fp_operator"
13046 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
13047 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
13048 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13049 && COMMUTATIVE_ARITH_P (operands[3])
13050 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13051 "* return output_387_binary_op (insn, operands);"
13052 [(set (attr "type")
13053 (if_then_else (eq_attr "alternative" "1,2")
13054 (if_then_else (match_operand:MODEF 3 "mult_operator")
13055 (const_string "ssemul")
13056 (const_string "sseadd"))
13057 (if_then_else (match_operand:MODEF 3 "mult_operator")
13058 (const_string "fmul")
13059 (const_string "fop"))))
13060 (set_attr "isa" "*,noavx,avx")
13061 (set_attr "prefix" "orig,orig,vex")
13062 (set_attr "mode" "<MODE>")])
13064 (define_insn "*fop_<mode>_comm_sse"
13065 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13066 (match_operator:MODEF 3 "binary_fp_operator"
13067 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
13068 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13069 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13070 && COMMUTATIVE_ARITH_P (operands[3])
13071 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13072 "* return output_387_binary_op (insn, operands);"
13073 [(set (attr "type")
13074 (if_then_else (match_operand:MODEF 3 "mult_operator")
13075 (const_string "ssemul")
13076 (const_string "sseadd")))
13077 (set_attr "isa" "noavx,avx")
13078 (set_attr "prefix" "orig,vex")
13079 (set_attr "mode" "<MODE>")])
13081 (define_insn "*fop_<mode>_comm_i387"
13082 [(set (match_operand:MODEF 0 "register_operand" "=f")
13083 (match_operator:MODEF 3 "binary_fp_operator"
13084 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13085 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13086 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13087 && COMMUTATIVE_ARITH_P (operands[3])
13088 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13089 "* return output_387_binary_op (insn, operands);"
13090 [(set (attr "type")
13091 (if_then_else (match_operand:MODEF 3 "mult_operator")
13092 (const_string "fmul")
13093 (const_string "fop")))
13094 (set_attr "mode" "<MODE>")])
13096 (define_insn "*fop_<mode>_1_mixed"
13097 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13098 (match_operator:MODEF 3 "binary_fp_operator"
13099 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13100 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13101 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13102 && !COMMUTATIVE_ARITH_P (operands[3])
13103 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13104 "* return output_387_binary_op (insn, operands);"
13105 [(set (attr "type")
13106 (cond [(and (eq_attr "alternative" "2,3")
13107 (match_operand:MODEF 3 "mult_operator"))
13108 (const_string "ssemul")
13109 (and (eq_attr "alternative" "2,3")
13110 (match_operand:MODEF 3 "div_operator"))
13111 (const_string "ssediv")
13112 (eq_attr "alternative" "2,3")
13113 (const_string "sseadd")
13114 (match_operand:MODEF 3 "mult_operator")
13115 (const_string "fmul")
13116 (match_operand:MODEF 3 "div_operator")
13117 (const_string "fdiv")
13119 (const_string "fop")))
13120 (set_attr "isa" "*,*,noavx,avx")
13121 (set_attr "prefix" "orig,orig,orig,vex")
13122 (set_attr "mode" "<MODE>")])
13124 (define_insn "*rcpsf2_sse"
13125 [(set (match_operand:SF 0 "register_operand" "=x")
13126 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13129 "%vrcpss\t{%1, %d0|%d0, %1}"
13130 [(set_attr "type" "sse")
13131 (set_attr "atom_sse_attr" "rcp")
13132 (set_attr "btver2_sse_attr" "rcp")
13133 (set_attr "prefix" "maybe_vex")
13134 (set_attr "mode" "SF")])
13136 (define_insn "*fop_<mode>_1_sse"
13137 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13138 (match_operator:MODEF 3 "binary_fp_operator"
13139 [(match_operand:MODEF 1 "register_operand" "0,x")
13140 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13141 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13142 && !COMMUTATIVE_ARITH_P (operands[3])"
13143 "* return output_387_binary_op (insn, operands);"
13144 [(set (attr "type")
13145 (cond [(match_operand:MODEF 3 "mult_operator")
13146 (const_string "ssemul")
13147 (match_operand:MODEF 3 "div_operator")
13148 (const_string "ssediv")
13150 (const_string "sseadd")))
13151 (set_attr "isa" "noavx,avx")
13152 (set_attr "prefix" "orig,vex")
13153 (set_attr "mode" "<MODE>")])
13155 ;; This pattern is not fully shadowed by the pattern above.
13156 (define_insn "*fop_<mode>_1_i387"
13157 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13158 (match_operator:MODEF 3 "binary_fp_operator"
13159 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13160 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13161 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13162 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13163 && !COMMUTATIVE_ARITH_P (operands[3])
13164 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13165 "* return output_387_binary_op (insn, operands);"
13166 [(set (attr "type")
13167 (cond [(match_operand:MODEF 3 "mult_operator")
13168 (const_string "fmul")
13169 (match_operand:MODEF 3 "div_operator")
13170 (const_string "fdiv")
13172 (const_string "fop")))
13173 (set_attr "mode" "<MODE>")])
13175 ;; ??? Add SSE splitters for these!
13176 (define_insn "*fop_<MODEF:mode>_2_i387"
13177 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13178 (match_operator:MODEF 3 "binary_fp_operator"
13180 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13181 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13182 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13183 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13184 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13185 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13186 [(set (attr "type")
13187 (cond [(match_operand:MODEF 3 "mult_operator")
13188 (const_string "fmul")
13189 (match_operand:MODEF 3 "div_operator")
13190 (const_string "fdiv")
13192 (const_string "fop")))
13193 (set_attr "fp_int_src" "true")
13194 (set_attr "mode" "<SWI24:MODE>")])
13196 (define_insn "*fop_<MODEF:mode>_3_i387"
13197 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13198 (match_operator:MODEF 3 "binary_fp_operator"
13199 [(match_operand:MODEF 1 "register_operand" "0,0")
13201 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13202 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13203 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13204 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13205 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13206 [(set (attr "type")
13207 (cond [(match_operand:MODEF 3 "mult_operator")
13208 (const_string "fmul")
13209 (match_operand:MODEF 3 "div_operator")
13210 (const_string "fdiv")
13212 (const_string "fop")))
13213 (set_attr "fp_int_src" "true")
13214 (set_attr "mode" "<MODE>")])
13216 (define_insn "*fop_df_4_i387"
13217 [(set (match_operand:DF 0 "register_operand" "=f,f")
13218 (match_operator:DF 3 "binary_fp_operator"
13220 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13221 (match_operand:DF 2 "register_operand" "0,f")]))]
13222 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13223 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13224 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13225 "* return output_387_binary_op (insn, operands);"
13226 [(set (attr "type")
13227 (cond [(match_operand:DF 3 "mult_operator")
13228 (const_string "fmul")
13229 (match_operand:DF 3 "div_operator")
13230 (const_string "fdiv")
13232 (const_string "fop")))
13233 (set_attr "mode" "SF")])
13235 (define_insn "*fop_df_5_i387"
13236 [(set (match_operand:DF 0 "register_operand" "=f,f")
13237 (match_operator:DF 3 "binary_fp_operator"
13238 [(match_operand:DF 1 "register_operand" "0,f")
13240 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13241 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13242 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13243 "* return output_387_binary_op (insn, operands);"
13244 [(set (attr "type")
13245 (cond [(match_operand:DF 3 "mult_operator")
13246 (const_string "fmul")
13247 (match_operand:DF 3 "div_operator")
13248 (const_string "fdiv")
13250 (const_string "fop")))
13251 (set_attr "mode" "SF")])
13253 (define_insn "*fop_df_6_i387"
13254 [(set (match_operand:DF 0 "register_operand" "=f,f")
13255 (match_operator:DF 3 "binary_fp_operator"
13257 (match_operand:SF 1 "register_operand" "0,f"))
13259 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13260 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13261 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13262 "* return output_387_binary_op (insn, operands);"
13263 [(set (attr "type")
13264 (cond [(match_operand:DF 3 "mult_operator")
13265 (const_string "fmul")
13266 (match_operand:DF 3 "div_operator")
13267 (const_string "fdiv")
13269 (const_string "fop")))
13270 (set_attr "mode" "SF")])
13272 (define_insn "*fop_xf_comm_i387"
13273 [(set (match_operand:XF 0 "register_operand" "=f")
13274 (match_operator:XF 3 "binary_fp_operator"
13275 [(match_operand:XF 1 "register_operand" "%0")
13276 (match_operand:XF 2 "register_operand" "f")]))]
13278 && COMMUTATIVE_ARITH_P (operands[3])"
13279 "* return output_387_binary_op (insn, operands);"
13280 [(set (attr "type")
13281 (if_then_else (match_operand:XF 3 "mult_operator")
13282 (const_string "fmul")
13283 (const_string "fop")))
13284 (set_attr "mode" "XF")])
13286 (define_insn "*fop_xf_1_i387"
13287 [(set (match_operand:XF 0 "register_operand" "=f,f")
13288 (match_operator:XF 3 "binary_fp_operator"
13289 [(match_operand:XF 1 "register_operand" "0,f")
13290 (match_operand:XF 2 "register_operand" "f,0")]))]
13292 && !COMMUTATIVE_ARITH_P (operands[3])"
13293 "* return output_387_binary_op (insn, operands);"
13294 [(set (attr "type")
13295 (cond [(match_operand:XF 3 "mult_operator")
13296 (const_string "fmul")
13297 (match_operand:XF 3 "div_operator")
13298 (const_string "fdiv")
13300 (const_string "fop")))
13301 (set_attr "mode" "XF")])
13303 (define_insn "*fop_xf_2_i387"
13304 [(set (match_operand:XF 0 "register_operand" "=f,f")
13305 (match_operator:XF 3 "binary_fp_operator"
13307 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13308 (match_operand:XF 2 "register_operand" "0,0")]))]
13309 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13310 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13311 [(set (attr "type")
13312 (cond [(match_operand:XF 3 "mult_operator")
13313 (const_string "fmul")
13314 (match_operand:XF 3 "div_operator")
13315 (const_string "fdiv")
13317 (const_string "fop")))
13318 (set_attr "fp_int_src" "true")
13319 (set_attr "mode" "<MODE>")])
13321 (define_insn "*fop_xf_3_i387"
13322 [(set (match_operand:XF 0 "register_operand" "=f,f")
13323 (match_operator:XF 3 "binary_fp_operator"
13324 [(match_operand:XF 1 "register_operand" "0,0")
13326 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13327 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13328 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13329 [(set (attr "type")
13330 (cond [(match_operand:XF 3 "mult_operator")
13331 (const_string "fmul")
13332 (match_operand:XF 3 "div_operator")
13333 (const_string "fdiv")
13335 (const_string "fop")))
13336 (set_attr "fp_int_src" "true")
13337 (set_attr "mode" "<MODE>")])
13339 (define_insn "*fop_xf_4_i387"
13340 [(set (match_operand:XF 0 "register_operand" "=f,f")
13341 (match_operator:XF 3 "binary_fp_operator"
13343 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13344 (match_operand:XF 2 "register_operand" "0,f")]))]
13346 "* return output_387_binary_op (insn, operands);"
13347 [(set (attr "type")
13348 (cond [(match_operand:XF 3 "mult_operator")
13349 (const_string "fmul")
13350 (match_operand:XF 3 "div_operator")
13351 (const_string "fdiv")
13353 (const_string "fop")))
13354 (set_attr "mode" "<MODE>")])
13356 (define_insn "*fop_xf_5_i387"
13357 [(set (match_operand:XF 0 "register_operand" "=f,f")
13358 (match_operator:XF 3 "binary_fp_operator"
13359 [(match_operand:XF 1 "register_operand" "0,f")
13361 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13363 "* return output_387_binary_op (insn, operands);"
13364 [(set (attr "type")
13365 (cond [(match_operand:XF 3 "mult_operator")
13366 (const_string "fmul")
13367 (match_operand:XF 3 "div_operator")
13368 (const_string "fdiv")
13370 (const_string "fop")))
13371 (set_attr "mode" "<MODE>")])
13373 (define_insn "*fop_xf_6_i387"
13374 [(set (match_operand:XF 0 "register_operand" "=f,f")
13375 (match_operator:XF 3 "binary_fp_operator"
13377 (match_operand:MODEF 1 "register_operand" "0,f"))
13379 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13381 "* return output_387_binary_op (insn, operands);"
13382 [(set (attr "type")
13383 (cond [(match_operand:XF 3 "mult_operator")
13384 (const_string "fmul")
13385 (match_operand:XF 3 "div_operator")
13386 (const_string "fdiv")
13388 (const_string "fop")))
13389 (set_attr "mode" "<MODE>")])
13392 [(set (match_operand 0 "register_operand")
13393 (match_operator 3 "binary_fp_operator"
13394 [(float (match_operand:SWI24 1 "register_operand"))
13395 (match_operand 2 "register_operand")]))]
13397 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13398 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13401 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13402 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13403 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13404 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13405 GET_MODE (operands[3]),
13408 ix86_free_from_memory (GET_MODE (operands[1]));
13413 [(set (match_operand 0 "register_operand")
13414 (match_operator 3 "binary_fp_operator"
13415 [(match_operand 1 "register_operand")
13416 (float (match_operand:SWI24 2 "register_operand"))]))]
13418 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13419 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13422 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13423 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13424 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13425 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13426 GET_MODE (operands[3]),
13429 ix86_free_from_memory (GET_MODE (operands[2]));
13433 ;; FPU special functions.
13435 ;; This pattern implements a no-op XFmode truncation for
13436 ;; all fancy i386 XFmode math functions.
13438 (define_insn "truncxf<mode>2_i387_noop_unspec"
13439 [(set (match_operand:MODEF 0 "register_operand" "=f")
13440 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13441 UNSPEC_TRUNC_NOOP))]
13442 "TARGET_USE_FANCY_MATH_387"
13443 "* return output_387_reg_move (insn, operands);"
13444 [(set_attr "type" "fmov")
13445 (set_attr "mode" "<MODE>")])
13447 (define_insn "sqrtxf2"
13448 [(set (match_operand:XF 0 "register_operand" "=f")
13449 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13450 "TARGET_USE_FANCY_MATH_387"
13452 [(set_attr "type" "fpspc")
13453 (set_attr "mode" "XF")
13454 (set_attr "athlon_decode" "direct")
13455 (set_attr "amdfam10_decode" "direct")
13456 (set_attr "bdver1_decode" "direct")])
13458 (define_insn "sqrt_extend<mode>xf2_i387"
13459 [(set (match_operand:XF 0 "register_operand" "=f")
13462 (match_operand:MODEF 1 "register_operand" "0"))))]
13463 "TARGET_USE_FANCY_MATH_387"
13465 [(set_attr "type" "fpspc")
13466 (set_attr "mode" "XF")
13467 (set_attr "athlon_decode" "direct")
13468 (set_attr "amdfam10_decode" "direct")
13469 (set_attr "bdver1_decode" "direct")])
13471 (define_insn "*rsqrtsf2_sse"
13472 [(set (match_operand:SF 0 "register_operand" "=x")
13473 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13476 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13477 [(set_attr "type" "sse")
13478 (set_attr "atom_sse_attr" "rcp")
13479 (set_attr "btver2_sse_attr" "rcp")
13480 (set_attr "prefix" "maybe_vex")
13481 (set_attr "mode" "SF")])
13483 (define_expand "rsqrtsf2"
13484 [(set (match_operand:SF 0 "register_operand")
13485 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
13489 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13493 (define_insn "*sqrt<mode>2_sse"
13494 [(set (match_operand:MODEF 0 "register_operand" "=x")
13496 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13497 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13498 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13499 [(set_attr "type" "sse")
13500 (set_attr "atom_sse_attr" "sqrt")
13501 (set_attr "btver2_sse_attr" "sqrt")
13502 (set_attr "prefix" "maybe_vex")
13503 (set_attr "mode" "<MODE>")
13504 (set_attr "athlon_decode" "*")
13505 (set_attr "amdfam10_decode" "*")
13506 (set_attr "bdver1_decode" "*")])
13508 (define_expand "sqrt<mode>2"
13509 [(set (match_operand:MODEF 0 "register_operand")
13511 (match_operand:MODEF 1 "nonimmediate_operand")))]
13512 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13513 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13515 if (<MODE>mode == SFmode
13517 && TARGET_RECIP_SQRT
13518 && !optimize_function_for_size_p (cfun)
13519 && flag_finite_math_only && !flag_trapping_math
13520 && flag_unsafe_math_optimizations)
13522 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13526 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13528 rtx op0 = gen_reg_rtx (XFmode);
13529 rtx op1 = force_reg (<MODE>mode, operands[1]);
13531 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13532 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13537 (define_insn "fpremxf4_i387"
13538 [(set (match_operand:XF 0 "register_operand" "=f")
13539 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13540 (match_operand:XF 3 "register_operand" "1")]
13542 (set (match_operand:XF 1 "register_operand" "=u")
13543 (unspec:XF [(match_dup 2) (match_dup 3)]
13545 (set (reg:CCFP FPSR_REG)
13546 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13548 "TARGET_USE_FANCY_MATH_387"
13550 [(set_attr "type" "fpspc")
13551 (set_attr "mode" "XF")])
13553 (define_expand "fmodxf3"
13554 [(use (match_operand:XF 0 "register_operand"))
13555 (use (match_operand:XF 1 "general_operand"))
13556 (use (match_operand:XF 2 "general_operand"))]
13557 "TARGET_USE_FANCY_MATH_387"
13559 rtx label = gen_label_rtx ();
13561 rtx op1 = gen_reg_rtx (XFmode);
13562 rtx op2 = gen_reg_rtx (XFmode);
13564 emit_move_insn (op2, operands[2]);
13565 emit_move_insn (op1, operands[1]);
13567 emit_label (label);
13568 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13569 ix86_emit_fp_unordered_jump (label);
13570 LABEL_NUSES (label) = 1;
13572 emit_move_insn (operands[0], op1);
13576 (define_expand "fmod<mode>3"
13577 [(use (match_operand:MODEF 0 "register_operand"))
13578 (use (match_operand:MODEF 1 "general_operand"))
13579 (use (match_operand:MODEF 2 "general_operand"))]
13580 "TARGET_USE_FANCY_MATH_387"
13582 rtx (*gen_truncxf) (rtx, rtx);
13584 rtx label = gen_label_rtx ();
13586 rtx op1 = gen_reg_rtx (XFmode);
13587 rtx op2 = gen_reg_rtx (XFmode);
13589 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13590 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13592 emit_label (label);
13593 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13594 ix86_emit_fp_unordered_jump (label);
13595 LABEL_NUSES (label) = 1;
13597 /* Truncate the result properly for strict SSE math. */
13598 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13599 && !TARGET_MIX_SSE_I387)
13600 gen_truncxf = gen_truncxf<mode>2;
13602 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13604 emit_insn (gen_truncxf (operands[0], op1));
13608 (define_insn "fprem1xf4_i387"
13609 [(set (match_operand:XF 0 "register_operand" "=f")
13610 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13611 (match_operand:XF 3 "register_operand" "1")]
13613 (set (match_operand:XF 1 "register_operand" "=u")
13614 (unspec:XF [(match_dup 2) (match_dup 3)]
13616 (set (reg:CCFP FPSR_REG)
13617 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13619 "TARGET_USE_FANCY_MATH_387"
13621 [(set_attr "type" "fpspc")
13622 (set_attr "mode" "XF")])
13624 (define_expand "remainderxf3"
13625 [(use (match_operand:XF 0 "register_operand"))
13626 (use (match_operand:XF 1 "general_operand"))
13627 (use (match_operand:XF 2 "general_operand"))]
13628 "TARGET_USE_FANCY_MATH_387"
13630 rtx label = gen_label_rtx ();
13632 rtx op1 = gen_reg_rtx (XFmode);
13633 rtx op2 = gen_reg_rtx (XFmode);
13635 emit_move_insn (op2, operands[2]);
13636 emit_move_insn (op1, operands[1]);
13638 emit_label (label);
13639 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13640 ix86_emit_fp_unordered_jump (label);
13641 LABEL_NUSES (label) = 1;
13643 emit_move_insn (operands[0], op1);
13647 (define_expand "remainder<mode>3"
13648 [(use (match_operand:MODEF 0 "register_operand"))
13649 (use (match_operand:MODEF 1 "general_operand"))
13650 (use (match_operand:MODEF 2 "general_operand"))]
13651 "TARGET_USE_FANCY_MATH_387"
13653 rtx (*gen_truncxf) (rtx, rtx);
13655 rtx label = gen_label_rtx ();
13657 rtx op1 = gen_reg_rtx (XFmode);
13658 rtx op2 = gen_reg_rtx (XFmode);
13660 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13661 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13663 emit_label (label);
13665 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13666 ix86_emit_fp_unordered_jump (label);
13667 LABEL_NUSES (label) = 1;
13669 /* Truncate the result properly for strict SSE math. */
13670 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13671 && !TARGET_MIX_SSE_I387)
13672 gen_truncxf = gen_truncxf<mode>2;
13674 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13676 emit_insn (gen_truncxf (operands[0], op1));
13680 (define_int_iterator SINCOS
13684 (define_int_attr sincos
13685 [(UNSPEC_SIN "sin")
13686 (UNSPEC_COS "cos")])
13688 (define_insn "*<sincos>xf2_i387"
13689 [(set (match_operand:XF 0 "register_operand" "=f")
13690 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13692 "TARGET_USE_FANCY_MATH_387
13693 && flag_unsafe_math_optimizations"
13695 [(set_attr "type" "fpspc")
13696 (set_attr "mode" "XF")])
13698 (define_insn "*<sincos>_extend<mode>xf2_i387"
13699 [(set (match_operand:XF 0 "register_operand" "=f")
13700 (unspec:XF [(float_extend:XF
13701 (match_operand:MODEF 1 "register_operand" "0"))]
13703 "TARGET_USE_FANCY_MATH_387
13704 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13705 || TARGET_MIX_SSE_I387)
13706 && flag_unsafe_math_optimizations"
13708 [(set_attr "type" "fpspc")
13709 (set_attr "mode" "XF")])
13711 ;; When sincos pattern is defined, sin and cos builtin functions will be
13712 ;; expanded to sincos pattern with one of its outputs left unused.
13713 ;; CSE pass will figure out if two sincos patterns can be combined,
13714 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13715 ;; depending on the unused output.
13717 (define_insn "sincosxf3"
13718 [(set (match_operand:XF 0 "register_operand" "=f")
13719 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13720 UNSPEC_SINCOS_COS))
13721 (set (match_operand:XF 1 "register_operand" "=u")
13722 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13723 "TARGET_USE_FANCY_MATH_387
13724 && flag_unsafe_math_optimizations"
13726 [(set_attr "type" "fpspc")
13727 (set_attr "mode" "XF")])
13730 [(set (match_operand:XF 0 "register_operand")
13731 (unspec:XF [(match_operand:XF 2 "register_operand")]
13732 UNSPEC_SINCOS_COS))
13733 (set (match_operand:XF 1 "register_operand")
13734 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13735 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13736 && can_create_pseudo_p ()"
13737 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13740 [(set (match_operand:XF 0 "register_operand")
13741 (unspec:XF [(match_operand:XF 2 "register_operand")]
13742 UNSPEC_SINCOS_COS))
13743 (set (match_operand:XF 1 "register_operand")
13744 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13745 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13746 && can_create_pseudo_p ()"
13747 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13749 (define_insn "sincos_extend<mode>xf3_i387"
13750 [(set (match_operand:XF 0 "register_operand" "=f")
13751 (unspec:XF [(float_extend:XF
13752 (match_operand:MODEF 2 "register_operand" "0"))]
13753 UNSPEC_SINCOS_COS))
13754 (set (match_operand:XF 1 "register_operand" "=u")
13755 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13756 "TARGET_USE_FANCY_MATH_387
13757 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13758 || TARGET_MIX_SSE_I387)
13759 && flag_unsafe_math_optimizations"
13761 [(set_attr "type" "fpspc")
13762 (set_attr "mode" "XF")])
13765 [(set (match_operand:XF 0 "register_operand")
13766 (unspec:XF [(float_extend:XF
13767 (match_operand:MODEF 2 "register_operand"))]
13768 UNSPEC_SINCOS_COS))
13769 (set (match_operand:XF 1 "register_operand")
13770 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13771 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13772 && can_create_pseudo_p ()"
13773 [(set (match_dup 1)
13774 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13777 [(set (match_operand:XF 0 "register_operand")
13778 (unspec:XF [(float_extend:XF
13779 (match_operand:MODEF 2 "register_operand"))]
13780 UNSPEC_SINCOS_COS))
13781 (set (match_operand:XF 1 "register_operand")
13782 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13783 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13784 && can_create_pseudo_p ()"
13785 [(set (match_dup 0)
13786 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13788 (define_expand "sincos<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);
13798 rtx op1 = gen_reg_rtx (XFmode);
13800 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13801 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13802 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13806 (define_insn "fptanxf4_i387"
13807 [(set (match_operand:XF 0 "register_operand" "=f")
13808 (match_operand:XF 3 "const_double_operand" "F"))
13809 (set (match_operand:XF 1 "register_operand" "=u")
13810 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13812 "TARGET_USE_FANCY_MATH_387
13813 && flag_unsafe_math_optimizations
13814 && standard_80387_constant_p (operands[3]) == 2"
13816 [(set_attr "type" "fpspc")
13817 (set_attr "mode" "XF")])
13819 (define_insn "fptan_extend<mode>xf4_i387"
13820 [(set (match_operand:MODEF 0 "register_operand" "=f")
13821 (match_operand:MODEF 3 "const_double_operand" "F"))
13822 (set (match_operand:XF 1 "register_operand" "=u")
13823 (unspec:XF [(float_extend:XF
13824 (match_operand:MODEF 2 "register_operand" "0"))]
13826 "TARGET_USE_FANCY_MATH_387
13827 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13828 || TARGET_MIX_SSE_I387)
13829 && flag_unsafe_math_optimizations
13830 && standard_80387_constant_p (operands[3]) == 2"
13832 [(set_attr "type" "fpspc")
13833 (set_attr "mode" "XF")])
13835 (define_expand "tanxf2"
13836 [(use (match_operand:XF 0 "register_operand"))
13837 (use (match_operand:XF 1 "register_operand"))]
13838 "TARGET_USE_FANCY_MATH_387
13839 && flag_unsafe_math_optimizations"
13841 rtx one = gen_reg_rtx (XFmode);
13842 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13844 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13848 (define_expand "tan<mode>2"
13849 [(use (match_operand:MODEF 0 "register_operand"))
13850 (use (match_operand:MODEF 1 "register_operand"))]
13851 "TARGET_USE_FANCY_MATH_387
13852 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13853 || TARGET_MIX_SSE_I387)
13854 && flag_unsafe_math_optimizations"
13856 rtx op0 = gen_reg_rtx (XFmode);
13858 rtx one = gen_reg_rtx (<MODE>mode);
13859 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13861 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13862 operands[1], op2));
13863 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13867 (define_insn "*fpatanxf3_i387"
13868 [(set (match_operand:XF 0 "register_operand" "=f")
13869 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13870 (match_operand:XF 2 "register_operand" "u")]
13872 (clobber (match_scratch:XF 3 "=2"))]
13873 "TARGET_USE_FANCY_MATH_387
13874 && flag_unsafe_math_optimizations"
13876 [(set_attr "type" "fpspc")
13877 (set_attr "mode" "XF")])
13879 (define_insn "fpatan_extend<mode>xf3_i387"
13880 [(set (match_operand:XF 0 "register_operand" "=f")
13881 (unspec:XF [(float_extend:XF
13882 (match_operand:MODEF 1 "register_operand" "0"))
13884 (match_operand:MODEF 2 "register_operand" "u"))]
13886 (clobber (match_scratch:XF 3 "=2"))]
13887 "TARGET_USE_FANCY_MATH_387
13888 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13889 || TARGET_MIX_SSE_I387)
13890 && flag_unsafe_math_optimizations"
13892 [(set_attr "type" "fpspc")
13893 (set_attr "mode" "XF")])
13895 (define_expand "atan2xf3"
13896 [(parallel [(set (match_operand:XF 0 "register_operand")
13897 (unspec:XF [(match_operand:XF 2 "register_operand")
13898 (match_operand:XF 1 "register_operand")]
13900 (clobber (match_scratch:XF 3))])]
13901 "TARGET_USE_FANCY_MATH_387
13902 && flag_unsafe_math_optimizations")
13904 (define_expand "atan2<mode>3"
13905 [(use (match_operand:MODEF 0 "register_operand"))
13906 (use (match_operand:MODEF 1 "register_operand"))
13907 (use (match_operand:MODEF 2 "register_operand"))]
13908 "TARGET_USE_FANCY_MATH_387
13909 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13910 || TARGET_MIX_SSE_I387)
13911 && flag_unsafe_math_optimizations"
13913 rtx op0 = gen_reg_rtx (XFmode);
13915 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13916 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13920 (define_expand "atanxf2"
13921 [(parallel [(set (match_operand:XF 0 "register_operand")
13922 (unspec:XF [(match_dup 2)
13923 (match_operand:XF 1 "register_operand")]
13925 (clobber (match_scratch:XF 3))])]
13926 "TARGET_USE_FANCY_MATH_387
13927 && flag_unsafe_math_optimizations"
13929 operands[2] = gen_reg_rtx (XFmode);
13930 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13933 (define_expand "atan<mode>2"
13934 [(use (match_operand:MODEF 0 "register_operand"))
13935 (use (match_operand:MODEF 1 "register_operand"))]
13936 "TARGET_USE_FANCY_MATH_387
13937 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13938 || TARGET_MIX_SSE_I387)
13939 && flag_unsafe_math_optimizations"
13941 rtx op0 = gen_reg_rtx (XFmode);
13943 rtx op2 = gen_reg_rtx (<MODE>mode);
13944 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13946 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13947 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13951 (define_expand "asinxf2"
13952 [(set (match_dup 2)
13953 (mult:XF (match_operand:XF 1 "register_operand")
13955 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13956 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13957 (parallel [(set (match_operand:XF 0 "register_operand")
13958 (unspec:XF [(match_dup 5) (match_dup 1)]
13960 (clobber (match_scratch:XF 6))])]
13961 "TARGET_USE_FANCY_MATH_387
13962 && flag_unsafe_math_optimizations"
13966 if (optimize_insn_for_size_p ())
13969 for (i = 2; i < 6; i++)
13970 operands[i] = gen_reg_rtx (XFmode);
13972 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13975 (define_expand "asin<mode>2"
13976 [(use (match_operand:MODEF 0 "register_operand"))
13977 (use (match_operand:MODEF 1 "general_operand"))]
13978 "TARGET_USE_FANCY_MATH_387
13979 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13980 || TARGET_MIX_SSE_I387)
13981 && flag_unsafe_math_optimizations"
13983 rtx op0 = gen_reg_rtx (XFmode);
13984 rtx op1 = gen_reg_rtx (XFmode);
13986 if (optimize_insn_for_size_p ())
13989 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13990 emit_insn (gen_asinxf2 (op0, op1));
13991 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13995 (define_expand "acosxf2"
13996 [(set (match_dup 2)
13997 (mult:XF (match_operand:XF 1 "register_operand")
13999 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
14000 (set (match_dup 5) (sqrt:XF (match_dup 4)))
14001 (parallel [(set (match_operand:XF 0 "register_operand")
14002 (unspec:XF [(match_dup 1) (match_dup 5)]
14004 (clobber (match_scratch:XF 6))])]
14005 "TARGET_USE_FANCY_MATH_387
14006 && flag_unsafe_math_optimizations"
14010 if (optimize_insn_for_size_p ())
14013 for (i = 2; i < 6; i++)
14014 operands[i] = gen_reg_rtx (XFmode);
14016 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
14019 (define_expand "acos<mode>2"
14020 [(use (match_operand:MODEF 0 "register_operand"))
14021 (use (match_operand:MODEF 1 "general_operand"))]
14022 "TARGET_USE_FANCY_MATH_387
14023 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14024 || TARGET_MIX_SSE_I387)
14025 && flag_unsafe_math_optimizations"
14027 rtx op0 = gen_reg_rtx (XFmode);
14028 rtx op1 = gen_reg_rtx (XFmode);
14030 if (optimize_insn_for_size_p ())
14033 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14034 emit_insn (gen_acosxf2 (op0, op1));
14035 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14039 (define_insn "fyl2xxf3_i387"
14040 [(set (match_operand:XF 0 "register_operand" "=f")
14041 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14042 (match_operand:XF 2 "register_operand" "u")]
14044 (clobber (match_scratch:XF 3 "=2"))]
14045 "TARGET_USE_FANCY_MATH_387
14046 && flag_unsafe_math_optimizations"
14048 [(set_attr "type" "fpspc")
14049 (set_attr "mode" "XF")])
14051 (define_insn "fyl2x_extend<mode>xf3_i387"
14052 [(set (match_operand:XF 0 "register_operand" "=f")
14053 (unspec:XF [(float_extend:XF
14054 (match_operand:MODEF 1 "register_operand" "0"))
14055 (match_operand:XF 2 "register_operand" "u")]
14057 (clobber (match_scratch:XF 3 "=2"))]
14058 "TARGET_USE_FANCY_MATH_387
14059 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14060 || TARGET_MIX_SSE_I387)
14061 && flag_unsafe_math_optimizations"
14063 [(set_attr "type" "fpspc")
14064 (set_attr "mode" "XF")])
14066 (define_expand "logxf2"
14067 [(parallel [(set (match_operand:XF 0 "register_operand")
14068 (unspec:XF [(match_operand:XF 1 "register_operand")
14069 (match_dup 2)] UNSPEC_FYL2X))
14070 (clobber (match_scratch:XF 3))])]
14071 "TARGET_USE_FANCY_MATH_387
14072 && flag_unsafe_math_optimizations"
14074 operands[2] = gen_reg_rtx (XFmode);
14075 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14078 (define_expand "log<mode>2"
14079 [(use (match_operand:MODEF 0 "register_operand"))
14080 (use (match_operand:MODEF 1 "register_operand"))]
14081 "TARGET_USE_FANCY_MATH_387
14082 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14083 || TARGET_MIX_SSE_I387)
14084 && flag_unsafe_math_optimizations"
14086 rtx op0 = gen_reg_rtx (XFmode);
14088 rtx op2 = gen_reg_rtx (XFmode);
14089 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14091 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14092 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14096 (define_expand "log10xf2"
14097 [(parallel [(set (match_operand:XF 0 "register_operand")
14098 (unspec:XF [(match_operand:XF 1 "register_operand")
14099 (match_dup 2)] UNSPEC_FYL2X))
14100 (clobber (match_scratch:XF 3))])]
14101 "TARGET_USE_FANCY_MATH_387
14102 && flag_unsafe_math_optimizations"
14104 operands[2] = gen_reg_rtx (XFmode);
14105 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14108 (define_expand "log10<mode>2"
14109 [(use (match_operand:MODEF 0 "register_operand"))
14110 (use (match_operand:MODEF 1 "register_operand"))]
14111 "TARGET_USE_FANCY_MATH_387
14112 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14113 || TARGET_MIX_SSE_I387)
14114 && flag_unsafe_math_optimizations"
14116 rtx op0 = gen_reg_rtx (XFmode);
14118 rtx op2 = gen_reg_rtx (XFmode);
14119 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14121 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14122 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14126 (define_expand "log2xf2"
14127 [(parallel [(set (match_operand:XF 0 "register_operand")
14128 (unspec:XF [(match_operand:XF 1 "register_operand")
14129 (match_dup 2)] UNSPEC_FYL2X))
14130 (clobber (match_scratch:XF 3))])]
14131 "TARGET_USE_FANCY_MATH_387
14132 && flag_unsafe_math_optimizations"
14134 operands[2] = gen_reg_rtx (XFmode);
14135 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14138 (define_expand "log2<mode>2"
14139 [(use (match_operand:MODEF 0 "register_operand"))
14140 (use (match_operand:MODEF 1 "register_operand"))]
14141 "TARGET_USE_FANCY_MATH_387
14142 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14143 || TARGET_MIX_SSE_I387)
14144 && flag_unsafe_math_optimizations"
14146 rtx op0 = gen_reg_rtx (XFmode);
14148 rtx op2 = gen_reg_rtx (XFmode);
14149 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14151 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14152 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14156 (define_insn "fyl2xp1xf3_i387"
14157 [(set (match_operand:XF 0 "register_operand" "=f")
14158 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14159 (match_operand:XF 2 "register_operand" "u")]
14161 (clobber (match_scratch:XF 3 "=2"))]
14162 "TARGET_USE_FANCY_MATH_387
14163 && flag_unsafe_math_optimizations"
14165 [(set_attr "type" "fpspc")
14166 (set_attr "mode" "XF")])
14168 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14169 [(set (match_operand:XF 0 "register_operand" "=f")
14170 (unspec:XF [(float_extend:XF
14171 (match_operand:MODEF 1 "register_operand" "0"))
14172 (match_operand:XF 2 "register_operand" "u")]
14174 (clobber (match_scratch:XF 3 "=2"))]
14175 "TARGET_USE_FANCY_MATH_387
14176 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14177 || TARGET_MIX_SSE_I387)
14178 && flag_unsafe_math_optimizations"
14180 [(set_attr "type" "fpspc")
14181 (set_attr "mode" "XF")])
14183 (define_expand "log1pxf2"
14184 [(use (match_operand:XF 0 "register_operand"))
14185 (use (match_operand:XF 1 "register_operand"))]
14186 "TARGET_USE_FANCY_MATH_387
14187 && flag_unsafe_math_optimizations"
14189 if (optimize_insn_for_size_p ())
14192 ix86_emit_i387_log1p (operands[0], operands[1]);
14196 (define_expand "log1p<mode>2"
14197 [(use (match_operand:MODEF 0 "register_operand"))
14198 (use (match_operand:MODEF 1 "register_operand"))]
14199 "TARGET_USE_FANCY_MATH_387
14200 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14201 || TARGET_MIX_SSE_I387)
14202 && flag_unsafe_math_optimizations"
14206 if (optimize_insn_for_size_p ())
14209 op0 = gen_reg_rtx (XFmode);
14211 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14213 ix86_emit_i387_log1p (op0, operands[1]);
14214 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14218 (define_insn "fxtractxf3_i387"
14219 [(set (match_operand:XF 0 "register_operand" "=f")
14220 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14221 UNSPEC_XTRACT_FRACT))
14222 (set (match_operand:XF 1 "register_operand" "=u")
14223 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14224 "TARGET_USE_FANCY_MATH_387
14225 && flag_unsafe_math_optimizations"
14227 [(set_attr "type" "fpspc")
14228 (set_attr "mode" "XF")])
14230 (define_insn "fxtract_extend<mode>xf3_i387"
14231 [(set (match_operand:XF 0 "register_operand" "=f")
14232 (unspec:XF [(float_extend:XF
14233 (match_operand:MODEF 2 "register_operand" "0"))]
14234 UNSPEC_XTRACT_FRACT))
14235 (set (match_operand:XF 1 "register_operand" "=u")
14236 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14237 "TARGET_USE_FANCY_MATH_387
14238 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14239 || TARGET_MIX_SSE_I387)
14240 && flag_unsafe_math_optimizations"
14242 [(set_attr "type" "fpspc")
14243 (set_attr "mode" "XF")])
14245 (define_expand "logbxf2"
14246 [(parallel [(set (match_dup 2)
14247 (unspec:XF [(match_operand:XF 1 "register_operand")]
14248 UNSPEC_XTRACT_FRACT))
14249 (set (match_operand:XF 0 "register_operand")
14250 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14251 "TARGET_USE_FANCY_MATH_387
14252 && flag_unsafe_math_optimizations"
14253 "operands[2] = gen_reg_rtx (XFmode);")
14255 (define_expand "logb<mode>2"
14256 [(use (match_operand:MODEF 0 "register_operand"))
14257 (use (match_operand:MODEF 1 "register_operand"))]
14258 "TARGET_USE_FANCY_MATH_387
14259 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14260 || TARGET_MIX_SSE_I387)
14261 && flag_unsafe_math_optimizations"
14263 rtx op0 = gen_reg_rtx (XFmode);
14264 rtx op1 = gen_reg_rtx (XFmode);
14266 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14267 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14271 (define_expand "ilogbxf2"
14272 [(use (match_operand:SI 0 "register_operand"))
14273 (use (match_operand:XF 1 "register_operand"))]
14274 "TARGET_USE_FANCY_MATH_387
14275 && flag_unsafe_math_optimizations"
14279 if (optimize_insn_for_size_p ())
14282 op0 = gen_reg_rtx (XFmode);
14283 op1 = gen_reg_rtx (XFmode);
14285 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14286 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14290 (define_expand "ilogb<mode>2"
14291 [(use (match_operand:SI 0 "register_operand"))
14292 (use (match_operand:MODEF 1 "register_operand"))]
14293 "TARGET_USE_FANCY_MATH_387
14294 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14295 || TARGET_MIX_SSE_I387)
14296 && flag_unsafe_math_optimizations"
14300 if (optimize_insn_for_size_p ())
14303 op0 = gen_reg_rtx (XFmode);
14304 op1 = gen_reg_rtx (XFmode);
14306 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14307 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14311 (define_insn "*f2xm1xf2_i387"
14312 [(set (match_operand:XF 0 "register_operand" "=f")
14313 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14315 "TARGET_USE_FANCY_MATH_387
14316 && flag_unsafe_math_optimizations"
14318 [(set_attr "type" "fpspc")
14319 (set_attr "mode" "XF")])
14321 (define_insn "*fscalexf4_i387"
14322 [(set (match_operand:XF 0 "register_operand" "=f")
14323 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14324 (match_operand:XF 3 "register_operand" "1")]
14325 UNSPEC_FSCALE_FRACT))
14326 (set (match_operand:XF 1 "register_operand" "=u")
14327 (unspec:XF [(match_dup 2) (match_dup 3)]
14328 UNSPEC_FSCALE_EXP))]
14329 "TARGET_USE_FANCY_MATH_387
14330 && flag_unsafe_math_optimizations"
14332 [(set_attr "type" "fpspc")
14333 (set_attr "mode" "XF")])
14335 (define_expand "expNcorexf3"
14336 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14337 (match_operand:XF 2 "register_operand")))
14338 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14339 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14340 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14341 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14342 (parallel [(set (match_operand:XF 0 "register_operand")
14343 (unspec:XF [(match_dup 8) (match_dup 4)]
14344 UNSPEC_FSCALE_FRACT))
14346 (unspec:XF [(match_dup 8) (match_dup 4)]
14347 UNSPEC_FSCALE_EXP))])]
14348 "TARGET_USE_FANCY_MATH_387
14349 && flag_unsafe_math_optimizations"
14353 if (optimize_insn_for_size_p ())
14356 for (i = 3; i < 10; i++)
14357 operands[i] = gen_reg_rtx (XFmode);
14359 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14362 (define_expand "expxf2"
14363 [(use (match_operand:XF 0 "register_operand"))
14364 (use (match_operand:XF 1 "register_operand"))]
14365 "TARGET_USE_FANCY_MATH_387
14366 && flag_unsafe_math_optimizations"
14370 if (optimize_insn_for_size_p ())
14373 op2 = gen_reg_rtx (XFmode);
14374 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14376 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14380 (define_expand "exp<mode>2"
14381 [(use (match_operand:MODEF 0 "register_operand"))
14382 (use (match_operand:MODEF 1 "general_operand"))]
14383 "TARGET_USE_FANCY_MATH_387
14384 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14385 || TARGET_MIX_SSE_I387)
14386 && flag_unsafe_math_optimizations"
14390 if (optimize_insn_for_size_p ())
14393 op0 = gen_reg_rtx (XFmode);
14394 op1 = gen_reg_rtx (XFmode);
14396 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14397 emit_insn (gen_expxf2 (op0, op1));
14398 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14402 (define_expand "exp10xf2"
14403 [(use (match_operand:XF 0 "register_operand"))
14404 (use (match_operand:XF 1 "register_operand"))]
14405 "TARGET_USE_FANCY_MATH_387
14406 && flag_unsafe_math_optimizations"
14410 if (optimize_insn_for_size_p ())
14413 op2 = gen_reg_rtx (XFmode);
14414 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14416 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14420 (define_expand "exp10<mode>2"
14421 [(use (match_operand:MODEF 0 "register_operand"))
14422 (use (match_operand:MODEF 1 "general_operand"))]
14423 "TARGET_USE_FANCY_MATH_387
14424 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14425 || TARGET_MIX_SSE_I387)
14426 && flag_unsafe_math_optimizations"
14430 if (optimize_insn_for_size_p ())
14433 op0 = gen_reg_rtx (XFmode);
14434 op1 = gen_reg_rtx (XFmode);
14436 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14437 emit_insn (gen_exp10xf2 (op0, op1));
14438 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14442 (define_expand "exp2xf2"
14443 [(use (match_operand:XF 0 "register_operand"))
14444 (use (match_operand:XF 1 "register_operand"))]
14445 "TARGET_USE_FANCY_MATH_387
14446 && flag_unsafe_math_optimizations"
14450 if (optimize_insn_for_size_p ())
14453 op2 = gen_reg_rtx (XFmode);
14454 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14456 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14460 (define_expand "exp2<mode>2"
14461 [(use (match_operand:MODEF 0 "register_operand"))
14462 (use (match_operand:MODEF 1 "general_operand"))]
14463 "TARGET_USE_FANCY_MATH_387
14464 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14465 || TARGET_MIX_SSE_I387)
14466 && flag_unsafe_math_optimizations"
14470 if (optimize_insn_for_size_p ())
14473 op0 = gen_reg_rtx (XFmode);
14474 op1 = gen_reg_rtx (XFmode);
14476 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14477 emit_insn (gen_exp2xf2 (op0, op1));
14478 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14482 (define_expand "expm1xf2"
14483 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14485 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14486 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14487 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14488 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14489 (parallel [(set (match_dup 7)
14490 (unspec:XF [(match_dup 6) (match_dup 4)]
14491 UNSPEC_FSCALE_FRACT))
14493 (unspec:XF [(match_dup 6) (match_dup 4)]
14494 UNSPEC_FSCALE_EXP))])
14495 (parallel [(set (match_dup 10)
14496 (unspec:XF [(match_dup 9) (match_dup 8)]
14497 UNSPEC_FSCALE_FRACT))
14498 (set (match_dup 11)
14499 (unspec:XF [(match_dup 9) (match_dup 8)]
14500 UNSPEC_FSCALE_EXP))])
14501 (set (match_dup 12) (minus:XF (match_dup 10)
14502 (float_extend:XF (match_dup 13))))
14503 (set (match_operand:XF 0 "register_operand")
14504 (plus:XF (match_dup 12) (match_dup 7)))]
14505 "TARGET_USE_FANCY_MATH_387
14506 && flag_unsafe_math_optimizations"
14510 if (optimize_insn_for_size_p ())
14513 for (i = 2; i < 13; i++)
14514 operands[i] = gen_reg_rtx (XFmode);
14517 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14519 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14522 (define_expand "expm1<mode>2"
14523 [(use (match_operand:MODEF 0 "register_operand"))
14524 (use (match_operand:MODEF 1 "general_operand"))]
14525 "TARGET_USE_FANCY_MATH_387
14526 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14527 || TARGET_MIX_SSE_I387)
14528 && flag_unsafe_math_optimizations"
14532 if (optimize_insn_for_size_p ())
14535 op0 = gen_reg_rtx (XFmode);
14536 op1 = gen_reg_rtx (XFmode);
14538 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14539 emit_insn (gen_expm1xf2 (op0, op1));
14540 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14544 (define_expand "ldexpxf3"
14545 [(set (match_dup 3)
14546 (float:XF (match_operand:SI 2 "register_operand")))
14547 (parallel [(set (match_operand:XF 0 " register_operand")
14548 (unspec:XF [(match_operand:XF 1 "register_operand")
14550 UNSPEC_FSCALE_FRACT))
14552 (unspec:XF [(match_dup 1) (match_dup 3)]
14553 UNSPEC_FSCALE_EXP))])]
14554 "TARGET_USE_FANCY_MATH_387
14555 && flag_unsafe_math_optimizations"
14557 if (optimize_insn_for_size_p ())
14560 operands[3] = gen_reg_rtx (XFmode);
14561 operands[4] = gen_reg_rtx (XFmode);
14564 (define_expand "ldexp<mode>3"
14565 [(use (match_operand:MODEF 0 "register_operand"))
14566 (use (match_operand:MODEF 1 "general_operand"))
14567 (use (match_operand:SI 2 "register_operand"))]
14568 "TARGET_USE_FANCY_MATH_387
14569 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14570 || TARGET_MIX_SSE_I387)
14571 && flag_unsafe_math_optimizations"
14575 if (optimize_insn_for_size_p ())
14578 op0 = gen_reg_rtx (XFmode);
14579 op1 = gen_reg_rtx (XFmode);
14581 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14582 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14583 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14587 (define_expand "scalbxf3"
14588 [(parallel [(set (match_operand:XF 0 " register_operand")
14589 (unspec:XF [(match_operand:XF 1 "register_operand")
14590 (match_operand:XF 2 "register_operand")]
14591 UNSPEC_FSCALE_FRACT))
14593 (unspec:XF [(match_dup 1) (match_dup 2)]
14594 UNSPEC_FSCALE_EXP))])]
14595 "TARGET_USE_FANCY_MATH_387
14596 && flag_unsafe_math_optimizations"
14598 if (optimize_insn_for_size_p ())
14601 operands[3] = gen_reg_rtx (XFmode);
14604 (define_expand "scalb<mode>3"
14605 [(use (match_operand:MODEF 0 "register_operand"))
14606 (use (match_operand:MODEF 1 "general_operand"))
14607 (use (match_operand:MODEF 2 "general_operand"))]
14608 "TARGET_USE_FANCY_MATH_387
14609 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14610 || TARGET_MIX_SSE_I387)
14611 && flag_unsafe_math_optimizations"
14615 if (optimize_insn_for_size_p ())
14618 op0 = gen_reg_rtx (XFmode);
14619 op1 = gen_reg_rtx (XFmode);
14620 op2 = gen_reg_rtx (XFmode);
14622 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14623 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14624 emit_insn (gen_scalbxf3 (op0, op1, op2));
14625 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14629 (define_expand "significandxf2"
14630 [(parallel [(set (match_operand:XF 0 "register_operand")
14631 (unspec:XF [(match_operand:XF 1 "register_operand")]
14632 UNSPEC_XTRACT_FRACT))
14634 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14635 "TARGET_USE_FANCY_MATH_387
14636 && flag_unsafe_math_optimizations"
14637 "operands[2] = gen_reg_rtx (XFmode);")
14639 (define_expand "significand<mode>2"
14640 [(use (match_operand:MODEF 0 "register_operand"))
14641 (use (match_operand:MODEF 1 "register_operand"))]
14642 "TARGET_USE_FANCY_MATH_387
14643 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14644 || TARGET_MIX_SSE_I387)
14645 && flag_unsafe_math_optimizations"
14647 rtx op0 = gen_reg_rtx (XFmode);
14648 rtx op1 = gen_reg_rtx (XFmode);
14650 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14651 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14656 (define_insn "sse4_1_round<mode>2"
14657 [(set (match_operand:MODEF 0 "register_operand" "=x")
14658 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14659 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14662 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14663 [(set_attr "type" "ssecvt")
14664 (set_attr "prefix_extra" "1")
14665 (set_attr "prefix" "maybe_vex")
14666 (set_attr "mode" "<MODE>")])
14668 (define_insn "rintxf2"
14669 [(set (match_operand:XF 0 "register_operand" "=f")
14670 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14672 "TARGET_USE_FANCY_MATH_387
14673 && flag_unsafe_math_optimizations"
14675 [(set_attr "type" "fpspc")
14676 (set_attr "mode" "XF")])
14678 (define_expand "rint<mode>2"
14679 [(use (match_operand:MODEF 0 "register_operand"))
14680 (use (match_operand:MODEF 1 "register_operand"))]
14681 "(TARGET_USE_FANCY_MATH_387
14682 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14683 || TARGET_MIX_SSE_I387)
14684 && flag_unsafe_math_optimizations)
14685 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14686 && !flag_trapping_math)"
14688 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14689 && !flag_trapping_math)
14692 emit_insn (gen_sse4_1_round<mode>2
14693 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14694 else if (optimize_insn_for_size_p ())
14697 ix86_expand_rint (operands[0], operands[1]);
14701 rtx op0 = gen_reg_rtx (XFmode);
14702 rtx op1 = gen_reg_rtx (XFmode);
14704 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14705 emit_insn (gen_rintxf2 (op0, op1));
14707 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14712 (define_expand "round<mode>2"
14713 [(match_operand:X87MODEF 0 "register_operand")
14714 (match_operand:X87MODEF 1 "nonimmediate_operand")]
14715 "(TARGET_USE_FANCY_MATH_387
14716 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14717 || TARGET_MIX_SSE_I387)
14718 && flag_unsafe_math_optimizations)
14719 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14720 && !flag_trapping_math && !flag_rounding_math)"
14722 if (optimize_insn_for_size_p ())
14725 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14726 && !flag_trapping_math && !flag_rounding_math)
14730 operands[1] = force_reg (<MODE>mode, operands[1]);
14731 ix86_expand_round_sse4 (operands[0], operands[1]);
14733 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14734 ix86_expand_round (operands[0], operands[1]);
14736 ix86_expand_rounddf_32 (operands[0], operands[1]);
14740 operands[1] = force_reg (<MODE>mode, operands[1]);
14741 ix86_emit_i387_round (operands[0], operands[1]);
14746 (define_insn_and_split "*fistdi2_1"
14747 [(set (match_operand:DI 0 "nonimmediate_operand")
14748 (unspec:DI [(match_operand:XF 1 "register_operand")]
14750 "TARGET_USE_FANCY_MATH_387
14751 && can_create_pseudo_p ()"
14756 if (memory_operand (operands[0], VOIDmode))
14757 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14760 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14761 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14766 [(set_attr "type" "fpspc")
14767 (set_attr "mode" "DI")])
14769 (define_insn "fistdi2"
14770 [(set (match_operand:DI 0 "memory_operand" "=m")
14771 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14773 (clobber (match_scratch:XF 2 "=&1f"))]
14774 "TARGET_USE_FANCY_MATH_387"
14775 "* return output_fix_trunc (insn, operands, false);"
14776 [(set_attr "type" "fpspc")
14777 (set_attr "mode" "DI")])
14779 (define_insn "fistdi2_with_temp"
14780 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14781 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14783 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14784 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14785 "TARGET_USE_FANCY_MATH_387"
14787 [(set_attr "type" "fpspc")
14788 (set_attr "mode" "DI")])
14791 [(set (match_operand:DI 0 "register_operand")
14792 (unspec:DI [(match_operand:XF 1 "register_operand")]
14794 (clobber (match_operand:DI 2 "memory_operand"))
14795 (clobber (match_scratch 3))]
14797 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14798 (clobber (match_dup 3))])
14799 (set (match_dup 0) (match_dup 2))])
14802 [(set (match_operand:DI 0 "memory_operand")
14803 (unspec:DI [(match_operand:XF 1 "register_operand")]
14805 (clobber (match_operand:DI 2 "memory_operand"))
14806 (clobber (match_scratch 3))]
14808 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14809 (clobber (match_dup 3))])])
14811 (define_insn_and_split "*fist<mode>2_1"
14812 [(set (match_operand:SWI24 0 "register_operand")
14813 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14815 "TARGET_USE_FANCY_MATH_387
14816 && can_create_pseudo_p ()"
14821 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14822 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14826 [(set_attr "type" "fpspc")
14827 (set_attr "mode" "<MODE>")])
14829 (define_insn "fist<mode>2"
14830 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14831 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14833 "TARGET_USE_FANCY_MATH_387"
14834 "* return output_fix_trunc (insn, operands, false);"
14835 [(set_attr "type" "fpspc")
14836 (set_attr "mode" "<MODE>")])
14838 (define_insn "fist<mode>2_with_temp"
14839 [(set (match_operand:SWI24 0 "register_operand" "=r")
14840 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14842 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14843 "TARGET_USE_FANCY_MATH_387"
14845 [(set_attr "type" "fpspc")
14846 (set_attr "mode" "<MODE>")])
14849 [(set (match_operand:SWI24 0 "register_operand")
14850 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14852 (clobber (match_operand:SWI24 2 "memory_operand"))]
14854 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14855 (set (match_dup 0) (match_dup 2))])
14858 [(set (match_operand:SWI24 0 "memory_operand")
14859 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14861 (clobber (match_operand:SWI24 2 "memory_operand"))]
14863 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14865 (define_expand "lrintxf<mode>2"
14866 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
14867 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
14869 "TARGET_USE_FANCY_MATH_387")
14871 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
14872 [(set (match_operand:SWI48 0 "nonimmediate_operand")
14873 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
14874 UNSPEC_FIX_NOTRUNC))]
14875 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
14877 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14878 [(match_operand:SWI248x 0 "nonimmediate_operand")
14879 (match_operand:X87MODEF 1 "register_operand")]
14880 "(TARGET_USE_FANCY_MATH_387
14881 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14882 || TARGET_MIX_SSE_I387)
14883 && flag_unsafe_math_optimizations)
14884 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14885 && <SWI248x:MODE>mode != HImode
14886 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14887 && !flag_trapping_math && !flag_rounding_math)"
14889 if (optimize_insn_for_size_p ())
14892 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14893 && <SWI248x:MODE>mode != HImode
14894 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14895 && !flag_trapping_math && !flag_rounding_math)
14896 ix86_expand_lround (operands[0], operands[1]);
14898 ix86_emit_i387_round (operands[0], operands[1]);
14902 (define_int_iterator FRNDINT_ROUNDING
14903 [UNSPEC_FRNDINT_FLOOR
14904 UNSPEC_FRNDINT_CEIL
14905 UNSPEC_FRNDINT_TRUNC])
14907 (define_int_iterator FIST_ROUNDING
14911 ;; Base name for define_insn
14912 (define_int_attr rounding_insn
14913 [(UNSPEC_FRNDINT_FLOOR "floor")
14914 (UNSPEC_FRNDINT_CEIL "ceil")
14915 (UNSPEC_FRNDINT_TRUNC "btrunc")
14916 (UNSPEC_FIST_FLOOR "floor")
14917 (UNSPEC_FIST_CEIL "ceil")])
14919 (define_int_attr rounding
14920 [(UNSPEC_FRNDINT_FLOOR "floor")
14921 (UNSPEC_FRNDINT_CEIL "ceil")
14922 (UNSPEC_FRNDINT_TRUNC "trunc")
14923 (UNSPEC_FIST_FLOOR "floor")
14924 (UNSPEC_FIST_CEIL "ceil")])
14926 (define_int_attr ROUNDING
14927 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
14928 (UNSPEC_FRNDINT_CEIL "CEIL")
14929 (UNSPEC_FRNDINT_TRUNC "TRUNC")
14930 (UNSPEC_FIST_FLOOR "FLOOR")
14931 (UNSPEC_FIST_CEIL "CEIL")])
14933 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14934 (define_insn_and_split "frndintxf2_<rounding>"
14935 [(set (match_operand:XF 0 "register_operand")
14936 (unspec:XF [(match_operand:XF 1 "register_operand")]
14938 (clobber (reg:CC FLAGS_REG))]
14939 "TARGET_USE_FANCY_MATH_387
14940 && flag_unsafe_math_optimizations
14941 && can_create_pseudo_p ()"
14946 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
14948 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14949 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
14951 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
14952 operands[2], operands[3]));
14955 [(set_attr "type" "frndint")
14956 (set_attr "i387_cw" "<rounding>")
14957 (set_attr "mode" "XF")])
14959 (define_insn "frndintxf2_<rounding>_i387"
14960 [(set (match_operand:XF 0 "register_operand" "=f")
14961 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14963 (use (match_operand:HI 2 "memory_operand" "m"))
14964 (use (match_operand:HI 3 "memory_operand" "m"))]
14965 "TARGET_USE_FANCY_MATH_387
14966 && flag_unsafe_math_optimizations"
14967 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14968 [(set_attr "type" "frndint")
14969 (set_attr "i387_cw" "<rounding>")
14970 (set_attr "mode" "XF")])
14972 (define_expand "<rounding_insn>xf2"
14973 [(parallel [(set (match_operand:XF 0 "register_operand")
14974 (unspec:XF [(match_operand:XF 1 "register_operand")]
14976 (clobber (reg:CC FLAGS_REG))])]
14977 "TARGET_USE_FANCY_MATH_387
14978 && flag_unsafe_math_optimizations
14979 && !optimize_insn_for_size_p ()")
14981 (define_expand "<rounding_insn><mode>2"
14982 [(parallel [(set (match_operand:MODEF 0 "register_operand")
14983 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
14985 (clobber (reg:CC FLAGS_REG))])]
14986 "(TARGET_USE_FANCY_MATH_387
14987 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14988 || TARGET_MIX_SSE_I387)
14989 && flag_unsafe_math_optimizations)
14990 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14991 && !flag_trapping_math)"
14993 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14994 && !flag_trapping_math)
14997 emit_insn (gen_sse4_1_round<mode>2
14998 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
14999 else if (optimize_insn_for_size_p ())
15001 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15003 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15004 ix86_expand_floorceil (operands[0], operands[1], true);
15005 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15006 ix86_expand_floorceil (operands[0], operands[1], false);
15007 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15008 ix86_expand_trunc (operands[0], operands[1]);
15010 gcc_unreachable ();
15014 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15015 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
15016 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15017 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15018 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
15019 ix86_expand_truncdf_32 (operands[0], operands[1]);
15021 gcc_unreachable ();
15028 if (optimize_insn_for_size_p ())
15031 op0 = gen_reg_rtx (XFmode);
15032 op1 = gen_reg_rtx (XFmode);
15033 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15034 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
15036 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15041 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15042 (define_insn_and_split "frndintxf2_mask_pm"
15043 [(set (match_operand:XF 0 "register_operand")
15044 (unspec:XF [(match_operand:XF 1 "register_operand")]
15045 UNSPEC_FRNDINT_MASK_PM))
15046 (clobber (reg:CC FLAGS_REG))]
15047 "TARGET_USE_FANCY_MATH_387
15048 && flag_unsafe_math_optimizations
15049 && can_create_pseudo_p ()"
15054 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15056 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15057 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15059 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15060 operands[2], operands[3]));
15063 [(set_attr "type" "frndint")
15064 (set_attr "i387_cw" "mask_pm")
15065 (set_attr "mode" "XF")])
15067 (define_insn "frndintxf2_mask_pm_i387"
15068 [(set (match_operand:XF 0 "register_operand" "=f")
15069 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15070 UNSPEC_FRNDINT_MASK_PM))
15071 (use (match_operand:HI 2 "memory_operand" "m"))
15072 (use (match_operand:HI 3 "memory_operand" "m"))]
15073 "TARGET_USE_FANCY_MATH_387
15074 && flag_unsafe_math_optimizations"
15075 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15076 [(set_attr "type" "frndint")
15077 (set_attr "i387_cw" "mask_pm")
15078 (set_attr "mode" "XF")])
15080 (define_expand "nearbyintxf2"
15081 [(parallel [(set (match_operand:XF 0 "register_operand")
15082 (unspec:XF [(match_operand:XF 1 "register_operand")]
15083 UNSPEC_FRNDINT_MASK_PM))
15084 (clobber (reg:CC FLAGS_REG))])]
15085 "TARGET_USE_FANCY_MATH_387
15086 && flag_unsafe_math_optimizations")
15088 (define_expand "nearbyint<mode>2"
15089 [(use (match_operand:MODEF 0 "register_operand"))
15090 (use (match_operand:MODEF 1 "register_operand"))]
15091 "TARGET_USE_FANCY_MATH_387
15092 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15093 || TARGET_MIX_SSE_I387)
15094 && flag_unsafe_math_optimizations"
15096 rtx op0 = gen_reg_rtx (XFmode);
15097 rtx op1 = gen_reg_rtx (XFmode);
15099 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15100 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15102 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15106 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15107 (define_insn_and_split "*fist<mode>2_<rounding>_1"
15108 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15109 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15111 (clobber (reg:CC FLAGS_REG))]
15112 "TARGET_USE_FANCY_MATH_387
15113 && flag_unsafe_math_optimizations
15114 && can_create_pseudo_p ()"
15119 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
15121 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15122 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
15123 if (memory_operand (operands[0], VOIDmode))
15124 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
15125 operands[2], operands[3]));
15128 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15129 emit_insn (gen_fist<mode>2_<rounding>_with_temp
15130 (operands[0], operands[1], operands[2],
15131 operands[3], operands[4]));
15135 [(set_attr "type" "fistp")
15136 (set_attr "i387_cw" "<rounding>")
15137 (set_attr "mode" "<MODE>")])
15139 (define_insn "fistdi2_<rounding>"
15140 [(set (match_operand:DI 0 "memory_operand" "=m")
15141 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15143 (use (match_operand:HI 2 "memory_operand" "m"))
15144 (use (match_operand:HI 3 "memory_operand" "m"))
15145 (clobber (match_scratch:XF 4 "=&1f"))]
15146 "TARGET_USE_FANCY_MATH_387
15147 && flag_unsafe_math_optimizations"
15148 "* return output_fix_trunc (insn, operands, false);"
15149 [(set_attr "type" "fistp")
15150 (set_attr "i387_cw" "<rounding>")
15151 (set_attr "mode" "DI")])
15153 (define_insn "fistdi2_<rounding>_with_temp"
15154 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15155 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15157 (use (match_operand:HI 2 "memory_operand" "m,m"))
15158 (use (match_operand:HI 3 "memory_operand" "m,m"))
15159 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15160 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15161 "TARGET_USE_FANCY_MATH_387
15162 && flag_unsafe_math_optimizations"
15164 [(set_attr "type" "fistp")
15165 (set_attr "i387_cw" "<rounding>")
15166 (set_attr "mode" "DI")])
15169 [(set (match_operand:DI 0 "register_operand")
15170 (unspec:DI [(match_operand:XF 1 "register_operand")]
15172 (use (match_operand:HI 2 "memory_operand"))
15173 (use (match_operand:HI 3 "memory_operand"))
15174 (clobber (match_operand:DI 4 "memory_operand"))
15175 (clobber (match_scratch 5))]
15177 [(parallel [(set (match_dup 4)
15178 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15179 (use (match_dup 2))
15180 (use (match_dup 3))
15181 (clobber (match_dup 5))])
15182 (set (match_dup 0) (match_dup 4))])
15185 [(set (match_operand:DI 0 "memory_operand")
15186 (unspec:DI [(match_operand:XF 1 "register_operand")]
15188 (use (match_operand:HI 2 "memory_operand"))
15189 (use (match_operand:HI 3 "memory_operand"))
15190 (clobber (match_operand:DI 4 "memory_operand"))
15191 (clobber (match_scratch 5))]
15193 [(parallel [(set (match_dup 0)
15194 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
15195 (use (match_dup 2))
15196 (use (match_dup 3))
15197 (clobber (match_dup 5))])])
15199 (define_insn "fist<mode>2_<rounding>"
15200 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15201 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15203 (use (match_operand:HI 2 "memory_operand" "m"))
15204 (use (match_operand:HI 3 "memory_operand" "m"))]
15205 "TARGET_USE_FANCY_MATH_387
15206 && flag_unsafe_math_optimizations"
15207 "* return output_fix_trunc (insn, operands, false);"
15208 [(set_attr "type" "fistp")
15209 (set_attr "i387_cw" "<rounding>")
15210 (set_attr "mode" "<MODE>")])
15212 (define_insn "fist<mode>2_<rounding>_with_temp"
15213 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15214 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15216 (use (match_operand:HI 2 "memory_operand" "m,m"))
15217 (use (match_operand:HI 3 "memory_operand" "m,m"))
15218 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15219 "TARGET_USE_FANCY_MATH_387
15220 && flag_unsafe_math_optimizations"
15222 [(set_attr "type" "fistp")
15223 (set_attr "i387_cw" "<rounding>")
15224 (set_attr "mode" "<MODE>")])
15227 [(set (match_operand:SWI24 0 "register_operand")
15228 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15230 (use (match_operand:HI 2 "memory_operand"))
15231 (use (match_operand:HI 3 "memory_operand"))
15232 (clobber (match_operand:SWI24 4 "memory_operand"))]
15234 [(parallel [(set (match_dup 4)
15235 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15236 (use (match_dup 2))
15237 (use (match_dup 3))])
15238 (set (match_dup 0) (match_dup 4))])
15241 [(set (match_operand:SWI24 0 "memory_operand")
15242 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15244 (use (match_operand:HI 2 "memory_operand"))
15245 (use (match_operand:HI 3 "memory_operand"))
15246 (clobber (match_operand:SWI24 4 "memory_operand"))]
15248 [(parallel [(set (match_dup 0)
15249 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
15250 (use (match_dup 2))
15251 (use (match_dup 3))])])
15253 (define_expand "l<rounding_insn>xf<mode>2"
15254 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15255 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15257 (clobber (reg:CC FLAGS_REG))])]
15258 "TARGET_USE_FANCY_MATH_387
15259 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15260 && flag_unsafe_math_optimizations")
15262 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
15263 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
15264 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
15266 (clobber (reg:CC FLAGS_REG))])]
15267 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15268 && !flag_trapping_math"
15270 if (TARGET_64BIT && optimize_insn_for_size_p ())
15273 if (ROUND_<ROUNDING> == ROUND_FLOOR)
15274 ix86_expand_lfloorceil (operands[0], operands[1], true);
15275 else if (ROUND_<ROUNDING> == ROUND_CEIL)
15276 ix86_expand_lfloorceil (operands[0], operands[1], false);
15278 gcc_unreachable ();
15283 (define_insn "fxam<mode>2_i387"
15284 [(set (match_operand:HI 0 "register_operand" "=a")
15286 [(match_operand:X87MODEF 1 "register_operand" "f")]
15288 "TARGET_USE_FANCY_MATH_387"
15289 "fxam\n\tfnstsw\t%0"
15290 [(set_attr "type" "multi")
15291 (set_attr "length" "4")
15292 (set_attr "unit" "i387")
15293 (set_attr "mode" "<MODE>")])
15295 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15296 [(set (match_operand:HI 0 "register_operand")
15298 [(match_operand:MODEF 1 "memory_operand")]
15300 "TARGET_USE_FANCY_MATH_387
15301 && can_create_pseudo_p ()"
15304 [(set (match_dup 2)(match_dup 1))
15306 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15308 operands[2] = gen_reg_rtx (<MODE>mode);
15310 MEM_VOLATILE_P (operands[1]) = 1;
15312 [(set_attr "type" "multi")
15313 (set_attr "unit" "i387")
15314 (set_attr "mode" "<MODE>")])
15316 (define_expand "isinfxf2"
15317 [(use (match_operand:SI 0 "register_operand"))
15318 (use (match_operand:XF 1 "register_operand"))]
15319 "TARGET_USE_FANCY_MATH_387
15320 && TARGET_C99_FUNCTIONS"
15322 rtx mask = GEN_INT (0x45);
15323 rtx val = GEN_INT (0x05);
15327 rtx scratch = gen_reg_rtx (HImode);
15328 rtx res = gen_reg_rtx (QImode);
15330 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15332 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15333 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15334 cond = gen_rtx_fmt_ee (EQ, QImode,
15335 gen_rtx_REG (CCmode, FLAGS_REG),
15337 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15338 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15342 (define_expand "isinf<mode>2"
15343 [(use (match_operand:SI 0 "register_operand"))
15344 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15345 "TARGET_USE_FANCY_MATH_387
15346 && TARGET_C99_FUNCTIONS
15347 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15349 rtx mask = GEN_INT (0x45);
15350 rtx val = GEN_INT (0x05);
15354 rtx scratch = gen_reg_rtx (HImode);
15355 rtx res = gen_reg_rtx (QImode);
15357 /* Remove excess precision by forcing value through memory. */
15358 if (memory_operand (operands[1], VOIDmode))
15359 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15362 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15364 emit_move_insn (temp, operands[1]);
15365 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15368 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15369 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15370 cond = gen_rtx_fmt_ee (EQ, QImode,
15371 gen_rtx_REG (CCmode, FLAGS_REG),
15373 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15374 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15378 (define_expand "signbitxf2"
15379 [(use (match_operand:SI 0 "register_operand"))
15380 (use (match_operand:XF 1 "register_operand"))]
15381 "TARGET_USE_FANCY_MATH_387"
15383 rtx scratch = gen_reg_rtx (HImode);
15385 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15386 emit_insn (gen_andsi3 (operands[0],
15387 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15391 (define_insn "movmsk_df"
15392 [(set (match_operand:SI 0 "register_operand" "=r")
15394 [(match_operand:DF 1 "register_operand" "x")]
15396 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15397 "%vmovmskpd\t{%1, %0|%0, %1}"
15398 [(set_attr "type" "ssemov")
15399 (set_attr "prefix" "maybe_vex")
15400 (set_attr "mode" "DF")])
15402 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15403 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15404 (define_expand "signbitdf2"
15405 [(use (match_operand:SI 0 "register_operand"))
15406 (use (match_operand:DF 1 "register_operand"))]
15407 "TARGET_USE_FANCY_MATH_387
15408 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15410 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15412 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15413 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15417 rtx scratch = gen_reg_rtx (HImode);
15419 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15420 emit_insn (gen_andsi3 (operands[0],
15421 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15426 (define_expand "signbitsf2"
15427 [(use (match_operand:SI 0 "register_operand"))
15428 (use (match_operand:SF 1 "register_operand"))]
15429 "TARGET_USE_FANCY_MATH_387
15430 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15432 rtx scratch = gen_reg_rtx (HImode);
15434 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15435 emit_insn (gen_andsi3 (operands[0],
15436 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15440 ;; Block operation instructions
15443 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15446 [(set_attr "length" "1")
15447 (set_attr "length_immediate" "0")
15448 (set_attr "modrm" "0")])
15450 (define_expand "movmem<mode>"
15451 [(use (match_operand:BLK 0 "memory_operand"))
15452 (use (match_operand:BLK 1 "memory_operand"))
15453 (use (match_operand:SWI48 2 "nonmemory_operand"))
15454 (use (match_operand:SWI48 3 "const_int_operand"))
15455 (use (match_operand:SI 4 "const_int_operand"))
15456 (use (match_operand:SI 5 "const_int_operand"))]
15459 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15460 operands[4], operands[5]))
15466 ;; Most CPUs don't like single string operations
15467 ;; Handle this case here to simplify previous expander.
15469 (define_expand "strmov"
15470 [(set (match_dup 4) (match_operand 3 "memory_operand"))
15471 (set (match_operand 1 "memory_operand") (match_dup 4))
15472 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
15473 (clobber (reg:CC FLAGS_REG))])
15474 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
15475 (clobber (reg:CC FLAGS_REG))])]
15478 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15480 /* If .md ever supports :P for Pmode, these can be directly
15481 in the pattern above. */
15482 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15483 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15485 /* Can't use this if the user has appropriated esi or edi. */
15486 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15487 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15489 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15490 operands[2], operands[3],
15491 operands[5], operands[6]));
15495 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15498 (define_expand "strmov_singleop"
15499 [(parallel [(set (match_operand 1 "memory_operand")
15500 (match_operand 3 "memory_operand"))
15501 (set (match_operand 0 "register_operand")
15503 (set (match_operand 2 "register_operand")
15504 (match_operand 5))])]
15506 "ix86_current_function_needs_cld = 1;")
15508 (define_insn "*strmovdi_rex_1"
15509 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15510 (mem:DI (match_operand:P 3 "register_operand" "1")))
15511 (set (match_operand:P 0 "register_operand" "=D")
15512 (plus:P (match_dup 2)
15514 (set (match_operand:P 1 "register_operand" "=S")
15515 (plus:P (match_dup 3)
15518 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15520 [(set_attr "type" "str")
15521 (set_attr "memory" "both")
15522 (set_attr "mode" "DI")])
15524 (define_insn "*strmovsi_1"
15525 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15526 (mem:SI (match_operand:P 3 "register_operand" "1")))
15527 (set (match_operand:P 0 "register_operand" "=D")
15528 (plus:P (match_dup 2)
15530 (set (match_operand:P 1 "register_operand" "=S")
15531 (plus:P (match_dup 3)
15533 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15535 [(set_attr "type" "str")
15536 (set_attr "memory" "both")
15537 (set_attr "mode" "SI")])
15539 (define_insn "*strmovhi_1"
15540 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15541 (mem:HI (match_operand:P 3 "register_operand" "1")))
15542 (set (match_operand:P 0 "register_operand" "=D")
15543 (plus:P (match_dup 2)
15545 (set (match_operand:P 1 "register_operand" "=S")
15546 (plus:P (match_dup 3)
15548 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15550 [(set_attr "type" "str")
15551 (set_attr "memory" "both")
15552 (set_attr "mode" "HI")])
15554 (define_insn "*strmovqi_1"
15555 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15556 (mem:QI (match_operand:P 3 "register_operand" "1")))
15557 (set (match_operand:P 0 "register_operand" "=D")
15558 (plus:P (match_dup 2)
15560 (set (match_operand:P 1 "register_operand" "=S")
15561 (plus:P (match_dup 3)
15563 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15565 [(set_attr "type" "str")
15566 (set_attr "memory" "both")
15567 (set (attr "prefix_rex")
15569 (match_test "<P:MODE>mode == DImode")
15571 (const_string "*")))
15572 (set_attr "mode" "QI")])
15574 (define_expand "rep_mov"
15575 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
15576 (set (match_operand 0 "register_operand")
15578 (set (match_operand 2 "register_operand")
15580 (set (match_operand 1 "memory_operand")
15581 (match_operand 3 "memory_operand"))
15582 (use (match_dup 4))])]
15584 "ix86_current_function_needs_cld = 1;")
15586 (define_insn "*rep_movdi_rex64"
15587 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15588 (set (match_operand:P 0 "register_operand" "=D")
15589 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15591 (match_operand:P 3 "register_operand" "0")))
15592 (set (match_operand:P 1 "register_operand" "=S")
15593 (plus:P (ashift:P (match_dup 5) (const_int 3))
15594 (match_operand:P 4 "register_operand" "1")))
15595 (set (mem:BLK (match_dup 3))
15596 (mem:BLK (match_dup 4)))
15597 (use (match_dup 5))]
15599 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15601 [(set_attr "type" "str")
15602 (set_attr "prefix_rep" "1")
15603 (set_attr "memory" "both")
15604 (set_attr "mode" "DI")])
15606 (define_insn "*rep_movsi"
15607 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15608 (set (match_operand:P 0 "register_operand" "=D")
15609 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15611 (match_operand:P 3 "register_operand" "0")))
15612 (set (match_operand:P 1 "register_operand" "=S")
15613 (plus:P (ashift:P (match_dup 5) (const_int 2))
15614 (match_operand:P 4 "register_operand" "1")))
15615 (set (mem:BLK (match_dup 3))
15616 (mem:BLK (match_dup 4)))
15617 (use (match_dup 5))]
15618 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15619 "%^rep{%;} movs{l|d}"
15620 [(set_attr "type" "str")
15621 (set_attr "prefix_rep" "1")
15622 (set_attr "memory" "both")
15623 (set_attr "mode" "SI")])
15625 (define_insn "*rep_movqi"
15626 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15627 (set (match_operand:P 0 "register_operand" "=D")
15628 (plus:P (match_operand:P 3 "register_operand" "0")
15629 (match_operand:P 5 "register_operand" "2")))
15630 (set (match_operand:P 1 "register_operand" "=S")
15631 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15632 (set (mem:BLK (match_dup 3))
15633 (mem:BLK (match_dup 4)))
15634 (use (match_dup 5))]
15635 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15637 [(set_attr "type" "str")
15638 (set_attr "prefix_rep" "1")
15639 (set_attr "memory" "both")
15640 (set_attr "mode" "QI")])
15642 (define_expand "setmem<mode>"
15643 [(use (match_operand:BLK 0 "memory_operand"))
15644 (use (match_operand:SWI48 1 "nonmemory_operand"))
15645 (use (match_operand:QI 2 "nonmemory_operand"))
15646 (use (match_operand 3 "const_int_operand"))
15647 (use (match_operand:SI 4 "const_int_operand"))
15648 (use (match_operand:SI 5 "const_int_operand"))]
15651 if (ix86_expand_setmem (operands[0], operands[1],
15652 operands[2], operands[3],
15653 operands[4], operands[5]))
15659 ;; Most CPUs don't like single string operations
15660 ;; Handle this case here to simplify previous expander.
15662 (define_expand "strset"
15663 [(set (match_operand 1 "memory_operand")
15664 (match_operand 2 "register_operand"))
15665 (parallel [(set (match_operand 0 "register_operand")
15667 (clobber (reg:CC FLAGS_REG))])]
15670 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15671 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15673 /* If .md ever supports :P for Pmode, this can be directly
15674 in the pattern above. */
15675 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15676 GEN_INT (GET_MODE_SIZE (GET_MODE
15678 /* Can't use this if the user has appropriated eax or edi. */
15679 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15680 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15682 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15688 (define_expand "strset_singleop"
15689 [(parallel [(set (match_operand 1 "memory_operand")
15690 (match_operand 2 "register_operand"))
15691 (set (match_operand 0 "register_operand")
15693 (unspec [(const_int 0)] UNSPEC_STOS)])]
15695 "ix86_current_function_needs_cld = 1;")
15697 (define_insn "*strsetdi_rex_1"
15698 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
15699 (match_operand:DI 2 "register_operand" "a"))
15700 (set (match_operand:P 0 "register_operand" "=D")
15701 (plus:P (match_dup 1)
15703 (unspec [(const_int 0)] UNSPEC_STOS)]
15705 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15707 [(set_attr "type" "str")
15708 (set_attr "memory" "store")
15709 (set_attr "mode" "DI")])
15711 (define_insn "*strsetsi_1"
15712 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15713 (match_operand:SI 2 "register_operand" "a"))
15714 (set (match_operand:P 0 "register_operand" "=D")
15715 (plus:P (match_dup 1)
15717 (unspec [(const_int 0)] UNSPEC_STOS)]
15718 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15720 [(set_attr "type" "str")
15721 (set_attr "memory" "store")
15722 (set_attr "mode" "SI")])
15724 (define_insn "*strsethi_1"
15725 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15726 (match_operand:HI 2 "register_operand" "a"))
15727 (set (match_operand:P 0 "register_operand" "=D")
15728 (plus:P (match_dup 1)
15730 (unspec [(const_int 0)] UNSPEC_STOS)]
15731 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15733 [(set_attr "type" "str")
15734 (set_attr "memory" "store")
15735 (set_attr "mode" "HI")])
15737 (define_insn "*strsetqi_1"
15738 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15739 (match_operand:QI 2 "register_operand" "a"))
15740 (set (match_operand:P 0 "register_operand" "=D")
15741 (plus:P (match_dup 1)
15743 (unspec [(const_int 0)] UNSPEC_STOS)]
15744 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15746 [(set_attr "type" "str")
15747 (set_attr "memory" "store")
15748 (set (attr "prefix_rex")
15750 (match_test "<P:MODE>mode == DImode")
15752 (const_string "*")))
15753 (set_attr "mode" "QI")])
15755 (define_expand "rep_stos"
15756 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
15757 (set (match_operand 0 "register_operand")
15759 (set (match_operand 2 "memory_operand") (const_int 0))
15760 (use (match_operand 3 "register_operand"))
15761 (use (match_dup 1))])]
15763 "ix86_current_function_needs_cld = 1;")
15765 (define_insn "*rep_stosdi_rex64"
15766 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15767 (set (match_operand:P 0 "register_operand" "=D")
15768 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15770 (match_operand:P 3 "register_operand" "0")))
15771 (set (mem:BLK (match_dup 3))
15773 (use (match_operand:DI 2 "register_operand" "a"))
15774 (use (match_dup 4))]
15776 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15778 [(set_attr "type" "str")
15779 (set_attr "prefix_rep" "1")
15780 (set_attr "memory" "store")
15781 (set_attr "mode" "DI")])
15783 (define_insn "*rep_stossi"
15784 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15785 (set (match_operand:P 0 "register_operand" "=D")
15786 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15788 (match_operand:P 3 "register_operand" "0")))
15789 (set (mem:BLK (match_dup 3))
15791 (use (match_operand:SI 2 "register_operand" "a"))
15792 (use (match_dup 4))]
15793 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15794 "%^rep{%;} stos{l|d}"
15795 [(set_attr "type" "str")
15796 (set_attr "prefix_rep" "1")
15797 (set_attr "memory" "store")
15798 (set_attr "mode" "SI")])
15800 (define_insn "*rep_stosqi"
15801 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15802 (set (match_operand:P 0 "register_operand" "=D")
15803 (plus:P (match_operand:P 3 "register_operand" "0")
15804 (match_operand:P 4 "register_operand" "1")))
15805 (set (mem:BLK (match_dup 3))
15807 (use (match_operand:QI 2 "register_operand" "a"))
15808 (use (match_dup 4))]
15809 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15811 [(set_attr "type" "str")
15812 (set_attr "prefix_rep" "1")
15813 (set_attr "memory" "store")
15814 (set (attr "prefix_rex")
15816 (match_test "<P:MODE>mode == DImode")
15818 (const_string "*")))
15819 (set_attr "mode" "QI")])
15821 (define_expand "cmpstrnsi"
15822 [(set (match_operand:SI 0 "register_operand")
15823 (compare:SI (match_operand:BLK 1 "general_operand")
15824 (match_operand:BLK 2 "general_operand")))
15825 (use (match_operand 3 "general_operand"))
15826 (use (match_operand 4 "immediate_operand"))]
15829 rtx addr1, addr2, out, outlow, count, countreg, align;
15831 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15834 /* Can't use this if the user has appropriated ecx, esi or edi. */
15835 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
15840 out = gen_reg_rtx (SImode);
15842 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
15843 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
15844 if (addr1 != XEXP (operands[1], 0))
15845 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15846 if (addr2 != XEXP (operands[2], 0))
15847 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15849 count = operands[3];
15850 countreg = ix86_zero_extend_to_Pmode (count);
15852 /* %%% Iff we are testing strict equality, we can use known alignment
15853 to good advantage. This may be possible with combine, particularly
15854 once cc0 is dead. */
15855 align = operands[4];
15857 if (CONST_INT_P (count))
15859 if (INTVAL (count) == 0)
15861 emit_move_insn (operands[0], const0_rtx);
15864 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15865 operands[1], operands[2]));
15869 rtx (*gen_cmp) (rtx, rtx);
15871 gen_cmp = (TARGET_64BIT
15872 ? gen_cmpdi_1 : gen_cmpsi_1);
15874 emit_insn (gen_cmp (countreg, countreg));
15875 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15876 operands[1], operands[2]));
15879 outlow = gen_lowpart (QImode, out);
15880 emit_insn (gen_cmpintqi (outlow));
15881 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15883 if (operands[0] != out)
15884 emit_move_insn (operands[0], out);
15889 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15891 (define_expand "cmpintqi"
15892 [(set (match_dup 1)
15893 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15895 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15896 (parallel [(set (match_operand:QI 0 "register_operand")
15897 (minus:QI (match_dup 1)
15899 (clobber (reg:CC FLAGS_REG))])]
15902 operands[1] = gen_reg_rtx (QImode);
15903 operands[2] = gen_reg_rtx (QImode);
15906 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15907 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
15909 (define_expand "cmpstrnqi_nz_1"
15910 [(parallel [(set (reg:CC FLAGS_REG)
15911 (compare:CC (match_operand 4 "memory_operand")
15912 (match_operand 5 "memory_operand")))
15913 (use (match_operand 2 "register_operand"))
15914 (use (match_operand:SI 3 "immediate_operand"))
15915 (clobber (match_operand 0 "register_operand"))
15916 (clobber (match_operand 1 "register_operand"))
15917 (clobber (match_dup 2))])]
15919 "ix86_current_function_needs_cld = 1;")
15921 (define_insn "*cmpstrnqi_nz_1"
15922 [(set (reg:CC FLAGS_REG)
15923 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15924 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
15925 (use (match_operand:P 6 "register_operand" "2"))
15926 (use (match_operand:SI 3 "immediate_operand" "i"))
15927 (clobber (match_operand:P 0 "register_operand" "=S"))
15928 (clobber (match_operand:P 1 "register_operand" "=D"))
15929 (clobber (match_operand:P 2 "register_operand" "=c"))]
15930 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15932 [(set_attr "type" "str")
15933 (set_attr "mode" "QI")
15934 (set (attr "prefix_rex")
15936 (match_test "<P:MODE>mode == DImode")
15938 (const_string "*")))
15939 (set_attr "prefix_rep" "1")])
15941 ;; The same, but the count is not known to not be zero.
15943 (define_expand "cmpstrnqi_1"
15944 [(parallel [(set (reg:CC FLAGS_REG)
15945 (if_then_else:CC (ne (match_operand 2 "register_operand")
15947 (compare:CC (match_operand 4 "memory_operand")
15948 (match_operand 5 "memory_operand"))
15950 (use (match_operand:SI 3 "immediate_operand"))
15951 (use (reg:CC FLAGS_REG))
15952 (clobber (match_operand 0 "register_operand"))
15953 (clobber (match_operand 1 "register_operand"))
15954 (clobber (match_dup 2))])]
15956 "ix86_current_function_needs_cld = 1;")
15958 (define_insn "*cmpstrnqi_1"
15959 [(set (reg:CC FLAGS_REG)
15960 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
15962 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15963 (mem:BLK (match_operand:P 5 "register_operand" "1")))
15965 (use (match_operand:SI 3 "immediate_operand" "i"))
15966 (use (reg:CC FLAGS_REG))
15967 (clobber (match_operand:P 0 "register_operand" "=S"))
15968 (clobber (match_operand:P 1 "register_operand" "=D"))
15969 (clobber (match_operand:P 2 "register_operand" "=c"))]
15970 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15972 [(set_attr "type" "str")
15973 (set_attr "mode" "QI")
15974 (set (attr "prefix_rex")
15976 (match_test "<P:MODE>mode == DImode")
15978 (const_string "*")))
15979 (set_attr "prefix_rep" "1")])
15981 (define_expand "strlen<mode>"
15982 [(set (match_operand:P 0 "register_operand")
15983 (unspec:P [(match_operand:BLK 1 "general_operand")
15984 (match_operand:QI 2 "immediate_operand")
15985 (match_operand 3 "immediate_operand")]
15989 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15995 (define_expand "strlenqi_1"
15996 [(parallel [(set (match_operand 0 "register_operand")
15998 (clobber (match_operand 1 "register_operand"))
15999 (clobber (reg:CC FLAGS_REG))])]
16001 "ix86_current_function_needs_cld = 1;")
16003 (define_insn "*strlenqi_1"
16004 [(set (match_operand:P 0 "register_operand" "=&c")
16005 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16006 (match_operand:QI 2 "register_operand" "a")
16007 (match_operand:P 3 "immediate_operand" "i")
16008 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16009 (clobber (match_operand:P 1 "register_operand" "=D"))
16010 (clobber (reg:CC FLAGS_REG))]
16011 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16012 "%^repnz{%;} scasb"
16013 [(set_attr "type" "str")
16014 (set_attr "mode" "QI")
16015 (set (attr "prefix_rex")
16017 (match_test "<P:MODE>mode == DImode")
16019 (const_string "*")))
16020 (set_attr "prefix_rep" "1")])
16022 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16023 ;; handled in combine, but it is not currently up to the task.
16024 ;; When used for their truth value, the cmpstrn* expanders generate
16033 ;; The intermediate three instructions are unnecessary.
16035 ;; This one handles cmpstrn*_nz_1...
16038 (set (reg:CC FLAGS_REG)
16039 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16040 (mem:BLK (match_operand 5 "register_operand"))))
16041 (use (match_operand 6 "register_operand"))
16042 (use (match_operand:SI 3 "immediate_operand"))
16043 (clobber (match_operand 0 "register_operand"))
16044 (clobber (match_operand 1 "register_operand"))
16045 (clobber (match_operand 2 "register_operand"))])
16046 (set (match_operand:QI 7 "register_operand")
16047 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16048 (set (match_operand:QI 8 "register_operand")
16049 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16050 (set (reg FLAGS_REG)
16051 (compare (match_dup 7) (match_dup 8)))
16053 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16055 (set (reg:CC FLAGS_REG)
16056 (compare:CC (mem:BLK (match_dup 4))
16057 (mem:BLK (match_dup 5))))
16058 (use (match_dup 6))
16059 (use (match_dup 3))
16060 (clobber (match_dup 0))
16061 (clobber (match_dup 1))
16062 (clobber (match_dup 2))])])
16064 ;; ...and this one handles cmpstrn*_1.
16067 (set (reg:CC FLAGS_REG)
16068 (if_then_else:CC (ne (match_operand 6 "register_operand")
16070 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16071 (mem:BLK (match_operand 5 "register_operand")))
16073 (use (match_operand:SI 3 "immediate_operand"))
16074 (use (reg:CC FLAGS_REG))
16075 (clobber (match_operand 0 "register_operand"))
16076 (clobber (match_operand 1 "register_operand"))
16077 (clobber (match_operand 2 "register_operand"))])
16078 (set (match_operand:QI 7 "register_operand")
16079 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16080 (set (match_operand:QI 8 "register_operand")
16081 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16082 (set (reg FLAGS_REG)
16083 (compare (match_dup 7) (match_dup 8)))
16085 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16087 (set (reg:CC FLAGS_REG)
16088 (if_then_else:CC (ne (match_dup 6)
16090 (compare:CC (mem:BLK (match_dup 4))
16091 (mem:BLK (match_dup 5)))
16093 (use (match_dup 3))
16094 (use (reg:CC FLAGS_REG))
16095 (clobber (match_dup 0))
16096 (clobber (match_dup 1))
16097 (clobber (match_dup 2))])])
16099 ;; Conditional move instructions.
16101 (define_expand "mov<mode>cc"
16102 [(set (match_operand:SWIM 0 "register_operand")
16103 (if_then_else:SWIM (match_operand 1 "comparison_operator")
16104 (match_operand:SWIM 2 "<general_operand>")
16105 (match_operand:SWIM 3 "<general_operand>")))]
16107 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16109 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16110 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16111 ;; So just document what we're doing explicitly.
16113 (define_expand "x86_mov<mode>cc_0_m1"
16115 [(set (match_operand:SWI48 0 "register_operand")
16116 (if_then_else:SWI48
16117 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16118 [(match_operand 1 "flags_reg_operand")
16122 (clobber (reg:CC FLAGS_REG))])])
16124 (define_insn "*x86_mov<mode>cc_0_m1"
16125 [(set (match_operand:SWI48 0 "register_operand" "=r")
16126 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16127 [(reg FLAGS_REG) (const_int 0)])
16130 (clobber (reg:CC FLAGS_REG))]
16132 "sbb{<imodesuffix>}\t%0, %0"
16133 ; Since we don't have the proper number of operands for an alu insn,
16134 ; fill in all the blanks.
16135 [(set_attr "type" "alu")
16136 (set_attr "use_carry" "1")
16137 (set_attr "pent_pair" "pu")
16138 (set_attr "memory" "none")
16139 (set_attr "imm_disp" "false")
16140 (set_attr "mode" "<MODE>")
16141 (set_attr "length_immediate" "0")])
16143 (define_insn "*x86_mov<mode>cc_0_m1_se"
16144 [(set (match_operand:SWI48 0 "register_operand" "=r")
16145 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16146 [(reg FLAGS_REG) (const_int 0)])
16149 (clobber (reg:CC FLAGS_REG))]
16151 "sbb{<imodesuffix>}\t%0, %0"
16152 [(set_attr "type" "alu")
16153 (set_attr "use_carry" "1")
16154 (set_attr "pent_pair" "pu")
16155 (set_attr "memory" "none")
16156 (set_attr "imm_disp" "false")
16157 (set_attr "mode" "<MODE>")
16158 (set_attr "length_immediate" "0")])
16160 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16161 [(set (match_operand:SWI48 0 "register_operand" "=r")
16162 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16163 [(reg FLAGS_REG) (const_int 0)])))
16164 (clobber (reg:CC FLAGS_REG))]
16166 "sbb{<imodesuffix>}\t%0, %0"
16167 [(set_attr "type" "alu")
16168 (set_attr "use_carry" "1")
16169 (set_attr "pent_pair" "pu")
16170 (set_attr "memory" "none")
16171 (set_attr "imm_disp" "false")
16172 (set_attr "mode" "<MODE>")
16173 (set_attr "length_immediate" "0")])
16175 (define_insn "*mov<mode>cc_noc"
16176 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16177 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16178 [(reg FLAGS_REG) (const_int 0)])
16179 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16180 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16181 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16183 cmov%O2%C1\t{%2, %0|%0, %2}
16184 cmov%O2%c1\t{%3, %0|%0, %3}"
16185 [(set_attr "type" "icmov")
16186 (set_attr "mode" "<MODE>")])
16188 ;; Don't do conditional moves with memory inputs. This splitter helps
16189 ;; register starved x86_32 by forcing inputs into registers before reload.
16191 [(set (match_operand:SWI248 0 "register_operand")
16192 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16193 [(reg FLAGS_REG) (const_int 0)])
16194 (match_operand:SWI248 2 "nonimmediate_operand")
16195 (match_operand:SWI248 3 "nonimmediate_operand")))]
16196 "!TARGET_64BIT && TARGET_CMOVE
16197 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16198 && (MEM_P (operands[2]) || MEM_P (operands[3]))
16199 && can_create_pseudo_p ()
16200 && optimize_insn_for_speed_p ()"
16201 [(set (match_dup 0)
16202 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
16204 if (MEM_P (operands[2]))
16205 operands[2] = force_reg (<MODE>mode, operands[2]);
16206 if (MEM_P (operands[3]))
16207 operands[3] = force_reg (<MODE>mode, operands[3]);
16210 (define_insn "*movqicc_noc"
16211 [(set (match_operand:QI 0 "register_operand" "=r,r")
16212 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16213 [(reg FLAGS_REG) (const_int 0)])
16214 (match_operand:QI 2 "register_operand" "r,0")
16215 (match_operand:QI 3 "register_operand" "0,r")))]
16216 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16218 [(set_attr "type" "icmov")
16219 (set_attr "mode" "QI")])
16222 [(set (match_operand:SWI12 0 "register_operand")
16223 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
16224 [(reg FLAGS_REG) (const_int 0)])
16225 (match_operand:SWI12 2 "register_operand")
16226 (match_operand:SWI12 3 "register_operand")))]
16227 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16228 && reload_completed"
16229 [(set (match_dup 0)
16230 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16232 operands[0] = gen_lowpart (SImode, operands[0]);
16233 operands[2] = gen_lowpart (SImode, operands[2]);
16234 operands[3] = gen_lowpart (SImode, operands[3]);
16237 ;; Don't do conditional moves with memory inputs
16239 [(match_scratch:SWI248 2 "r")
16240 (set (match_operand:SWI248 0 "register_operand")
16241 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16242 [(reg FLAGS_REG) (const_int 0)])
16244 (match_operand:SWI248 3 "memory_operand")))]
16245 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16246 && optimize_insn_for_speed_p ()"
16247 [(set (match_dup 2) (match_dup 3))
16249 (if_then_else:SWI248 (match_dup 1) (match_dup 0) (match_dup 2)))])
16252 [(match_scratch:SWI248 2 "r")
16253 (set (match_operand:SWI248 0 "register_operand")
16254 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16255 [(reg FLAGS_REG) (const_int 0)])
16256 (match_operand:SWI248 3 "memory_operand")
16258 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16259 && optimize_insn_for_speed_p ()"
16260 [(set (match_dup 2) (match_dup 3))
16262 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 0)))])
16264 (define_expand "mov<mode>cc"
16265 [(set (match_operand:X87MODEF 0 "register_operand")
16266 (if_then_else:X87MODEF
16267 (match_operand 1 "comparison_operator")
16268 (match_operand:X87MODEF 2 "register_operand")
16269 (match_operand:X87MODEF 3 "register_operand")))]
16270 "(TARGET_80387 && TARGET_CMOVE)
16271 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16272 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16274 (define_insn "*movxfcc_1"
16275 [(set (match_operand:XF 0 "register_operand" "=f,f")
16276 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16277 [(reg FLAGS_REG) (const_int 0)])
16278 (match_operand:XF 2 "register_operand" "f,0")
16279 (match_operand:XF 3 "register_operand" "0,f")))]
16280 "TARGET_80387 && TARGET_CMOVE"
16282 fcmov%F1\t{%2, %0|%0, %2}
16283 fcmov%f1\t{%3, %0|%0, %3}"
16284 [(set_attr "type" "fcmov")
16285 (set_attr "mode" "XF")])
16287 (define_insn "*movdfcc_1_rex64"
16288 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16289 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16290 [(reg FLAGS_REG) (const_int 0)])
16291 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16292 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16293 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16294 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16296 fcmov%F1\t{%2, %0|%0, %2}
16297 fcmov%f1\t{%3, %0|%0, %3}
16298 cmov%O2%C1\t{%2, %0|%0, %2}
16299 cmov%O2%c1\t{%3, %0|%0, %3}"
16300 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16301 (set_attr "mode" "DF,DF,DI,DI")])
16303 (define_insn "*movdfcc_1"
16304 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16305 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16306 [(reg FLAGS_REG) (const_int 0)])
16307 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16308 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16309 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16310 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16312 fcmov%F1\t{%2, %0|%0, %2}
16313 fcmov%f1\t{%3, %0|%0, %3}
16316 [(set_attr "type" "fcmov,fcmov,multi,multi")
16317 (set_attr "mode" "DF,DF,DI,DI")])
16320 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16321 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16322 [(reg FLAGS_REG) (const_int 0)])
16323 (match_operand:DF 2 "nonimmediate_operand")
16324 (match_operand:DF 3 "nonimmediate_operand")))]
16325 "!TARGET_64BIT && reload_completed"
16326 [(set (match_dup 2)
16327 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16329 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16331 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16332 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16335 (define_insn "*movsfcc_1_387"
16336 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16337 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16338 [(reg FLAGS_REG) (const_int 0)])
16339 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16340 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16341 "TARGET_80387 && TARGET_CMOVE
16342 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16344 fcmov%F1\t{%2, %0|%0, %2}
16345 fcmov%f1\t{%3, %0|%0, %3}
16346 cmov%O2%C1\t{%2, %0|%0, %2}
16347 cmov%O2%c1\t{%3, %0|%0, %3}"
16348 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16349 (set_attr "mode" "SF,SF,SI,SI")])
16351 ;; Don't do conditional moves with memory inputs. This splitter helps
16352 ;; register starved x86_32 by forcing inputs into registers before reload.
16354 [(set (match_operand:MODEF 0 "register_operand")
16355 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
16356 [(reg FLAGS_REG) (const_int 0)])
16357 (match_operand:MODEF 2 "nonimmediate_operand")
16358 (match_operand:MODEF 3 "nonimmediate_operand")))]
16359 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16360 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16361 && (MEM_P (operands[2]) || MEM_P (operands[3]))
16362 && can_create_pseudo_p ()
16363 && optimize_insn_for_speed_p ()"
16364 [(set (match_dup 0)
16365 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
16367 if (MEM_P (operands[2]))
16368 operands[2] = force_reg (<MODE>mode, operands[2]);
16369 if (MEM_P (operands[3]))
16370 operands[3] = force_reg (<MODE>mode, operands[3]);
16373 ;; Don't do conditional moves with memory inputs
16375 [(match_scratch:MODEF 2 "r")
16376 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16377 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16378 [(reg FLAGS_REG) (const_int 0)])
16380 (match_operand:MODEF 3 "memory_operand")))]
16381 "(<MODE>mode != DFmode || TARGET_64BIT)
16382 && TARGET_80387 && TARGET_CMOVE
16383 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16384 && optimize_insn_for_speed_p ()"
16385 [(set (match_dup 2) (match_dup 3))
16387 (if_then_else:MODEF (match_dup 1) (match_dup 0) (match_dup 2)))])
16390 [(match_scratch:MODEF 2 "r")
16391 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
16392 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
16393 [(reg FLAGS_REG) (const_int 0)])
16394 (match_operand:MODEF 3 "memory_operand")
16396 "(<MODE>mode != DFmode || TARGET_64BIT)
16397 && TARGET_80387 && TARGET_CMOVE
16398 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
16399 && optimize_insn_for_speed_p ()"
16400 [(set (match_dup 2) (match_dup 3))
16402 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 0)))])
16404 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16405 ;; the scalar versions to have only XMM registers as operands.
16407 ;; XOP conditional move
16408 (define_insn "*xop_pcmov_<mode>"
16409 [(set (match_operand:MODEF 0 "register_operand" "=x")
16410 (if_then_else:MODEF
16411 (match_operand:MODEF 1 "register_operand" "x")
16412 (match_operand:MODEF 2 "register_operand" "x")
16413 (match_operand:MODEF 3 "register_operand" "x")))]
16415 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16416 [(set_attr "type" "sse4arg")])
16418 ;; These versions of the min/max patterns are intentionally ignorant of
16419 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16420 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16421 ;; are undefined in this condition, we're certain this is correct.
16423 (define_insn "<code><mode>3"
16424 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16426 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16427 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16428 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16430 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16431 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16432 [(set_attr "isa" "noavx,avx")
16433 (set_attr "prefix" "orig,vex")
16434 (set_attr "type" "sseadd")
16435 (set_attr "mode" "<MODE>")])
16437 ;; These versions of the min/max patterns implement exactly the operations
16438 ;; min = (op1 < op2 ? op1 : op2)
16439 ;; max = (!(op1 < op2) ? op1 : op2)
16440 ;; Their operands are not commutative, and thus they may be used in the
16441 ;; presence of -0.0 and NaN.
16443 (define_int_iterator IEEE_MAXMIN
16447 (define_int_attr ieee_maxmin
16448 [(UNSPEC_IEEE_MAX "max")
16449 (UNSPEC_IEEE_MIN "min")])
16451 (define_insn "*ieee_s<ieee_maxmin><mode>3"
16452 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16454 [(match_operand:MODEF 1 "register_operand" "0,x")
16455 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16457 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16459 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
16460 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16461 [(set_attr "isa" "noavx,avx")
16462 (set_attr "prefix" "orig,vex")
16463 (set_attr "type" "sseadd")
16464 (set_attr "mode" "<MODE>")])
16466 ;; Make two stack loads independent:
16468 ;; fld %st(0) -> fld bb
16469 ;; fmul bb fmul %st(1), %st
16471 ;; Actually we only match the last two instructions for simplicity.
16473 [(set (match_operand 0 "fp_register_operand")
16474 (match_operand 1 "fp_register_operand"))
16476 (match_operator 2 "binary_fp_operator"
16478 (match_operand 3 "memory_operand")]))]
16479 "REGNO (operands[0]) != REGNO (operands[1])"
16480 [(set (match_dup 0) (match_dup 3))
16481 (set (match_dup 0) (match_dup 4))]
16483 ;; The % modifier is not operational anymore in peephole2's, so we have to
16484 ;; swap the operands manually in the case of addition and multiplication.
16488 if (COMMUTATIVE_ARITH_P (operands[2]))
16489 op0 = operands[0], op1 = operands[1];
16491 op0 = operands[1], op1 = operands[0];
16493 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16494 GET_MODE (operands[2]),
16498 ;; Conditional addition patterns
16499 (define_expand "add<mode>cc"
16500 [(match_operand:SWI 0 "register_operand")
16501 (match_operand 1 "ordered_comparison_operator")
16502 (match_operand:SWI 2 "register_operand")
16503 (match_operand:SWI 3 "const_int_operand")]
16505 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16507 ;; Misc patterns (?)
16509 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16510 ;; Otherwise there will be nothing to keep
16512 ;; [(set (reg ebp) (reg esp))]
16513 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16514 ;; (clobber (eflags)]
16515 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16517 ;; in proper program order.
16519 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16520 [(set (match_operand:P 0 "register_operand" "=r,r")
16521 (plus:P (match_operand:P 1 "register_operand" "0,r")
16522 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16523 (clobber (reg:CC FLAGS_REG))
16524 (clobber (mem:BLK (scratch)))]
16527 switch (get_attr_type (insn))
16530 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16533 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16534 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16535 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16537 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16540 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16541 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16544 [(set (attr "type")
16545 (cond [(and (eq_attr "alternative" "0")
16546 (not (match_test "TARGET_OPT_AGU")))
16547 (const_string "alu")
16548 (match_operand:<MODE> 2 "const0_operand")
16549 (const_string "imov")
16551 (const_string "lea")))
16552 (set (attr "length_immediate")
16553 (cond [(eq_attr "type" "imov")
16555 (and (eq_attr "type" "alu")
16556 (match_operand 2 "const128_operand"))
16559 (const_string "*")))
16560 (set_attr "mode" "<MODE>")])
16562 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16563 [(set (match_operand:P 0 "register_operand" "=r")
16564 (minus:P (match_operand:P 1 "register_operand" "0")
16565 (match_operand:P 2 "register_operand" "r")))
16566 (clobber (reg:CC FLAGS_REG))
16567 (clobber (mem:BLK (scratch)))]
16569 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16570 [(set_attr "type" "alu")
16571 (set_attr "mode" "<MODE>")])
16573 (define_insn "allocate_stack_worker_probe_<mode>"
16574 [(set (match_operand:P 0 "register_operand" "=a")
16575 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16576 UNSPECV_STACK_PROBE))
16577 (clobber (reg:CC FLAGS_REG))]
16578 "ix86_target_stack_probe ()"
16579 "call\t___chkstk_ms"
16580 [(set_attr "type" "multi")
16581 (set_attr "length" "5")])
16583 (define_expand "allocate_stack"
16584 [(match_operand 0 "register_operand")
16585 (match_operand 1 "general_operand")]
16586 "ix86_target_stack_probe ()"
16590 #ifndef CHECK_STACK_LIMIT
16591 #define CHECK_STACK_LIMIT 0
16594 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16595 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16599 rtx (*insn) (rtx, rtx);
16601 x = copy_to_mode_reg (Pmode, operands[1]);
16603 insn = (TARGET_64BIT
16604 ? gen_allocate_stack_worker_probe_di
16605 : gen_allocate_stack_worker_probe_si);
16607 emit_insn (insn (x, x));
16610 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16611 stack_pointer_rtx, 0, OPTAB_DIRECT);
16613 if (x != stack_pointer_rtx)
16614 emit_move_insn (stack_pointer_rtx, x);
16616 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16620 ;; Use IOR for stack probes, this is shorter.
16621 (define_expand "probe_stack"
16622 [(match_operand 0 "memory_operand")]
16625 rtx (*gen_ior3) (rtx, rtx, rtx);
16627 gen_ior3 = (GET_MODE (operands[0]) == DImode
16628 ? gen_iordi3 : gen_iorsi3);
16630 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16634 (define_insn "adjust_stack_and_probe<mode>"
16635 [(set (match_operand:P 0 "register_operand" "=r")
16636 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16637 UNSPECV_PROBE_STACK_RANGE))
16638 (set (reg:P SP_REG)
16639 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16640 (clobber (reg:CC FLAGS_REG))
16641 (clobber (mem:BLK (scratch)))]
16643 "* return output_adjust_stack_and_probe (operands[0]);"
16644 [(set_attr "type" "multi")])
16646 (define_insn "probe_stack_range<mode>"
16647 [(set (match_operand:P 0 "register_operand" "=r")
16648 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16649 (match_operand:P 2 "const_int_operand" "n")]
16650 UNSPECV_PROBE_STACK_RANGE))
16651 (clobber (reg:CC FLAGS_REG))]
16653 "* return output_probe_stack_range (operands[0], operands[2]);"
16654 [(set_attr "type" "multi")])
16656 (define_expand "builtin_setjmp_receiver"
16657 [(label_ref (match_operand 0))]
16658 "!TARGET_64BIT && flag_pic"
16664 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16665 rtx label_rtx = gen_label_rtx ();
16666 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16667 xops[0] = xops[1] = picreg;
16668 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16669 ix86_expand_binary_operator (MINUS, SImode, xops);
16673 emit_insn (gen_set_got (pic_offset_table_rtx));
16677 (define_insn_and_split "nonlocal_goto_receiver"
16678 [(unspec_volatile [(const_int 0)] UNSPECV_NLGR)]
16679 "TARGET_MACHO && !TARGET_64BIT && flag_pic"
16681 "&& reload_completed"
16684 if (crtl->uses_pic_offset_table)
16687 rtx label_rtx = gen_label_rtx ();
16690 /* Get a new pic base. */
16691 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16692 /* Correct this with the offset from the new to the old. */
16693 xops[0] = xops[1] = pic_offset_table_rtx;
16694 label_rtx = gen_rtx_LABEL_REF (SImode, label_rtx);
16695 tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, label_rtx),
16696 UNSPEC_MACHOPIC_OFFSET);
16697 xops[2] = gen_rtx_CONST (Pmode, tmp);
16698 ix86_expand_binary_operator (MINUS, SImode, xops);
16701 /* No pic reg restore needed. */
16702 emit_note (NOTE_INSN_DELETED);
16707 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16710 [(set (match_operand 0 "register_operand")
16711 (match_operator 3 "promotable_binary_operator"
16712 [(match_operand 1 "register_operand")
16713 (match_operand 2 "aligned_operand")]))
16714 (clobber (reg:CC FLAGS_REG))]
16715 "! TARGET_PARTIAL_REG_STALL && reload_completed
16716 && ((GET_MODE (operands[0]) == HImode
16717 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16718 /* ??? next two lines just !satisfies_constraint_K (...) */
16719 || !CONST_INT_P (operands[2])
16720 || satisfies_constraint_K (operands[2])))
16721 || (GET_MODE (operands[0]) == QImode
16722 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16723 [(parallel [(set (match_dup 0)
16724 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16725 (clobber (reg:CC FLAGS_REG))])]
16727 operands[0] = gen_lowpart (SImode, operands[0]);
16728 operands[1] = gen_lowpart (SImode, operands[1]);
16729 if (GET_CODE (operands[3]) != ASHIFT)
16730 operands[2] = gen_lowpart (SImode, operands[2]);
16731 PUT_MODE (operands[3], SImode);
16734 ; Promote the QImode tests, as i386 has encoding of the AND
16735 ; instruction with 32-bit sign-extended immediate and thus the
16736 ; instruction size is unchanged, except in the %eax case for
16737 ; which it is increased by one byte, hence the ! optimize_size.
16739 [(set (match_operand 0 "flags_reg_operand")
16740 (match_operator 2 "compare_operator"
16741 [(and (match_operand 3 "aligned_operand")
16742 (match_operand 4 "const_int_operand"))
16744 (set (match_operand 1 "register_operand")
16745 (and (match_dup 3) (match_dup 4)))]
16746 "! TARGET_PARTIAL_REG_STALL && reload_completed
16747 && optimize_insn_for_speed_p ()
16748 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16749 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16750 /* Ensure that the operand will remain sign-extended immediate. */
16751 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16752 [(parallel [(set (match_dup 0)
16753 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16756 (and:SI (match_dup 3) (match_dup 4)))])]
16759 = gen_int_mode (INTVAL (operands[4])
16760 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16761 operands[1] = gen_lowpart (SImode, operands[1]);
16762 operands[3] = gen_lowpart (SImode, operands[3]);
16765 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16766 ; the TEST instruction with 32-bit sign-extended immediate and thus
16767 ; the instruction size would at least double, which is not what we
16768 ; want even with ! optimize_size.
16770 [(set (match_operand 0 "flags_reg_operand")
16771 (match_operator 1 "compare_operator"
16772 [(and (match_operand:HI 2 "aligned_operand")
16773 (match_operand:HI 3 "const_int_operand"))
16775 "! TARGET_PARTIAL_REG_STALL && reload_completed
16776 && ! TARGET_FAST_PREFIX
16777 && optimize_insn_for_speed_p ()
16778 /* Ensure that the operand will remain sign-extended immediate. */
16779 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16780 [(set (match_dup 0)
16781 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16785 = gen_int_mode (INTVAL (operands[3])
16786 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16787 operands[2] = gen_lowpart (SImode, operands[2]);
16791 [(set (match_operand 0 "register_operand")
16792 (neg (match_operand 1 "register_operand")))
16793 (clobber (reg:CC FLAGS_REG))]
16794 "! TARGET_PARTIAL_REG_STALL && reload_completed
16795 && (GET_MODE (operands[0]) == HImode
16796 || (GET_MODE (operands[0]) == QImode
16797 && (TARGET_PROMOTE_QImode
16798 || optimize_insn_for_size_p ())))"
16799 [(parallel [(set (match_dup 0)
16800 (neg:SI (match_dup 1)))
16801 (clobber (reg:CC FLAGS_REG))])]
16803 operands[0] = gen_lowpart (SImode, operands[0]);
16804 operands[1] = gen_lowpart (SImode, operands[1]);
16808 [(set (match_operand 0 "register_operand")
16809 (not (match_operand 1 "register_operand")))]
16810 "! TARGET_PARTIAL_REG_STALL && reload_completed
16811 && (GET_MODE (operands[0]) == HImode
16812 || (GET_MODE (operands[0]) == QImode
16813 && (TARGET_PROMOTE_QImode
16814 || optimize_insn_for_size_p ())))"
16815 [(set (match_dup 0)
16816 (not:SI (match_dup 1)))]
16818 operands[0] = gen_lowpart (SImode, operands[0]);
16819 operands[1] = gen_lowpart (SImode, operands[1]);
16822 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16823 ;; transform a complex memory operation into two memory to register operations.
16825 ;; Don't push memory operands
16827 [(set (match_operand:SWI 0 "push_operand")
16828 (match_operand:SWI 1 "memory_operand"))
16829 (match_scratch:SWI 2 "<r>")]
16830 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16831 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16832 [(set (match_dup 2) (match_dup 1))
16833 (set (match_dup 0) (match_dup 2))])
16835 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16838 [(set (match_operand:SF 0 "push_operand")
16839 (match_operand:SF 1 "memory_operand"))
16840 (match_scratch:SF 2 "r")]
16841 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16842 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16843 [(set (match_dup 2) (match_dup 1))
16844 (set (match_dup 0) (match_dup 2))])
16846 ;; Don't move an immediate directly to memory when the instruction
16847 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
16849 [(match_scratch:SWI124 1 "<r>")
16850 (set (match_operand:SWI124 0 "memory_operand")
16852 "optimize_insn_for_speed_p ()
16853 && ((<MODE>mode == HImode
16854 && TARGET_LCP_STALL)
16855 || (!TARGET_USE_MOV0
16856 && TARGET_SPLIT_LONG_MOVES
16857 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
16858 && peep2_regno_dead_p (0, FLAGS_REG)"
16859 [(parallel [(set (match_dup 2) (const_int 0))
16860 (clobber (reg:CC FLAGS_REG))])
16861 (set (match_dup 0) (match_dup 1))]
16862 "operands[2] = gen_lowpart (SImode, operands[1]);")
16865 [(match_scratch:SWI124 2 "<r>")
16866 (set (match_operand:SWI124 0 "memory_operand")
16867 (match_operand:SWI124 1 "immediate_operand"))]
16868 "optimize_insn_for_speed_p ()
16869 && ((<MODE>mode == HImode
16870 && TARGET_LCP_STALL)
16871 || (TARGET_SPLIT_LONG_MOVES
16872 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
16873 [(set (match_dup 2) (match_dup 1))
16874 (set (match_dup 0) (match_dup 2))])
16876 ;; Don't compare memory with zero, load and use a test instead.
16878 [(set (match_operand 0 "flags_reg_operand")
16879 (match_operator 1 "compare_operator"
16880 [(match_operand:SI 2 "memory_operand")
16882 (match_scratch:SI 3 "r")]
16883 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16884 [(set (match_dup 3) (match_dup 2))
16885 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16887 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16888 ;; Don't split NOTs with a displacement operand, because resulting XOR
16889 ;; will not be pairable anyway.
16891 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16892 ;; represented using a modRM byte. The XOR replacement is long decoded,
16893 ;; so this split helps here as well.
16895 ;; Note: Can't do this as a regular split because we can't get proper
16896 ;; lifetime information then.
16899 [(set (match_operand:SWI124 0 "nonimmediate_operand")
16900 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
16901 "optimize_insn_for_speed_p ()
16902 && ((TARGET_NOT_UNPAIRABLE
16903 && (!MEM_P (operands[0])
16904 || !memory_displacement_operand (operands[0], <MODE>mode)))
16905 || (TARGET_NOT_VECTORMODE
16906 && long_memory_operand (operands[0], <MODE>mode)))
16907 && peep2_regno_dead_p (0, FLAGS_REG)"
16908 [(parallel [(set (match_dup 0)
16909 (xor:SWI124 (match_dup 1) (const_int -1)))
16910 (clobber (reg:CC FLAGS_REG))])])
16912 ;; Non pairable "test imm, reg" instructions can be translated to
16913 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16914 ;; byte opcode instead of two, have a short form for byte operands),
16915 ;; so do it for other CPUs as well. Given that the value was dead,
16916 ;; this should not create any new dependencies. Pass on the sub-word
16917 ;; versions if we're concerned about partial register stalls.
16920 [(set (match_operand 0 "flags_reg_operand")
16921 (match_operator 1 "compare_operator"
16922 [(and:SI (match_operand:SI 2 "register_operand")
16923 (match_operand:SI 3 "immediate_operand"))
16925 "ix86_match_ccmode (insn, CCNOmode)
16926 && (true_regnum (operands[2]) != AX_REG
16927 || satisfies_constraint_K (operands[3]))
16928 && peep2_reg_dead_p (1, operands[2])"
16930 [(set (match_dup 0)
16931 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16934 (and:SI (match_dup 2) (match_dup 3)))])])
16936 ;; We don't need to handle HImode case, because it will be promoted to SImode
16937 ;; on ! TARGET_PARTIAL_REG_STALL
16940 [(set (match_operand 0 "flags_reg_operand")
16941 (match_operator 1 "compare_operator"
16942 [(and:QI (match_operand:QI 2 "register_operand")
16943 (match_operand:QI 3 "immediate_operand"))
16945 "! TARGET_PARTIAL_REG_STALL
16946 && ix86_match_ccmode (insn, CCNOmode)
16947 && true_regnum (operands[2]) != AX_REG
16948 && peep2_reg_dead_p (1, operands[2])"
16950 [(set (match_dup 0)
16951 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16954 (and:QI (match_dup 2) (match_dup 3)))])])
16957 [(set (match_operand 0 "flags_reg_operand")
16958 (match_operator 1 "compare_operator"
16961 (match_operand 2 "ext_register_operand")
16964 (match_operand 3 "const_int_operand"))
16966 "! TARGET_PARTIAL_REG_STALL
16967 && ix86_match_ccmode (insn, CCNOmode)
16968 && true_regnum (operands[2]) != AX_REG
16969 && peep2_reg_dead_p (1, operands[2])"
16970 [(parallel [(set (match_dup 0)
16979 (set (zero_extract:SI (match_dup 2)
16987 (match_dup 3)))])])
16989 ;; Don't do logical operations with memory inputs.
16991 [(match_scratch:SI 2 "r")
16992 (parallel [(set (match_operand:SI 0 "register_operand")
16993 (match_operator:SI 3 "arith_or_logical_operator"
16995 (match_operand:SI 1 "memory_operand")]))
16996 (clobber (reg:CC FLAGS_REG))])]
16997 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
16998 [(set (match_dup 2) (match_dup 1))
16999 (parallel [(set (match_dup 0)
17000 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17001 (clobber (reg:CC FLAGS_REG))])])
17004 [(match_scratch:SI 2 "r")
17005 (parallel [(set (match_operand:SI 0 "register_operand")
17006 (match_operator:SI 3 "arith_or_logical_operator"
17007 [(match_operand:SI 1 "memory_operand")
17009 (clobber (reg:CC FLAGS_REG))])]
17010 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17011 [(set (match_dup 2) (match_dup 1))
17012 (parallel [(set (match_dup 0)
17013 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17014 (clobber (reg:CC FLAGS_REG))])])
17016 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17017 ;; refers to the destination of the load!
17020 [(set (match_operand:SI 0 "register_operand")
17021 (match_operand:SI 1 "register_operand"))
17022 (parallel [(set (match_dup 0)
17023 (match_operator:SI 3 "commutative_operator"
17025 (match_operand:SI 2 "memory_operand")]))
17026 (clobber (reg:CC FLAGS_REG))])]
17027 "REGNO (operands[0]) != REGNO (operands[1])
17028 && GENERAL_REGNO_P (REGNO (operands[0]))
17029 && GENERAL_REGNO_P (REGNO (operands[1]))"
17030 [(set (match_dup 0) (match_dup 4))
17031 (parallel [(set (match_dup 0)
17032 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17033 (clobber (reg:CC FLAGS_REG))])]
17034 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17037 [(set (match_operand 0 "register_operand")
17038 (match_operand 1 "register_operand"))
17040 (match_operator 3 "commutative_operator"
17042 (match_operand 2 "memory_operand")]))]
17043 "REGNO (operands[0]) != REGNO (operands[1])
17044 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17045 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17046 [(set (match_dup 0) (match_dup 2))
17048 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17050 ; Don't do logical operations with memory outputs
17052 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17053 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17054 ; the same decoder scheduling characteristics as the original.
17057 [(match_scratch:SI 2 "r")
17058 (parallel [(set (match_operand:SI 0 "memory_operand")
17059 (match_operator:SI 3 "arith_or_logical_operator"
17061 (match_operand:SI 1 "nonmemory_operand")]))
17062 (clobber (reg:CC FLAGS_REG))])]
17063 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17064 /* Do not split stack checking probes. */
17065 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17066 [(set (match_dup 2) (match_dup 0))
17067 (parallel [(set (match_dup 2)
17068 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17069 (clobber (reg:CC FLAGS_REG))])
17070 (set (match_dup 0) (match_dup 2))])
17073 [(match_scratch:SI 2 "r")
17074 (parallel [(set (match_operand:SI 0 "memory_operand")
17075 (match_operator:SI 3 "arith_or_logical_operator"
17076 [(match_operand:SI 1 "nonmemory_operand")
17078 (clobber (reg:CC FLAGS_REG))])]
17079 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17080 /* Do not split stack checking probes. */
17081 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17082 [(set (match_dup 2) (match_dup 0))
17083 (parallel [(set (match_dup 2)
17084 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17085 (clobber (reg:CC FLAGS_REG))])
17086 (set (match_dup 0) (match_dup 2))])
17088 ;; Attempt to use arith or logical operations with memory outputs with
17089 ;; setting of flags.
17091 [(set (match_operand:SWI 0 "register_operand")
17092 (match_operand:SWI 1 "memory_operand"))
17093 (parallel [(set (match_dup 0)
17094 (match_operator:SWI 3 "plusminuslogic_operator"
17096 (match_operand:SWI 2 "<nonmemory_operand>")]))
17097 (clobber (reg:CC FLAGS_REG))])
17098 (set (match_dup 1) (match_dup 0))
17099 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17100 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17101 && peep2_reg_dead_p (4, operands[0])
17102 && !reg_overlap_mentioned_p (operands[0], operands[1])
17103 && !reg_overlap_mentioned_p (operands[0], operands[2])
17104 && (<MODE>mode != QImode
17105 || immediate_operand (operands[2], QImode)
17106 || q_regs_operand (operands[2], QImode))
17107 && ix86_match_ccmode (peep2_next_insn (3),
17108 (GET_CODE (operands[3]) == PLUS
17109 || GET_CODE (operands[3]) == MINUS)
17110 ? CCGOCmode : CCNOmode)"
17111 [(parallel [(set (match_dup 4) (match_dup 5))
17112 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17113 (match_dup 2)]))])]
17115 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17116 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17117 copy_rtx (operands[1]),
17118 copy_rtx (operands[2]));
17119 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17120 operands[5], const0_rtx);
17124 [(parallel [(set (match_operand:SWI 0 "register_operand")
17125 (match_operator:SWI 2 "plusminuslogic_operator"
17127 (match_operand:SWI 1 "memory_operand")]))
17128 (clobber (reg:CC FLAGS_REG))])
17129 (set (match_dup 1) (match_dup 0))
17130 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17131 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17132 && GET_CODE (operands[2]) != MINUS
17133 && peep2_reg_dead_p (3, operands[0])
17134 && !reg_overlap_mentioned_p (operands[0], operands[1])
17135 && ix86_match_ccmode (peep2_next_insn (2),
17136 GET_CODE (operands[2]) == PLUS
17137 ? CCGOCmode : CCNOmode)"
17138 [(parallel [(set (match_dup 3) (match_dup 4))
17139 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17140 (match_dup 0)]))])]
17142 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17143 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17144 copy_rtx (operands[1]),
17145 copy_rtx (operands[0]));
17146 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17147 operands[4], const0_rtx);
17151 [(set (match_operand:SWI12 0 "register_operand")
17152 (match_operand:SWI12 1 "memory_operand"))
17153 (parallel [(set (match_operand:SI 4 "register_operand")
17154 (match_operator:SI 3 "plusminuslogic_operator"
17156 (match_operand:SI 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 && REG_P (operands[0]) && REG_P (operands[4])
17162 && REGNO (operands[0]) == REGNO (operands[4])
17163 && peep2_reg_dead_p (4, operands[0])
17164 && (<MODE>mode != QImode
17165 || immediate_operand (operands[2], SImode)
17166 || q_regs_operand (operands[2], SImode))
17167 && !reg_overlap_mentioned_p (operands[0], operands[1])
17168 && !reg_overlap_mentioned_p (operands[0], operands[2])
17169 && ix86_match_ccmode (peep2_next_insn (3),
17170 (GET_CODE (operands[3]) == PLUS
17171 || GET_CODE (operands[3]) == MINUS)
17172 ? CCGOCmode : CCNOmode)"
17173 [(parallel [(set (match_dup 4) (match_dup 5))
17174 (set (match_dup 1) (match_dup 6))])]
17176 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17177 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17178 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17179 copy_rtx (operands[1]), operands[2]);
17180 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17181 operands[5], const0_rtx);
17182 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17183 copy_rtx (operands[1]),
17184 copy_rtx (operands[2]));
17187 ;; Attempt to always use XOR for zeroing registers.
17189 [(set (match_operand 0 "register_operand")
17190 (match_operand 1 "const0_operand"))]
17191 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17192 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17193 && GENERAL_REG_P (operands[0])
17194 && peep2_regno_dead_p (0, FLAGS_REG)"
17195 [(parallel [(set (match_dup 0) (const_int 0))
17196 (clobber (reg:CC FLAGS_REG))])]
17197 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17200 [(set (strict_low_part (match_operand 0 "register_operand"))
17202 "(GET_MODE (operands[0]) == QImode
17203 || GET_MODE (operands[0]) == HImode)
17204 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17205 && peep2_regno_dead_p (0, FLAGS_REG)"
17206 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17207 (clobber (reg:CC FLAGS_REG))])])
17209 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17211 [(set (match_operand:SWI248 0 "register_operand")
17213 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17214 && peep2_regno_dead_p (0, FLAGS_REG)"
17215 [(parallel [(set (match_dup 0) (const_int -1))
17216 (clobber (reg:CC FLAGS_REG))])]
17218 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17219 operands[0] = gen_lowpart (SImode, operands[0]);
17222 ;; Attempt to convert simple lea to add/shift.
17223 ;; These can be created by move expanders.
17224 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
17225 ;; relevant lea instructions were already split.
17228 [(set (match_operand:SWI48 0 "register_operand")
17229 (plus:SWI48 (match_dup 0)
17230 (match_operand:SWI48 1 "<nonmemory_operand>")))]
17232 && peep2_regno_dead_p (0, FLAGS_REG)"
17233 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17234 (clobber (reg:CC FLAGS_REG))])])
17237 [(set (match_operand:SWI48 0 "register_operand")
17238 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
17241 && peep2_regno_dead_p (0, FLAGS_REG)"
17242 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17243 (clobber (reg:CC FLAGS_REG))])])
17246 [(set (match_operand:DI 0 "register_operand")
17248 (plus:SI (match_operand:SI 1 "register_operand")
17249 (match_operand:SI 2 "nonmemory_operand"))))]
17250 "TARGET_64BIT && !TARGET_OPT_AGU
17251 && REGNO (operands[0]) == REGNO (operands[1])
17252 && peep2_regno_dead_p (0, FLAGS_REG)"
17253 [(parallel [(set (match_dup 0)
17254 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
17255 (clobber (reg:CC FLAGS_REG))])])
17258 [(set (match_operand:DI 0 "register_operand")
17260 (plus:SI (match_operand:SI 1 "nonmemory_operand")
17261 (match_operand:SI 2 "register_operand"))))]
17262 "TARGET_64BIT && !TARGET_OPT_AGU
17263 && REGNO (operands[0]) == REGNO (operands[2])
17264 && peep2_regno_dead_p (0, FLAGS_REG)"
17265 [(parallel [(set (match_dup 0)
17266 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
17267 (clobber (reg:CC FLAGS_REG))])])
17270 [(set (match_operand:SWI48 0 "register_operand")
17271 (mult:SWI48 (match_dup 0)
17272 (match_operand:SWI48 1 "const_int_operand")))]
17273 "exact_log2 (INTVAL (operands[1])) >= 0
17274 && peep2_regno_dead_p (0, FLAGS_REG)"
17275 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
17276 (clobber (reg:CC FLAGS_REG))])]
17277 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17280 [(set (match_operand:DI 0 "register_operand")
17282 (mult:SI (match_operand:SI 1 "register_operand")
17283 (match_operand:SI 2 "const_int_operand"))))]
17285 && exact_log2 (INTVAL (operands[2])) >= 0
17286 && REGNO (operands[0]) == REGNO (operands[1])
17287 && peep2_regno_dead_p (0, FLAGS_REG)"
17288 [(parallel [(set (match_dup 0)
17289 (zero_extend (ashift:SI (match_dup 1) (match_dup 2))))
17290 (clobber (reg:CC FLAGS_REG))])]
17291 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17293 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17294 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17295 ;; On many CPUs it is also faster, since special hardware to avoid esp
17296 ;; dependencies is present.
17298 ;; While some of these conversions may be done using splitters, we use
17299 ;; peepholes in order to allow combine_stack_adjustments pass to see
17300 ;; nonobfuscated RTL.
17302 ;; Convert prologue esp subtractions to push.
17303 ;; We need register to push. In order to keep verify_flow_info happy we have
17305 ;; - use scratch and clobber it in order to avoid dependencies
17306 ;; - use already live register
17307 ;; We can't use the second way right now, since there is no reliable way how to
17308 ;; verify that given register is live. First choice will also most likely in
17309 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17310 ;; call clobbered registers are dead. We may want to use base pointer as an
17311 ;; alternative when no register is available later.
17314 [(match_scratch:W 1 "r")
17315 (parallel [(set (reg:P SP_REG)
17316 (plus:P (reg:P SP_REG)
17317 (match_operand:P 0 "const_int_operand")))
17318 (clobber (reg:CC FLAGS_REG))
17319 (clobber (mem:BLK (scratch)))])]
17320 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17321 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17322 [(clobber (match_dup 1))
17323 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17324 (clobber (mem:BLK (scratch)))])])
17327 [(match_scratch:W 1 "r")
17328 (parallel [(set (reg:P SP_REG)
17329 (plus:P (reg:P SP_REG)
17330 (match_operand:P 0 "const_int_operand")))
17331 (clobber (reg:CC FLAGS_REG))
17332 (clobber (mem:BLK (scratch)))])]
17333 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17334 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17335 [(clobber (match_dup 1))
17336 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17337 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17338 (clobber (mem:BLK (scratch)))])])
17340 ;; Convert esp subtractions to push.
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 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17348 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17349 [(clobber (match_dup 1))
17350 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17353 [(match_scratch:W 1 "r")
17354 (parallel [(set (reg:P SP_REG)
17355 (plus:P (reg:P SP_REG)
17356 (match_operand:P 0 "const_int_operand")))
17357 (clobber (reg:CC FLAGS_REG))])]
17358 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17359 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17360 [(clobber (match_dup 1))
17361 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17362 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17364 ;; Convert epilogue deallocator to pop.
17366 [(match_scratch:W 1 "r")
17367 (parallel [(set (reg:P SP_REG)
17368 (plus:P (reg:P SP_REG)
17369 (match_operand:P 0 "const_int_operand")))
17370 (clobber (reg:CC FLAGS_REG))
17371 (clobber (mem:BLK (scratch)))])]
17372 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17373 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17374 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17375 (clobber (mem:BLK (scratch)))])])
17377 ;; Two pops case is tricky, since pop causes dependency
17378 ;; on destination register. We use two registers if available.
17380 [(match_scratch:W 1 "r")
17381 (match_scratch:W 2 "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 (clobber (mem:BLK (scratch)))])]
17387 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17388 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17389 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17390 (clobber (mem:BLK (scratch)))])
17391 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
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 "optimize_insn_for_size_p ()
17401 && INTVAL (operands[0]) == 2*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)))])
17404 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17406 ;; Convert esp additions to pop.
17408 [(match_scratch:W 1 "r")
17409 (parallel [(set (reg:P SP_REG)
17410 (plus:P (reg:P SP_REG)
17411 (match_operand:P 0 "const_int_operand")))
17412 (clobber (reg:CC FLAGS_REG))])]
17413 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17414 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17416 ;; Two pops case is tricky, since pop causes dependency
17417 ;; on destination register. We use two registers if available.
17419 [(match_scratch:W 1 "r")
17420 (match_scratch:W 2 "r")
17421 (parallel [(set (reg:P SP_REG)
17422 (plus:P (reg:P SP_REG)
17423 (match_operand:P 0 "const_int_operand")))
17424 (clobber (reg:CC FLAGS_REG))])]
17425 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17426 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17427 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17430 [(match_scratch:W 1 "r")
17431 (parallel [(set (reg:P SP_REG)
17432 (plus:P (reg:P SP_REG)
17433 (match_operand:P 0 "const_int_operand")))
17434 (clobber (reg:CC FLAGS_REG))])]
17435 "optimize_insn_for_size_p ()
17436 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17437 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17438 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17440 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17441 ;; required and register dies. Similarly for 128 to -128.
17443 [(set (match_operand 0 "flags_reg_operand")
17444 (match_operator 1 "compare_operator"
17445 [(match_operand 2 "register_operand")
17446 (match_operand 3 "const_int_operand")]))]
17447 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17448 && incdec_operand (operands[3], GET_MODE (operands[3])))
17449 || (!TARGET_FUSE_CMP_AND_BRANCH
17450 && INTVAL (operands[3]) == 128))
17451 && ix86_match_ccmode (insn, CCGCmode)
17452 && peep2_reg_dead_p (1, operands[2])"
17453 [(parallel [(set (match_dup 0)
17454 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17455 (clobber (match_dup 2))])])
17457 ;; Convert imul by three, five and nine into lea
17460 [(set (match_operand:SWI48 0 "register_operand")
17461 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
17462 (match_operand:SWI48 2 "const359_operand")))
17463 (clobber (reg:CC FLAGS_REG))])]
17464 "!TARGET_PARTIAL_REG_STALL
17465 || <MODE>mode == SImode
17466 || optimize_function_for_size_p (cfun)"
17467 [(set (match_dup 0)
17468 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17470 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17474 [(set (match_operand:SWI48 0 "register_operand")
17475 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17476 (match_operand:SWI48 2 "const359_operand")))
17477 (clobber (reg:CC FLAGS_REG))])]
17478 "optimize_insn_for_speed_p ()
17479 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17480 [(set (match_dup 0) (match_dup 1))
17482 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17484 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17486 ;; imul $32bit_imm, mem, reg is vector decoded, while
17487 ;; imul $32bit_imm, reg, reg is direct decoded.
17489 [(match_scratch:SWI48 3 "r")
17490 (parallel [(set (match_operand:SWI48 0 "register_operand")
17491 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
17492 (match_operand:SWI48 2 "immediate_operand")))
17493 (clobber (reg:CC FLAGS_REG))])]
17494 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17495 && !satisfies_constraint_K (operands[2])"
17496 [(set (match_dup 3) (match_dup 1))
17497 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17498 (clobber (reg:CC FLAGS_REG))])])
17501 [(match_scratch:SI 3 "r")
17502 (parallel [(set (match_operand:DI 0 "register_operand")
17504 (mult:SI (match_operand:SI 1 "memory_operand")
17505 (match_operand:SI 2 "immediate_operand"))))
17506 (clobber (reg:CC FLAGS_REG))])]
17508 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17509 && !satisfies_constraint_K (operands[2])"
17510 [(set (match_dup 3) (match_dup 1))
17511 (parallel [(set (match_dup 0)
17512 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17513 (clobber (reg:CC FLAGS_REG))])])
17515 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17516 ;; Convert it into imul reg, reg
17517 ;; It would be better to force assembler to encode instruction using long
17518 ;; immediate, but there is apparently no way to do so.
17520 [(parallel [(set (match_operand:SWI248 0 "register_operand")
17522 (match_operand:SWI248 1 "nonimmediate_operand")
17523 (match_operand:SWI248 2 "const_int_operand")))
17524 (clobber (reg:CC FLAGS_REG))])
17525 (match_scratch:SWI248 3 "r")]
17526 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17527 && satisfies_constraint_K (operands[2])"
17528 [(set (match_dup 3) (match_dup 2))
17529 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17530 (clobber (reg:CC FLAGS_REG))])]
17532 if (!rtx_equal_p (operands[0], operands[1]))
17533 emit_move_insn (operands[0], operands[1]);
17536 ;; After splitting up read-modify operations, array accesses with memory
17537 ;; operands might end up in form:
17539 ;; movl 4(%esp), %edx
17541 ;; instead of pre-splitting:
17543 ;; addl 4(%esp), %eax
17545 ;; movl 4(%esp), %edx
17546 ;; leal (%edx,%eax,4), %eax
17549 [(match_scratch:W 5 "r")
17550 (parallel [(set (match_operand 0 "register_operand")
17551 (ashift (match_operand 1 "register_operand")
17552 (match_operand 2 "const_int_operand")))
17553 (clobber (reg:CC FLAGS_REG))])
17554 (parallel [(set (match_operand 3 "register_operand")
17555 (plus (match_dup 0)
17556 (match_operand 4 "x86_64_general_operand")))
17557 (clobber (reg:CC FLAGS_REG))])]
17558 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17559 /* Validate MODE for lea. */
17560 && ((!TARGET_PARTIAL_REG_STALL
17561 && (GET_MODE (operands[0]) == QImode
17562 || GET_MODE (operands[0]) == HImode))
17563 || GET_MODE (operands[0]) == SImode
17564 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17565 && (rtx_equal_p (operands[0], operands[3])
17566 || peep2_reg_dead_p (2, operands[0]))
17567 /* We reorder load and the shift. */
17568 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17569 [(set (match_dup 5) (match_dup 4))
17570 (set (match_dup 0) (match_dup 1))]
17572 enum machine_mode op1mode = GET_MODE (operands[1]);
17573 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17574 int scale = 1 << INTVAL (operands[2]);
17575 rtx index = gen_lowpart (word_mode, operands[1]);
17576 rtx base = gen_lowpart (word_mode, operands[5]);
17577 rtx dest = gen_lowpart (mode, operands[3]);
17579 operands[1] = gen_rtx_PLUS (word_mode, base,
17580 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
17581 operands[5] = base;
17582 if (mode != word_mode)
17583 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17584 if (op1mode != word_mode)
17585 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17586 operands[0] = dest;
17589 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17590 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17591 ;; caught for use by garbage collectors and the like. Using an insn that
17592 ;; maps to SIGILL makes it more likely the program will rightfully die.
17593 ;; Keeping with tradition, "6" is in honor of #UD.
17594 (define_insn "trap"
17595 [(trap_if (const_int 1) (const_int 6))]
17597 { return ASM_SHORT "0x0b0f"; }
17598 [(set_attr "length" "2")])
17600 (define_expand "prefetch"
17601 [(prefetch (match_operand 0 "address_operand")
17602 (match_operand:SI 1 "const_int_operand")
17603 (match_operand:SI 2 "const_int_operand"))]
17604 "TARGET_PREFETCH_SSE || TARGET_PRFCHW"
17606 bool write = INTVAL (operands[1]) != 0;
17607 int locality = INTVAL (operands[2]);
17609 gcc_assert (IN_RANGE (locality, 0, 3));
17611 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17612 supported by SSE counterpart or the SSE prefetch is not available
17613 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17615 if (TARGET_PRFCHW && (write || !TARGET_PREFETCH_SSE))
17616 operands[2] = GEN_INT (3);
17618 operands[1] = const0_rtx;
17621 (define_insn "*prefetch_sse"
17622 [(prefetch (match_operand 0 "address_operand" "p")
17624 (match_operand:SI 1 "const_int_operand"))]
17625 "TARGET_PREFETCH_SSE"
17627 static const char * const patterns[4] = {
17628 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17631 int locality = INTVAL (operands[1]);
17632 gcc_assert (IN_RANGE (locality, 0, 3));
17634 return patterns[locality];
17636 [(set_attr "type" "sse")
17637 (set_attr "atom_sse_attr" "prefetch")
17638 (set (attr "length_address")
17639 (symbol_ref "memory_address_length (operands[0], false)"))
17640 (set_attr "memory" "none")])
17642 (define_insn "*prefetch_3dnow"
17643 [(prefetch (match_operand 0 "address_operand" "p")
17644 (match_operand:SI 1 "const_int_operand" "n")
17648 if (INTVAL (operands[1]) == 0)
17649 return "prefetch\t%a0";
17651 return "prefetchw\t%a0";
17653 [(set_attr "type" "mmx")
17654 (set (attr "length_address")
17655 (symbol_ref "memory_address_length (operands[0], false)"))
17656 (set_attr "memory" "none")])
17658 (define_expand "stack_protect_set"
17659 [(match_operand 0 "memory_operand")
17660 (match_operand 1 "memory_operand")]
17661 "!TARGET_HAS_BIONIC"
17663 rtx (*insn)(rtx, rtx);
17665 #ifdef TARGET_THREAD_SSP_OFFSET
17666 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17667 insn = (TARGET_LP64
17668 ? gen_stack_tls_protect_set_di
17669 : gen_stack_tls_protect_set_si);
17671 insn = (TARGET_LP64
17672 ? gen_stack_protect_set_di
17673 : gen_stack_protect_set_si);
17676 emit_insn (insn (operands[0], operands[1]));
17680 (define_insn "stack_protect_set_<mode>"
17681 [(set (match_operand:PTR 0 "memory_operand" "=m")
17682 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17684 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17685 (clobber (reg:CC FLAGS_REG))]
17686 "!TARGET_HAS_BIONIC"
17687 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17688 [(set_attr "type" "multi")])
17690 (define_insn "stack_tls_protect_set_<mode>"
17691 [(set (match_operand:PTR 0 "memory_operand" "=m")
17692 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17693 UNSPEC_SP_TLS_SET))
17694 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17695 (clobber (reg:CC FLAGS_REG))]
17697 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17698 [(set_attr "type" "multi")])
17700 (define_expand "stack_protect_test"
17701 [(match_operand 0 "memory_operand")
17702 (match_operand 1 "memory_operand")
17704 "!TARGET_HAS_BIONIC"
17706 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17708 rtx (*insn)(rtx, rtx, rtx);
17710 #ifdef TARGET_THREAD_SSP_OFFSET
17711 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17712 insn = (TARGET_LP64
17713 ? gen_stack_tls_protect_test_di
17714 : gen_stack_tls_protect_test_si);
17716 insn = (TARGET_LP64
17717 ? gen_stack_protect_test_di
17718 : gen_stack_protect_test_si);
17721 emit_insn (insn (flags, operands[0], operands[1]));
17723 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17724 flags, const0_rtx, operands[2]));
17728 (define_insn "stack_protect_test_<mode>"
17729 [(set (match_operand:CCZ 0 "flags_reg_operand")
17730 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17731 (match_operand:PTR 2 "memory_operand" "m")]
17733 (clobber (match_scratch:PTR 3 "=&r"))]
17734 "!TARGET_HAS_BIONIC"
17735 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17736 [(set_attr "type" "multi")])
17738 (define_insn "stack_tls_protect_test_<mode>"
17739 [(set (match_operand:CCZ 0 "flags_reg_operand")
17740 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17741 (match_operand:PTR 2 "const_int_operand" "i")]
17742 UNSPEC_SP_TLS_TEST))
17743 (clobber (match_scratch:PTR 3 "=r"))]
17745 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17746 [(set_attr "type" "multi")])
17748 (define_insn "sse4_2_crc32<mode>"
17749 [(set (match_operand:SI 0 "register_operand" "=r")
17751 [(match_operand:SI 1 "register_operand" "0")
17752 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17754 "TARGET_SSE4_2 || TARGET_CRC32"
17755 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17756 [(set_attr "type" "sselog1")
17757 (set_attr "prefix_rep" "1")
17758 (set_attr "prefix_extra" "1")
17759 (set (attr "prefix_data16")
17760 (if_then_else (match_operand:HI 2)
17762 (const_string "*")))
17763 (set (attr "prefix_rex")
17764 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
17766 (const_string "*")))
17767 (set_attr "mode" "SI")])
17769 (define_insn "sse4_2_crc32di"
17770 [(set (match_operand:DI 0 "register_operand" "=r")
17772 [(match_operand:DI 1 "register_operand" "0")
17773 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17775 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17776 "crc32{q}\t{%2, %0|%0, %2}"
17777 [(set_attr "type" "sselog1")
17778 (set_attr "prefix_rep" "1")
17779 (set_attr "prefix_extra" "1")
17780 (set_attr "mode" "DI")])
17782 (define_insn "rdpmc"
17783 [(set (match_operand:DI 0 "register_operand" "=A")
17784 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17788 [(set_attr "type" "other")
17789 (set_attr "length" "2")])
17791 (define_insn "rdpmc_rex64"
17792 [(set (match_operand:DI 0 "register_operand" "=a")
17793 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17795 (set (match_operand:DI 1 "register_operand" "=d")
17796 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
17799 [(set_attr "type" "other")
17800 (set_attr "length" "2")])
17802 (define_insn "rdtsc"
17803 [(set (match_operand:DI 0 "register_operand" "=A")
17804 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17807 [(set_attr "type" "other")
17808 (set_attr "length" "2")])
17810 (define_insn "rdtsc_rex64"
17811 [(set (match_operand:DI 0 "register_operand" "=a")
17812 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17813 (set (match_operand:DI 1 "register_operand" "=d")
17814 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17817 [(set_attr "type" "other")
17818 (set_attr "length" "2")])
17820 (define_insn "rdtscp"
17821 [(set (match_operand:DI 0 "register_operand" "=A")
17822 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17823 (set (match_operand:SI 1 "register_operand" "=c")
17824 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17827 [(set_attr "type" "other")
17828 (set_attr "length" "3")])
17830 (define_insn "rdtscp_rex64"
17831 [(set (match_operand:DI 0 "register_operand" "=a")
17832 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17833 (set (match_operand:DI 1 "register_operand" "=d")
17834 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17835 (set (match_operand:SI 2 "register_operand" "=c")
17836 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17839 [(set_attr "type" "other")
17840 (set_attr "length" "3")])
17842 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17844 ;; FXSR, XSAVE and XSAVEOPT instructions
17846 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17848 (define_insn "fxsave"
17849 [(set (match_operand:BLK 0 "memory_operand" "=m")
17850 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
17853 [(set_attr "type" "other")
17854 (set_attr "memory" "store")
17855 (set (attr "length")
17856 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17858 (define_insn "fxsave64"
17859 [(set (match_operand:BLK 0 "memory_operand" "=m")
17860 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
17861 "TARGET_64BIT && TARGET_FXSR"
17863 [(set_attr "type" "other")
17864 (set_attr "memory" "store")
17865 (set (attr "length")
17866 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17868 (define_insn "fxrstor"
17869 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
17873 [(set_attr "type" "other")
17874 (set_attr "memory" "load")
17875 (set (attr "length")
17876 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17878 (define_insn "fxrstor64"
17879 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
17880 UNSPECV_FXRSTOR64)]
17881 "TARGET_64BIT && TARGET_FXSR"
17883 [(set_attr "type" "other")
17884 (set_attr "memory" "load")
17885 (set (attr "length")
17886 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17888 (define_int_iterator ANY_XSAVE
17890 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")])
17892 (define_int_iterator ANY_XSAVE64
17894 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")])
17896 (define_int_attr xsave
17897 [(UNSPECV_XSAVE "xsave")
17898 (UNSPECV_XSAVE64 "xsave64")
17899 (UNSPECV_XSAVEOPT "xsaveopt")
17900 (UNSPECV_XSAVEOPT64 "xsaveopt64")])
17902 (define_insn "<xsave>"
17903 [(set (match_operand:BLK 0 "memory_operand" "=m")
17904 (unspec_volatile:BLK
17905 [(match_operand:DI 1 "register_operand" "A")]
17907 "!TARGET_64BIT && TARGET_XSAVE"
17909 [(set_attr "type" "other")
17910 (set_attr "memory" "store")
17911 (set (attr "length")
17912 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17914 (define_insn "<xsave>_rex64"
17915 [(set (match_operand:BLK 0 "memory_operand" "=m")
17916 (unspec_volatile:BLK
17917 [(match_operand:SI 1 "register_operand" "a")
17918 (match_operand:SI 2 "register_operand" "d")]
17920 "TARGET_64BIT && TARGET_XSAVE"
17922 [(set_attr "type" "other")
17923 (set_attr "memory" "store")
17924 (set (attr "length")
17925 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17927 (define_insn "<xsave>"
17928 [(set (match_operand:BLK 0 "memory_operand" "=m")
17929 (unspec_volatile:BLK
17930 [(match_operand:SI 1 "register_operand" "a")
17931 (match_operand:SI 2 "register_operand" "d")]
17933 "TARGET_64BIT && TARGET_XSAVE"
17935 [(set_attr "type" "other")
17936 (set_attr "memory" "store")
17937 (set (attr "length")
17938 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17940 (define_insn "xrstor"
17941 [(unspec_volatile:BLK
17942 [(match_operand:BLK 0 "memory_operand" "m")
17943 (match_operand:DI 1 "register_operand" "A")]
17945 "!TARGET_64BIT && TARGET_XSAVE"
17947 [(set_attr "type" "other")
17948 (set_attr "memory" "load")
17949 (set (attr "length")
17950 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17952 (define_insn "xrstor_rex64"
17953 [(unspec_volatile:BLK
17954 [(match_operand:BLK 0 "memory_operand" "m")
17955 (match_operand:SI 1 "register_operand" "a")
17956 (match_operand:SI 2 "register_operand" "d")]
17958 "TARGET_64BIT && TARGET_XSAVE"
17960 [(set_attr "type" "other")
17961 (set_attr "memory" "load")
17962 (set (attr "length")
17963 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17965 (define_insn "xrstor64"
17966 [(unspec_volatile:BLK
17967 [(match_operand:BLK 0 "memory_operand" "m")
17968 (match_operand:SI 1 "register_operand" "a")
17969 (match_operand:SI 2 "register_operand" "d")]
17971 "TARGET_64BIT && TARGET_XSAVE"
17973 [(set_attr "type" "other")
17974 (set_attr "memory" "load")
17975 (set (attr "length")
17976 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17978 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17980 ;; LWP instructions
17982 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17984 (define_expand "lwp_llwpcb"
17985 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17986 UNSPECV_LLWP_INTRINSIC)]
17989 (define_insn "*lwp_llwpcb<mode>1"
17990 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17991 UNSPECV_LLWP_INTRINSIC)]
17994 [(set_attr "type" "lwp")
17995 (set_attr "mode" "<MODE>")
17996 (set_attr "length" "5")])
17998 (define_expand "lwp_slwpcb"
17999 [(set (match_operand 0 "register_operand" "=r")
18000 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18005 insn = (Pmode == DImode
18007 : gen_lwp_slwpcbsi);
18009 emit_insn (insn (operands[0]));
18013 (define_insn "lwp_slwpcb<mode>"
18014 [(set (match_operand:P 0 "register_operand" "=r")
18015 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18018 [(set_attr "type" "lwp")
18019 (set_attr "mode" "<MODE>")
18020 (set_attr "length" "5")])
18022 (define_expand "lwp_lwpval<mode>3"
18023 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18024 (match_operand:SI 2 "nonimmediate_operand" "rm")
18025 (match_operand:SI 3 "const_int_operand" "i")]
18026 UNSPECV_LWPVAL_INTRINSIC)]
18028 ;; Avoid unused variable warning.
18029 "(void) operands[0];")
18031 (define_insn "*lwp_lwpval<mode>3_1"
18032 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18033 (match_operand:SI 1 "nonimmediate_operand" "rm")
18034 (match_operand:SI 2 "const_int_operand" "i")]
18035 UNSPECV_LWPVAL_INTRINSIC)]
18037 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18038 [(set_attr "type" "lwp")
18039 (set_attr "mode" "<MODE>")
18040 (set (attr "length")
18041 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18043 (define_expand "lwp_lwpins<mode>3"
18044 [(set (reg:CCC FLAGS_REG)
18045 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18046 (match_operand:SI 2 "nonimmediate_operand" "rm")
18047 (match_operand:SI 3 "const_int_operand" "i")]
18048 UNSPECV_LWPINS_INTRINSIC))
18049 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18050 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18053 (define_insn "*lwp_lwpins<mode>3_1"
18054 [(set (reg:CCC FLAGS_REG)
18055 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18056 (match_operand:SI 1 "nonimmediate_operand" "rm")
18057 (match_operand:SI 2 "const_int_operand" "i")]
18058 UNSPECV_LWPINS_INTRINSIC))]
18060 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18061 [(set_attr "type" "lwp")
18062 (set_attr "mode" "<MODE>")
18063 (set (attr "length")
18064 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18066 (define_int_iterator RDFSGSBASE
18070 (define_int_iterator WRFSGSBASE
18074 (define_int_attr fsgs
18075 [(UNSPECV_RDFSBASE "fs")
18076 (UNSPECV_RDGSBASE "gs")
18077 (UNSPECV_WRFSBASE "fs")
18078 (UNSPECV_WRGSBASE "gs")])
18080 (define_insn "rd<fsgs>base<mode>"
18081 [(set (match_operand:SWI48 0 "register_operand" "=r")
18082 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
18083 "TARGET_64BIT && TARGET_FSGSBASE"
18085 [(set_attr "type" "other")
18086 (set_attr "prefix_extra" "2")])
18088 (define_insn "wr<fsgs>base<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_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18099 (set (reg:CCC FLAGS_REG)
18100 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18103 [(set_attr "type" "other")
18104 (set_attr "prefix_extra" "1")])
18106 (define_insn "rdseed<mode>_1"
18107 [(set (match_operand:SWI248 0 "register_operand" "=r")
18108 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
18109 (set (reg:CCC FLAGS_REG)
18110 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
18113 [(set_attr "type" "other")
18114 (set_attr "prefix_extra" "1")])
18116 (define_expand "pause"
18117 [(set (match_dup 0)
18118 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18121 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18122 MEM_VOLATILE_P (operands[0]) = 1;
18125 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18126 ;; They have the same encoding.
18127 (define_insn "*pause"
18128 [(set (match_operand:BLK 0)
18129 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18132 [(set_attr "length" "2")
18133 (set_attr "memory" "unknown")])
18135 (define_expand "xbegin"
18136 [(set (match_operand:SI 0 "register_operand")
18137 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
18140 rtx label = gen_label_rtx ();
18142 /* xbegin is emitted as jump_insn, so reload won't be able
18143 to reload its operand. Force the value into AX hard register. */
18144 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
18145 emit_move_insn (ax_reg, constm1_rtx);
18147 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
18149 emit_label (label);
18150 LABEL_NUSES (label) = 1;
18152 emit_move_insn (operands[0], ax_reg);
18157 (define_insn "xbegin_1"
18159 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18161 (label_ref (match_operand 1))
18163 (set (match_operand:SI 0 "register_operand" "+a")
18164 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
18167 [(set_attr "type" "other")
18168 (set_attr "length" "6")])
18170 (define_insn "xend"
18171 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18174 [(set_attr "type" "other")
18175 (set_attr "length" "3")])
18177 (define_insn "xabort"
18178 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18182 [(set_attr "type" "other")
18183 (set_attr "length" "3")])
18185 (define_expand "xtest"
18186 [(set (match_operand:QI 0 "register_operand")
18187 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18190 emit_insn (gen_xtest_1 ());
18192 ix86_expand_setcc (operands[0], NE,
18193 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18197 (define_insn "xtest_1"
18198 [(set (reg:CCZ FLAGS_REG)
18199 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18202 [(set_attr "type" "other")
18203 (set_attr "length" "3")])
18207 (include "sync.md")