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,slm,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,
337 imul,imulx,idiv,icmp,test,ibr,setcc,icmov,
338 push,pop,call,callv,leave,
340 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
341 fxch,fistp,fisttp,frndint,
342 sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
343 ssemul,sseimul,ssediv,sselog,sselog1,
344 sseishft,sseishft1,ssecmp,ssecomi,
345 ssecvt,ssecvt1,sseicvt,sseins,
346 sseshuf,sseshuf1,ssemuladd,sse4arg,
348 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
349 (const_string "other"))
351 ;; Main data type used by the insn
353 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
354 (const_string "unknown"))
356 ;; The CPU unit operations uses.
357 (define_attr "unit" "integer,i387,sse,mmx,unknown"
358 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,
359 fxch,fistp,fisttp,frndint")
360 (const_string "i387")
361 (eq_attr "type" "sse,ssemov,sseadd,sseadd1,sseiadd,sseiadd1,
362 ssemul,sseimul,ssediv,sselog,sselog1,
363 sseishft,sseishft1,ssecmp,ssecomi,
364 ssecvt,ssecvt1,sseicvt,sseins,
365 sseshuf,sseshuf1,ssemuladd,sse4arg")
367 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
369 (eq_attr "type" "other")
370 (const_string "unknown")]
371 (const_string "integer")))
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,
621 sselog1,sseshuf1,sseadd1,sseiadd1,sseishft1,
622 mmx,mmxmov,mmxcmp,mmxcvt")
623 (match_operand 2 "memory_operand"))
624 (const_string "load")
625 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
626 (match_operand 3 "memory_operand"))
627 (const_string "load")
629 (const_string "none")))
631 ;; Indicates if an instruction has both an immediate and a displacement.
633 (define_attr "imm_disp" "false,true,unknown"
634 (cond [(eq_attr "type" "other,multi")
635 (const_string "unknown")
636 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
637 (and (match_operand 0 "memory_displacement_operand")
638 (match_operand 1 "immediate_operand")))
639 (const_string "true")
640 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
641 (and (match_operand 0 "memory_displacement_operand")
642 (match_operand 2 "immediate_operand")))
643 (const_string "true")
645 (const_string "false")))
647 ;; Indicates if an FP operation has an integer source.
649 (define_attr "fp_int_src" "false,true"
650 (const_string "false"))
652 ;; Defines rounding mode of an FP operation.
654 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
655 (const_string "any"))
657 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
658 (define_attr "use_carry" "0,1" (const_string "0"))
660 ;; Define attribute to indicate unaligned ssemov insns
661 (define_attr "movu" "0,1" (const_string "0"))
663 ;; Used to control the "enabled" attribute on a per-instruction basis.
664 (define_attr "isa" "base,x64,x64_sse4,x64_sse4_noavx,x64_avx,nox64,
665 sse2,sse2_noavx,sse3,sse4,sse4_noavx,avx,noavx,
666 avx2,noavx2,bmi2,fma4,fma"
667 (const_string "base"))
669 (define_attr "enabled" ""
670 (cond [(eq_attr "isa" "x64") (symbol_ref "TARGET_64BIT")
671 (eq_attr "isa" "x64_sse4")
672 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1")
673 (eq_attr "isa" "x64_sse4_noavx")
674 (symbol_ref "TARGET_64BIT && TARGET_SSE4_1 && !TARGET_AVX")
675 (eq_attr "isa" "x64_avx")
676 (symbol_ref "TARGET_64BIT && TARGET_AVX")
677 (eq_attr "isa" "nox64") (symbol_ref "!TARGET_64BIT")
678 (eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
679 (eq_attr "isa" "sse2_noavx")
680 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
681 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
682 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
683 (eq_attr "isa" "sse4_noavx")
684 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
685 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
686 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
687 (eq_attr "isa" "avx2") (symbol_ref "TARGET_AVX2")
688 (eq_attr "isa" "noavx2") (symbol_ref "!TARGET_AVX2")
689 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
690 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
691 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
695 ;; Describe a user's asm statement.
696 (define_asm_attributes
697 [(set_attr "length" "128")
698 (set_attr "type" "multi")])
700 (define_code_iterator plusminus [plus minus])
702 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
704 ;; Base name for define_insn
705 (define_code_attr plusminus_insn
706 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
707 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
709 ;; Base name for insn mnemonic.
710 (define_code_attr plusminus_mnemonic
711 [(plus "add") (ss_plus "adds") (us_plus "addus")
712 (minus "sub") (ss_minus "subs") (us_minus "subus")])
713 (define_code_attr plusminus_carry_mnemonic
714 [(plus "adc") (minus "sbb")])
716 ;; Mark commutative operators as such in constraints.
717 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
718 (minus "") (ss_minus "") (us_minus "")])
720 ;; Mapping of max and min
721 (define_code_iterator maxmin [smax smin umax umin])
723 ;; Mapping of signed max and min
724 (define_code_iterator smaxmin [smax smin])
726 ;; Mapping of unsigned max and min
727 (define_code_iterator umaxmin [umax umin])
729 ;; Base name for integer and FP insn mnemonic
730 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
731 (umax "maxu") (umin "minu")])
732 (define_code_attr maxmin_float [(smax "max") (smin "min")])
734 ;; Mapping of logic operators
735 (define_code_iterator any_logic [and ior xor])
736 (define_code_iterator any_or [ior xor])
738 ;; Base name for insn mnemonic.
739 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
741 ;; Mapping of logic-shift operators
742 (define_code_iterator any_lshift [ashift lshiftrt])
744 ;; Mapping of shift-right operators
745 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
747 ;; Mapping of all shift operators
748 (define_code_iterator any_shift [ashift lshiftrt ashiftrt])
750 ;; Base name for define_insn
751 (define_code_attr shift_insn
752 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
754 ;; Base name for insn mnemonic.
755 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
756 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
758 ;; Mapping of rotate operators
759 (define_code_iterator any_rotate [rotate rotatert])
761 ;; Base name for define_insn
762 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
764 ;; Base name for insn mnemonic.
765 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
767 ;; Mapping of abs neg operators
768 (define_code_iterator absneg [abs neg])
770 ;; Base name for x87 insn mnemonic.
771 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
773 ;; Used in signed and unsigned widening multiplications.
774 (define_code_iterator any_extend [sign_extend zero_extend])
776 ;; Prefix for insn menmonic.
777 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
779 ;; Prefix for define_insn
780 (define_code_attr u [(sign_extend "") (zero_extend "u")])
781 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
782 (define_code_attr u_bool [(sign_extend "false") (zero_extend "true")])
784 ;; All integer modes.
785 (define_mode_iterator SWI1248x [QI HI SI DI])
787 ;; All integer modes without QImode.
788 (define_mode_iterator SWI248x [HI SI DI])
790 ;; All integer modes without QImode and HImode.
791 (define_mode_iterator SWI48x [SI DI])
793 ;; All integer modes without SImode and DImode.
794 (define_mode_iterator SWI12 [QI HI])
796 ;; All integer modes without DImode.
797 (define_mode_iterator SWI124 [QI HI SI])
799 ;; All integer modes without QImode and DImode.
800 (define_mode_iterator SWI24 [HI SI])
802 ;; Single word integer modes.
803 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
805 ;; Single word integer modes without QImode.
806 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
808 ;; Single word integer modes without QImode and HImode.
809 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
811 ;; All math-dependant single and double word integer modes.
812 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
813 (HI "TARGET_HIMODE_MATH")
814 SI DI (TI "TARGET_64BIT")])
816 ;; Math-dependant single word integer modes.
817 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
818 (HI "TARGET_HIMODE_MATH")
819 SI (DI "TARGET_64BIT")])
821 ;; Math-dependant integer modes without DImode.
822 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
823 (HI "TARGET_HIMODE_MATH")
826 ;; Math-dependant single word integer modes without QImode.
827 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
828 SI (DI "TARGET_64BIT")])
830 ;; Double word integer modes.
831 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
832 (TI "TARGET_64BIT")])
834 ;; Double word integer modes as mode attribute.
835 (define_mode_attr DWI [(SI "DI") (DI "TI")])
836 (define_mode_attr dwi [(SI "di") (DI "ti")])
838 ;; Half mode for double word integer modes.
839 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
840 (DI "TARGET_64BIT")])
842 ;; Instruction suffix for integer modes.
843 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
845 ;; Pointer size prefix for integer modes (Intel asm dialect)
846 (define_mode_attr iptrsize [(QI "BYTE")
851 ;; Register class for integer modes.
852 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
854 ;; Immediate operand constraint for integer modes.
855 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
857 ;; General operand constraint for word modes.
858 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
860 ;; Immediate operand constraint for double integer modes.
861 (define_mode_attr di [(SI "nF") (DI "e")])
863 ;; Immediate operand constraint for shifts.
864 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
866 ;; General operand predicate for integer modes.
867 (define_mode_attr general_operand
868 [(QI "general_operand")
869 (HI "general_operand")
870 (SI "x86_64_general_operand")
871 (DI "x86_64_general_operand")
872 (TI "x86_64_general_operand")])
874 ;; General sign/zero extend operand predicate for integer modes.
875 (define_mode_attr general_szext_operand
876 [(QI "general_operand")
877 (HI "general_operand")
878 (SI "x86_64_szext_general_operand")
879 (DI "x86_64_szext_general_operand")])
881 ;; Immediate operand predicate for integer modes.
882 (define_mode_attr immediate_operand
883 [(QI "immediate_operand")
884 (HI "immediate_operand")
885 (SI "x86_64_immediate_operand")
886 (DI "x86_64_immediate_operand")])
888 ;; Nonmemory operand predicate for integer modes.
889 (define_mode_attr nonmemory_operand
890 [(QI "nonmemory_operand")
891 (HI "nonmemory_operand")
892 (SI "x86_64_nonmemory_operand")
893 (DI "x86_64_nonmemory_operand")])
895 ;; Operand predicate for shifts.
896 (define_mode_attr shift_operand
897 [(QI "nonimmediate_operand")
898 (HI "nonimmediate_operand")
899 (SI "nonimmediate_operand")
900 (DI "shiftdi_operand")
901 (TI "register_operand")])
903 ;; Operand predicate for shift argument.
904 (define_mode_attr shift_immediate_operand
905 [(QI "const_1_to_31_operand")
906 (HI "const_1_to_31_operand")
907 (SI "const_1_to_31_operand")
908 (DI "const_1_to_63_operand")])
910 ;; Input operand predicate for arithmetic left shifts.
911 (define_mode_attr ashl_input_operand
912 [(QI "nonimmediate_operand")
913 (HI "nonimmediate_operand")
914 (SI "nonimmediate_operand")
915 (DI "ashldi_input_operand")
916 (TI "reg_or_pm1_operand")])
918 ;; SSE and x87 SFmode and DFmode floating point modes
919 (define_mode_iterator MODEF [SF DF])
921 ;; All x87 floating point modes
922 (define_mode_iterator X87MODEF [SF DF XF])
924 ;; SSE instruction suffix for various modes
925 (define_mode_attr ssemodesuffix
927 (V8SF "ps") (V4DF "pd")
928 (V4SF "ps") (V2DF "pd")
929 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
930 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
932 ;; SSE vector suffix for floating point modes
933 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
935 ;; SSE vector mode corresponding to a scalar mode
936 (define_mode_attr ssevecmode
937 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
938 (define_mode_attr ssevecmodelower
939 [(QI "v16qi") (HI "v8hi") (SI "v4si") (DI "v2di") (SF "v4sf") (DF "v2df")])
941 ;; Instruction suffix for REX 64bit operators.
942 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
944 ;; This mode iterator allows :P to be used for patterns that operate on
945 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
946 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
948 ;; This mode iterator allows :W to be used for patterns that operate on
949 ;; word_mode sized quantities.
950 (define_mode_iterator W
951 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
953 ;; This mode iterator allows :PTR to be used for patterns that operate on
954 ;; ptr_mode sized quantities.
955 (define_mode_iterator PTR
956 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
958 ;; Scheduling descriptions
960 (include "pentium.md")
963 (include "athlon.md")
964 (include "bdver1.md")
965 (include "bdver3.md")
966 (include "btver2.md")
973 ;; Operand and operator predicates and constraints
975 (include "predicates.md")
976 (include "constraints.md")
979 ;; Compare and branch/compare and store instructions.
981 (define_expand "cbranch<mode>4"
982 [(set (reg:CC FLAGS_REG)
983 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
984 (match_operand:SDWIM 2 "<general_operand>")))
985 (set (pc) (if_then_else
986 (match_operator 0 "ordered_comparison_operator"
987 [(reg:CC FLAGS_REG) (const_int 0)])
988 (label_ref (match_operand 3))
992 if (MEM_P (operands[1]) && MEM_P (operands[2]))
993 operands[1] = force_reg (<MODE>mode, operands[1]);
994 ix86_expand_branch (GET_CODE (operands[0]),
995 operands[1], operands[2], operands[3]);
999 (define_expand "cstore<mode>4"
1000 [(set (reg:CC FLAGS_REG)
1001 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
1002 (match_operand:SWIM 3 "<general_operand>")))
1003 (set (match_operand:QI 0 "register_operand")
1004 (match_operator 1 "ordered_comparison_operator"
1005 [(reg:CC FLAGS_REG) (const_int 0)]))]
1008 if (MEM_P (operands[2]) && MEM_P (operands[3]))
1009 operands[2] = force_reg (<MODE>mode, operands[2]);
1010 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1011 operands[2], operands[3]);
1015 (define_expand "cmp<mode>_1"
1016 [(set (reg:CC FLAGS_REG)
1017 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
1018 (match_operand:SWI48 1 "<general_operand>")))])
1020 (define_insn "*cmp<mode>_ccno_1"
1021 [(set (reg FLAGS_REG)
1022 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
1023 (match_operand:SWI 1 "const0_operand")))]
1024 "ix86_match_ccmode (insn, CCNOmode)"
1026 test{<imodesuffix>}\t%0, %0
1027 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1028 [(set_attr "type" "test,icmp")
1029 (set_attr "length_immediate" "0,1")
1030 (set_attr "mode" "<MODE>")])
1032 (define_insn "*cmp<mode>_1"
1033 [(set (reg FLAGS_REG)
1034 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1035 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
1036 "ix86_match_ccmode (insn, CCmode)"
1037 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1038 [(set_attr "type" "icmp")
1039 (set_attr "mode" "<MODE>")])
1041 (define_insn "*cmp<mode>_minus_1"
1042 [(set (reg FLAGS_REG)
1044 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1045 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1047 "ix86_match_ccmode (insn, CCGOCmode)"
1048 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1049 [(set_attr "type" "icmp")
1050 (set_attr "mode" "<MODE>")])
1052 (define_insn "*cmpqi_ext_1"
1053 [(set (reg FLAGS_REG)
1055 (match_operand:QI 0 "nonimmediate_x64nomem_operand" "Q,m")
1058 (match_operand 1 "ext_register_operand" "Q,Q")
1060 (const_int 8)) 0)))]
1061 "ix86_match_ccmode (insn, CCmode)"
1062 "cmp{b}\t{%h1, %0|%0, %h1}"
1063 [(set_attr "isa" "*,nox64")
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 "const_int_operand")))])
1092 (define_insn "*cmpqi_ext_3"
1093 [(set (reg FLAGS_REG)
1097 (match_operand 0 "ext_register_operand" "Q,Q")
1100 (match_operand:QI 1 "general_x64nomem_operand" "Qn,m")))]
1101 "ix86_match_ccmode (insn, CCmode)"
1102 "cmp{b}\t{%1, %h0|%h0, %1}"
1103 [(set_attr "isa" "*,nox64")
1104 (set_attr "type" "icmp")
1105 (set_attr "modrm" "1")
1106 (set_attr "mode" "QI")])
1108 (define_insn "*cmpqi_ext_4"
1109 [(set (reg FLAGS_REG)
1113 (match_operand 0 "ext_register_operand" "Q")
1118 (match_operand 1 "ext_register_operand" "Q")
1120 (const_int 8)) 0)))]
1121 "ix86_match_ccmode (insn, CCmode)"
1122 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1123 [(set_attr "type" "icmp")
1124 (set_attr "mode" "QI")])
1126 ;; These implement float point compares.
1127 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1128 ;; which would allow mix and match FP modes on the compares. Which is what
1129 ;; the old patterns did, but with many more of them.
1131 (define_expand "cbranchxf4"
1132 [(set (reg:CC FLAGS_REG)
1133 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1134 (match_operand:XF 2 "nonmemory_operand")))
1135 (set (pc) (if_then_else
1136 (match_operator 0 "ix86_fp_comparison_operator"
1139 (label_ref (match_operand 3))
1143 ix86_expand_branch (GET_CODE (operands[0]),
1144 operands[1], operands[2], operands[3]);
1148 (define_expand "cstorexf4"
1149 [(set (reg:CC FLAGS_REG)
1150 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1151 (match_operand:XF 3 "nonmemory_operand")))
1152 (set (match_operand:QI 0 "register_operand")
1153 (match_operator 1 "ix86_fp_comparison_operator"
1158 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1159 operands[2], operands[3]);
1163 (define_expand "cbranch<mode>4"
1164 [(set (reg:CC FLAGS_REG)
1165 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1166 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1167 (set (pc) (if_then_else
1168 (match_operator 0 "ix86_fp_comparison_operator"
1171 (label_ref (match_operand 3))
1173 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1175 ix86_expand_branch (GET_CODE (operands[0]),
1176 operands[1], operands[2], operands[3]);
1180 (define_expand "cstore<mode>4"
1181 [(set (reg:CC FLAGS_REG)
1182 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1183 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1184 (set (match_operand:QI 0 "register_operand")
1185 (match_operator 1 "ix86_fp_comparison_operator"
1188 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1190 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1191 operands[2], operands[3]);
1195 (define_expand "cbranchcc4"
1196 [(set (pc) (if_then_else
1197 (match_operator 0 "comparison_operator"
1198 [(match_operand 1 "flags_reg_operand")
1199 (match_operand 2 "const0_operand")])
1200 (label_ref (match_operand 3))
1204 ix86_expand_branch (GET_CODE (operands[0]),
1205 operands[1], operands[2], operands[3]);
1209 (define_expand "cstorecc4"
1210 [(set (match_operand:QI 0 "register_operand")
1211 (match_operator 1 "comparison_operator"
1212 [(match_operand 2 "flags_reg_operand")
1213 (match_operand 3 "const0_operand")]))]
1216 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1217 operands[2], operands[3]);
1222 ;; FP compares, step 1:
1223 ;; Set the FP condition codes.
1225 ;; CCFPmode compare with exceptions
1226 ;; CCFPUmode compare with no exceptions
1228 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1229 ;; used to manage the reg stack popping would not be preserved.
1231 (define_insn "*cmp<mode>_0_i387"
1232 [(set (match_operand:HI 0 "register_operand" "=a")
1235 (match_operand:X87MODEF 1 "register_operand" "f")
1236 (match_operand:X87MODEF 2 "const0_operand"))]
1239 "* return output_fp_compare (insn, operands, false, false);"
1240 [(set_attr "type" "multi")
1241 (set_attr "unit" "i387")
1242 (set_attr "mode" "<MODE>")])
1244 (define_insn_and_split "*cmp<mode>_0_cc_i387"
1245 [(set (reg:CCFP FLAGS_REG)
1247 (match_operand:X87MODEF 1 "register_operand" "f")
1248 (match_operand:X87MODEF 2 "const0_operand")))
1249 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1250 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1252 "&& reload_completed"
1255 [(compare:CCFP (match_dup 1)(match_dup 2))]
1257 (set (reg:CC FLAGS_REG)
1258 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1260 [(set_attr "type" "multi")
1261 (set_attr "unit" "i387")
1262 (set_attr "mode" "<MODE>")])
1264 (define_insn "*cmpxf_i387"
1265 [(set (match_operand:HI 0 "register_operand" "=a")
1268 (match_operand:XF 1 "register_operand" "f")
1269 (match_operand:XF 2 "register_operand" "f"))]
1272 "* return output_fp_compare (insn, operands, false, false);"
1273 [(set_attr "type" "multi")
1274 (set_attr "unit" "i387")
1275 (set_attr "mode" "XF")])
1277 (define_insn_and_split "*cmpxf_cc_i387"
1278 [(set (reg:CCFP FLAGS_REG)
1280 (match_operand:XF 1 "register_operand" "f")
1281 (match_operand:XF 2 "register_operand" "f")))
1282 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1283 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1285 "&& reload_completed"
1288 [(compare:CCFP (match_dup 1)(match_dup 2))]
1290 (set (reg:CC FLAGS_REG)
1291 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1293 [(set_attr "type" "multi")
1294 (set_attr "unit" "i387")
1295 (set_attr "mode" "XF")])
1297 (define_insn "*cmp<mode>_i387"
1298 [(set (match_operand:HI 0 "register_operand" "=a")
1301 (match_operand:MODEF 1 "register_operand" "f")
1302 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1305 "* return output_fp_compare (insn, operands, false, false);"
1306 [(set_attr "type" "multi")
1307 (set_attr "unit" "i387")
1308 (set_attr "mode" "<MODE>")])
1310 (define_insn_and_split "*cmp<mode>_cc_i387"
1311 [(set (reg:CCFP FLAGS_REG)
1313 (match_operand:MODEF 1 "register_operand" "f")
1314 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1315 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1316 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1318 "&& reload_completed"
1321 [(compare:CCFP (match_dup 1)(match_dup 2))]
1323 (set (reg:CC FLAGS_REG)
1324 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1326 [(set_attr "type" "multi")
1327 (set_attr "unit" "i387")
1328 (set_attr "mode" "<MODE>")])
1330 (define_insn "*cmpu<mode>_i387"
1331 [(set (match_operand:HI 0 "register_operand" "=a")
1334 (match_operand:X87MODEF 1 "register_operand" "f")
1335 (match_operand:X87MODEF 2 "register_operand" "f"))]
1338 "* return output_fp_compare (insn, operands, false, true);"
1339 [(set_attr "type" "multi")
1340 (set_attr "unit" "i387")
1341 (set_attr "mode" "<MODE>")])
1343 (define_insn_and_split "*cmpu<mode>_cc_i387"
1344 [(set (reg:CCFPU FLAGS_REG)
1346 (match_operand:X87MODEF 1 "register_operand" "f")
1347 (match_operand:X87MODEF 2 "register_operand" "f")))
1348 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1349 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE"
1351 "&& reload_completed"
1354 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1356 (set (reg:CC FLAGS_REG)
1357 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1359 [(set_attr "type" "multi")
1360 (set_attr "unit" "i387")
1361 (set_attr "mode" "<MODE>")])
1363 (define_insn "*cmp<X87MODEF:mode>_<SWI24:mode>_i387"
1364 [(set (match_operand:HI 0 "register_operand" "=a")
1367 (match_operand:X87MODEF 1 "register_operand" "f")
1368 (match_operator:X87MODEF 3 "float_operator"
1369 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1372 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1373 || optimize_function_for_size_p (cfun))"
1374 "* return output_fp_compare (insn, operands, false, false);"
1375 [(set_attr "type" "multi")
1376 (set_attr "unit" "i387")
1377 (set_attr "fp_int_src" "true")
1378 (set_attr "mode" "<SWI24:MODE>")])
1380 (define_insn_and_split "*cmp<X87MODEF:mode>_<SWI24:mode>_cc_i387"
1381 [(set (reg:CCFP FLAGS_REG)
1383 (match_operand:X87MODEF 1 "register_operand" "f")
1384 (match_operator:X87MODEF 3 "float_operator"
1385 [(match_operand:SWI24 2 "memory_operand" "m")])))
1386 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1387 "TARGET_80387 && TARGET_SAHF && !TARGET_CMOVE
1388 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
1389 || optimize_function_for_size_p (cfun))"
1391 "&& reload_completed"
1396 (match_op_dup 3 [(match_dup 2)]))]
1398 (set (reg:CC FLAGS_REG)
1399 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1401 [(set_attr "type" "multi")
1402 (set_attr "unit" "i387")
1403 (set_attr "fp_int_src" "true")
1404 (set_attr "mode" "<SWI24:MODE>")])
1406 ;; FP compares, step 2
1407 ;; Move the fpsw to ax.
1409 (define_insn "x86_fnstsw_1"
1410 [(set (match_operand:HI 0 "register_operand" "=a")
1411 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1414 [(set (attr "length")
1415 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1416 (set_attr "mode" "SI")
1417 (set_attr "unit" "i387")])
1419 ;; FP compares, step 3
1420 ;; Get ax into flags, general case.
1422 (define_insn "x86_sahf_1"
1423 [(set (reg:CC FLAGS_REG)
1424 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1428 #ifndef HAVE_AS_IX86_SAHF
1430 return ASM_BYTE "0x9e";
1435 [(set_attr "length" "1")
1436 (set_attr "athlon_decode" "vector")
1437 (set_attr "amdfam10_decode" "direct")
1438 (set_attr "bdver1_decode" "direct")
1439 (set_attr "mode" "SI")])
1441 ;; Pentium Pro can do steps 1 through 3 in one go.
1442 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1443 ;; (these i387 instructions set flags directly)
1445 (define_mode_iterator FPCMP [CCFP CCFPU])
1446 (define_mode_attr unord [(CCFP "") (CCFPU "u")])
1448 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_mixed"
1449 [(set (reg:FPCMP FLAGS_REG)
1451 (match_operand:MODEF 0 "register_operand" "f,x")
1452 (match_operand:MODEF 1 "nonimmediate_operand" "f,xm")))]
1453 "TARGET_MIX_SSE_I387
1454 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1455 "* return output_fp_compare (insn, operands, true,
1456 <FPCMP:MODE>mode == CCFPUmode);"
1457 [(set_attr "type" "fcmp,ssecomi")
1458 (set_attr "prefix" "orig,maybe_vex")
1459 (set_attr "mode" "<MODEF:MODE>")
1460 (set (attr "prefix_rep")
1461 (if_then_else (eq_attr "type" "ssecomi")
1463 (const_string "*")))
1464 (set (attr "prefix_data16")
1465 (cond [(eq_attr "type" "fcmp")
1467 (eq_attr "mode" "DF")
1470 (const_string "0")))
1471 (set_attr "athlon_decode" "vector")
1472 (set_attr "amdfam10_decode" "direct")
1473 (set_attr "bdver1_decode" "double")])
1475 (define_insn "*cmpi<FPCMP:unord><MODEF:mode>_sse"
1476 [(set (reg:FPCMP FLAGS_REG)
1478 (match_operand:MODEF 0 "register_operand" "x")
1479 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
1481 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)"
1482 "* return output_fp_compare (insn, operands, true,
1483 <FPCMP:MODE>mode == CCFPUmode);"
1484 [(set_attr "type" "ssecomi")
1485 (set_attr "prefix" "maybe_vex")
1486 (set_attr "mode" "<MODEF:MODE>")
1487 (set_attr "prefix_rep" "0")
1488 (set (attr "prefix_data16")
1489 (if_then_else (eq_attr "mode" "DF")
1491 (const_string "0")))
1492 (set_attr "athlon_decode" "vector")
1493 (set_attr "amdfam10_decode" "direct")
1494 (set_attr "bdver1_decode" "double")])
1496 (define_insn "*cmpi<FPCMP:unord><X87MODEF:mode>_i387"
1497 [(set (reg:FPCMP FLAGS_REG)
1499 (match_operand:X87MODEF 0 "register_operand" "f")
1500 (match_operand:X87MODEF 1 "register_operand" "f")))]
1501 "TARGET_80387 && TARGET_CMOVE
1502 && !(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
1503 "* return output_fp_compare (insn, operands, true,
1504 <FPCMP:MODE>mode == CCFPUmode);"
1505 [(set_attr "type" "fcmp")
1506 (set_attr "mode" "<X87MODEF:MODE>")
1507 (set_attr "athlon_decode" "vector")
1508 (set_attr "amdfam10_decode" "direct")
1509 (set_attr "bdver1_decode" "double")])
1511 ;; Push/pop instructions.
1513 (define_insn "*push<mode>2"
1514 [(set (match_operand:DWI 0 "push_operand" "=<")
1515 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1518 [(set_attr "type" "multi")
1519 (set_attr "mode" "<MODE>")])
1522 [(set (match_operand:TI 0 "push_operand")
1523 (match_operand:TI 1 "general_operand"))]
1524 "TARGET_64BIT && reload_completed
1525 && !SSE_REG_P (operands[1])"
1527 "ix86_split_long_move (operands); DONE;")
1529 (define_insn "*pushdi2_rex64"
1530 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1531 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1536 [(set_attr "type" "push,multi")
1537 (set_attr "mode" "DI")])
1539 ;; Convert impossible pushes of immediate to existing instructions.
1540 ;; First try to get scratch register and go through it. In case this
1541 ;; fails, push sign extended lower part first and then overwrite
1542 ;; upper part by 32bit move.
1544 [(match_scratch:DI 2 "r")
1545 (set (match_operand:DI 0 "push_operand")
1546 (match_operand:DI 1 "immediate_operand"))]
1547 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1548 && !x86_64_immediate_operand (operands[1], DImode)"
1549 [(set (match_dup 2) (match_dup 1))
1550 (set (match_dup 0) (match_dup 2))])
1552 ;; We need to define this as both peepholer and splitter for case
1553 ;; peephole2 pass is not run.
1554 ;; "&& 1" is needed to keep it from matching the previous pattern.
1556 [(set (match_operand:DI 0 "push_operand")
1557 (match_operand:DI 1 "immediate_operand"))]
1558 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1559 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1560 [(set (match_dup 0) (match_dup 1))
1561 (set (match_dup 2) (match_dup 3))]
1563 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1565 operands[1] = gen_lowpart (DImode, operands[2]);
1566 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1571 [(set (match_operand:DI 0 "push_operand")
1572 (match_operand:DI 1 "immediate_operand"))]
1573 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1574 ? epilogue_completed : reload_completed)
1575 && !symbolic_operand (operands[1], DImode)
1576 && !x86_64_immediate_operand (operands[1], DImode)"
1577 [(set (match_dup 0) (match_dup 1))
1578 (set (match_dup 2) (match_dup 3))]
1580 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1582 operands[1] = gen_lowpart (DImode, operands[2]);
1583 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1588 [(set (match_operand:DI 0 "push_operand")
1589 (match_operand:DI 1 "general_operand"))]
1590 "!TARGET_64BIT && reload_completed
1591 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1593 "ix86_split_long_move (operands); DONE;")
1595 (define_insn "*pushsi2"
1596 [(set (match_operand:SI 0 "push_operand" "=<")
1597 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1600 [(set_attr "type" "push")
1601 (set_attr "mode" "SI")])
1603 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1604 ;; "push a byte/word". But actually we use pushl, which has the effect
1605 ;; of rounding the amount pushed up to a word.
1607 ;; For TARGET_64BIT we always round up to 8 bytes.
1608 (define_insn "*push<mode>2_rex64"
1609 [(set (match_operand:SWI124 0 "push_operand" "=X")
1610 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1613 [(set_attr "type" "push")
1614 (set_attr "mode" "DI")])
1616 (define_insn "*push<mode>2"
1617 [(set (match_operand:SWI12 0 "push_operand" "=X")
1618 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1621 [(set_attr "type" "push")
1622 (set_attr "mode" "SI")])
1624 (define_insn "*push<mode>2_prologue"
1625 [(set (match_operand:W 0 "push_operand" "=<")
1626 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1627 (clobber (mem:BLK (scratch)))]
1629 "push{<imodesuffix>}\t%1"
1630 [(set_attr "type" "push")
1631 (set_attr "mode" "<MODE>")])
1633 (define_insn "*pop<mode>1"
1634 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1635 (match_operand:W 1 "pop_operand" ">"))]
1637 "pop{<imodesuffix>}\t%0"
1638 [(set_attr "type" "pop")
1639 (set_attr "mode" "<MODE>")])
1641 (define_insn "*pop<mode>1_epilogue"
1642 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1643 (match_operand:W 1 "pop_operand" ">"))
1644 (clobber (mem:BLK (scratch)))]
1646 "pop{<imodesuffix>}\t%0"
1647 [(set_attr "type" "pop")
1648 (set_attr "mode" "<MODE>")])
1650 ;; Move instructions.
1652 ;; Reload patterns to support multi-word load/store
1653 ;; with non-offsetable address.
1654 (define_expand "reload_noff_store"
1655 [(parallel [(match_operand 0 "memory_operand" "=m")
1656 (match_operand 1 "register_operand" "r")
1657 (match_operand:DI 2 "register_operand" "=&r")])]
1660 rtx mem = operands[0];
1661 rtx addr = XEXP (mem, 0);
1663 emit_move_insn (operands[2], addr);
1664 mem = replace_equiv_address_nv (mem, operands[2]);
1666 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
1670 (define_expand "reload_noff_load"
1671 [(parallel [(match_operand 0 "register_operand" "=r")
1672 (match_operand 1 "memory_operand" "m")
1673 (match_operand:DI 2 "register_operand" "=r")])]
1676 rtx mem = operands[1];
1677 rtx addr = XEXP (mem, 0);
1679 emit_move_insn (operands[2], addr);
1680 mem = replace_equiv_address_nv (mem, operands[2]);
1682 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
1686 (define_expand "movoi"
1687 [(set (match_operand:OI 0 "nonimmediate_operand")
1688 (match_operand:OI 1 "general_operand"))]
1690 "ix86_expand_move (OImode, operands); DONE;")
1692 (define_expand "movti"
1693 [(set (match_operand:TI 0 "nonimmediate_operand")
1694 (match_operand:TI 1 "nonimmediate_operand"))]
1695 "TARGET_64BIT || TARGET_SSE"
1698 ix86_expand_move (TImode, operands);
1699 else if (push_operand (operands[0], TImode))
1700 ix86_expand_push (TImode, operands[1]);
1702 ix86_expand_vector_move (TImode, operands);
1706 ;; This expands to what emit_move_complex would generate if we didn't
1707 ;; have a movti pattern. Having this avoids problems with reload on
1708 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1709 ;; to have around all the time.
1710 (define_expand "movcdi"
1711 [(set (match_operand:CDI 0 "nonimmediate_operand")
1712 (match_operand:CDI 1 "general_operand"))]
1715 if (push_operand (operands[0], CDImode))
1716 emit_move_complex_push (CDImode, operands[0], operands[1]);
1718 emit_move_complex_parts (operands[0], operands[1]);
1722 (define_expand "mov<mode>"
1723 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1724 (match_operand:SWI1248x 1 "general_operand"))]
1726 "ix86_expand_move (<MODE>mode, operands); DONE;")
1728 (define_insn "*mov<mode>_xor"
1729 [(set (match_operand:SWI48 0 "register_operand" "=r")
1730 (match_operand:SWI48 1 "const0_operand"))
1731 (clobber (reg:CC FLAGS_REG))]
1734 [(set_attr "type" "alu1")
1735 (set_attr "mode" "SI")
1736 (set_attr "length_immediate" "0")])
1738 (define_insn "*mov<mode>_or"
1739 [(set (match_operand:SWI48 0 "register_operand" "=r")
1740 (match_operand:SWI48 1 "const_int_operand"))
1741 (clobber (reg:CC FLAGS_REG))]
1743 && operands[1] == constm1_rtx"
1744 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1745 [(set_attr "type" "alu1")
1746 (set_attr "mode" "<MODE>")
1747 (set_attr "length_immediate" "1")])
1749 (define_insn "*movoi_internal_avx"
1750 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x ,m")
1751 (match_operand:OI 1 "vector_move_operand" "C ,xm,x"))]
1752 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1754 switch (get_attr_type (insn))
1757 return standard_sse_constant_opcode (insn, operands[1]);
1760 if (misaligned_operand (operands[0], OImode)
1761 || misaligned_operand (operands[1], OImode))
1763 if (get_attr_mode (insn) == MODE_V8SF)
1764 return "vmovups\t{%1, %0|%0, %1}";
1766 return "vmovdqu\t{%1, %0|%0, %1}";
1770 if (get_attr_mode (insn) == MODE_V8SF)
1771 return "vmovaps\t{%1, %0|%0, %1}";
1773 return "vmovdqa\t{%1, %0|%0, %1}";
1780 [(set_attr "type" "sselog1,ssemov,ssemov")
1781 (set_attr "prefix" "vex")
1783 (cond [(match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
1784 (const_string "V8SF")
1785 (and (eq_attr "alternative" "2")
1786 (match_test "TARGET_SSE_TYPELESS_STORES"))
1787 (const_string "V8SF")
1789 (const_string "OI")))])
1791 (define_insn "*movti_internal"
1792 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r ,o ,x,x ,m")
1793 (match_operand:TI 1 "general_operand" "riFo,re,C,xm,x"))]
1794 "(TARGET_64BIT || TARGET_SSE)
1795 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1797 switch (get_attr_type (insn))
1803 return standard_sse_constant_opcode (insn, operands[1]);
1806 /* TDmode values are passed as TImode on the stack. Moving them
1807 to stack may result in unaligned memory access. */
1808 if (misaligned_operand (operands[0], TImode)
1809 || misaligned_operand (operands[1], TImode))
1811 if (get_attr_mode (insn) == MODE_V4SF)
1812 return "%vmovups\t{%1, %0|%0, %1}";
1814 return "%vmovdqu\t{%1, %0|%0, %1}";
1818 if (get_attr_mode (insn) == MODE_V4SF)
1819 return "%vmovaps\t{%1, %0|%0, %1}";
1821 return "%vmovdqa\t{%1, %0|%0, %1}";
1828 [(set_attr "isa" "x64,x64,*,*,*")
1829 (set_attr "type" "multi,multi,sselog1,ssemov,ssemov")
1830 (set (attr "prefix")
1831 (if_then_else (eq_attr "type" "sselog1,ssemov")
1832 (const_string "maybe_vex")
1833 (const_string "orig")))
1835 (cond [(eq_attr "alternative" "0,1")
1837 (ior (not (match_test "TARGET_SSE2"))
1838 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
1839 (const_string "V4SF")
1840 (and (eq_attr "alternative" "4")
1841 (match_test "TARGET_SSE_TYPELESS_STORES"))
1842 (const_string "V4SF")
1843 (match_test "TARGET_AVX")
1845 (match_test "optimize_function_for_size_p (cfun)")
1846 (const_string "V4SF")
1848 (const_string "TI")))])
1851 [(set (match_operand:TI 0 "nonimmediate_operand")
1852 (match_operand:TI 1 "general_operand"))]
1854 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1856 "ix86_split_long_move (operands); DONE;")
1858 (define_insn "*movdi_internal"
1859 [(set (match_operand:DI 0 "nonimmediate_operand"
1860 "=r ,o ,r,r ,r,m ,*y,*y,?*y,?m,?r ,?*Ym,*x,*x,*x,m ,?r ,?r,?*Yi,?*Ym,?*Yi")
1861 (match_operand:DI 1 "general_operand"
1862 "riFo,riF,Z,rem,i,re,C ,*y,m ,*y,*Yn,r ,C ,*x,m ,*x,*Yj,*x,r ,*Yj ,*Yn"))]
1863 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1865 switch (get_attr_type (insn))
1871 return "pxor\t%0, %0";
1874 #ifndef HAVE_AS_IX86_INTERUNIT_MOVQ
1875 /* Handle broken assemblers that require movd instead of movq. */
1876 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1877 return "movd\t{%1, %0|%0, %1}";
1879 return "movq\t{%1, %0|%0, %1}";
1882 if (GENERAL_REG_P (operands[0]))
1883 return "%vpextrq\t{$0, %1, %0|%0, %1, 0}";
1885 return standard_sse_constant_opcode (insn, operands[1]);
1888 switch (get_attr_mode (insn))
1891 #ifndef HAVE_AS_IX86_INTERUNIT_MOVQ
1892 /* Handle broken assemblers that require movd instead of movq. */
1893 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1894 return "%vmovd\t{%1, %0|%0, %1}";
1896 return "%vmovq\t{%1, %0|%0, %1}";
1898 return "%vmovdqa\t{%1, %0|%0, %1}";
1901 gcc_assert (!TARGET_AVX);
1902 return "movlps\t{%1, %0|%0, %1}";
1904 return "%vmovaps\t{%1, %0|%0, %1}";
1911 if (SSE_REG_P (operands[0]))
1912 return "movq2dq\t{%1, %0|%0, %1}";
1914 return "movdq2q\t{%1, %0|%0, %1}";
1917 return "lea{q}\t{%E1, %0|%0, %E1}";
1920 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1921 if (get_attr_mode (insn) == MODE_SI)
1922 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1923 else if (which_alternative == 4)
1924 return "movabs{q}\t{%1, %0|%0, %1}";
1925 else if (ix86_use_lea_for_mov (insn, operands))
1926 return "lea{q}\t{%E1, %0|%0, %E1}";
1928 return "mov{q}\t{%1, %0|%0, %1}";
1935 (cond [(eq_attr "alternative" "0,1")
1936 (const_string "nox64")
1937 (eq_attr "alternative" "2,3,4,5,10,11,16,18")
1938 (const_string "x64")
1939 (eq_attr "alternative" "17")
1940 (const_string "x64_sse4")
1942 (const_string "*")))
1944 (cond [(eq_attr "alternative" "0,1")
1945 (const_string "multi")
1946 (eq_attr "alternative" "6")
1947 (const_string "mmx")
1948 (eq_attr "alternative" "7,8,9,10,11")
1949 (const_string "mmxmov")
1950 (eq_attr "alternative" "12,17")
1951 (const_string "sselog1")
1952 (eq_attr "alternative" "13,14,15,16,18")
1953 (const_string "ssemov")
1954 (eq_attr "alternative" "19,20")
1955 (const_string "ssecvt")
1956 (match_operand 1 "pic_32bit_operand")
1957 (const_string "lea")
1959 (const_string "imov")))
1962 (and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
1964 (const_string "*")))
1965 (set (attr "length_immediate")
1966 (cond [(and (eq_attr "alternative" "4") (eq_attr "type" "imov"))
1968 (eq_attr "alternative" "17")
1971 (const_string "*")))
1972 (set (attr "prefix_rex")
1973 (if_then_else (eq_attr "alternative" "10,11,16,17,18")
1975 (const_string "*")))
1976 (set (attr "prefix_extra")
1977 (if_then_else (eq_attr "alternative" "17")
1979 (const_string "*")))
1980 (set (attr "prefix")
1981 (if_then_else (eq_attr "type" "sselog1,ssemov")
1982 (const_string "maybe_vex")
1983 (const_string "orig")))
1984 (set (attr "prefix_data16")
1985 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
1987 (const_string "*")))
1989 (cond [(eq_attr "alternative" "2")
1991 (eq_attr "alternative" "12,13")
1992 (cond [(ior (not (match_test "TARGET_SSE2"))
1993 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
1994 (const_string "V4SF")
1995 (match_test "TARGET_AVX")
1997 (match_test "optimize_function_for_size_p (cfun)")
1998 (const_string "V4SF")
2000 (const_string "TI"))
2002 (and (eq_attr "alternative" "14,15")
2003 (not (match_test "TARGET_SSE2")))
2004 (const_string "V2SF")
2005 (eq_attr "alternative" "17")
2008 (const_string "DI")))])
2011 [(set (match_operand:DI 0 "nonimmediate_operand")
2012 (match_operand:DI 1 "general_operand"))]
2013 "!TARGET_64BIT && reload_completed
2014 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2015 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2017 "ix86_split_long_move (operands); DONE;")
2019 (define_insn "*movsi_internal"
2020 [(set (match_operand:SI 0 "nonimmediate_operand"
2021 "=r,m ,*y,*y,?rm,?*y,*x,*x,*x,m ,?r ,?r,?*Yi")
2022 (match_operand:SI 1 "general_operand"
2023 "g ,re,C ,*y,*y ,rm ,C ,*x,m ,*x,*Yj,*x,r"))]
2024 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2026 switch (get_attr_type (insn))
2029 if (GENERAL_REG_P (operands[0]))
2030 return "%vpextrd\t{$0, %1, %0|%0, %1, 0}";
2032 return standard_sse_constant_opcode (insn, operands[1]);
2035 switch (get_attr_mode (insn))
2038 return "%vmovd\t{%1, %0|%0, %1}";
2040 return "%vmovdqa\t{%1, %0|%0, %1}";
2043 return "%vmovaps\t{%1, %0|%0, %1}";
2046 gcc_assert (!TARGET_AVX);
2047 return "movss\t{%1, %0|%0, %1}";
2054 return "pxor\t%0, %0";
2057 switch (get_attr_mode (insn))
2060 return "movq\t{%1, %0|%0, %1}";
2062 return "movd\t{%1, %0|%0, %1}";
2069 return "lea{l}\t{%E1, %0|%0, %E1}";
2072 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2073 if (ix86_use_lea_for_mov (insn, operands))
2074 return "lea{l}\t{%E1, %0|%0, %E1}";
2076 return "mov{l}\t{%1, %0|%0, %1}";
2083 (if_then_else (eq_attr "alternative" "11")
2084 (const_string "sse4")
2085 (const_string "*")))
2087 (cond [(eq_attr "alternative" "2")
2088 (const_string "mmx")
2089 (eq_attr "alternative" "3,4,5")
2090 (const_string "mmxmov")
2091 (eq_attr "alternative" "6,11")
2092 (const_string "sselog1")
2093 (eq_attr "alternative" "7,8,9,10,12")
2094 (const_string "ssemov")
2095 (match_operand 1 "pic_32bit_operand")
2096 (const_string "lea")
2098 (const_string "imov")))
2099 (set (attr "length_immediate")
2100 (if_then_else (eq_attr "alternative" "11")
2102 (const_string "*")))
2103 (set (attr "prefix_extra")
2104 (if_then_else (eq_attr "alternative" "11")
2106 (const_string "*")))
2107 (set (attr "prefix")
2108 (if_then_else (eq_attr "type" "sselog1,ssemov")
2109 (const_string "maybe_vex")
2110 (const_string "orig")))
2111 (set (attr "prefix_data16")
2112 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2114 (const_string "*")))
2116 (cond [(eq_attr "alternative" "2,3")
2118 (eq_attr "alternative" "6,7")
2119 (cond [(ior (not (match_test "TARGET_SSE2"))
2120 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2121 (const_string "V4SF")
2122 (match_test "TARGET_AVX")
2124 (match_test "optimize_function_for_size_p (cfun)")
2125 (const_string "V4SF")
2127 (const_string "TI"))
2129 (and (eq_attr "alternative" "8,9")
2130 (not (match_test "TARGET_SSE2")))
2132 (eq_attr "alternative" "11")
2135 (const_string "SI")))])
2137 (define_insn "*movhi_internal"
2138 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r ,r ,m")
2139 (match_operand:HI 1 "general_operand" "r ,rn,rm,rn"))]
2140 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2142 switch (get_attr_type (insn))
2145 /* movzwl is faster than movw on p2 due to partial word stalls,
2146 though not as fast as an aligned movl. */
2147 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2149 if (get_attr_mode (insn) == MODE_SI)
2150 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2152 return "mov{w}\t{%1, %0|%0, %1}";
2156 (cond [(match_test "optimize_function_for_size_p (cfun)")
2157 (const_string "imov")
2158 (and (eq_attr "alternative" "0")
2159 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2160 (not (match_test "TARGET_HIMODE_MATH"))))
2161 (const_string "imov")
2162 (and (eq_attr "alternative" "1,2")
2163 (match_operand:HI 1 "aligned_operand"))
2164 (const_string "imov")
2165 (and (match_test "TARGET_MOVX")
2166 (eq_attr "alternative" "0,2"))
2167 (const_string "imovx")
2169 (const_string "imov")))
2171 (cond [(eq_attr "type" "imovx")
2173 (and (eq_attr "alternative" "1,2")
2174 (match_operand:HI 1 "aligned_operand"))
2176 (and (eq_attr "alternative" "0")
2177 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2178 (not (match_test "TARGET_HIMODE_MATH"))))
2181 (const_string "HI")))])
2183 ;; Situation is quite tricky about when to choose full sized (SImode) move
2184 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2185 ;; partial register dependency machines (such as AMD Athlon), where QImode
2186 ;; moves issue extra dependency and for partial register stalls machines
2187 ;; that don't use QImode patterns (and QImode move cause stall on the next
2190 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2191 ;; register stall machines with, where we use QImode instructions, since
2192 ;; partial register stall can be caused there. Then we use movzx.
2193 (define_insn "*movqi_internal"
2194 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2195 (match_operand:QI 1 "general_operand" "q ,qn,qm,q,rn,qm,qn"))]
2196 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2198 switch (get_attr_type (insn))
2201 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2202 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2204 if (get_attr_mode (insn) == MODE_SI)
2205 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2207 return "mov{b}\t{%1, %0|%0, %1}";
2211 (cond [(and (eq_attr "alternative" "5")
2212 (not (match_operand:QI 1 "aligned_operand")))
2213 (const_string "imovx")
2214 (match_test "optimize_function_for_size_p (cfun)")
2215 (const_string "imov")
2216 (and (eq_attr "alternative" "3")
2217 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2218 (not (match_test "TARGET_QIMODE_MATH"))))
2219 (const_string "imov")
2220 (eq_attr "alternative" "3,5")
2221 (const_string "imovx")
2222 (and (match_test "TARGET_MOVX")
2223 (eq_attr "alternative" "2"))
2224 (const_string "imovx")
2226 (const_string "imov")))
2228 (cond [(eq_attr "alternative" "3,4,5")
2230 (eq_attr "alternative" "6")
2232 (eq_attr "type" "imovx")
2234 (and (eq_attr "type" "imov")
2235 (and (eq_attr "alternative" "0,1")
2236 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2237 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2238 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2240 ;; Avoid partial register stalls when not using QImode arithmetic
2241 (and (eq_attr "type" "imov")
2242 (and (eq_attr "alternative" "0,1")
2243 (and (match_test "TARGET_PARTIAL_REG_STALL")
2244 (not (match_test "TARGET_QIMODE_MATH")))))
2247 (const_string "QI")))])
2249 ;; Stores and loads of ax to arbitrary constant address.
2250 ;; We fake an second form of instruction to force reload to load address
2251 ;; into register when rax is not available
2252 (define_insn "*movabs<mode>_1"
2253 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2254 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2255 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2257 movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1}
2258 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2259 [(set_attr "type" "imov")
2260 (set_attr "modrm" "0,*")
2261 (set_attr "length_address" "8,0")
2262 (set_attr "length_immediate" "0,*")
2263 (set_attr "memory" "store")
2264 (set_attr "mode" "<MODE>")])
2266 (define_insn "*movabs<mode>_2"
2267 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2268 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2269 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2271 movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]}
2272 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2273 [(set_attr "type" "imov")
2274 (set_attr "modrm" "0,*")
2275 (set_attr "length_address" "8,0")
2276 (set_attr "length_immediate" "0")
2277 (set_attr "memory" "load")
2278 (set_attr "mode" "<MODE>")])
2280 (define_insn "swap<mode>"
2281 [(set (match_operand:SWI48 0 "register_operand" "+r")
2282 (match_operand:SWI48 1 "register_operand" "+r"))
2286 "xchg{<imodesuffix>}\t%1, %0"
2287 [(set_attr "type" "imov")
2288 (set_attr "mode" "<MODE>")
2289 (set_attr "pent_pair" "np")
2290 (set_attr "athlon_decode" "vector")
2291 (set_attr "amdfam10_decode" "double")
2292 (set_attr "bdver1_decode" "double")])
2294 (define_insn "*swap<mode>_1"
2295 [(set (match_operand:SWI12 0 "register_operand" "+r")
2296 (match_operand:SWI12 1 "register_operand" "+r"))
2299 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2301 [(set_attr "type" "imov")
2302 (set_attr "mode" "SI")
2303 (set_attr "pent_pair" "np")
2304 (set_attr "athlon_decode" "vector")
2305 (set_attr "amdfam10_decode" "double")
2306 (set_attr "bdver1_decode" "double")])
2308 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2309 ;; is disabled for AMDFAM10
2310 (define_insn "*swap<mode>_2"
2311 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2312 (match_operand:SWI12 1 "register_operand" "+<r>"))
2315 "TARGET_PARTIAL_REG_STALL"
2316 "xchg{<imodesuffix>}\t%1, %0"
2317 [(set_attr "type" "imov")
2318 (set_attr "mode" "<MODE>")
2319 (set_attr "pent_pair" "np")
2320 (set_attr "athlon_decode" "vector")])
2322 (define_expand "movstrict<mode>"
2323 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2324 (match_operand:SWI12 1 "general_operand"))]
2327 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2329 if (GET_CODE (operands[0]) == SUBREG
2330 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2332 /* Don't generate memory->memory moves, go through a register */
2333 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2334 operands[1] = force_reg (<MODE>mode, operands[1]);
2337 (define_insn "*movstrict<mode>_1"
2338 [(set (strict_low_part
2339 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2340 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2341 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2342 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2343 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2344 [(set_attr "type" "imov")
2345 (set_attr "mode" "<MODE>")])
2347 (define_insn "*movstrict<mode>_xor"
2348 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2349 (match_operand:SWI12 1 "const0_operand"))
2350 (clobber (reg:CC FLAGS_REG))]
2352 "xor{<imodesuffix>}\t%0, %0"
2353 [(set_attr "type" "alu1")
2354 (set_attr "mode" "<MODE>")
2355 (set_attr "length_immediate" "0")])
2357 (define_insn "*mov<mode>_extv_1"
2358 [(set (match_operand:SWI24 0 "register_operand" "=R")
2359 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2363 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2364 [(set_attr "type" "imovx")
2365 (set_attr "mode" "SI")])
2367 (define_insn "*movqi_extv_1"
2368 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2369 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2374 switch (get_attr_type (insn))
2377 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2379 return "mov{b}\t{%h1, %0|%0, %h1}";
2382 [(set_attr "isa" "*,*,nox64")
2384 (if_then_else (and (match_operand:QI 0 "register_operand")
2385 (ior (not (match_operand:QI 0 "QIreg_operand"))
2386 (match_test "TARGET_MOVX")))
2387 (const_string "imovx")
2388 (const_string "imov")))
2390 (if_then_else (eq_attr "type" "imovx")
2392 (const_string "QI")))])
2394 (define_insn "*mov<mode>_extzv_1"
2395 [(set (match_operand:SWI48 0 "register_operand" "=R")
2396 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2400 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2401 [(set_attr "type" "imovx")
2402 (set_attr "mode" "SI")])
2404 (define_insn "*movqi_extzv_2"
2405 [(set (match_operand:QI 0 "nonimmediate_x64nomem_operand" "=Q,?R,m")
2407 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q,Q")
2412 switch (get_attr_type (insn))
2415 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2417 return "mov{b}\t{%h1, %0|%0, %h1}";
2420 [(set_attr "isa" "*,*,nox64")
2422 (if_then_else (and (match_operand:QI 0 "register_operand")
2423 (ior (not (match_operand:QI 0 "QIreg_operand"))
2424 (match_test "TARGET_MOVX")))
2425 (const_string "imovx")
2426 (const_string "imov")))
2428 (if_then_else (eq_attr "type" "imovx")
2430 (const_string "QI")))])
2432 (define_insn "mov<mode>_insv_1"
2433 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "+Q,Q")
2436 (match_operand:SWI48 1 "general_x64nomem_operand" "Qn,m"))]
2439 if (CONST_INT_P (operands[1]))
2440 operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2441 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2443 [(set_attr "isa" "*,nox64")
2444 (set_attr "type" "imov")
2445 (set_attr "mode" "QI")])
2447 (define_insn "*movqi_insv_2"
2448 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2451 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2454 "mov{b}\t{%h1, %h0|%h0, %h1}"
2455 [(set_attr "type" "imov")
2456 (set_attr "mode" "QI")])
2458 ;; Floating point push instructions.
2460 (define_insn "*pushtf"
2461 [(set (match_operand:TF 0 "push_operand" "=<,<")
2462 (match_operand:TF 1 "general_no_elim_operand" "x,*roF"))]
2463 "TARGET_64BIT || TARGET_SSE"
2465 /* This insn should be already split before reg-stack. */
2468 [(set_attr "isa" "*,x64")
2469 (set_attr "type" "multi")
2470 (set_attr "unit" "sse,*")
2471 (set_attr "mode" "TF,DI")])
2473 ;; %%% Kill this when call knows how to work this out.
2475 [(set (match_operand:TF 0 "push_operand")
2476 (match_operand:TF 1 "sse_reg_operand"))]
2477 "TARGET_SSE && reload_completed"
2478 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2479 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2481 (define_insn "*pushxf"
2482 [(set (match_operand:XF 0 "push_operand" "=<,<")
2483 (match_operand:XF 1 "general_no_elim_operand" "f,Yx*roF"))]
2486 /* This insn should be already split before reg-stack. */
2489 [(set_attr "type" "multi")
2490 (set_attr "unit" "i387,*")
2492 (cond [(eq_attr "alternative" "1")
2493 (if_then_else (match_test "TARGET_64BIT")
2495 (const_string "SI"))
2497 (const_string "XF")))])
2499 ;; %%% Kill this when call knows how to work this out.
2501 [(set (match_operand:XF 0 "push_operand")
2502 (match_operand:XF 1 "fp_register_operand"))]
2504 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2505 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2506 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2508 (define_insn "*pushdf"
2509 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2510 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*roF,rmF,x"))]
2513 /* This insn should be already split before reg-stack. */
2516 [(set_attr "isa" "*,nox64,x64,sse2")
2517 (set_attr "type" "multi")
2518 (set_attr "unit" "i387,*,*,sse")
2519 (set_attr "mode" "DF,SI,DI,DF")])
2521 ;; %%% Kill this when call knows how to work this out.
2523 [(set (match_operand:DF 0 "push_operand")
2524 (match_operand:DF 1 "any_fp_register_operand"))]
2526 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2527 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2529 (define_insn "*pushsf_rex64"
2530 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2531 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2534 /* Anything else should be already split before reg-stack. */
2535 gcc_assert (which_alternative == 1);
2536 return "push{q}\t%q1";
2538 [(set_attr "type" "multi,push,multi")
2539 (set_attr "unit" "i387,*,*")
2540 (set_attr "mode" "SF,DI,SF")])
2542 (define_insn "*pushsf"
2543 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2544 (match_operand:SF 1 "general_no_elim_operand" "f,rmF,x"))]
2547 /* Anything else should be already split before reg-stack. */
2548 gcc_assert (which_alternative == 1);
2549 return "push{l}\t%1";
2551 [(set_attr "type" "multi,push,multi")
2552 (set_attr "unit" "i387,*,*")
2553 (set_attr "mode" "SF,SI,SF")])
2555 ;; %%% Kill this when call knows how to work this out.
2557 [(set (match_operand:SF 0 "push_operand")
2558 (match_operand:SF 1 "any_fp_register_operand"))]
2560 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2561 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2562 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2565 [(set (match_operand:SF 0 "push_operand")
2566 (match_operand:SF 1 "memory_operand"))]
2568 && (operands[2] = find_constant_src (insn))"
2569 [(set (match_dup 0) (match_dup 2))])
2572 [(set (match_operand 0 "push_operand")
2573 (match_operand 1 "general_operand"))]
2575 && (GET_MODE (operands[0]) == TFmode
2576 || GET_MODE (operands[0]) == XFmode
2577 || GET_MODE (operands[0]) == DFmode)
2578 && !ANY_FP_REG_P (operands[1])"
2580 "ix86_split_long_move (operands); DONE;")
2582 ;; Floating point move instructions.
2584 (define_expand "movtf"
2585 [(set (match_operand:TF 0 "nonimmediate_operand")
2586 (match_operand:TF 1 "nonimmediate_operand"))]
2587 "TARGET_64BIT || TARGET_SSE"
2588 "ix86_expand_move (TFmode, operands); DONE;")
2590 (define_expand "mov<mode>"
2591 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2592 (match_operand:X87MODEF 1 "general_operand"))]
2594 "ix86_expand_move (<MODE>mode, operands); DONE;")
2596 (define_insn "*movtf_internal"
2597 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,x ,m,?*r ,!o")
2598 (match_operand:TF 1 "general_operand" "C ,xm,x,*roF,*rC"))]
2599 "(TARGET_64BIT || TARGET_SSE)
2600 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2601 && (!can_create_pseudo_p ()
2602 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2603 || GET_CODE (operands[1]) != CONST_DOUBLE
2604 || (optimize_function_for_size_p (cfun)
2605 && standard_sse_constant_p (operands[1])
2606 && !memory_operand (operands[0], TFmode))
2607 || (!TARGET_MEMORY_MISMATCH_STALL
2608 && memory_operand (operands[0], TFmode)))"
2610 switch (get_attr_type (insn))
2613 return standard_sse_constant_opcode (insn, operands[1]);
2616 /* Handle misaligned load/store since we
2617 don't have movmisaligntf pattern. */
2618 if (misaligned_operand (operands[0], TFmode)
2619 || misaligned_operand (operands[1], TFmode))
2621 if (get_attr_mode (insn) == MODE_V4SF)
2622 return "%vmovups\t{%1, %0|%0, %1}";
2624 return "%vmovdqu\t{%1, %0|%0, %1}";
2628 if (get_attr_mode (insn) == MODE_V4SF)
2629 return "%vmovaps\t{%1, %0|%0, %1}";
2631 return "%vmovdqa\t{%1, %0|%0, %1}";
2641 [(set_attr "isa" "*,*,*,x64,x64")
2642 (set_attr "type" "sselog1,ssemov,ssemov,multi,multi")
2643 (set (attr "prefix")
2644 (if_then_else (eq_attr "type" "sselog1,ssemov")
2645 (const_string "maybe_vex")
2646 (const_string "orig")))
2648 (cond [(eq_attr "alternative" "3,4")
2650 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL")
2651 (const_string "V4SF")
2652 (and (eq_attr "alternative" "2")
2653 (match_test "TARGET_SSE_TYPELESS_STORES"))
2654 (const_string "V4SF")
2655 (match_test "TARGET_AVX")
2657 (ior (not (match_test "TARGET_SSE2"))
2658 (match_test "optimize_function_for_size_p (cfun)"))
2659 (const_string "V4SF")
2661 (const_string "TI")))])
2663 ;; Possible store forwarding (partial memory) stall in alternatives 4 and 5.
2664 (define_insn "*movxf_internal"
2665 [(set (match_operand:XF 0 "nonimmediate_operand"
2666 "=f,m,f,?Yx*r ,!o ,!o")
2667 (match_operand:XF 1 "general_operand"
2668 "fm,f,G,Yx*roF,Yx*rF,Yx*rC"))]
2669 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2670 && (!can_create_pseudo_p ()
2671 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2672 || GET_CODE (operands[1]) != CONST_DOUBLE
2673 || (optimize_function_for_size_p (cfun)
2674 && standard_80387_constant_p (operands[1]) > 0
2675 && !memory_operand (operands[0], XFmode))
2676 || (!TARGET_MEMORY_MISMATCH_STALL
2677 && memory_operand (operands[0], XFmode)))"
2679 switch (get_attr_type (insn))
2682 if (which_alternative == 2)
2683 return standard_80387_constant_opcode (operands[1]);
2684 return output_387_reg_move (insn, operands);
2693 [(set_attr "isa" "*,*,*,*,nox64,x64")
2694 (set_attr "type" "fmov,fmov,fmov,multi,multi,multi")
2696 (cond [(eq_attr "alternative" "3,4,5")
2697 (if_then_else (match_test "TARGET_64BIT")
2699 (const_string "SI"))
2701 (const_string "XF")))])
2703 ;; Possible store forwarding (partial memory) stall in alternative 4.
2704 (define_insn "*movdf_internal"
2705 [(set (match_operand:DF 0 "nonimmediate_operand"
2706 "=Yf*f,m ,Yf*f,?Yd*r ,!o ,?r,?m,?r,?r,x,x,x,m,*x,*x,*x,m ,r ,Yi")
2707 (match_operand:DF 1 "general_operand"
2708 "Yf*fm,Yf*f,G ,Yd*roF,Yd*rF,rm,rC,C ,F ,C,x,m,x,C ,*x,m ,*x,Yj,r"))]
2709 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2710 && (!can_create_pseudo_p ()
2711 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2712 || GET_CODE (operands[1]) != CONST_DOUBLE
2713 || (optimize_function_for_size_p (cfun)
2714 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2715 && standard_80387_constant_p (operands[1]) > 0)
2716 || (TARGET_SSE2 && TARGET_SSE_MATH
2717 && standard_sse_constant_p (operands[1])))
2718 && !memory_operand (operands[0], DFmode))
2719 || ((TARGET_64BIT || !TARGET_MEMORY_MISMATCH_STALL)
2720 && memory_operand (operands[0], DFmode)))"
2722 switch (get_attr_type (insn))
2725 if (which_alternative == 2)
2726 return standard_80387_constant_opcode (operands[1]);
2727 return output_387_reg_move (insn, operands);
2733 if (get_attr_mode (insn) == MODE_SI)
2734 return "mov{l}\t{%1, %k0|%k0, %1}";
2735 else if (which_alternative == 8)
2736 return "movabs{q}\t{%1, %0|%0, %1}";
2738 return "mov{q}\t{%1, %0|%0, %1}";
2741 return standard_sse_constant_opcode (insn, operands[1]);
2744 switch (get_attr_mode (insn))
2747 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2748 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2749 return "%vmovsd\t{%1, %0|%0, %1}";
2752 return "%vmovaps\t{%1, %0|%0, %1}";
2754 return "%vmovapd\t{%1, %0|%0, %1}";
2757 gcc_assert (!TARGET_AVX);
2758 return "movlps\t{%1, %0|%0, %1}";
2760 gcc_assert (!TARGET_AVX);
2761 return "movlpd\t{%1, %0|%0, %1}";
2764 #ifndef HAVE_AS_IX86_INTERUNIT_MOVQ
2765 /* Handle broken assemblers that require movd instead of movq. */
2766 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2767 return "%vmovd\t{%1, %0|%0, %1}";
2769 return "%vmovq\t{%1, %0|%0, %1}";
2780 (cond [(eq_attr "alternative" "3,4")
2781 (const_string "nox64")
2782 (eq_attr "alternative" "5,6,7,8,17,18")
2783 (const_string "x64")
2784 (eq_attr "alternative" "9,10,11,12")
2785 (const_string "sse2")
2787 (const_string "*")))
2789 (cond [(eq_attr "alternative" "0,1,2")
2790 (const_string "fmov")
2791 (eq_attr "alternative" "3,4")
2792 (const_string "multi")
2793 (eq_attr "alternative" "5,6,7,8")
2794 (const_string "imov")
2795 (eq_attr "alternative" "9,13")
2796 (const_string "sselog1")
2798 (const_string "ssemov")))
2800 (if_then_else (eq_attr "alternative" "8")
2802 (const_string "*")))
2803 (set (attr "length_immediate")
2804 (if_then_else (eq_attr "alternative" "8")
2806 (const_string "*")))
2807 (set (attr "prefix")
2808 (if_then_else (eq_attr "type" "sselog1,ssemov")
2809 (const_string "maybe_vex")
2810 (const_string "orig")))
2811 (set (attr "prefix_data16")
2813 (ior (and (eq_attr "type" "ssemov") (eq_attr "mode" "DI"))
2814 (eq_attr "mode" "V1DF"))
2816 (const_string "*")))
2818 (cond [(eq_attr "alternative" "3,4,7")
2820 (eq_attr "alternative" "5,6,8,17,18")
2823 /* xorps is one byte shorter for non-AVX targets. */
2824 (eq_attr "alternative" "9,13")
2825 (cond [(not (match_test "TARGET_SSE2"))
2826 (const_string "V4SF")
2827 (match_test "TARGET_AVX")
2828 (const_string "V2DF")
2829 (match_test "optimize_function_for_size_p (cfun)")
2830 (const_string "V4SF")
2831 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
2834 (const_string "V2DF"))
2836 /* For architectures resolving dependencies on
2837 whole SSE registers use movapd to break dependency
2838 chains, otherwise use short move to avoid extra work. */
2840 /* movaps is one byte shorter for non-AVX targets. */
2841 (eq_attr "alternative" "10,14")
2842 (cond [(ior (not (match_test "TARGET_SSE2"))
2843 (match_test "TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL"))
2844 (const_string "V4SF")
2845 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2846 (const_string "V2DF")
2847 (match_test "TARGET_AVX")
2849 (match_test "optimize_function_for_size_p (cfun)")
2850 (const_string "V4SF")
2852 (const_string "DF"))
2854 /* For architectures resolving dependencies on register
2855 parts we may avoid extra work to zero out upper part
2857 (eq_attr "alternative" "11,15")
2858 (cond [(not (match_test "TARGET_SSE2"))
2859 (const_string "V2SF")
2860 (match_test "TARGET_AVX")
2862 (match_test "TARGET_SSE_SPLIT_REGS")
2863 (const_string "V1DF")
2865 (const_string "DF"))
2867 (and (eq_attr "alternative" "12,16")
2868 (not (match_test "TARGET_SSE2")))
2869 (const_string "V2SF")
2871 (const_string "DF")))])
2873 (define_insn "*movsf_internal"
2874 [(set (match_operand:SF 0 "nonimmediate_operand"
2875 "=Yf*f,m ,Yf*f,?r ,?m,x,x,x,m,?r,?Yi,!*y,!*y,!m,!r ,!*Ym")
2876 (match_operand:SF 1 "general_operand"
2877 "Yf*fm,Yf*f,G ,rmF,rF,C,x,m,x,Yj,r ,*y ,m ,*y,*Yn,r"))]
2878 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2879 && (!can_create_pseudo_p ()
2880 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2881 || GET_CODE (operands[1]) != CONST_DOUBLE
2882 || (optimize_function_for_size_p (cfun)
2883 && ((!TARGET_SSE_MATH
2884 && standard_80387_constant_p (operands[1]) > 0)
2886 && standard_sse_constant_p (operands[1]))))
2887 || memory_operand (operands[0], SFmode))"
2889 switch (get_attr_type (insn))
2892 if (which_alternative == 2)
2893 return standard_80387_constant_opcode (operands[1]);
2894 return output_387_reg_move (insn, operands);
2897 return "mov{l}\t{%1, %0|%0, %1}";
2900 return standard_sse_constant_opcode (insn, operands[1]);
2903 switch (get_attr_mode (insn))
2906 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2907 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
2908 return "%vmovss\t{%1, %0|%0, %1}";
2911 return "%vmovaps\t{%1, %0|%0, %1}";
2914 return "%vmovd\t{%1, %0|%0, %1}";
2921 switch (get_attr_mode (insn))
2924 return "movq\t{%1, %0|%0, %1}";
2926 return "movd\t{%1, %0|%0, %1}";
2937 (cond [(eq_attr "alternative" "0,1,2")
2938 (const_string "fmov")
2939 (eq_attr "alternative" "3,4")
2940 (const_string "imov")
2941 (eq_attr "alternative" "5")
2942 (const_string "sselog1")
2943 (eq_attr "alternative" "11,12,13,14,15")
2944 (const_string "mmxmov")
2946 (const_string "ssemov")))
2947 (set (attr "prefix")
2948 (if_then_else (eq_attr "type" "sselog1,ssemov")
2949 (const_string "maybe_vex")
2950 (const_string "orig")))
2951 (set (attr "prefix_data16")
2952 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2954 (const_string "*")))
2956 (cond [(eq_attr "alternative" "3,4,9,10,14,15")
2958 (eq_attr "alternative" "11")
2960 (eq_attr "alternative" "5")
2961 (cond [(not (match_test "TARGET_SSE2"))
2962 (const_string "V4SF")
2963 (match_test "TARGET_AVX")
2964 (const_string "V4SF")
2965 (match_test "optimize_function_for_size_p (cfun)")
2966 (const_string "V4SF")
2967 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
2970 (const_string "V4SF"))
2972 /* For architectures resolving dependencies on
2973 whole SSE registers use APS move to break dependency
2974 chains, otherwise use short move to avoid extra work.
2976 Do the same for architectures resolving dependencies on
2977 the parts. While in DF mode it is better to always handle
2978 just register parts, the SF mode is different due to lack
2979 of instructions to load just part of the register. It is
2980 better to maintain the whole registers in single format
2981 to avoid problems on using packed logical operations. */
2982 (and (eq_attr "alternative" "6")
2983 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2984 (match_test "TARGET_SSE_SPLIT_REGS")))
2985 (const_string "V4SF")
2987 (const_string "SF")))])
2990 [(set (match_operand 0 "any_fp_register_operand")
2991 (match_operand 1 "memory_operand"))]
2993 && (GET_MODE (operands[0]) == TFmode
2994 || GET_MODE (operands[0]) == XFmode
2995 || GET_MODE (operands[0]) == DFmode
2996 || GET_MODE (operands[0]) == SFmode)
2997 && (operands[2] = find_constant_src (insn))"
2998 [(set (match_dup 0) (match_dup 2))]
3000 rtx c = operands[2];
3001 int r = REGNO (operands[0]);
3003 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3004 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3009 [(set (match_operand 0 "any_fp_register_operand")
3010 (float_extend (match_operand 1 "memory_operand")))]
3012 && (GET_MODE (operands[0]) == TFmode
3013 || GET_MODE (operands[0]) == XFmode
3014 || GET_MODE (operands[0]) == DFmode)
3015 && (operands[2] = find_constant_src (insn))"
3016 [(set (match_dup 0) (match_dup 2))]
3018 rtx c = operands[2];
3019 int r = REGNO (operands[0]);
3021 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3022 || (STACK_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3026 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3028 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3029 (match_operand:X87MODEF 1 "immediate_operand"))]
3031 && (standard_80387_constant_p (operands[1]) == 8
3032 || standard_80387_constant_p (operands[1]) == 9)"
3033 [(set (match_dup 0)(match_dup 1))
3035 (neg:X87MODEF (match_dup 0)))]
3039 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3040 if (real_isnegzero (&r))
3041 operands[1] = CONST0_RTX (<MODE>mode);
3043 operands[1] = CONST1_RTX (<MODE>mode);
3047 [(set (match_operand 0 "nonimmediate_operand")
3048 (match_operand 1 "general_operand"))]
3050 && (GET_MODE (operands[0]) == TFmode
3051 || GET_MODE (operands[0]) == XFmode
3052 || GET_MODE (operands[0]) == DFmode)
3053 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3055 "ix86_split_long_move (operands); DONE;")
3057 (define_insn "swapxf"
3058 [(set (match_operand:XF 0 "register_operand" "+f")
3059 (match_operand:XF 1 "register_operand" "+f"))
3064 if (STACK_TOP_P (operands[0]))
3069 [(set_attr "type" "fxch")
3070 (set_attr "mode" "XF")])
3072 (define_insn "*swap<mode>"
3073 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3074 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3077 "TARGET_80387 || reload_completed"
3079 if (STACK_TOP_P (operands[0]))
3084 [(set_attr "type" "fxch")
3085 (set_attr "mode" "<MODE>")])
3087 ;; Zero extension instructions
3089 (define_expand "zero_extendsidi2"
3090 [(set (match_operand:DI 0 "nonimmediate_operand")
3091 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3093 (define_insn "*zero_extendsidi2"
3094 [(set (match_operand:DI 0 "nonimmediate_operand"
3095 "=r,?r,?o,r ,o,?*Ym,?!*y,?r ,?r,?*Yi,?*x")
3097 (match_operand:SI 1 "x86_64_zext_operand"
3098 "0 ,rm,r ,rmWz,0,r ,m ,*Yj,*x,r ,m")))]
3101 switch (get_attr_type (insn))
3104 if (ix86_use_lea_for_mov (insn, operands))
3105 return "lea{l}\t{%E1, %k0|%k0, %E1}";
3107 return "mov{l}\t{%1, %k0|%k0, %1}";
3113 return "movd\t{%1, %0|%0, %1}";
3116 return "%vpextrd\t{$0, %1, %k0|%k0, %1, 0}";
3119 if (GENERAL_REG_P (operands[0]))
3120 return "%vmovd\t{%1, %k0|%k0, %1}";
3122 return "%vmovd\t{%1, %0|%0, %1}";
3129 (cond [(eq_attr "alternative" "0,1,2")
3130 (const_string "nox64")
3131 (eq_attr "alternative" "3,7")
3132 (const_string "x64")
3133 (eq_attr "alternative" "8")
3134 (const_string "x64_sse4")
3135 (eq_attr "alternative" "10")
3136 (const_string "sse2")
3138 (const_string "*")))
3140 (cond [(eq_attr "alternative" "0,1,2,4")
3141 (const_string "multi")
3142 (eq_attr "alternative" "5,6")
3143 (const_string "mmxmov")
3144 (eq_attr "alternative" "7,9,10")
3145 (const_string "ssemov")
3146 (eq_attr "alternative" "8")
3147 (const_string "sselog1")
3149 (const_string "imovx")))
3150 (set (attr "prefix_extra")
3151 (if_then_else (eq_attr "alternative" "8")
3153 (const_string "*")))
3154 (set (attr "length_immediate")
3155 (if_then_else (eq_attr "alternative" "8")
3157 (const_string "*")))
3158 (set (attr "prefix")
3159 (if_then_else (eq_attr "type" "ssemov,sselog1")
3160 (const_string "maybe_vex")
3161 (const_string "orig")))
3162 (set (attr "prefix_0f")
3163 (if_then_else (eq_attr "type" "imovx")
3165 (const_string "*")))
3167 (cond [(eq_attr "alternative" "5,6")
3169 (eq_attr "alternative" "7,8,9")
3172 (const_string "SI")))])
3175 [(set (match_operand:DI 0 "memory_operand")
3176 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3178 [(set (match_dup 4) (const_int 0))]
3179 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3182 [(set (match_operand:DI 0 "register_operand")
3183 (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3184 "!TARGET_64BIT && reload_completed
3185 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3186 && true_regnum (operands[0]) == true_regnum (operands[1])"
3187 [(set (match_dup 4) (const_int 0))]
3188 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3191 [(set (match_operand:DI 0 "nonimmediate_operand")
3192 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3193 "!TARGET_64BIT && reload_completed
3194 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3195 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3196 [(set (match_dup 3) (match_dup 1))
3197 (set (match_dup 4) (const_int 0))]
3198 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3200 (define_insn "zero_extend<mode>di2"
3201 [(set (match_operand:DI 0 "register_operand" "=r")
3203 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3205 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3206 [(set_attr "type" "imovx")
3207 (set_attr "mode" "SI")])
3209 (define_expand "zero_extend<mode>si2"
3210 [(set (match_operand:SI 0 "register_operand")
3211 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3214 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3216 operands[1] = force_reg (<MODE>mode, operands[1]);
3217 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3222 (define_insn_and_split "zero_extend<mode>si2_and"
3223 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3225 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3226 (clobber (reg:CC FLAGS_REG))]
3227 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3229 "&& reload_completed"
3230 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3231 (clobber (reg:CC FLAGS_REG))])]
3233 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3235 ix86_expand_clear (operands[0]);
3237 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3238 emit_insn (gen_movstrict<mode>
3239 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3243 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3245 [(set_attr "type" "alu1")
3246 (set_attr "mode" "SI")])
3248 (define_insn "*zero_extend<mode>si2"
3249 [(set (match_operand:SI 0 "register_operand" "=r")
3251 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3252 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3253 "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3254 [(set_attr "type" "imovx")
3255 (set_attr "mode" "SI")])
3257 (define_expand "zero_extendqihi2"
3258 [(set (match_operand:HI 0 "register_operand")
3259 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3262 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3264 operands[1] = force_reg (QImode, operands[1]);
3265 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3270 (define_insn_and_split "zero_extendqihi2_and"
3271 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3272 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3273 (clobber (reg:CC FLAGS_REG))]
3274 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3276 "&& reload_completed"
3277 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3278 (clobber (reg:CC FLAGS_REG))])]
3280 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3282 ix86_expand_clear (operands[0]);
3284 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3285 emit_insn (gen_movstrictqi
3286 (gen_lowpart (QImode, operands[0]), operands[1]));
3290 operands[0] = gen_lowpart (SImode, operands[0]);
3292 [(set_attr "type" "alu1")
3293 (set_attr "mode" "SI")])
3295 ; zero extend to SImode to avoid partial register stalls
3296 (define_insn "*zero_extendqihi2"
3297 [(set (match_operand:HI 0 "register_operand" "=r")
3298 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3299 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3300 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3301 [(set_attr "type" "imovx")
3302 (set_attr "mode" "SI")])
3304 ;; Sign extension instructions
3306 (define_expand "extendsidi2"
3307 [(set (match_operand:DI 0 "register_operand")
3308 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3313 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3318 (define_insn "*extendsidi2_rex64"
3319 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3320 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3324 movs{lq|x}\t{%1, %0|%0, %1}"
3325 [(set_attr "type" "imovx")
3326 (set_attr "mode" "DI")
3327 (set_attr "prefix_0f" "0")
3328 (set_attr "modrm" "0,1")])
3330 (define_insn "extendsidi2_1"
3331 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3332 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3333 (clobber (reg:CC FLAGS_REG))
3334 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3338 ;; Split the memory case. If the source register doesn't die, it will stay
3339 ;; this way, if it does die, following peephole2s take care of it.
3341 [(set (match_operand:DI 0 "memory_operand")
3342 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3343 (clobber (reg:CC FLAGS_REG))
3344 (clobber (match_operand:SI 2 "register_operand"))]
3348 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3350 emit_move_insn (operands[3], operands[1]);
3352 /* Generate a cltd if possible and doing so it profitable. */
3353 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3354 && true_regnum (operands[1]) == AX_REG
3355 && true_regnum (operands[2]) == DX_REG)
3357 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3361 emit_move_insn (operands[2], operands[1]);
3362 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3364 emit_move_insn (operands[4], operands[2]);
3368 ;; Peepholes for the case where the source register does die, after
3369 ;; being split with the above splitter.
3371 [(set (match_operand:SI 0 "memory_operand")
3372 (match_operand:SI 1 "register_operand"))
3373 (set (match_operand:SI 2 "register_operand") (match_dup 1))
3374 (parallel [(set (match_dup 2)
3375 (ashiftrt:SI (match_dup 2) (const_int 31)))
3376 (clobber (reg:CC FLAGS_REG))])
3377 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3378 "REGNO (operands[1]) != REGNO (operands[2])
3379 && peep2_reg_dead_p (2, operands[1])
3380 && peep2_reg_dead_p (4, operands[2])
3381 && !reg_mentioned_p (operands[2], operands[3])"
3382 [(set (match_dup 0) (match_dup 1))
3383 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3384 (clobber (reg:CC FLAGS_REG))])
3385 (set (match_dup 3) (match_dup 1))])
3388 [(set (match_operand:SI 0 "memory_operand")
3389 (match_operand:SI 1 "register_operand"))
3390 (parallel [(set (match_operand:SI 2 "register_operand")
3391 (ashiftrt:SI (match_dup 1) (const_int 31)))
3392 (clobber (reg:CC FLAGS_REG))])
3393 (set (match_operand:SI 3 "memory_operand") (match_dup 2))]
3394 "/* cltd is shorter than sarl $31, %eax */
3395 !optimize_function_for_size_p (cfun)
3396 && true_regnum (operands[1]) == AX_REG
3397 && true_regnum (operands[2]) == DX_REG
3398 && peep2_reg_dead_p (2, operands[1])
3399 && peep2_reg_dead_p (3, operands[2])
3400 && !reg_mentioned_p (operands[2], operands[3])"
3401 [(set (match_dup 0) (match_dup 1))
3402 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3403 (clobber (reg:CC FLAGS_REG))])
3404 (set (match_dup 3) (match_dup 1))])
3406 ;; Extend to register case. Optimize case where source and destination
3407 ;; registers match and cases where we can use cltd.
3409 [(set (match_operand:DI 0 "register_operand")
3410 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3411 (clobber (reg:CC FLAGS_REG))
3412 (clobber (match_scratch:SI 2))]
3416 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3418 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3419 emit_move_insn (operands[3], operands[1]);
3421 /* Generate a cltd if possible and doing so it profitable. */
3422 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3423 && true_regnum (operands[3]) == AX_REG
3424 && true_regnum (operands[4]) == DX_REG)
3426 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3430 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3431 emit_move_insn (operands[4], operands[1]);
3433 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3437 (define_insn "extend<mode>di2"
3438 [(set (match_operand:DI 0 "register_operand" "=r")
3440 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3442 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3443 [(set_attr "type" "imovx")
3444 (set_attr "mode" "DI")])
3446 (define_insn "extendhisi2"
3447 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3448 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3451 switch (get_attr_prefix_0f (insn))
3454 return "{cwtl|cwde}";
3456 return "movs{wl|x}\t{%1, %0|%0, %1}";
3459 [(set_attr "type" "imovx")
3460 (set_attr "mode" "SI")
3461 (set (attr "prefix_0f")
3462 ;; movsx is short decodable while cwtl is vector decoded.
3463 (if_then_else (and (eq_attr "cpu" "!k6")
3464 (eq_attr "alternative" "0"))
3466 (const_string "1")))
3468 (if_then_else (eq_attr "prefix_0f" "0")
3470 (const_string "1")))])
3472 (define_insn "*extendhisi2_zext"
3473 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3476 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3479 switch (get_attr_prefix_0f (insn))
3482 return "{cwtl|cwde}";
3484 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3487 [(set_attr "type" "imovx")
3488 (set_attr "mode" "SI")
3489 (set (attr "prefix_0f")
3490 ;; movsx is short decodable while cwtl is vector decoded.
3491 (if_then_else (and (eq_attr "cpu" "!k6")
3492 (eq_attr "alternative" "0"))
3494 (const_string "1")))
3496 (if_then_else (eq_attr "prefix_0f" "0")
3498 (const_string "1")))])
3500 (define_insn "extendqisi2"
3501 [(set (match_operand:SI 0 "register_operand" "=r")
3502 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3504 "movs{bl|x}\t{%1, %0|%0, %1}"
3505 [(set_attr "type" "imovx")
3506 (set_attr "mode" "SI")])
3508 (define_insn "*extendqisi2_zext"
3509 [(set (match_operand:DI 0 "register_operand" "=r")
3511 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3513 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3514 [(set_attr "type" "imovx")
3515 (set_attr "mode" "SI")])
3517 (define_insn "extendqihi2"
3518 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3519 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3522 switch (get_attr_prefix_0f (insn))
3525 return "{cbtw|cbw}";
3527 return "movs{bw|x}\t{%1, %0|%0, %1}";
3530 [(set_attr "type" "imovx")
3531 (set_attr "mode" "HI")
3532 (set (attr "prefix_0f")
3533 ;; movsx is short decodable while cwtl is vector decoded.
3534 (if_then_else (and (eq_attr "cpu" "!k6")
3535 (eq_attr "alternative" "0"))
3537 (const_string "1")))
3539 (if_then_else (eq_attr "prefix_0f" "0")
3541 (const_string "1")))])
3543 ;; Conversions between float and double.
3545 ;; These are all no-ops in the model used for the 80387.
3546 ;; So just emit moves.
3548 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3550 [(set (match_operand:DF 0 "push_operand")
3551 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3553 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3554 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3557 [(set (match_operand:XF 0 "push_operand")
3558 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3560 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3561 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3562 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3564 (define_expand "extendsfdf2"
3565 [(set (match_operand:DF 0 "nonimmediate_operand")
3566 (float_extend:DF (match_operand:SF 1 "general_operand")))]
3567 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3569 /* ??? Needed for compress_float_constant since all fp constants
3570 are TARGET_LEGITIMATE_CONSTANT_P. */
3571 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3573 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3574 && standard_80387_constant_p (operands[1]) > 0)
3576 operands[1] = simplify_const_unary_operation
3577 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3578 emit_move_insn_1 (operands[0], operands[1]);
3581 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3585 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3587 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3589 We do the conversion post reload to avoid producing of 128bit spills
3590 that might lead to ICE on 32bit target. The sequence unlikely combine
3593 [(set (match_operand:DF 0 "register_operand")
3595 (match_operand:SF 1 "nonimmediate_operand")))]
3596 "TARGET_USE_VECTOR_FP_CONVERTS
3597 && optimize_insn_for_speed_p ()
3598 && reload_completed && SSE_REG_P (operands[0])"
3603 (parallel [(const_int 0) (const_int 1)]))))]
3605 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3606 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3607 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3608 Try to avoid move when unpacking can be done in source. */
3609 if (REG_P (operands[1]))
3611 /* If it is unsafe to overwrite upper half of source, we need
3612 to move to destination and unpack there. */
3613 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3614 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3615 && true_regnum (operands[0]) != true_regnum (operands[1]))
3617 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3618 emit_move_insn (tmp, operands[1]);
3621 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3622 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3626 emit_insn (gen_vec_setv4sf_0 (operands[3],
3627 CONST0_RTX (V4SFmode), operands[1]));
3630 ;; It's more profitable to split and then extend in the same register.
3632 [(set (match_operand:DF 0 "register_operand")
3634 (match_operand:SF 1 "memory_operand")))]
3635 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
3636 && optimize_insn_for_speed_p ()
3637 && SSE_REG_P (operands[0])"
3638 [(set (match_dup 2) (match_dup 1))
3639 (set (match_dup 0) (float_extend:DF (match_dup 2)))]
3640 "operands[2] = gen_rtx_REG (SFmode, REGNO (operands[0]));")
3642 (define_insn "*extendsfdf2_mixed"
3643 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3645 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3646 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3648 switch (which_alternative)
3652 return output_387_reg_move (insn, operands);
3655 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3661 [(set_attr "type" "fmov,fmov,ssecvt")
3662 (set_attr "prefix" "orig,orig,maybe_vex")
3663 (set_attr "mode" "SF,XF,DF")])
3665 (define_insn "*extendsfdf2_sse"
3666 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3667 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3668 "TARGET_SSE2 && TARGET_SSE_MATH"
3669 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3670 [(set_attr "type" "ssecvt")
3671 (set_attr "prefix" "maybe_vex")
3672 (set_attr "mode" "DF")])
3674 (define_insn "*extendsfdf2_i387"
3675 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3676 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3678 "* return output_387_reg_move (insn, operands);"
3679 [(set_attr "type" "fmov")
3680 (set_attr "mode" "SF,XF")])
3682 (define_expand "extend<mode>xf2"
3683 [(set (match_operand:XF 0 "nonimmediate_operand")
3684 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
3687 /* ??? Needed for compress_float_constant since all fp constants
3688 are TARGET_LEGITIMATE_CONSTANT_P. */
3689 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3691 if (standard_80387_constant_p (operands[1]) > 0)
3693 operands[1] = simplify_const_unary_operation
3694 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3695 emit_move_insn_1 (operands[0], operands[1]);
3698 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3702 (define_insn "*extend<mode>xf2_i387"
3703 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3705 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3707 "* return output_387_reg_move (insn, operands);"
3708 [(set_attr "type" "fmov")
3709 (set_attr "mode" "<MODE>,XF")])
3711 ;; %%% This seems bad bad news.
3712 ;; This cannot output into an f-reg because there is no way to be sure
3713 ;; of truncating in that case. Otherwise this is just like a simple move
3714 ;; insn. So we pretend we can output to a reg in order to get better
3715 ;; register preferencing, but we really use a stack slot.
3717 ;; Conversion from DFmode to SFmode.
3719 (define_expand "truncdfsf2"
3720 [(set (match_operand:SF 0 "nonimmediate_operand")
3722 (match_operand:DF 1 "nonimmediate_operand")))]
3723 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3725 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3727 else if (flag_unsafe_math_optimizations)
3731 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3732 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3737 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
3739 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3741 We do the conversion post reload to avoid producing of 128bit spills
3742 that might lead to ICE on 32bit target. The sequence unlikely combine
3745 [(set (match_operand:SF 0 "register_operand")
3747 (match_operand:DF 1 "nonimmediate_operand")))]
3748 "TARGET_USE_VECTOR_FP_CONVERTS
3749 && optimize_insn_for_speed_p ()
3750 && reload_completed && SSE_REG_P (operands[0])"
3753 (float_truncate:V2SF
3757 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3758 operands[3] = CONST0_RTX (V2SFmode);
3759 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
3760 /* Use movsd for loading from memory, unpcklpd for registers.
3761 Try to avoid move when unpacking can be done in source, or SSE3
3762 movddup is available. */
3763 if (REG_P (operands[1]))
3766 && true_regnum (operands[0]) != true_regnum (operands[1])
3767 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3768 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
3770 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
3771 emit_move_insn (tmp, operands[1]);
3774 else if (!TARGET_SSE3)
3775 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3776 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
3779 emit_insn (gen_sse2_loadlpd (operands[4],
3780 CONST0_RTX (V2DFmode), operands[1]));
3783 ;; It's more profitable to split and then extend in the same register.
3785 [(set (match_operand:SF 0 "register_operand")
3787 (match_operand:DF 1 "memory_operand")))]
3788 "TARGET_SPLIT_MEM_OPND_FOR_FP_CONVERTS
3789 && optimize_insn_for_speed_p ()
3790 && SSE_REG_P (operands[0])"
3791 [(set (match_dup 2) (match_dup 1))
3792 (set (match_dup 0) (float_truncate:SF (match_dup 2)))]
3793 "operands[2] = gen_rtx_REG (DFmode, REGNO (operands[0]));")
3795 (define_expand "truncdfsf2_with_temp"
3796 [(parallel [(set (match_operand:SF 0)
3797 (float_truncate:SF (match_operand:DF 1)))
3798 (clobber (match_operand:SF 2))])])
3800 (define_insn "*truncdfsf_fast_mixed"
3801 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
3803 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
3804 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
3806 switch (which_alternative)
3809 return output_387_reg_move (insn, operands);
3811 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
3816 [(set_attr "type" "fmov,ssecvt")
3817 (set_attr "prefix" "orig,maybe_vex")
3818 (set_attr "mode" "SF")])
3820 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
3821 ;; because nothing we do here is unsafe.
3822 (define_insn "*truncdfsf_fast_sse"
3823 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
3825 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
3826 "TARGET_SSE2 && TARGET_SSE_MATH"
3827 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
3828 [(set_attr "type" "ssecvt")
3829 (set_attr "prefix" "maybe_vex")
3830 (set_attr "mode" "SF")])
3832 (define_insn "*truncdfsf_fast_i387"
3833 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
3835 (match_operand:DF 1 "nonimmediate_operand" "f")))]
3836 "TARGET_80387 && flag_unsafe_math_optimizations"
3837 "* return output_387_reg_move (insn, operands);"
3838 [(set_attr "type" "fmov")
3839 (set_attr "mode" "SF")])
3841 (define_insn "*truncdfsf_mixed"
3842 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
3844 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
3845 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
3846 "TARGET_MIX_SSE_I387"
3848 switch (which_alternative)
3851 return output_387_reg_move (insn, operands);
3853 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
3859 [(set_attr "isa" "*,sse2,*,*,*")
3860 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
3861 (set_attr "unit" "*,*,i387,i387,i387")
3862 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
3863 (set_attr "mode" "SF")])
3865 (define_insn "*truncdfsf_i387"
3866 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
3868 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
3869 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
3872 switch (which_alternative)
3875 return output_387_reg_move (insn, operands);
3881 [(set_attr "type" "fmov,multi,multi,multi")
3882 (set_attr "unit" "*,i387,i387,i387")
3883 (set_attr "mode" "SF")])
3885 (define_insn "*truncdfsf2_i387_1"
3886 [(set (match_operand:SF 0 "memory_operand" "=m")
3888 (match_operand:DF 1 "register_operand" "f")))]
3890 && !(TARGET_SSE2 && TARGET_SSE_MATH)
3891 && !TARGET_MIX_SSE_I387"
3892 "* return output_387_reg_move (insn, operands);"
3893 [(set_attr "type" "fmov")
3894 (set_attr "mode" "SF")])
3897 [(set (match_operand:SF 0 "register_operand")
3899 (match_operand:DF 1 "fp_register_operand")))
3900 (clobber (match_operand 2))]
3902 [(set (match_dup 2) (match_dup 1))
3903 (set (match_dup 0) (match_dup 2))]
3904 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
3906 ;; Conversion from XFmode to {SF,DF}mode
3908 (define_expand "truncxf<mode>2"
3909 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
3910 (float_truncate:MODEF
3911 (match_operand:XF 1 "register_operand")))
3912 (clobber (match_dup 2))])]
3915 if (flag_unsafe_math_optimizations)
3917 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
3918 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
3919 if (reg != operands[0])
3920 emit_move_insn (operands[0], reg);
3924 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
3927 (define_insn "*truncxfsf2_mixed"
3928 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
3930 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
3931 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
3934 gcc_assert (!which_alternative);
3935 return output_387_reg_move (insn, operands);
3937 [(set_attr "type" "fmov,multi,multi,multi")
3938 (set_attr "unit" "*,i387,i387,i387")
3939 (set_attr "mode" "SF")])
3941 (define_insn "*truncxfdf2_mixed"
3942 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
3944 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
3945 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
3948 gcc_assert (!which_alternative);
3949 return output_387_reg_move (insn, operands);
3951 [(set_attr "isa" "*,*,sse2,*")
3952 (set_attr "type" "fmov,multi,multi,multi")
3953 (set_attr "unit" "*,i387,i387,i387")
3954 (set_attr "mode" "DF")])
3956 (define_insn "truncxf<mode>2_i387_noop"
3957 [(set (match_operand:MODEF 0 "register_operand" "=f")
3958 (float_truncate:MODEF
3959 (match_operand:XF 1 "register_operand" "f")))]
3960 "TARGET_80387 && flag_unsafe_math_optimizations"
3961 "* return output_387_reg_move (insn, operands);"
3962 [(set_attr "type" "fmov")
3963 (set_attr "mode" "<MODE>")])
3965 (define_insn "*truncxf<mode>2_i387"
3966 [(set (match_operand:MODEF 0 "memory_operand" "=m")
3967 (float_truncate:MODEF
3968 (match_operand:XF 1 "register_operand" "f")))]
3970 "* return output_387_reg_move (insn, operands);"
3971 [(set_attr "type" "fmov")
3972 (set_attr "mode" "<MODE>")])
3975 [(set (match_operand:MODEF 0 "register_operand")
3976 (float_truncate:MODEF
3977 (match_operand:XF 1 "register_operand")))
3978 (clobber (match_operand:MODEF 2 "memory_operand"))]
3979 "TARGET_80387 && reload_completed"
3980 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
3981 (set (match_dup 0) (match_dup 2))])
3984 [(set (match_operand:MODEF 0 "memory_operand")
3985 (float_truncate:MODEF
3986 (match_operand:XF 1 "register_operand")))
3987 (clobber (match_operand:MODEF 2 "memory_operand"))]
3989 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
3991 ;; Signed conversion to DImode.
3993 (define_expand "fix_truncxfdi2"
3994 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
3995 (fix:DI (match_operand:XF 1 "register_operand")))
3996 (clobber (reg:CC FLAGS_REG))])]
4001 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4006 (define_expand "fix_trunc<mode>di2"
4007 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4008 (fix:DI (match_operand:MODEF 1 "register_operand")))
4009 (clobber (reg:CC FLAGS_REG))])]
4010 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4013 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4015 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4018 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4020 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4021 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4022 if (out != operands[0])
4023 emit_move_insn (operands[0], out);
4028 ;; Signed conversion to SImode.
4030 (define_expand "fix_truncxfsi2"
4031 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4032 (fix:SI (match_operand:XF 1 "register_operand")))
4033 (clobber (reg:CC FLAGS_REG))])]
4038 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4043 (define_expand "fix_trunc<mode>si2"
4044 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4045 (fix:SI (match_operand:MODEF 1 "register_operand")))
4046 (clobber (reg:CC FLAGS_REG))])]
4047 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4050 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4052 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4055 if (SSE_FLOAT_MODE_P (<MODE>mode))
4057 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4058 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4059 if (out != operands[0])
4060 emit_move_insn (operands[0], out);
4065 ;; Signed conversion to HImode.
4067 (define_expand "fix_trunc<mode>hi2"
4068 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4069 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4070 (clobber (reg:CC FLAGS_REG))])]
4072 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4076 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4081 ;; Unsigned conversion to SImode.
4083 (define_expand "fixuns_trunc<mode>si2"
4085 [(set (match_operand:SI 0 "register_operand")
4087 (match_operand:MODEF 1 "nonimmediate_operand")))
4089 (clobber (match_scratch:<ssevecmode> 3))
4090 (clobber (match_scratch:<ssevecmode> 4))])]
4091 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4093 enum machine_mode mode = <MODE>mode;
4094 enum machine_mode vecmode = <ssevecmode>mode;
4095 REAL_VALUE_TYPE TWO31r;
4098 if (optimize_insn_for_size_p ())
4101 real_ldexp (&TWO31r, &dconst1, 31);
4102 two31 = const_double_from_real_value (TWO31r, mode);
4103 two31 = ix86_build_const_vector (vecmode, true, two31);
4104 operands[2] = force_reg (vecmode, two31);
4107 (define_insn_and_split "*fixuns_trunc<mode>_1"
4108 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4110 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4111 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4112 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4113 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4114 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4115 && optimize_function_for_speed_p (cfun)"
4117 "&& reload_completed"
4120 ix86_split_convert_uns_si_sse (operands);
4124 ;; Unsigned conversion to HImode.
4125 ;; Without these patterns, we'll try the unsigned SI conversion which
4126 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4128 (define_expand "fixuns_trunc<mode>hi2"
4130 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4131 (set (match_operand:HI 0 "nonimmediate_operand")
4132 (subreg:HI (match_dup 2) 0))]
4133 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4134 "operands[2] = gen_reg_rtx (SImode);")
4136 ;; When SSE is available, it is always faster to use it!
4137 (define_insn "fix_trunc<MODEF:mode><SWI48:mode>_sse"
4138 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
4139 (fix:SWI48 (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4140 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4141 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4142 "%vcvtt<MODEF:ssemodesuffix>2si<SWI48:rex64suffix>\t{%1, %0|%0, %1}"
4143 [(set_attr "type" "sseicvt")
4144 (set_attr "prefix" "maybe_vex")
4145 (set (attr "prefix_rex")
4147 (match_test "<SWI48:MODE>mode == DImode")
4149 (const_string "*")))
4150 (set_attr "mode" "<MODEF:MODE>")
4151 (set_attr "athlon_decode" "double,vector")
4152 (set_attr "amdfam10_decode" "double,double")
4153 (set_attr "bdver1_decode" "double,double")])
4155 ;; Avoid vector decoded forms of the instruction.
4157 [(match_scratch:MODEF 2 "x")
4158 (set (match_operand:SWI48 0 "register_operand")
4159 (fix:SWI48 (match_operand:MODEF 1 "memory_operand")))]
4160 "TARGET_AVOID_VECTOR_DECODE
4161 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode)
4162 && optimize_insn_for_speed_p ()"
4163 [(set (match_dup 2) (match_dup 1))
4164 (set (match_dup 0) (fix:SWI48 (match_dup 2)))])
4166 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4167 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4168 (fix:SWI248x (match_operand 1 "register_operand")))]
4169 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4171 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4172 && (TARGET_64BIT || <MODE>mode != DImode))
4174 && can_create_pseudo_p ()"
4179 if (memory_operand (operands[0], VOIDmode))
4180 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4183 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4184 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4190 [(set_attr "type" "fisttp")
4191 (set_attr "mode" "<MODE>")])
4193 (define_insn "fix_trunc<mode>_i387_fisttp"
4194 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4195 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4196 (clobber (match_scratch:XF 2 "=&1f"))]
4197 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4199 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4200 && (TARGET_64BIT || <MODE>mode != DImode))
4201 && TARGET_SSE_MATH)"
4202 "* return output_fix_trunc (insn, operands, true);"
4203 [(set_attr "type" "fisttp")
4204 (set_attr "mode" "<MODE>")])
4206 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4207 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4208 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4209 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4210 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4211 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4213 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4214 && (TARGET_64BIT || <MODE>mode != DImode))
4215 && TARGET_SSE_MATH)"
4217 [(set_attr "type" "fisttp")
4218 (set_attr "mode" "<MODE>")])
4221 [(set (match_operand:SWI248x 0 "register_operand")
4222 (fix:SWI248x (match_operand 1 "register_operand")))
4223 (clobber (match_operand:SWI248x 2 "memory_operand"))
4224 (clobber (match_scratch 3))]
4226 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4227 (clobber (match_dup 3))])
4228 (set (match_dup 0) (match_dup 2))])
4231 [(set (match_operand:SWI248x 0 "memory_operand")
4232 (fix:SWI248x (match_operand 1 "register_operand")))
4233 (clobber (match_operand:SWI248x 2 "memory_operand"))
4234 (clobber (match_scratch 3))]
4236 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4237 (clobber (match_dup 3))])])
4239 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4240 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4241 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4242 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4243 ;; function in i386.c.
4244 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4245 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4246 (fix:SWI248x (match_operand 1 "register_operand")))
4247 (clobber (reg:CC FLAGS_REG))]
4248 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4250 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4251 && (TARGET_64BIT || <MODE>mode != DImode))
4252 && can_create_pseudo_p ()"
4257 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4259 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4260 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4261 if (memory_operand (operands[0], VOIDmode))
4262 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4263 operands[2], operands[3]));
4266 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4267 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4268 operands[2], operands[3],
4273 [(set_attr "type" "fistp")
4274 (set_attr "i387_cw" "trunc")
4275 (set_attr "mode" "<MODE>")])
4277 (define_insn "fix_truncdi_i387"
4278 [(set (match_operand:DI 0 "memory_operand" "=m")
4279 (fix:DI (match_operand 1 "register_operand" "f")))
4280 (use (match_operand:HI 2 "memory_operand" "m"))
4281 (use (match_operand:HI 3 "memory_operand" "m"))
4282 (clobber (match_scratch:XF 4 "=&1f"))]
4283 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4285 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4286 "* return output_fix_trunc (insn, operands, false);"
4287 [(set_attr "type" "fistp")
4288 (set_attr "i387_cw" "trunc")
4289 (set_attr "mode" "DI")])
4291 (define_insn "fix_truncdi_i387_with_temp"
4292 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4293 (fix:DI (match_operand 1 "register_operand" "f,f")))
4294 (use (match_operand:HI 2 "memory_operand" "m,m"))
4295 (use (match_operand:HI 3 "memory_operand" "m,m"))
4296 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4297 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4298 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4300 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4302 [(set_attr "type" "fistp")
4303 (set_attr "i387_cw" "trunc")
4304 (set_attr "mode" "DI")])
4307 [(set (match_operand:DI 0 "register_operand")
4308 (fix:DI (match_operand 1 "register_operand")))
4309 (use (match_operand:HI 2 "memory_operand"))
4310 (use (match_operand:HI 3 "memory_operand"))
4311 (clobber (match_operand:DI 4 "memory_operand"))
4312 (clobber (match_scratch 5))]
4314 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4317 (clobber (match_dup 5))])
4318 (set (match_dup 0) (match_dup 4))])
4321 [(set (match_operand:DI 0 "memory_operand")
4322 (fix:DI (match_operand 1 "register_operand")))
4323 (use (match_operand:HI 2 "memory_operand"))
4324 (use (match_operand:HI 3 "memory_operand"))
4325 (clobber (match_operand:DI 4 "memory_operand"))
4326 (clobber (match_scratch 5))]
4328 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4331 (clobber (match_dup 5))])])
4333 (define_insn "fix_trunc<mode>_i387"
4334 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4335 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4336 (use (match_operand:HI 2 "memory_operand" "m"))
4337 (use (match_operand:HI 3 "memory_operand" "m"))]
4338 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4340 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4341 "* return output_fix_trunc (insn, operands, false);"
4342 [(set_attr "type" "fistp")
4343 (set_attr "i387_cw" "trunc")
4344 (set_attr "mode" "<MODE>")])
4346 (define_insn "fix_trunc<mode>_i387_with_temp"
4347 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4348 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4349 (use (match_operand:HI 2 "memory_operand" "m,m"))
4350 (use (match_operand:HI 3 "memory_operand" "m,m"))
4351 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4352 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4354 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4356 [(set_attr "type" "fistp")
4357 (set_attr "i387_cw" "trunc")
4358 (set_attr "mode" "<MODE>")])
4361 [(set (match_operand:SWI24 0 "register_operand")
4362 (fix:SWI24 (match_operand 1 "register_operand")))
4363 (use (match_operand:HI 2 "memory_operand"))
4364 (use (match_operand:HI 3 "memory_operand"))
4365 (clobber (match_operand:SWI24 4 "memory_operand"))]
4367 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4369 (use (match_dup 3))])
4370 (set (match_dup 0) (match_dup 4))])
4373 [(set (match_operand:SWI24 0 "memory_operand")
4374 (fix:SWI24 (match_operand 1 "register_operand")))
4375 (use (match_operand:HI 2 "memory_operand"))
4376 (use (match_operand:HI 3 "memory_operand"))
4377 (clobber (match_operand:SWI24 4 "memory_operand"))]
4379 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4381 (use (match_dup 3))])])
4383 (define_insn "x86_fnstcw_1"
4384 [(set (match_operand:HI 0 "memory_operand" "=m")
4385 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4388 [(set (attr "length")
4389 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4390 (set_attr "mode" "HI")
4391 (set_attr "unit" "i387")
4392 (set_attr "bdver1_decode" "vector")])
4394 (define_insn "x86_fldcw_1"
4395 [(set (reg:HI FPCR_REG)
4396 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4399 [(set (attr "length")
4400 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4401 (set_attr "mode" "HI")
4402 (set_attr "unit" "i387")
4403 (set_attr "athlon_decode" "vector")
4404 (set_attr "amdfam10_decode" "vector")
4405 (set_attr "bdver1_decode" "vector")])
4407 ;; Conversion between fixed point and floating point.
4409 ;; Even though we only accept memory inputs, the backend _really_
4410 ;; wants to be able to do this between registers.
4412 (define_expand "floathi<mode>2"
4413 [(set (match_operand:X87MODEF 0 "register_operand")
4414 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand")))]
4416 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4417 || TARGET_MIX_SSE_I387)")
4419 ;; Pre-reload splitter to add memory clobber to the pattern.
4420 (define_insn_and_split "*floathi<mode>2_1"
4421 [(set (match_operand:X87MODEF 0 "register_operand")
4422 (float:X87MODEF (match_operand:HI 1 "register_operand")))]
4424 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4425 || TARGET_MIX_SSE_I387)
4426 && can_create_pseudo_p ()"
4429 [(parallel [(set (match_dup 0)
4430 (float:X87MODEF (match_dup 1)))
4431 (clobber (match_dup 2))])]
4432 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4434 (define_insn "*floathi<mode>2_i387_with_temp"
4435 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4436 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4437 (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4439 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4440 || TARGET_MIX_SSE_I387)"
4442 [(set_attr "type" "fmov,multi")
4443 (set_attr "mode" "<MODE>")
4444 (set_attr "unit" "*,i387")
4445 (set_attr "fp_int_src" "true")])
4447 (define_insn "*floathi<mode>2_i387"
4448 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4449 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4451 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4452 || TARGET_MIX_SSE_I387)"
4454 [(set_attr "type" "fmov")
4455 (set_attr "mode" "<MODE>")
4456 (set_attr "fp_int_src" "true")])
4459 [(set (match_operand:X87MODEF 0 "register_operand")
4460 (float:X87MODEF (match_operand:HI 1 "register_operand")))
4461 (clobber (match_operand:HI 2 "memory_operand"))]
4463 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4464 || TARGET_MIX_SSE_I387)
4465 && reload_completed"
4466 [(set (match_dup 2) (match_dup 1))
4467 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4470 [(set (match_operand:X87MODEF 0 "register_operand")
4471 (float:X87MODEF (match_operand:HI 1 "memory_operand")))
4472 (clobber (match_operand:HI 2 "memory_operand"))]
4474 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4475 || TARGET_MIX_SSE_I387)
4476 && reload_completed"
4477 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4479 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4480 [(set (match_operand:X87MODEF 0 "register_operand")
4482 (match_operand:SWI48x 1 "nonimmediate_operand")))]
4484 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4485 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4487 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4488 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4489 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4491 rtx reg = gen_reg_rtx (XFmode);
4492 rtx (*insn)(rtx, rtx);
4494 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4496 if (<X87MODEF:MODE>mode == SFmode)
4497 insn = gen_truncxfsf2;
4498 else if (<X87MODEF:MODE>mode == DFmode)
4499 insn = gen_truncxfdf2;
4503 emit_insn (insn (operands[0], reg));
4508 ;; Pre-reload splitter to add memory clobber to the pattern.
4509 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4510 [(set (match_operand:X87MODEF 0 "register_operand")
4511 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))]
4513 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4514 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4515 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4516 || TARGET_MIX_SSE_I387))
4517 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4518 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4519 && ((<SWI48x:MODE>mode == SImode
4520 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4521 && optimize_function_for_speed_p (cfun)
4522 && flag_trapping_math)
4523 || !(TARGET_INTER_UNIT_CONVERSIONS
4524 || optimize_function_for_size_p (cfun)))))
4525 && can_create_pseudo_p ()"
4528 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4529 (clobber (match_dup 2))])]
4531 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4533 /* Avoid store forwarding (partial memory) stall penalty
4534 by passing DImode value through XMM registers. */
4535 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4536 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4537 && optimize_function_for_speed_p (cfun))
4539 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4546 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4547 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4549 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4550 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4551 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4552 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4554 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4555 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4556 (set_attr "unit" "*,i387,*,*,*")
4557 (set_attr "athlon_decode" "*,*,double,direct,double")
4558 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4559 (set_attr "bdver1_decode" "*,*,double,direct,double")
4560 (set_attr "fp_int_src" "true")])
4562 (define_insn "*floatsi<mode>2_vector_mixed"
4563 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4564 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4565 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4566 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4570 [(set_attr "type" "fmov,sseicvt")
4571 (set_attr "mode" "<MODE>,<ssevecmode>")
4572 (set_attr "unit" "i387,*")
4573 (set_attr "athlon_decode" "*,direct")
4574 (set_attr "amdfam10_decode" "*,double")
4575 (set_attr "bdver1_decode" "*,direct")
4576 (set_attr "fp_int_src" "true")])
4578 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_with_temp"
4579 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4581 (match_operand:SWI48 1 "nonimmediate_operand" "m,?r,r,m")))
4582 (clobber (match_operand:SWI48 2 "memory_operand" "=X,m,m,X"))]
4583 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4585 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4586 (set_attr "mode" "<MODEF:MODE>")
4587 (set_attr "unit" "*,i387,*,*")
4588 (set_attr "athlon_decode" "*,*,double,direct")
4589 (set_attr "amdfam10_decode" "*,*,vector,double")
4590 (set_attr "bdver1_decode" "*,*,double,direct")
4591 (set_attr "fp_int_src" "true")])
4594 [(set (match_operand:MODEF 0 "register_operand")
4595 (float:MODEF (match_operand:SWI48 1 "register_operand")))
4596 (clobber (match_operand:SWI48 2 "memory_operand"))]
4597 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4598 && TARGET_INTER_UNIT_CONVERSIONS
4599 && reload_completed && SSE_REG_P (operands[0])"
4600 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4603 [(set (match_operand:MODEF 0 "register_operand")
4604 (float:MODEF (match_operand:SWI48 1 "register_operand")))
4605 (clobber (match_operand:SWI48 2 "memory_operand"))]
4606 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4607 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4608 && reload_completed && SSE_REG_P (operands[0])"
4609 [(set (match_dup 2) (match_dup 1))
4610 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4612 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_interunit"
4613 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4615 (match_operand:SWI48 1 "nonimmediate_operand" "m,r,m")))]
4616 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4617 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4620 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}
4621 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4622 [(set_attr "type" "fmov,sseicvt,sseicvt")
4623 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4624 (set_attr "mode" "<MODEF:MODE>")
4625 (set (attr "prefix_rex")
4627 (and (eq_attr "prefix" "maybe_vex")
4628 (match_test "<SWI48:MODE>mode == DImode"))
4630 (const_string "*")))
4631 (set_attr "unit" "i387,*,*")
4632 (set_attr "athlon_decode" "*,double,direct")
4633 (set_attr "amdfam10_decode" "*,vector,double")
4634 (set_attr "bdver1_decode" "*,double,direct")
4635 (set_attr "fp_int_src" "true")])
4637 (define_insn "*float<SWI48:mode><MODEF:mode>2_mixed_nointerunit"
4638 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4640 (match_operand:SWI48 1 "memory_operand" "m,m")))]
4641 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4642 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4645 %vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4646 [(set_attr "type" "fmov,sseicvt")
4647 (set_attr "prefix" "orig,maybe_vex")
4648 (set_attr "mode" "<MODEF:MODE>")
4649 (set (attr "prefix_rex")
4651 (and (eq_attr "prefix" "maybe_vex")
4652 (match_test "<SWI48:MODE>mode == DImode"))
4654 (const_string "*")))
4655 (set_attr "athlon_decode" "*,direct")
4656 (set_attr "amdfam10_decode" "*,double")
4657 (set_attr "bdver1_decode" "*,direct")
4658 (set_attr "fp_int_src" "true")])
4660 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4661 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4663 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4664 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4665 "TARGET_SSE2 && TARGET_SSE_MATH
4666 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4668 [(set_attr "type" "sseicvt")
4669 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4670 (set_attr "athlon_decode" "double,direct,double")
4671 (set_attr "amdfam10_decode" "vector,double,double")
4672 (set_attr "bdver1_decode" "double,direct,double")
4673 (set_attr "fp_int_src" "true")])
4675 (define_insn "*floatsi<mode>2_vector_sse"
4676 [(set (match_operand:MODEF 0 "register_operand" "=x")
4677 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4678 "TARGET_SSE2 && TARGET_SSE_MATH
4679 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4681 [(set_attr "type" "sseicvt")
4682 (set_attr "mode" "<MODE>")
4683 (set_attr "athlon_decode" "direct")
4684 (set_attr "amdfam10_decode" "double")
4685 (set_attr "bdver1_decode" "direct")
4686 (set_attr "fp_int_src" "true")])
4689 [(set (match_operand:MODEF 0 "register_operand")
4690 (float:MODEF (match_operand:SI 1 "register_operand")))
4691 (clobber (match_operand:SI 2 "memory_operand"))]
4692 "TARGET_SSE2 && TARGET_SSE_MATH
4693 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4694 && reload_completed && SSE_REG_P (operands[0])"
4697 rtx op1 = operands[1];
4699 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4701 if (GET_CODE (op1) == SUBREG)
4702 op1 = SUBREG_REG (op1);
4704 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES_TO_VEC)
4706 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4707 emit_insn (gen_sse2_loadld (operands[4],
4708 CONST0_RTX (V4SImode), operands[1]));
4710 /* We can ignore possible trapping value in the
4711 high part of SSE register for non-trapping math. */
4712 else if (SSE_REG_P (op1) && !flag_trapping_math)
4713 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4716 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4717 emit_move_insn (operands[2], operands[1]);
4718 emit_insn (gen_sse2_loadld (operands[4],
4719 CONST0_RTX (V4SImode), operands[2]));
4721 if (<ssevecmode>mode == V4SFmode)
4722 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4724 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4729 [(set (match_operand:MODEF 0 "register_operand")
4730 (float:MODEF (match_operand:SI 1 "memory_operand")))
4731 (clobber (match_operand:SI 2 "memory_operand"))]
4732 "TARGET_SSE2 && TARGET_SSE_MATH
4733 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4734 && reload_completed && SSE_REG_P (operands[0])"
4737 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4739 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4741 emit_insn (gen_sse2_loadld (operands[4],
4742 CONST0_RTX (V4SImode), operands[1]));
4743 if (<ssevecmode>mode == V4SFmode)
4744 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4746 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4751 [(set (match_operand:MODEF 0 "register_operand")
4752 (float:MODEF (match_operand:SI 1 "register_operand")))]
4753 "TARGET_SSE2 && TARGET_SSE_MATH
4754 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4755 && reload_completed && SSE_REG_P (operands[0])"
4758 rtx op1 = operands[1];
4760 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4762 if (GET_CODE (op1) == SUBREG)
4763 op1 = SUBREG_REG (op1);
4765 if (GENERAL_REG_P (op1))
4767 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4768 if (TARGET_INTER_UNIT_MOVES_TO_VEC)
4769 emit_insn (gen_sse2_loadld (operands[4],
4770 CONST0_RTX (V4SImode), operands[1]));
4773 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
4775 emit_insn (gen_sse2_loadld (operands[4],
4776 CONST0_RTX (V4SImode), operands[5]));
4777 ix86_free_from_memory (GET_MODE (operands[1]));
4780 /* We can ignore possible trapping value in the
4781 high part of SSE register for non-trapping math. */
4782 else if (SSE_REG_P (op1) && !flag_trapping_math)
4783 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4786 if (<ssevecmode>mode == V4SFmode)
4787 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4789 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4794 [(set (match_operand:MODEF 0 "register_operand")
4795 (float:MODEF (match_operand:SI 1 "memory_operand")))]
4796 "TARGET_SSE2 && TARGET_SSE_MATH
4797 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4798 && reload_completed && SSE_REG_P (operands[0])"
4801 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4803 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4805 emit_insn (gen_sse2_loadld (operands[4],
4806 CONST0_RTX (V4SImode), operands[1]));
4807 if (<ssevecmode>mode == V4SFmode)
4808 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4810 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4814 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_with_temp"
4815 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
4817 (match_operand:SWI48 1 "nonimmediate_operand" "r,m")))
4818 (clobber (match_operand:SWI48 2 "memory_operand" "=m,X"))]
4819 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
4821 [(set_attr "type" "sseicvt")
4822 (set_attr "mode" "<MODEF:MODE>")
4823 (set_attr "athlon_decode" "double,direct")
4824 (set_attr "amdfam10_decode" "vector,double")
4825 (set_attr "bdver1_decode" "double,direct")
4826 (set_attr "btver2_decode" "double,double")
4827 (set_attr "fp_int_src" "true")])
4829 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_interunit"
4830 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
4832 (match_operand:SWI48 1 "nonimmediate_operand" "r,m")))]
4833 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
4834 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4835 "%vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4836 [(set_attr "type" "sseicvt")
4837 (set_attr "prefix" "maybe_vex")
4838 (set_attr "mode" "<MODEF:MODE>")
4839 (set (attr "prefix_rex")
4841 (and (eq_attr "prefix" "maybe_vex")
4842 (match_test "<SWI48:MODE>mode == DImode"))
4844 (const_string "*")))
4845 (set_attr "athlon_decode" "double,direct")
4846 (set_attr "amdfam10_decode" "vector,double")
4847 (set_attr "bdver1_decode" "double,direct")
4848 (set_attr "btver2_decode" "double,double")
4849 (set_attr "fp_int_src" "true")])
4852 [(set (match_operand:MODEF 0 "register_operand")
4853 (float:MODEF (match_operand:SWI48 1 "nonimmediate_operand")))
4854 (clobber (match_operand:SWI48 2 "memory_operand"))]
4855 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
4856 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4857 && reload_completed && SSE_REG_P (operands[0])"
4858 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4860 (define_insn "*float<SWI48:mode><MODEF:mode>2_sse_nointerunit"
4861 [(set (match_operand:MODEF 0 "register_operand" "=x")
4863 (match_operand:SWI48 1 "memory_operand" "m")))]
4864 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
4865 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4866 "%vcvtsi2<MODEF:ssemodesuffix><SWI48:rex64suffix>\t{%1, %d0|%d0, %1}"
4867 [(set_attr "type" "sseicvt")
4868 (set_attr "prefix" "maybe_vex")
4869 (set_attr "mode" "<MODEF:MODE>")
4870 (set (attr "prefix_rex")
4872 (and (eq_attr "prefix" "maybe_vex")
4873 (match_test "<SWI48:MODE>mode == DImode"))
4875 (const_string "*")))
4876 (set_attr "athlon_decode" "direct")
4877 (set_attr "amdfam10_decode" "double")
4878 (set_attr "bdver1_decode" "direct")
4879 (set_attr "fp_int_src" "true")])
4882 [(set (match_operand:MODEF 0 "register_operand")
4883 (float:MODEF (match_operand:SWI48 1 "register_operand")))
4884 (clobber (match_operand:SWI48 2 "memory_operand"))]
4885 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
4886 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4887 && reload_completed && SSE_REG_P (operands[0])"
4888 [(set (match_dup 2) (match_dup 1))
4889 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4892 [(set (match_operand:MODEF 0 "register_operand")
4893 (float:MODEF (match_operand:SWI48 1 "memory_operand")))
4894 (clobber (match_operand:SWI48 2 "memory_operand"))]
4895 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
4896 && reload_completed && SSE_REG_P (operands[0])"
4897 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4899 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
4900 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4902 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
4903 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
4905 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
4909 [(set_attr "type" "fmov,multi")
4910 (set_attr "mode" "<X87MODEF:MODE>")
4911 (set_attr "unit" "*,i387")
4912 (set_attr "fp_int_src" "true")])
4914 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
4915 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4917 (match_operand:SWI48x 1 "memory_operand" "m")))]
4919 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
4921 [(set_attr "type" "fmov")
4922 (set_attr "mode" "<X87MODEF:MODE>")
4923 (set_attr "fp_int_src" "true")])
4926 [(set (match_operand:X87MODEF 0 "fp_register_operand")
4927 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))
4928 (clobber (match_operand:SWI48x 2 "memory_operand"))]
4930 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4931 && reload_completed"
4932 [(set (match_dup 2) (match_dup 1))
4933 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4936 [(set (match_operand:X87MODEF 0 "fp_register_operand")
4937 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand")))
4938 (clobber (match_operand:SWI48x 2 "memory_operand"))]
4940 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4941 && reload_completed"
4942 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4944 ;; Avoid partial SSE register dependency stalls
4947 [(set (match_operand:MODEF 0 "register_operand")
4948 (float:MODEF (match_operand:SI 1 "nonimmediate_operand")))]
4949 "TARGET_SSE2 && TARGET_SSE_MATH
4950 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4951 && optimize_function_for_speed_p (cfun)
4952 && reload_completed && SSE_REG_P (operands[0])"
4954 (vec_merge:<ssevecmode>
4955 (vec_duplicate:<ssevecmode>
4956 (float:MODEF (match_dup 1)))
4960 operands[0] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4962 emit_move_insn (operands[0], CONST0_RTX (<ssevecmode>mode));
4966 [(set (match_operand:MODEF 0 "register_operand")
4967 (float:MODEF (match_operand:DI 1 "nonimmediate_operand")))]
4968 "TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4969 && TARGET_SSE_PARTIAL_REG_DEPENDENCY
4970 && optimize_function_for_speed_p (cfun)
4971 && reload_completed && SSE_REG_P (operands[0])"
4973 (vec_merge:<ssevecmode>
4974 (vec_duplicate:<ssevecmode>
4975 (float:MODEF (match_dup 1)))
4979 operands[0] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4981 emit_move_insn (operands[0], CONST0_RTX (<ssevecmode>mode));
4984 ;; Avoid store forwarding (partial memory) stall penalty
4985 ;; by passing DImode value through XMM registers. */
4987 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
4988 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4990 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
4991 (clobber (match_scratch:V4SI 3 "=X,x"))
4992 (clobber (match_scratch:V4SI 4 "=X,x"))
4993 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
4994 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
4995 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
4996 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
4998 [(set_attr "type" "multi")
4999 (set_attr "mode" "<X87MODEF:MODE>")
5000 (set_attr "unit" "i387")
5001 (set_attr "fp_int_src" "true")])
5004 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5005 (float:X87MODEF (match_operand:DI 1 "register_operand")))
5006 (clobber (match_scratch:V4SI 3))
5007 (clobber (match_scratch:V4SI 4))
5008 (clobber (match_operand:DI 2 "memory_operand"))]
5009 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5010 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5011 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5012 && reload_completed"
5013 [(set (match_dup 2) (match_dup 3))
5014 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5016 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5017 Assemble the 64-bit DImode value in an xmm register. */
5018 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5019 gen_rtx_SUBREG (SImode, operands[1], 0)));
5020 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5021 gen_rtx_SUBREG (SImode, operands[1], 4)));
5022 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5025 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5029 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5030 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5031 (clobber (match_scratch:V4SI 3))
5032 (clobber (match_scratch:V4SI 4))
5033 (clobber (match_operand:DI 2 "memory_operand"))]
5034 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5035 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES_TO_VEC
5036 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5037 && reload_completed"
5038 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5040 ;; Avoid store forwarding (partial memory) stall penalty by extending
5041 ;; SImode value to DImode through XMM register instead of pushing two
5042 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES_TO_VEC
5043 ;; targets benefit from this optimization. Also note that fild
5044 ;; loads from memory only.
5046 (define_insn "*floatunssi<mode>2_1"
5047 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5048 (unsigned_float:X87MODEF
5049 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5050 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5051 (clobber (match_scratch:SI 3 "=X,x"))]
5053 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5056 [(set_attr "type" "multi")
5057 (set_attr "mode" "<MODE>")])
5060 [(set (match_operand:X87MODEF 0 "register_operand")
5061 (unsigned_float:X87MODEF
5062 (match_operand:SI 1 "register_operand")))
5063 (clobber (match_operand:DI 2 "memory_operand"))
5064 (clobber (match_scratch:SI 3))]
5066 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5068 && reload_completed"
5069 [(set (match_dup 2) (match_dup 1))
5071 (float:X87MODEF (match_dup 2)))]
5072 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5075 [(set (match_operand:X87MODEF 0 "register_operand")
5076 (unsigned_float:X87MODEF
5077 (match_operand:SI 1 "memory_operand")))
5078 (clobber (match_operand:DI 2 "memory_operand"))
5079 (clobber (match_scratch:SI 3))]
5081 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5083 && reload_completed"
5084 [(set (match_dup 2) (match_dup 3))
5086 (float:X87MODEF (match_dup 2)))]
5088 emit_move_insn (operands[3], operands[1]);
5089 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5092 (define_expand "floatunssi<mode>2"
5094 [(set (match_operand:X87MODEF 0 "register_operand")
5095 (unsigned_float:X87MODEF
5096 (match_operand:SI 1 "nonimmediate_operand")))
5097 (clobber (match_dup 2))
5098 (clobber (match_scratch:SI 3))])]
5100 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5102 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5104 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5106 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5110 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5113 (define_expand "floatunsdisf2"
5114 [(use (match_operand:SF 0 "register_operand"))
5115 (use (match_operand:DI 1 "nonimmediate_operand"))]
5116 "TARGET_64BIT && TARGET_SSE_MATH"
5117 "x86_emit_floatuns (operands); DONE;")
5119 (define_expand "floatunsdidf2"
5120 [(use (match_operand:DF 0 "register_operand"))
5121 (use (match_operand:DI 1 "nonimmediate_operand"))]
5122 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5123 && TARGET_SSE2 && TARGET_SSE_MATH"
5126 x86_emit_floatuns (operands);
5128 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5132 ;; Load effective address instructions
5134 (define_insn_and_split "*lea<mode>"
5135 [(set (match_operand:SWI48 0 "register_operand" "=r")
5136 (match_operand:SWI48 1 "lea_address_operand" "p"))]
5139 if (SImode_address_operand (operands[1], VOIDmode))
5141 gcc_assert (TARGET_64BIT);
5142 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5145 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5147 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5150 enum machine_mode mode = <MODE>mode;
5153 /* ix86_avoid_lea_for_addr re-recognizes insn and may
5154 change operands[] array behind our back. */
5155 pat = PATTERN (curr_insn);
5157 operands[0] = SET_DEST (pat);
5158 operands[1] = SET_SRC (pat);
5160 /* Emit all operations in SImode for zero-extended addresses. Recall
5161 that x86_64 inheretly zero-extends SImode operations to DImode. */
5162 if (SImode_address_operand (operands[1], VOIDmode))
5165 ix86_split_lea_for_addr (curr_insn, operands, mode);
5168 [(set_attr "type" "lea")
5171 (match_operand 1 "SImode_address_operand")
5173 (const_string "<MODE>")))])
5177 (define_expand "add<mode>3"
5178 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5179 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5180 (match_operand:SDWIM 2 "<general_operand>")))]
5182 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5184 (define_insn_and_split "*add<dwi>3_doubleword"
5185 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5187 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5188 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5189 (clobber (reg:CC FLAGS_REG))]
5190 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5193 [(parallel [(set (reg:CC FLAGS_REG)
5194 (unspec:CC [(match_dup 1) (match_dup 2)]
5197 (plus:DWIH (match_dup 1) (match_dup 2)))])
5198 (parallel [(set (match_dup 3)
5202 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5204 (clobber (reg:CC FLAGS_REG))])]
5205 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5207 (define_insn "*add<mode>3_cc"
5208 [(set (reg:CC FLAGS_REG)
5210 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5211 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5213 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5214 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5215 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5216 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5217 [(set_attr "type" "alu")
5218 (set_attr "mode" "<MODE>")])
5220 (define_insn "addqi3_cc"
5221 [(set (reg:CC FLAGS_REG)
5223 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5224 (match_operand:QI 2 "general_operand" "qn,qm")]
5226 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5227 (plus:QI (match_dup 1) (match_dup 2)))]
5228 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5229 "add{b}\t{%2, %0|%0, %2}"
5230 [(set_attr "type" "alu")
5231 (set_attr "mode" "QI")])
5233 (define_insn "*add<mode>_1"
5234 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5236 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5237 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5238 (clobber (reg:CC FLAGS_REG))]
5239 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5241 switch (get_attr_type (insn))
5247 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5248 if (operands[2] == const1_rtx)
5249 return "inc{<imodesuffix>}\t%0";
5252 gcc_assert (operands[2] == constm1_rtx);
5253 return "dec{<imodesuffix>}\t%0";
5257 /* For most processors, ADD is faster than LEA. This alternative
5258 was added to use ADD as much as possible. */
5259 if (which_alternative == 2)
5262 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5265 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5266 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5267 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5269 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5273 (cond [(eq_attr "alternative" "3")
5274 (const_string "lea")
5275 (match_operand:SWI48 2 "incdec_operand")
5276 (const_string "incdec")
5278 (const_string "alu")))
5279 (set (attr "length_immediate")
5281 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5283 (const_string "*")))
5284 (set_attr "mode" "<MODE>")])
5286 ;; It may seem that nonimmediate operand is proper one for operand 1.
5287 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5288 ;; we take care in ix86_binary_operator_ok to not allow two memory
5289 ;; operands so proper swapping will be done in reload. This allow
5290 ;; patterns constructed from addsi_1 to match.
5292 (define_insn "addsi_1_zext"
5293 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5295 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5296 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5297 (clobber (reg:CC FLAGS_REG))]
5298 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5300 switch (get_attr_type (insn))
5306 if (operands[2] == const1_rtx)
5307 return "inc{l}\t%k0";
5310 gcc_assert (operands[2] == constm1_rtx);
5311 return "dec{l}\t%k0";
5315 /* For most processors, ADD is faster than LEA. This alternative
5316 was added to use ADD as much as possible. */
5317 if (which_alternative == 1)
5320 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5323 if (x86_maybe_negate_const_int (&operands[2], SImode))
5324 return "sub{l}\t{%2, %k0|%k0, %2}";
5326 return "add{l}\t{%2, %k0|%k0, %2}";
5330 (cond [(eq_attr "alternative" "2")
5331 (const_string "lea")
5332 (match_operand:SI 2 "incdec_operand")
5333 (const_string "incdec")
5335 (const_string "alu")))
5336 (set (attr "length_immediate")
5338 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5340 (const_string "*")))
5341 (set_attr "mode" "SI")])
5343 (define_insn "*addhi_1"
5344 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5345 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5346 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5347 (clobber (reg:CC FLAGS_REG))]
5348 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5350 switch (get_attr_type (insn))
5356 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5357 if (operands[2] == const1_rtx)
5358 return "inc{w}\t%0";
5361 gcc_assert (operands[2] == constm1_rtx);
5362 return "dec{w}\t%0";
5366 /* For most processors, ADD is faster than LEA. This alternative
5367 was added to use ADD as much as possible. */
5368 if (which_alternative == 2)
5371 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5374 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5375 if (x86_maybe_negate_const_int (&operands[2], HImode))
5376 return "sub{w}\t{%2, %0|%0, %2}";
5378 return "add{w}\t{%2, %0|%0, %2}";
5382 (cond [(eq_attr "alternative" "3")
5383 (const_string "lea")
5384 (match_operand:HI 2 "incdec_operand")
5385 (const_string "incdec")
5387 (const_string "alu")))
5388 (set (attr "length_immediate")
5390 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5392 (const_string "*")))
5393 (set_attr "mode" "HI,HI,HI,SI")])
5395 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5396 (define_insn "*addqi_1"
5397 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5398 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5399 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5400 (clobber (reg:CC FLAGS_REG))]
5401 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5403 bool widen = (which_alternative == 3 || which_alternative == 4);
5405 switch (get_attr_type (insn))
5411 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5412 if (operands[2] == const1_rtx)
5413 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5416 gcc_assert (operands[2] == constm1_rtx);
5417 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5421 /* For most processors, ADD is faster than LEA. These alternatives
5422 were added to use ADD as much as possible. */
5423 if (which_alternative == 2 || which_alternative == 4)
5426 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5429 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5430 if (x86_maybe_negate_const_int (&operands[2], QImode))
5433 return "sub{l}\t{%2, %k0|%k0, %2}";
5435 return "sub{b}\t{%2, %0|%0, %2}";
5438 return "add{l}\t{%k2, %k0|%k0, %k2}";
5440 return "add{b}\t{%2, %0|%0, %2}";
5444 (cond [(eq_attr "alternative" "5")
5445 (const_string "lea")
5446 (match_operand:QI 2 "incdec_operand")
5447 (const_string "incdec")
5449 (const_string "alu")))
5450 (set (attr "length_immediate")
5452 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5454 (const_string "*")))
5455 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5457 (define_insn "*addqi_1_slp"
5458 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5459 (plus:QI (match_dup 0)
5460 (match_operand:QI 1 "general_operand" "qn,qm")))
5461 (clobber (reg:CC FLAGS_REG))]
5462 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5463 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5465 switch (get_attr_type (insn))
5468 if (operands[1] == const1_rtx)
5469 return "inc{b}\t%0";
5472 gcc_assert (operands[1] == constm1_rtx);
5473 return "dec{b}\t%0";
5477 if (x86_maybe_negate_const_int (&operands[1], QImode))
5478 return "sub{b}\t{%1, %0|%0, %1}";
5480 return "add{b}\t{%1, %0|%0, %1}";
5484 (if_then_else (match_operand:QI 1 "incdec_operand")
5485 (const_string "incdec")
5486 (const_string "alu1")))
5487 (set (attr "memory")
5488 (if_then_else (match_operand 1 "memory_operand")
5489 (const_string "load")
5490 (const_string "none")))
5491 (set_attr "mode" "QI")])
5493 ;; Split non destructive adds if we cannot use lea.
5495 [(set (match_operand:SWI48 0 "register_operand")
5496 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5497 (match_operand:SWI48 2 "x86_64_nonmemory_operand")))
5498 (clobber (reg:CC FLAGS_REG))]
5499 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5500 [(set (match_dup 0) (match_dup 1))
5501 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 2)))
5502 (clobber (reg:CC FLAGS_REG))])])
5504 ;; Convert add to the lea pattern to avoid flags dependency.
5506 [(set (match_operand:SWI 0 "register_operand")
5507 (plus:SWI (match_operand:SWI 1 "register_operand")
5508 (match_operand:SWI 2 "<nonmemory_operand>")))
5509 (clobber (reg:CC FLAGS_REG))]
5510 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5513 enum machine_mode mode = <MODE>mode;
5516 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5519 operands[0] = gen_lowpart (mode, operands[0]);
5520 operands[1] = gen_lowpart (mode, operands[1]);
5521 operands[2] = gen_lowpart (mode, operands[2]);
5524 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5526 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5530 ;; Split non destructive adds if we cannot use lea.
5532 [(set (match_operand:DI 0 "register_operand")
5534 (plus:SI (match_operand:SI 1 "register_operand")
5535 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5536 (clobber (reg:CC FLAGS_REG))]
5538 && reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5539 [(set (match_dup 3) (match_dup 1))
5540 (parallel [(set (match_dup 0)
5541 (zero_extend:DI (plus:SI (match_dup 3) (match_dup 2))))
5542 (clobber (reg:CC FLAGS_REG))])]
5543 "operands[3] = gen_lowpart (SImode, operands[0]);")
5545 ;; Convert add to the lea pattern to avoid flags dependency.
5547 [(set (match_operand:DI 0 "register_operand")
5549 (plus:SI (match_operand:SI 1 "register_operand")
5550 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5551 (clobber (reg:CC FLAGS_REG))]
5552 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5554 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5556 (define_insn "*add<mode>_2"
5557 [(set (reg FLAGS_REG)
5560 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5561 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5563 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5564 (plus:SWI (match_dup 1) (match_dup 2)))]
5565 "ix86_match_ccmode (insn, CCGOCmode)
5566 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5568 switch (get_attr_type (insn))
5571 if (operands[2] == const1_rtx)
5572 return "inc{<imodesuffix>}\t%0";
5575 gcc_assert (operands[2] == constm1_rtx);
5576 return "dec{<imodesuffix>}\t%0";
5580 if (which_alternative == 2)
5583 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5586 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5587 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5588 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5590 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5594 (if_then_else (match_operand:SWI 2 "incdec_operand")
5595 (const_string "incdec")
5596 (const_string "alu")))
5597 (set (attr "length_immediate")
5599 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5601 (const_string "*")))
5602 (set_attr "mode" "<MODE>")])
5604 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5605 (define_insn "*addsi_2_zext"
5606 [(set (reg FLAGS_REG)
5608 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5609 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5611 (set (match_operand:DI 0 "register_operand" "=r,r")
5612 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5613 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5614 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5616 switch (get_attr_type (insn))
5619 if (operands[2] == const1_rtx)
5620 return "inc{l}\t%k0";
5623 gcc_assert (operands[2] == constm1_rtx);
5624 return "dec{l}\t%k0";
5628 if (which_alternative == 1)
5631 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5634 if (x86_maybe_negate_const_int (&operands[2], SImode))
5635 return "sub{l}\t{%2, %k0|%k0, %2}";
5637 return "add{l}\t{%2, %k0|%k0, %2}";
5641 (if_then_else (match_operand:SI 2 "incdec_operand")
5642 (const_string "incdec")
5643 (const_string "alu")))
5644 (set (attr "length_immediate")
5646 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5648 (const_string "*")))
5649 (set_attr "mode" "SI")])
5651 (define_insn "*add<mode>_3"
5652 [(set (reg FLAGS_REG)
5654 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5655 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5656 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5657 "ix86_match_ccmode (insn, CCZmode)
5658 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5660 switch (get_attr_type (insn))
5663 if (operands[2] == const1_rtx)
5664 return "inc{<imodesuffix>}\t%0";
5667 gcc_assert (operands[2] == constm1_rtx);
5668 return "dec{<imodesuffix>}\t%0";
5672 if (which_alternative == 1)
5675 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5678 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5679 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5680 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5682 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5686 (if_then_else (match_operand:SWI 2 "incdec_operand")
5687 (const_string "incdec")
5688 (const_string "alu")))
5689 (set (attr "length_immediate")
5691 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5693 (const_string "*")))
5694 (set_attr "mode" "<MODE>")])
5696 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5697 (define_insn "*addsi_3_zext"
5698 [(set (reg FLAGS_REG)
5700 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5701 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5702 (set (match_operand:DI 0 "register_operand" "=r,r")
5703 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5704 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5705 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5707 switch (get_attr_type (insn))
5710 if (operands[2] == const1_rtx)
5711 return "inc{l}\t%k0";
5714 gcc_assert (operands[2] == constm1_rtx);
5715 return "dec{l}\t%k0";
5719 if (which_alternative == 1)
5722 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5725 if (x86_maybe_negate_const_int (&operands[2], SImode))
5726 return "sub{l}\t{%2, %k0|%k0, %2}";
5728 return "add{l}\t{%2, %k0|%k0, %2}";
5732 (if_then_else (match_operand:SI 2 "incdec_operand")
5733 (const_string "incdec")
5734 (const_string "alu")))
5735 (set (attr "length_immediate")
5737 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5739 (const_string "*")))
5740 (set_attr "mode" "SI")])
5742 ; For comparisons against 1, -1 and 128, we may generate better code
5743 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5744 ; is matched then. We can't accept general immediate, because for
5745 ; case of overflows, the result is messed up.
5746 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5747 ; only for comparisons not depending on it.
5749 (define_insn "*adddi_4"
5750 [(set (reg FLAGS_REG)
5752 (match_operand:DI 1 "nonimmediate_operand" "0")
5753 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5754 (clobber (match_scratch:DI 0 "=rm"))]
5756 && ix86_match_ccmode (insn, CCGCmode)"
5758 switch (get_attr_type (insn))
5761 if (operands[2] == constm1_rtx)
5762 return "inc{q}\t%0";
5765 gcc_assert (operands[2] == const1_rtx);
5766 return "dec{q}\t%0";
5770 if (x86_maybe_negate_const_int (&operands[2], DImode))
5771 return "add{q}\t{%2, %0|%0, %2}";
5773 return "sub{q}\t{%2, %0|%0, %2}";
5777 (if_then_else (match_operand:DI 2 "incdec_operand")
5778 (const_string "incdec")
5779 (const_string "alu")))
5780 (set (attr "length_immediate")
5782 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5784 (const_string "*")))
5785 (set_attr "mode" "DI")])
5787 ; For comparisons against 1, -1 and 128, we may generate better code
5788 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5789 ; is matched then. We can't accept general immediate, because for
5790 ; case of overflows, the result is messed up.
5791 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5792 ; only for comparisons not depending on it.
5794 (define_insn "*add<mode>_4"
5795 [(set (reg FLAGS_REG)
5797 (match_operand:SWI124 1 "nonimmediate_operand" "0")
5798 (match_operand:SWI124 2 "const_int_operand" "n")))
5799 (clobber (match_scratch:SWI124 0 "=<r>m"))]
5800 "ix86_match_ccmode (insn, CCGCmode)"
5802 switch (get_attr_type (insn))
5805 if (operands[2] == constm1_rtx)
5806 return "inc{<imodesuffix>}\t%0";
5809 gcc_assert (operands[2] == const1_rtx);
5810 return "dec{<imodesuffix>}\t%0";
5814 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5815 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5817 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5821 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
5822 (const_string "incdec")
5823 (const_string "alu")))
5824 (set (attr "length_immediate")
5826 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5828 (const_string "*")))
5829 (set_attr "mode" "<MODE>")])
5831 (define_insn "*add<mode>_5"
5832 [(set (reg FLAGS_REG)
5835 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
5836 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5838 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5839 "ix86_match_ccmode (insn, CCGOCmode)
5840 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5842 switch (get_attr_type (insn))
5845 if (operands[2] == const1_rtx)
5846 return "inc{<imodesuffix>}\t%0";
5849 gcc_assert (operands[2] == constm1_rtx);
5850 return "dec{<imodesuffix>}\t%0";
5854 if (which_alternative == 1)
5857 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5860 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5861 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5862 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5864 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5868 (if_then_else (match_operand:SWI 2 "incdec_operand")
5869 (const_string "incdec")
5870 (const_string "alu")))
5871 (set (attr "length_immediate")
5873 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5875 (const_string "*")))
5876 (set_attr "mode" "<MODE>")])
5878 (define_insn "addqi_ext_1"
5879 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
5884 (match_operand 1 "ext_register_operand" "0,0")
5887 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m")))
5888 (clobber (reg:CC FLAGS_REG))]
5891 switch (get_attr_type (insn))
5894 if (operands[2] == const1_rtx)
5895 return "inc{b}\t%h0";
5898 gcc_assert (operands[2] == constm1_rtx);
5899 return "dec{b}\t%h0";
5903 return "add{b}\t{%2, %h0|%h0, %2}";
5906 [(set_attr "isa" "*,nox64")
5908 (if_then_else (match_operand:QI 2 "incdec_operand")
5909 (const_string "incdec")
5910 (const_string "alu")))
5911 (set_attr "modrm" "1")
5912 (set_attr "mode" "QI")])
5914 (define_insn "*addqi_ext_2"
5915 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
5920 (match_operand 1 "ext_register_operand" "%0")
5924 (match_operand 2 "ext_register_operand" "Q")
5927 (clobber (reg:CC FLAGS_REG))]
5929 "add{b}\t{%h2, %h0|%h0, %h2}"
5930 [(set_attr "type" "alu")
5931 (set_attr "mode" "QI")])
5933 ;; The lea patterns for modes less than 32 bits need to be matched by
5934 ;; several insns converted to real lea by splitters.
5936 (define_insn_and_split "*lea_general_1"
5937 [(set (match_operand 0 "register_operand" "=r")
5938 (plus (plus (match_operand 1 "index_register_operand" "l")
5939 (match_operand 2 "register_operand" "r"))
5940 (match_operand 3 "immediate_operand" "i")))]
5941 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5942 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5943 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5944 && GET_MODE (operands[0]) == GET_MODE (operands[2])
5945 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5946 || GET_MODE (operands[3]) == VOIDmode)"
5948 "&& reload_completed"
5951 enum machine_mode mode = SImode;
5954 operands[0] = gen_lowpart (mode, operands[0]);
5955 operands[1] = gen_lowpart (mode, operands[1]);
5956 operands[2] = gen_lowpart (mode, operands[2]);
5957 operands[3] = gen_lowpart (mode, operands[3]);
5959 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
5962 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5965 [(set_attr "type" "lea")
5966 (set_attr "mode" "SI")])
5968 (define_insn_and_split "*lea_general_2"
5969 [(set (match_operand 0 "register_operand" "=r")
5970 (plus (mult (match_operand 1 "index_register_operand" "l")
5971 (match_operand 2 "const248_operand" "n"))
5972 (match_operand 3 "nonmemory_operand" "ri")))]
5973 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
5974 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5975 && GET_MODE (operands[0]) == GET_MODE (operands[1])
5976 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
5977 || GET_MODE (operands[3]) == VOIDmode)"
5979 "&& reload_completed"
5982 enum machine_mode mode = SImode;
5985 operands[0] = gen_lowpart (mode, operands[0]);
5986 operands[1] = gen_lowpart (mode, operands[1]);
5987 operands[3] = gen_lowpart (mode, operands[3]);
5989 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
5992 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5995 [(set_attr "type" "lea")
5996 (set_attr "mode" "SI")])
5998 (define_insn_and_split "*lea_general_3"
5999 [(set (match_operand 0 "register_operand" "=r")
6000 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6001 (match_operand 2 "const248_operand" "n"))
6002 (match_operand 3 "register_operand" "r"))
6003 (match_operand 4 "immediate_operand" "i")))]
6004 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6005 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6006 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6007 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6009 "&& reload_completed"
6012 enum machine_mode mode = SImode;
6015 operands[0] = gen_lowpart (mode, operands[0]);
6016 operands[1] = gen_lowpart (mode, operands[1]);
6017 operands[3] = gen_lowpart (mode, operands[3]);
6018 operands[4] = gen_lowpart (mode, operands[4]);
6020 pat = gen_rtx_PLUS (mode,
6022 gen_rtx_MULT (mode, operands[1],
6027 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6030 [(set_attr "type" "lea")
6031 (set_attr "mode" "SI")])
6033 (define_insn_and_split "*lea_general_4"
6034 [(set (match_operand 0 "register_operand" "=r")
6036 (match_operand 1 "index_register_operand" "l")
6037 (match_operand 2 "const_int_operand" "n"))
6038 (match_operand 3 "const_int_operand" "n")))]
6039 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6040 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6041 || GET_MODE (operands[0]) == SImode
6042 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6043 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6044 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6045 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6046 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6048 "&& reload_completed"
6051 enum machine_mode mode = GET_MODE (operands[0]);
6054 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6057 operands[0] = gen_lowpart (mode, operands[0]);
6058 operands[1] = gen_lowpart (mode, operands[1]);
6061 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6063 pat = plus_constant (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6064 INTVAL (operands[3]));
6066 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6069 [(set_attr "type" "lea")
6071 (if_then_else (match_operand:DI 0)
6073 (const_string "SI")))])
6075 ;; Subtract instructions
6077 (define_expand "sub<mode>3"
6078 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6079 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6080 (match_operand:SDWIM 2 "<general_operand>")))]
6082 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6084 (define_insn_and_split "*sub<dwi>3_doubleword"
6085 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6087 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6088 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6089 (clobber (reg:CC FLAGS_REG))]
6090 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6093 [(parallel [(set (reg:CC FLAGS_REG)
6094 (compare:CC (match_dup 1) (match_dup 2)))
6096 (minus:DWIH (match_dup 1) (match_dup 2)))])
6097 (parallel [(set (match_dup 3)
6101 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6103 (clobber (reg:CC FLAGS_REG))])]
6104 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6106 (define_insn "*sub<mode>_1"
6107 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6109 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6110 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6111 (clobber (reg:CC FLAGS_REG))]
6112 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6113 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6114 [(set_attr "type" "alu")
6115 (set_attr "mode" "<MODE>")])
6117 (define_insn "*subsi_1_zext"
6118 [(set (match_operand:DI 0 "register_operand" "=r")
6120 (minus:SI (match_operand:SI 1 "register_operand" "0")
6121 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6122 (clobber (reg:CC FLAGS_REG))]
6123 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6124 "sub{l}\t{%2, %k0|%k0, %2}"
6125 [(set_attr "type" "alu")
6126 (set_attr "mode" "SI")])
6128 (define_insn "*subqi_1_slp"
6129 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6130 (minus:QI (match_dup 0)
6131 (match_operand:QI 1 "general_operand" "qn,qm")))
6132 (clobber (reg:CC FLAGS_REG))]
6133 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6134 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6135 "sub{b}\t{%1, %0|%0, %1}"
6136 [(set_attr "type" "alu1")
6137 (set_attr "mode" "QI")])
6139 (define_insn "*sub<mode>_2"
6140 [(set (reg FLAGS_REG)
6143 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6144 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6146 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6147 (minus:SWI (match_dup 1) (match_dup 2)))]
6148 "ix86_match_ccmode (insn, CCGOCmode)
6149 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6150 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6151 [(set_attr "type" "alu")
6152 (set_attr "mode" "<MODE>")])
6154 (define_insn "*subsi_2_zext"
6155 [(set (reg FLAGS_REG)
6157 (minus:SI (match_operand:SI 1 "register_operand" "0")
6158 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6160 (set (match_operand:DI 0 "register_operand" "=r")
6162 (minus:SI (match_dup 1)
6164 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6165 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6166 "sub{l}\t{%2, %k0|%k0, %2}"
6167 [(set_attr "type" "alu")
6168 (set_attr "mode" "SI")])
6170 (define_insn "*sub<mode>_3"
6171 [(set (reg FLAGS_REG)
6172 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6173 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6174 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6175 (minus:SWI (match_dup 1) (match_dup 2)))]
6176 "ix86_match_ccmode (insn, CCmode)
6177 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6178 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6179 [(set_attr "type" "alu")
6180 (set_attr "mode" "<MODE>")])
6182 (define_insn "*subsi_3_zext"
6183 [(set (reg FLAGS_REG)
6184 (compare (match_operand:SI 1 "register_operand" "0")
6185 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6186 (set (match_operand:DI 0 "register_operand" "=r")
6188 (minus:SI (match_dup 1)
6190 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6191 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6192 "sub{l}\t{%2, %1|%1, %2}"
6193 [(set_attr "type" "alu")
6194 (set_attr "mode" "SI")])
6196 ;; Add with carry and subtract with borrow
6198 (define_expand "<plusminus_insn><mode>3_carry"
6200 [(set (match_operand:SWI 0 "nonimmediate_operand")
6202 (match_operand:SWI 1 "nonimmediate_operand")
6203 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6204 [(match_operand 3 "flags_reg_operand")
6206 (match_operand:SWI 2 "<general_operand>"))))
6207 (clobber (reg:CC FLAGS_REG))])]
6208 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6210 (define_insn "*<plusminus_insn><mode>3_carry"
6211 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6213 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6215 (match_operator 3 "ix86_carry_flag_operator"
6216 [(reg FLAGS_REG) (const_int 0)])
6217 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6218 (clobber (reg:CC FLAGS_REG))]
6219 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6220 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6221 [(set_attr "type" "alu")
6222 (set_attr "use_carry" "1")
6223 (set_attr "pent_pair" "pu")
6224 (set_attr "mode" "<MODE>")])
6226 (define_insn "*addsi3_carry_zext"
6227 [(set (match_operand:DI 0 "register_operand" "=r")
6229 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6230 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6231 [(reg FLAGS_REG) (const_int 0)])
6232 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6233 (clobber (reg:CC FLAGS_REG))]
6234 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6235 "adc{l}\t{%2, %k0|%k0, %2}"
6236 [(set_attr "type" "alu")
6237 (set_attr "use_carry" "1")
6238 (set_attr "pent_pair" "pu")
6239 (set_attr "mode" "SI")])
6241 (define_insn "*subsi3_carry_zext"
6242 [(set (match_operand:DI 0 "register_operand" "=r")
6244 (minus:SI (match_operand:SI 1 "register_operand" "0")
6245 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6246 [(reg FLAGS_REG) (const_int 0)])
6247 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6248 (clobber (reg:CC FLAGS_REG))]
6249 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6250 "sbb{l}\t{%2, %k0|%k0, %2}"
6251 [(set_attr "type" "alu")
6252 (set_attr "pent_pair" "pu")
6253 (set_attr "mode" "SI")])
6257 (define_insn "adcx<mode>3"
6258 [(set (reg:CCC FLAGS_REG)
6261 (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6263 (match_operator 4 "ix86_carry_flag_operator"
6264 [(match_operand 3 "flags_reg_operand") (const_int 0)])
6265 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
6267 (set (match_operand:SWI48 0 "register_operand" "=r")
6268 (plus:SWI48 (match_dup 1)
6269 (plus:SWI48 (match_op_dup 4
6270 [(match_dup 3) (const_int 0)])
6272 "TARGET_ADX && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6273 "adcx\t{%2, %0|%0, %2}"
6274 [(set_attr "type" "alu")
6275 (set_attr "use_carry" "1")
6276 (set_attr "mode" "<MODE>")])
6278 ;; Overflow setting add and subtract instructions
6280 (define_insn "*add<mode>3_cconly_overflow"
6281 [(set (reg:CCC FLAGS_REG)
6284 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6285 (match_operand:SWI 2 "<general_operand>" "<g>"))
6287 (clobber (match_scratch:SWI 0 "=<r>"))]
6288 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6289 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6290 [(set_attr "type" "alu")
6291 (set_attr "mode" "<MODE>")])
6293 (define_insn "*sub<mode>3_cconly_overflow"
6294 [(set (reg:CCC FLAGS_REG)
6297 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6298 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6301 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6302 [(set_attr "type" "icmp")
6303 (set_attr "mode" "<MODE>")])
6305 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6306 [(set (reg:CCC FLAGS_REG)
6309 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6310 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6312 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6313 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6314 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6315 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6316 [(set_attr "type" "alu")
6317 (set_attr "mode" "<MODE>")])
6319 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6320 [(set (reg:CCC FLAGS_REG)
6323 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6324 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6326 (set (match_operand:DI 0 "register_operand" "=r")
6327 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6328 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6329 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6330 [(set_attr "type" "alu")
6331 (set_attr "mode" "SI")])
6333 ;; The patterns that match these are at the end of this file.
6335 (define_expand "<plusminus_insn>xf3"
6336 [(set (match_operand:XF 0 "register_operand")
6338 (match_operand:XF 1 "register_operand")
6339 (match_operand:XF 2 "register_operand")))]
6342 (define_expand "<plusminus_insn><mode>3"
6343 [(set (match_operand:MODEF 0 "register_operand")
6345 (match_operand:MODEF 1 "register_operand")
6346 (match_operand:MODEF 2 "nonimmediate_operand")))]
6347 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6348 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6350 ;; Multiply instructions
6352 (define_expand "mul<mode>3"
6353 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6355 (match_operand:SWIM248 1 "register_operand")
6356 (match_operand:SWIM248 2 "<general_operand>")))
6357 (clobber (reg:CC FLAGS_REG))])])
6359 (define_expand "mulqi3"
6360 [(parallel [(set (match_operand:QI 0 "register_operand")
6362 (match_operand:QI 1 "register_operand")
6363 (match_operand:QI 2 "nonimmediate_operand")))
6364 (clobber (reg:CC FLAGS_REG))])]
6365 "TARGET_QIMODE_MATH")
6368 ;; IMUL reg32/64, reg32/64, imm8 Direct
6369 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6370 ;; IMUL reg32/64, reg32/64, imm32 Direct
6371 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6372 ;; IMUL reg32/64, reg32/64 Direct
6373 ;; IMUL reg32/64, mem32/64 Direct
6375 ;; On BDVER1, all above IMULs use DirectPath
6377 (define_insn "*mul<mode>3_1"
6378 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6380 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6381 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6382 (clobber (reg:CC FLAGS_REG))]
6383 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6385 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6386 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6387 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6388 [(set_attr "type" "imul")
6389 (set_attr "prefix_0f" "0,0,1")
6390 (set (attr "athlon_decode")
6391 (cond [(eq_attr "cpu" "athlon")
6392 (const_string "vector")
6393 (eq_attr "alternative" "1")
6394 (const_string "vector")
6395 (and (eq_attr "alternative" "2")
6396 (match_operand 1 "memory_operand"))
6397 (const_string "vector")]
6398 (const_string "direct")))
6399 (set (attr "amdfam10_decode")
6400 (cond [(and (eq_attr "alternative" "0,1")
6401 (match_operand 1 "memory_operand"))
6402 (const_string "vector")]
6403 (const_string "direct")))
6404 (set_attr "bdver1_decode" "direct")
6405 (set_attr "mode" "<MODE>")])
6407 (define_insn "*mulsi3_1_zext"
6408 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6410 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6411 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6412 (clobber (reg:CC FLAGS_REG))]
6414 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6416 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6417 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6418 imul{l}\t{%2, %k0|%k0, %2}"
6419 [(set_attr "type" "imul")
6420 (set_attr "prefix_0f" "0,0,1")
6421 (set (attr "athlon_decode")
6422 (cond [(eq_attr "cpu" "athlon")
6423 (const_string "vector")
6424 (eq_attr "alternative" "1")
6425 (const_string "vector")
6426 (and (eq_attr "alternative" "2")
6427 (match_operand 1 "memory_operand"))
6428 (const_string "vector")]
6429 (const_string "direct")))
6430 (set (attr "amdfam10_decode")
6431 (cond [(and (eq_attr "alternative" "0,1")
6432 (match_operand 1 "memory_operand"))
6433 (const_string "vector")]
6434 (const_string "direct")))
6435 (set_attr "bdver1_decode" "direct")
6436 (set_attr "mode" "SI")])
6439 ;; IMUL reg16, reg16, imm8 VectorPath
6440 ;; IMUL reg16, mem16, imm8 VectorPath
6441 ;; IMUL reg16, reg16, imm16 VectorPath
6442 ;; IMUL reg16, mem16, imm16 VectorPath
6443 ;; IMUL reg16, reg16 Direct
6444 ;; IMUL reg16, mem16 Direct
6446 ;; On BDVER1, all HI MULs use DoublePath
6448 (define_insn "*mulhi3_1"
6449 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6450 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6451 (match_operand:HI 2 "general_operand" "K,n,mr")))
6452 (clobber (reg:CC FLAGS_REG))]
6454 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6456 imul{w}\t{%2, %1, %0|%0, %1, %2}
6457 imul{w}\t{%2, %1, %0|%0, %1, %2}
6458 imul{w}\t{%2, %0|%0, %2}"
6459 [(set_attr "type" "imul")
6460 (set_attr "prefix_0f" "0,0,1")
6461 (set (attr "athlon_decode")
6462 (cond [(eq_attr "cpu" "athlon")
6463 (const_string "vector")
6464 (eq_attr "alternative" "1,2")
6465 (const_string "vector")]
6466 (const_string "direct")))
6467 (set (attr "amdfam10_decode")
6468 (cond [(eq_attr "alternative" "0,1")
6469 (const_string "vector")]
6470 (const_string "direct")))
6471 (set_attr "bdver1_decode" "double")
6472 (set_attr "mode" "HI")])
6474 ;;On AMDFAM10 and BDVER1
6478 (define_insn "*mulqi3_1"
6479 [(set (match_operand:QI 0 "register_operand" "=a")
6480 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6481 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6482 (clobber (reg:CC FLAGS_REG))]
6484 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6486 [(set_attr "type" "imul")
6487 (set_attr "length_immediate" "0")
6488 (set (attr "athlon_decode")
6489 (if_then_else (eq_attr "cpu" "athlon")
6490 (const_string "vector")
6491 (const_string "direct")))
6492 (set_attr "amdfam10_decode" "direct")
6493 (set_attr "bdver1_decode" "direct")
6494 (set_attr "mode" "QI")])
6496 (define_expand "<u>mul<mode><dwi>3"
6497 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6500 (match_operand:DWIH 1 "nonimmediate_operand"))
6502 (match_operand:DWIH 2 "register_operand"))))
6503 (clobber (reg:CC FLAGS_REG))])])
6505 (define_expand "<u>mulqihi3"
6506 [(parallel [(set (match_operand:HI 0 "register_operand")
6509 (match_operand:QI 1 "nonimmediate_operand"))
6511 (match_operand:QI 2 "register_operand"))))
6512 (clobber (reg:CC FLAGS_REG))])]
6513 "TARGET_QIMODE_MATH")
6515 (define_insn "*bmi2_umulditi3_1"
6516 [(set (match_operand:DI 0 "register_operand" "=r")
6518 (match_operand:DI 2 "nonimmediate_operand" "%d")
6519 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6520 (set (match_operand:DI 1 "register_operand" "=r")
6523 (mult:TI (zero_extend:TI (match_dup 2))
6524 (zero_extend:TI (match_dup 3)))
6526 "TARGET_64BIT && TARGET_BMI2
6527 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6528 "mulx\t{%3, %0, %1|%1, %0, %3}"
6529 [(set_attr "type" "imulx")
6530 (set_attr "prefix" "vex")
6531 (set_attr "mode" "DI")])
6533 (define_insn "*bmi2_umulsidi3_1"
6534 [(set (match_operand:SI 0 "register_operand" "=r")
6536 (match_operand:SI 2 "nonimmediate_operand" "%d")
6537 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6538 (set (match_operand:SI 1 "register_operand" "=r")
6541 (mult:DI (zero_extend:DI (match_dup 2))
6542 (zero_extend:DI (match_dup 3)))
6544 "!TARGET_64BIT && TARGET_BMI2
6545 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6546 "mulx\t{%3, %0, %1|%1, %0, %3}"
6547 [(set_attr "type" "imulx")
6548 (set_attr "prefix" "vex")
6549 (set_attr "mode" "SI")])
6551 (define_insn "*umul<mode><dwi>3_1"
6552 [(set (match_operand:<DWI> 0 "register_operand" "=r,A")
6555 (match_operand:DWIH 1 "nonimmediate_operand" "%d,0"))
6557 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6558 (clobber (reg:CC FLAGS_REG))]
6559 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6562 mul{<imodesuffix>}\t%2"
6563 [(set_attr "isa" "bmi2,*")
6564 (set_attr "type" "imulx,imul")
6565 (set_attr "length_immediate" "*,0")
6566 (set (attr "athlon_decode")
6567 (cond [(eq_attr "alternative" "1")
6568 (if_then_else (eq_attr "cpu" "athlon")
6569 (const_string "vector")
6570 (const_string "double"))]
6571 (const_string "*")))
6572 (set_attr "amdfam10_decode" "*,double")
6573 (set_attr "bdver1_decode" "*,direct")
6574 (set_attr "prefix" "vex,orig")
6575 (set_attr "mode" "<MODE>")])
6577 ;; Convert mul to the mulx pattern to avoid flags dependency.
6579 [(set (match_operand:<DWI> 0 "register_operand")
6582 (match_operand:DWIH 1 "register_operand"))
6584 (match_operand:DWIH 2 "nonimmediate_operand"))))
6585 (clobber (reg:CC FLAGS_REG))]
6586 "TARGET_BMI2 && reload_completed
6587 && true_regnum (operands[1]) == DX_REG"
6588 [(parallel [(set (match_dup 3)
6589 (mult:DWIH (match_dup 1) (match_dup 2)))
6593 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6594 (zero_extend:<DWI> (match_dup 2)))
6597 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6599 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6602 (define_insn "*mul<mode><dwi>3_1"
6603 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6606 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6608 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6609 (clobber (reg:CC FLAGS_REG))]
6610 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6611 "imul{<imodesuffix>}\t%2"
6612 [(set_attr "type" "imul")
6613 (set_attr "length_immediate" "0")
6614 (set (attr "athlon_decode")
6615 (if_then_else (eq_attr "cpu" "athlon")
6616 (const_string "vector")
6617 (const_string "double")))
6618 (set_attr "amdfam10_decode" "double")
6619 (set_attr "bdver1_decode" "direct")
6620 (set_attr "mode" "<MODE>")])
6622 (define_insn "*<u>mulqihi3_1"
6623 [(set (match_operand:HI 0 "register_operand" "=a")
6626 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6628 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6629 (clobber (reg:CC FLAGS_REG))]
6631 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6632 "<sgnprefix>mul{b}\t%2"
6633 [(set_attr "type" "imul")
6634 (set_attr "length_immediate" "0")
6635 (set (attr "athlon_decode")
6636 (if_then_else (eq_attr "cpu" "athlon")
6637 (const_string "vector")
6638 (const_string "direct")))
6639 (set_attr "amdfam10_decode" "direct")
6640 (set_attr "bdver1_decode" "direct")
6641 (set_attr "mode" "QI")])
6643 (define_expand "<s>mul<mode>3_highpart"
6644 [(parallel [(set (match_operand:SWI48 0 "register_operand")
6649 (match_operand:SWI48 1 "nonimmediate_operand"))
6651 (match_operand:SWI48 2 "register_operand")))
6653 (clobber (match_scratch:SWI48 3))
6654 (clobber (reg:CC FLAGS_REG))])]
6656 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6658 (define_insn "*<s>muldi3_highpart_1"
6659 [(set (match_operand:DI 0 "register_operand" "=d")
6664 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6666 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6668 (clobber (match_scratch:DI 3 "=1"))
6669 (clobber (reg:CC FLAGS_REG))]
6671 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6672 "<sgnprefix>mul{q}\t%2"
6673 [(set_attr "type" "imul")
6674 (set_attr "length_immediate" "0")
6675 (set (attr "athlon_decode")
6676 (if_then_else (eq_attr "cpu" "athlon")
6677 (const_string "vector")
6678 (const_string "double")))
6679 (set_attr "amdfam10_decode" "double")
6680 (set_attr "bdver1_decode" "direct")
6681 (set_attr "mode" "DI")])
6683 (define_insn "*<s>mulsi3_highpart_1"
6684 [(set (match_operand:SI 0 "register_operand" "=d")
6689 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6691 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6693 (clobber (match_scratch:SI 3 "=1"))
6694 (clobber (reg:CC FLAGS_REG))]
6695 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6696 "<sgnprefix>mul{l}\t%2"
6697 [(set_attr "type" "imul")
6698 (set_attr "length_immediate" "0")
6699 (set (attr "athlon_decode")
6700 (if_then_else (eq_attr "cpu" "athlon")
6701 (const_string "vector")
6702 (const_string "double")))
6703 (set_attr "amdfam10_decode" "double")
6704 (set_attr "bdver1_decode" "direct")
6705 (set_attr "mode" "SI")])
6707 (define_insn "*<s>mulsi3_highpart_zext"
6708 [(set (match_operand:DI 0 "register_operand" "=d")
6709 (zero_extend:DI (truncate:SI
6711 (mult:DI (any_extend:DI
6712 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6714 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6716 (clobber (match_scratch:SI 3 "=1"))
6717 (clobber (reg:CC FLAGS_REG))]
6719 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6720 "<sgnprefix>mul{l}\t%2"
6721 [(set_attr "type" "imul")
6722 (set_attr "length_immediate" "0")
6723 (set (attr "athlon_decode")
6724 (if_then_else (eq_attr "cpu" "athlon")
6725 (const_string "vector")
6726 (const_string "double")))
6727 (set_attr "amdfam10_decode" "double")
6728 (set_attr "bdver1_decode" "direct")
6729 (set_attr "mode" "SI")])
6731 ;; The patterns that match these are at the end of this file.
6733 (define_expand "mulxf3"
6734 [(set (match_operand:XF 0 "register_operand")
6735 (mult:XF (match_operand:XF 1 "register_operand")
6736 (match_operand:XF 2 "register_operand")))]
6739 (define_expand "mul<mode>3"
6740 [(set (match_operand:MODEF 0 "register_operand")
6741 (mult:MODEF (match_operand:MODEF 1 "register_operand")
6742 (match_operand:MODEF 2 "nonimmediate_operand")))]
6743 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6744 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6746 ;; Divide instructions
6748 ;; The patterns that match these are at the end of this file.
6750 (define_expand "divxf3"
6751 [(set (match_operand:XF 0 "register_operand")
6752 (div:XF (match_operand:XF 1 "register_operand")
6753 (match_operand:XF 2 "register_operand")))]
6756 (define_expand "divdf3"
6757 [(set (match_operand:DF 0 "register_operand")
6758 (div:DF (match_operand:DF 1 "register_operand")
6759 (match_operand:DF 2 "nonimmediate_operand")))]
6760 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
6761 || (TARGET_SSE2 && TARGET_SSE_MATH)")
6763 (define_expand "divsf3"
6764 [(set (match_operand:SF 0 "register_operand")
6765 (div:SF (match_operand:SF 1 "register_operand")
6766 (match_operand:SF 2 "nonimmediate_operand")))]
6767 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
6772 && optimize_insn_for_speed_p ()
6773 && flag_finite_math_only && !flag_trapping_math
6774 && flag_unsafe_math_optimizations)
6776 ix86_emit_swdivsf (operands[0], operands[1],
6777 operands[2], SFmode);
6782 ;; Divmod instructions.
6784 (define_expand "divmod<mode>4"
6785 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6787 (match_operand:SWIM248 1 "register_operand")
6788 (match_operand:SWIM248 2 "nonimmediate_operand")))
6789 (set (match_operand:SWIM248 3 "register_operand")
6790 (mod:SWIM248 (match_dup 1) (match_dup 2)))
6791 (clobber (reg:CC FLAGS_REG))])])
6793 ;; Split with 8bit unsigned divide:
6794 ;; if (dividend an divisor are in [0-255])
6795 ;; use 8bit unsigned integer divide
6797 ;; use original integer divide
6799 [(set (match_operand:SWI48 0 "register_operand")
6800 (div:SWI48 (match_operand:SWI48 2 "register_operand")
6801 (match_operand:SWI48 3 "nonimmediate_operand")))
6802 (set (match_operand:SWI48 1 "register_operand")
6803 (mod:SWI48 (match_dup 2) (match_dup 3)))
6804 (clobber (reg:CC FLAGS_REG))]
6805 "TARGET_USE_8BIT_IDIV
6806 && TARGET_QIMODE_MATH
6807 && can_create_pseudo_p ()
6808 && !optimize_insn_for_size_p ()"
6810 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
6812 (define_insn_and_split "divmod<mode>4_1"
6813 [(set (match_operand:SWI48 0 "register_operand" "=a")
6814 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
6815 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
6816 (set (match_operand:SWI48 1 "register_operand" "=&d")
6817 (mod:SWI48 (match_dup 2) (match_dup 3)))
6818 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
6819 (clobber (reg:CC FLAGS_REG))]
6823 [(parallel [(set (match_dup 1)
6824 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
6825 (clobber (reg:CC FLAGS_REG))])
6826 (parallel [(set (match_dup 0)
6827 (div:SWI48 (match_dup 2) (match_dup 3)))
6829 (mod:SWI48 (match_dup 2) (match_dup 3)))
6831 (clobber (reg:CC FLAGS_REG))])]
6833 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
6835 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
6836 operands[4] = operands[2];
6839 /* Avoid use of cltd in favor of a mov+shift. */
6840 emit_move_insn (operands[1], operands[2]);
6841 operands[4] = operands[1];
6844 [(set_attr "type" "multi")
6845 (set_attr "mode" "<MODE>")])
6847 (define_insn_and_split "*divmod<mode>4"
6848 [(set (match_operand:SWIM248 0 "register_operand" "=a")
6849 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
6850 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
6851 (set (match_operand:SWIM248 1 "register_operand" "=&d")
6852 (mod:SWIM248 (match_dup 2) (match_dup 3)))
6853 (clobber (reg:CC FLAGS_REG))]
6857 [(parallel [(set (match_dup 1)
6858 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
6859 (clobber (reg:CC FLAGS_REG))])
6860 (parallel [(set (match_dup 0)
6861 (div:SWIM248 (match_dup 2) (match_dup 3)))
6863 (mod:SWIM248 (match_dup 2) (match_dup 3)))
6865 (clobber (reg:CC FLAGS_REG))])]
6867 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
6869 if (<MODE>mode != HImode
6870 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
6871 operands[4] = operands[2];
6874 /* Avoid use of cltd in favor of a mov+shift. */
6875 emit_move_insn (operands[1], operands[2]);
6876 operands[4] = operands[1];
6879 [(set_attr "type" "multi")
6880 (set_attr "mode" "<MODE>")])
6882 (define_insn "*divmod<mode>4_noext"
6883 [(set (match_operand:SWIM248 0 "register_operand" "=a")
6884 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
6885 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
6886 (set (match_operand:SWIM248 1 "register_operand" "=d")
6887 (mod:SWIM248 (match_dup 2) (match_dup 3)))
6888 (use (match_operand:SWIM248 4 "register_operand" "1"))
6889 (clobber (reg:CC FLAGS_REG))]
6891 "idiv{<imodesuffix>}\t%3"
6892 [(set_attr "type" "idiv")
6893 (set_attr "mode" "<MODE>")])
6895 (define_expand "divmodqi4"
6896 [(parallel [(set (match_operand:QI 0 "register_operand")
6898 (match_operand:QI 1 "register_operand")
6899 (match_operand:QI 2 "nonimmediate_operand")))
6900 (set (match_operand:QI 3 "register_operand")
6901 (mod:QI (match_dup 1) (match_dup 2)))
6902 (clobber (reg:CC FLAGS_REG))])]
6903 "TARGET_QIMODE_MATH"
6908 tmp0 = gen_reg_rtx (HImode);
6909 tmp1 = gen_reg_rtx (HImode);
6911 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
6913 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
6914 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
6916 /* Extract remainder from AH. */
6917 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
6918 insn = emit_move_insn (operands[3], tmp1);
6920 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
6921 set_unique_reg_note (insn, REG_EQUAL, mod);
6923 /* Extract quotient from AL. */
6924 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
6926 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
6927 set_unique_reg_note (insn, REG_EQUAL, div);
6932 ;; Divide AX by r/m8, with result stored in
6935 ;; Change div/mod to HImode and extend the second argument to HImode
6936 ;; so that mode of div/mod matches with mode of arguments. Otherwise
6937 ;; combine may fail.
6938 (define_insn "divmodhiqi3"
6939 [(set (match_operand:HI 0 "register_operand" "=a")
6944 (mod:HI (match_operand:HI 1 "register_operand" "0")
6946 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
6950 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
6951 (clobber (reg:CC FLAGS_REG))]
6952 "TARGET_QIMODE_MATH"
6954 [(set_attr "type" "idiv")
6955 (set_attr "mode" "QI")])
6957 (define_expand "udivmod<mode>4"
6958 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6960 (match_operand:SWIM248 1 "register_operand")
6961 (match_operand:SWIM248 2 "nonimmediate_operand")))
6962 (set (match_operand:SWIM248 3 "register_operand")
6963 (umod:SWIM248 (match_dup 1) (match_dup 2)))
6964 (clobber (reg:CC FLAGS_REG))])])
6966 ;; Split with 8bit unsigned divide:
6967 ;; if (dividend an divisor are in [0-255])
6968 ;; use 8bit unsigned integer divide
6970 ;; use original integer divide
6972 [(set (match_operand:SWI48 0 "register_operand")
6973 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
6974 (match_operand:SWI48 3 "nonimmediate_operand")))
6975 (set (match_operand:SWI48 1 "register_operand")
6976 (umod:SWI48 (match_dup 2) (match_dup 3)))
6977 (clobber (reg:CC FLAGS_REG))]
6978 "TARGET_USE_8BIT_IDIV
6979 && TARGET_QIMODE_MATH
6980 && can_create_pseudo_p ()
6981 && !optimize_insn_for_size_p ()"
6983 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
6985 (define_insn_and_split "udivmod<mode>4_1"
6986 [(set (match_operand:SWI48 0 "register_operand" "=a")
6987 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
6988 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
6989 (set (match_operand:SWI48 1 "register_operand" "=&d")
6990 (umod:SWI48 (match_dup 2) (match_dup 3)))
6991 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
6992 (clobber (reg:CC FLAGS_REG))]
6996 [(set (match_dup 1) (const_int 0))
6997 (parallel [(set (match_dup 0)
6998 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7000 (umod:SWI48 (match_dup 2) (match_dup 3)))
7002 (clobber (reg:CC FLAGS_REG))])]
7004 [(set_attr "type" "multi")
7005 (set_attr "mode" "<MODE>")])
7007 (define_insn_and_split "*udivmod<mode>4"
7008 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7009 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7010 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7011 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7012 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7013 (clobber (reg:CC FLAGS_REG))]
7017 [(set (match_dup 1) (const_int 0))
7018 (parallel [(set (match_dup 0)
7019 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7021 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7023 (clobber (reg:CC FLAGS_REG))])]
7025 [(set_attr "type" "multi")
7026 (set_attr "mode" "<MODE>")])
7028 (define_insn "*udivmod<mode>4_noext"
7029 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7030 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7031 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7032 (set (match_operand:SWIM248 1 "register_operand" "=d")
7033 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7034 (use (match_operand:SWIM248 4 "register_operand" "1"))
7035 (clobber (reg:CC FLAGS_REG))]
7037 "div{<imodesuffix>}\t%3"
7038 [(set_attr "type" "idiv")
7039 (set_attr "mode" "<MODE>")])
7041 (define_expand "udivmodqi4"
7042 [(parallel [(set (match_operand:QI 0 "register_operand")
7044 (match_operand:QI 1 "register_operand")
7045 (match_operand:QI 2 "nonimmediate_operand")))
7046 (set (match_operand:QI 3 "register_operand")
7047 (umod:QI (match_dup 1) (match_dup 2)))
7048 (clobber (reg:CC FLAGS_REG))])]
7049 "TARGET_QIMODE_MATH"
7054 tmp0 = gen_reg_rtx (HImode);
7055 tmp1 = gen_reg_rtx (HImode);
7057 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7059 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7060 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7062 /* Extract remainder from AH. */
7063 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7064 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7065 insn = emit_move_insn (operands[3], tmp1);
7067 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7068 set_unique_reg_note (insn, REG_EQUAL, mod);
7070 /* Extract quotient from AL. */
7071 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7073 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7074 set_unique_reg_note (insn, REG_EQUAL, div);
7079 (define_insn "udivmodhiqi3"
7080 [(set (match_operand:HI 0 "register_operand" "=a")
7085 (mod:HI (match_operand:HI 1 "register_operand" "0")
7087 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7091 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7092 (clobber (reg:CC FLAGS_REG))]
7093 "TARGET_QIMODE_MATH"
7095 [(set_attr "type" "idiv")
7096 (set_attr "mode" "QI")])
7098 ;; We cannot use div/idiv for double division, because it causes
7099 ;; "division by zero" on the overflow and that's not what we expect
7100 ;; from truncate. Because true (non truncating) double division is
7101 ;; never generated, we can't create this insn anyway.
7104 ; [(set (match_operand:SI 0 "register_operand" "=a")
7106 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7108 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7109 ; (set (match_operand:SI 3 "register_operand" "=d")
7111 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7112 ; (clobber (reg:CC FLAGS_REG))]
7114 ; "div{l}\t{%2, %0|%0, %2}"
7115 ; [(set_attr "type" "idiv")])
7117 ;;- Logical AND instructions
7119 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7120 ;; Note that this excludes ah.
7122 (define_expand "testsi_ccno_1"
7123 [(set (reg:CCNO FLAGS_REG)
7125 (and:SI (match_operand:SI 0 "nonimmediate_operand")
7126 (match_operand:SI 1 "x86_64_nonmemory_operand"))
7129 (define_expand "testqi_ccz_1"
7130 [(set (reg:CCZ FLAGS_REG)
7131 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7132 (match_operand:QI 1 "nonmemory_operand"))
7135 (define_expand "testdi_ccno_1"
7136 [(set (reg:CCNO FLAGS_REG)
7138 (and:DI (match_operand:DI 0 "nonimmediate_operand")
7139 (match_operand:DI 1 "x86_64_szext_general_operand"))
7141 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7143 (define_insn "*testdi_1"
7144 [(set (reg FLAGS_REG)
7147 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7148 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7150 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7151 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7153 test{l}\t{%k1, %k0|%k0, %k1}
7154 test{l}\t{%k1, %k0|%k0, %k1}
7155 test{q}\t{%1, %0|%0, %1}
7156 test{q}\t{%1, %0|%0, %1}
7157 test{q}\t{%1, %0|%0, %1}"
7158 [(set_attr "type" "test")
7159 (set_attr "modrm" "0,1,0,1,1")
7160 (set_attr "mode" "SI,SI,DI,DI,DI")])
7162 (define_insn "*testqi_1_maybe_si"
7163 [(set (reg FLAGS_REG)
7166 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7167 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7169 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7170 && ix86_match_ccmode (insn,
7171 CONST_INT_P (operands[1])
7172 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7174 if (which_alternative == 3)
7176 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7177 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7178 return "test{l}\t{%1, %k0|%k0, %1}";
7180 return "test{b}\t{%1, %0|%0, %1}";
7182 [(set_attr "type" "test")
7183 (set_attr "modrm" "0,1,1,1")
7184 (set_attr "mode" "QI,QI,QI,SI")
7185 (set_attr "pent_pair" "uv,np,uv,np")])
7187 (define_insn "*test<mode>_1"
7188 [(set (reg FLAGS_REG)
7191 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7192 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7194 "ix86_match_ccmode (insn, CCNOmode)
7195 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7196 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7197 [(set_attr "type" "test")
7198 (set_attr "modrm" "0,1,1")
7199 (set_attr "mode" "<MODE>")
7200 (set_attr "pent_pair" "uv,np,uv")])
7202 (define_expand "testqi_ext_ccno_0"
7203 [(set (reg:CCNO FLAGS_REG)
7207 (match_operand 0 "ext_register_operand")
7210 (match_operand 1 "const_int_operand"))
7213 (define_insn "*testqi_ext_0"
7214 [(set (reg FLAGS_REG)
7218 (match_operand 0 "ext_register_operand" "Q")
7221 (match_operand 1 "const_int_operand" "n"))
7223 "ix86_match_ccmode (insn, CCNOmode)"
7224 "test{b}\t{%1, %h0|%h0, %1}"
7225 [(set_attr "type" "test")
7226 (set_attr "mode" "QI")
7227 (set_attr "length_immediate" "1")
7228 (set_attr "modrm" "1")
7229 (set_attr "pent_pair" "np")])
7231 (define_insn "*testqi_ext_1"
7232 [(set (reg FLAGS_REG)
7236 (match_operand 0 "ext_register_operand" "Q,Q")
7240 (match_operand:QI 1 "nonimmediate_x64nomem_operand" "Q,m")))
7242 "ix86_match_ccmode (insn, CCNOmode)"
7243 "test{b}\t{%1, %h0|%h0, %1}"
7244 [(set_attr "isa" "*,nox64")
7245 (set_attr "type" "test")
7246 (set_attr "mode" "QI")])
7248 (define_insn "*testqi_ext_2"
7249 [(set (reg FLAGS_REG)
7253 (match_operand 0 "ext_register_operand" "Q")
7257 (match_operand 1 "ext_register_operand" "Q")
7261 "ix86_match_ccmode (insn, CCNOmode)"
7262 "test{b}\t{%h1, %h0|%h0, %h1}"
7263 [(set_attr "type" "test")
7264 (set_attr "mode" "QI")])
7266 ;; Combine likes to form bit extractions for some tests. Humor it.
7267 (define_insn "*testqi_ext_3"
7268 [(set (reg FLAGS_REG)
7269 (compare (zero_extract:SWI48
7270 (match_operand 0 "nonimmediate_operand" "rm")
7271 (match_operand:SWI48 1 "const_int_operand")
7272 (match_operand:SWI48 2 "const_int_operand"))
7274 "ix86_match_ccmode (insn, CCNOmode)
7275 && ((TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7276 || GET_MODE (operands[0]) == SImode
7277 || GET_MODE (operands[0]) == HImode
7278 || GET_MODE (operands[0]) == QImode)
7279 /* Ensure that resulting mask is zero or sign extended operand. */
7280 && INTVAL (operands[2]) >= 0
7281 && ((INTVAL (operands[1]) > 0
7282 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32)
7283 || (<MODE>mode == DImode
7284 && INTVAL (operands[1]) > 32
7285 && INTVAL (operands[1]) + INTVAL (operands[2]) == 64))"
7289 [(set (match_operand 0 "flags_reg_operand")
7290 (match_operator 1 "compare_operator"
7292 (match_operand 2 "nonimmediate_operand")
7293 (match_operand 3 "const_int_operand")
7294 (match_operand 4 "const_int_operand"))
7296 "ix86_match_ccmode (insn, CCNOmode)"
7297 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7299 rtx val = operands[2];
7300 HOST_WIDE_INT len = INTVAL (operands[3]);
7301 HOST_WIDE_INT pos = INTVAL (operands[4]);
7303 enum machine_mode mode, submode;
7305 mode = GET_MODE (val);
7308 /* ??? Combine likes to put non-volatile mem extractions in QImode
7309 no matter the size of the test. So find a mode that works. */
7310 if (! MEM_VOLATILE_P (val))
7312 mode = smallest_mode_for_size (pos + len, MODE_INT);
7313 val = adjust_address (val, mode, 0);
7316 else if (GET_CODE (val) == SUBREG
7317 && (submode = GET_MODE (SUBREG_REG (val)),
7318 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7319 && pos + len <= GET_MODE_BITSIZE (submode)
7320 && GET_MODE_CLASS (submode) == MODE_INT)
7322 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7324 val = SUBREG_REG (val);
7326 else if (mode == HImode && pos + len <= 8)
7328 /* Small HImode tests can be converted to QImode. */
7330 val = gen_lowpart (QImode, val);
7333 if (len == HOST_BITS_PER_WIDE_INT)
7336 mask = ((HOST_WIDE_INT)1 << len) - 1;
7339 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7342 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7343 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7344 ;; this is relatively important trick.
7345 ;; Do the conversion only post-reload to avoid limiting of the register class
7348 [(set (match_operand 0 "flags_reg_operand")
7349 (match_operator 1 "compare_operator"
7350 [(and (match_operand 2 "register_operand")
7351 (match_operand 3 "const_int_operand"))
7354 && QI_REG_P (operands[2])
7355 && GET_MODE (operands[2]) != QImode
7356 && ((ix86_match_ccmode (insn, CCZmode)
7357 && !(INTVAL (operands[3]) & ~(255 << 8)))
7358 || (ix86_match_ccmode (insn, CCNOmode)
7359 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7362 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7366 operands[2] = gen_lowpart (SImode, operands[2]);
7367 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7371 [(set (match_operand 0 "flags_reg_operand")
7372 (match_operator 1 "compare_operator"
7373 [(and (match_operand 2 "nonimmediate_operand")
7374 (match_operand 3 "const_int_operand"))
7377 && GET_MODE (operands[2]) != QImode
7378 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7379 && ((ix86_match_ccmode (insn, CCZmode)
7380 && !(INTVAL (operands[3]) & ~255))
7381 || (ix86_match_ccmode (insn, CCNOmode)
7382 && !(INTVAL (operands[3]) & ~127)))"
7384 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7387 operands[2] = gen_lowpart (QImode, operands[2]);
7388 operands[3] = gen_lowpart (QImode, operands[3]);
7391 ;; %%% This used to optimize known byte-wide and operations to memory,
7392 ;; and sometimes to QImode registers. If this is considered useful,
7393 ;; it should be done with splitters.
7395 (define_expand "and<mode>3"
7396 [(set (match_operand:SWIM 0 "nonimmediate_operand")
7397 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7398 (match_operand:SWIM 2 "<general_szext_operand>")))]
7401 enum machine_mode mode = <MODE>mode;
7402 rtx (*insn) (rtx, rtx);
7404 if (CONST_INT_P (operands[2]) && REG_P (operands[0]))
7406 HOST_WIDE_INT ival = INTVAL (operands[2]);
7408 if (ival == (HOST_WIDE_INT) 0xffffffff)
7410 else if (ival == 0xffff)
7412 else if (ival == 0xff)
7416 if (mode == <MODE>mode)
7418 ix86_expand_binary_operator (AND, <MODE>mode, operands);
7422 if (<MODE>mode == DImode)
7423 insn = (mode == SImode)
7424 ? gen_zero_extendsidi2
7426 ? gen_zero_extendhidi2
7427 : gen_zero_extendqidi2;
7428 else if (<MODE>mode == SImode)
7429 insn = (mode == HImode)
7430 ? gen_zero_extendhisi2
7431 : gen_zero_extendqisi2;
7432 else if (<MODE>mode == HImode)
7433 insn = gen_zero_extendqihi2;
7437 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7441 (define_insn "*anddi_1"
7442 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7444 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7445 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7446 (clobber (reg:CC FLAGS_REG))]
7447 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7449 switch (get_attr_type (insn))
7455 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7456 if (get_attr_mode (insn) == MODE_SI)
7457 return "and{l}\t{%k2, %k0|%k0, %k2}";
7459 return "and{q}\t{%2, %0|%0, %2}";
7462 [(set_attr "type" "alu,alu,alu,imovx")
7463 (set_attr "length_immediate" "*,*,*,0")
7464 (set (attr "prefix_rex")
7466 (and (eq_attr "type" "imovx")
7467 (and (match_test "INTVAL (operands[2]) == 0xff")
7468 (match_operand 1 "ext_QIreg_operand")))
7470 (const_string "*")))
7471 (set_attr "mode" "SI,DI,DI,SI")])
7473 (define_insn "*andsi_1"
7474 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya")
7475 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7476 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7477 (clobber (reg:CC FLAGS_REG))]
7478 "ix86_binary_operator_ok (AND, SImode, operands)"
7480 switch (get_attr_type (insn))
7486 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7487 return "and{l}\t{%2, %0|%0, %2}";
7490 [(set_attr "type" "alu,alu,imovx")
7491 (set (attr "prefix_rex")
7493 (and (eq_attr "type" "imovx")
7494 (and (match_test "INTVAL (operands[2]) == 0xff")
7495 (match_operand 1 "ext_QIreg_operand")))
7497 (const_string "*")))
7498 (set_attr "length_immediate" "*,*,0")
7499 (set_attr "mode" "SI")])
7501 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7502 (define_insn "*andsi_1_zext"
7503 [(set (match_operand:DI 0 "register_operand" "=r")
7505 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7506 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7507 (clobber (reg:CC FLAGS_REG))]
7508 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7509 "and{l}\t{%2, %k0|%k0, %2}"
7510 [(set_attr "type" "alu")
7511 (set_attr "mode" "SI")])
7513 (define_insn "*andhi_1"
7514 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya")
7515 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7516 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7517 (clobber (reg:CC FLAGS_REG))]
7518 "ix86_binary_operator_ok (AND, HImode, operands)"
7520 switch (get_attr_type (insn))
7526 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7527 return "and{w}\t{%2, %0|%0, %2}";
7530 [(set_attr "type" "alu,alu,imovx")
7531 (set_attr "length_immediate" "*,*,0")
7532 (set (attr "prefix_rex")
7534 (and (eq_attr "type" "imovx")
7535 (match_operand 1 "ext_QIreg_operand"))
7537 (const_string "*")))
7538 (set_attr "mode" "HI,HI,SI")])
7540 ;; %%% Potential partial reg stall on alternative 2. What to do?
7541 (define_insn "*andqi_1"
7542 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7543 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7544 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7545 (clobber (reg:CC FLAGS_REG))]
7546 "ix86_binary_operator_ok (AND, QImode, operands)"
7548 and{b}\t{%2, %0|%0, %2}
7549 and{b}\t{%2, %0|%0, %2}
7550 and{l}\t{%k2, %k0|%k0, %k2}"
7551 [(set_attr "type" "alu")
7552 (set_attr "mode" "QI,QI,SI")])
7554 (define_insn "*andqi_1_slp"
7555 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7556 (and:QI (match_dup 0)
7557 (match_operand:QI 1 "general_operand" "qn,qmn")))
7558 (clobber (reg:CC FLAGS_REG))]
7559 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7560 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7561 "and{b}\t{%1, %0|%0, %1}"
7562 [(set_attr "type" "alu1")
7563 (set_attr "mode" "QI")])
7565 ;; Turn *anddi_1 into *andsi_1_zext if possible.
7567 [(set (match_operand:DI 0 "register_operand")
7568 (and:DI (subreg:DI (match_operand:SI 1 "register_operand") 0)
7569 (match_operand:DI 2 "x86_64_zext_immediate_operand")))
7570 (clobber (reg:CC FLAGS_REG))]
7572 [(parallel [(set (match_dup 0)
7573 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))
7574 (clobber (reg:CC FLAGS_REG))])]
7575 "operands[2] = gen_lowpart (SImode, operands[2]);")
7578 [(set (match_operand:SWI248 0 "register_operand")
7579 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
7580 (match_operand:SWI248 2 "const_int_operand")))
7581 (clobber (reg:CC FLAGS_REG))]
7583 && true_regnum (operands[0]) != true_regnum (operands[1])"
7586 HOST_WIDE_INT ival = INTVAL (operands[2]);
7587 enum machine_mode mode;
7588 rtx (*insn) (rtx, rtx);
7590 if (ival == (HOST_WIDE_INT) 0xffffffff)
7592 else if (ival == 0xffff)
7596 gcc_assert (ival == 0xff);
7600 if (<MODE>mode == DImode)
7601 insn = (mode == SImode)
7602 ? gen_zero_extendsidi2
7604 ? gen_zero_extendhidi2
7605 : gen_zero_extendqidi2;
7608 if (<MODE>mode != SImode)
7609 /* Zero extend to SImode to avoid partial register stalls. */
7610 operands[0] = gen_lowpart (SImode, operands[0]);
7612 insn = (mode == HImode)
7613 ? gen_zero_extendhisi2
7614 : gen_zero_extendqisi2;
7616 emit_insn (insn (operands[0], gen_lowpart (mode, operands[1])));
7621 [(set (match_operand 0 "register_operand")
7623 (const_int -65536)))
7624 (clobber (reg:CC FLAGS_REG))]
7625 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7626 || optimize_function_for_size_p (cfun)"
7627 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7628 "operands[1] = gen_lowpart (HImode, operands[0]);")
7631 [(set (match_operand 0 "ext_register_operand")
7634 (clobber (reg:CC FLAGS_REG))]
7635 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7636 && reload_completed"
7637 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7638 "operands[1] = gen_lowpart (QImode, operands[0]);")
7641 [(set (match_operand 0 "ext_register_operand")
7643 (const_int -65281)))
7644 (clobber (reg:CC FLAGS_REG))]
7645 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7646 && reload_completed"
7647 [(parallel [(set (zero_extract:SI (match_dup 0)
7651 (zero_extract:SI (match_dup 0)
7654 (zero_extract:SI (match_dup 0)
7657 (clobber (reg:CC FLAGS_REG))])]
7658 "operands[0] = gen_lowpart (SImode, operands[0]);")
7660 (define_insn "*anddi_2"
7661 [(set (reg FLAGS_REG)
7664 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7665 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7667 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7668 (and:DI (match_dup 1) (match_dup 2)))]
7669 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7670 && ix86_binary_operator_ok (AND, DImode, operands)"
7672 and{l}\t{%k2, %k0|%k0, %k2}
7673 and{q}\t{%2, %0|%0, %2}
7674 and{q}\t{%2, %0|%0, %2}"
7675 [(set_attr "type" "alu")
7676 (set_attr "mode" "SI,DI,DI")])
7678 (define_insn "*andqi_2_maybe_si"
7679 [(set (reg FLAGS_REG)
7681 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7682 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7684 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7685 (and:QI (match_dup 1) (match_dup 2)))]
7686 "ix86_binary_operator_ok (AND, QImode, operands)
7687 && ix86_match_ccmode (insn,
7688 CONST_INT_P (operands[2])
7689 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7691 if (which_alternative == 2)
7693 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7694 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7695 return "and{l}\t{%2, %k0|%k0, %2}";
7697 return "and{b}\t{%2, %0|%0, %2}";
7699 [(set_attr "type" "alu")
7700 (set_attr "mode" "QI,QI,SI")])
7702 (define_insn "*and<mode>_2"
7703 [(set (reg FLAGS_REG)
7704 (compare (and:SWI124
7705 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7706 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7708 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7709 (and:SWI124 (match_dup 1) (match_dup 2)))]
7710 "ix86_match_ccmode (insn, CCNOmode)
7711 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7712 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7713 [(set_attr "type" "alu")
7714 (set_attr "mode" "<MODE>")])
7716 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7717 (define_insn "*andsi_2_zext"
7718 [(set (reg FLAGS_REG)
7720 (match_operand:SI 1 "nonimmediate_operand" "%0")
7721 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7723 (set (match_operand:DI 0 "register_operand" "=r")
7724 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7725 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7726 && ix86_binary_operator_ok (AND, SImode, operands)"
7727 "and{l}\t{%2, %k0|%k0, %2}"
7728 [(set_attr "type" "alu")
7729 (set_attr "mode" "SI")])
7731 (define_insn "*andqi_2_slp"
7732 [(set (reg FLAGS_REG)
7734 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7735 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
7737 (set (strict_low_part (match_dup 0))
7738 (and:QI (match_dup 0) (match_dup 1)))]
7739 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7740 && ix86_match_ccmode (insn, CCNOmode)
7741 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7742 "and{b}\t{%1, %0|%0, %1}"
7743 [(set_attr "type" "alu1")
7744 (set_attr "mode" "QI")])
7746 ;; ??? A bug in recog prevents it from recognizing a const_int as an
7747 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
7748 ;; for a QImode operand, which of course failed.
7749 (define_insn "andqi_ext_0"
7750 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7755 (match_operand 1 "ext_register_operand" "0")
7758 (match_operand 2 "const_int_operand" "n")))
7759 (clobber (reg:CC FLAGS_REG))]
7761 "and{b}\t{%2, %h0|%h0, %2}"
7762 [(set_attr "type" "alu")
7763 (set_attr "length_immediate" "1")
7764 (set_attr "modrm" "1")
7765 (set_attr "mode" "QI")])
7767 ;; Generated by peephole translating test to and. This shows up
7768 ;; often in fp comparisons.
7769 (define_insn "*andqi_ext_0_cc"
7770 [(set (reg FLAGS_REG)
7774 (match_operand 1 "ext_register_operand" "0")
7777 (match_operand 2 "const_int_operand" "n"))
7779 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7788 "ix86_match_ccmode (insn, CCNOmode)"
7789 "and{b}\t{%2, %h0|%h0, %2}"
7790 [(set_attr "type" "alu")
7791 (set_attr "length_immediate" "1")
7792 (set_attr "modrm" "1")
7793 (set_attr "mode" "QI")])
7795 (define_insn "*andqi_ext_1"
7796 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
7801 (match_operand 1 "ext_register_operand" "0,0")
7805 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
7806 (clobber (reg:CC FLAGS_REG))]
7808 "and{b}\t{%2, %h0|%h0, %2}"
7809 [(set_attr "isa" "*,nox64")
7810 (set_attr "type" "alu")
7811 (set_attr "length_immediate" "0")
7812 (set_attr "mode" "QI")])
7814 (define_insn "*andqi_ext_2"
7815 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7820 (match_operand 1 "ext_register_operand" "%0")
7824 (match_operand 2 "ext_register_operand" "Q")
7827 (clobber (reg:CC FLAGS_REG))]
7829 "and{b}\t{%h2, %h0|%h0, %h2}"
7830 [(set_attr "type" "alu")
7831 (set_attr "length_immediate" "0")
7832 (set_attr "mode" "QI")])
7834 ;; Convert wide AND instructions with immediate operand to shorter QImode
7835 ;; equivalents when possible.
7836 ;; Don't do the splitting with memory operands, since it introduces risk
7837 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
7838 ;; for size, but that can (should?) be handled by generic code instead.
7840 [(set (match_operand 0 "register_operand")
7841 (and (match_operand 1 "register_operand")
7842 (match_operand 2 "const_int_operand")))
7843 (clobber (reg:CC FLAGS_REG))]
7845 && QI_REG_P (operands[0])
7846 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7847 && !(~INTVAL (operands[2]) & ~(255 << 8))
7848 && GET_MODE (operands[0]) != QImode"
7849 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
7850 (and:SI (zero_extract:SI (match_dup 1)
7851 (const_int 8) (const_int 8))
7853 (clobber (reg:CC FLAGS_REG))])]
7855 operands[0] = gen_lowpart (SImode, operands[0]);
7856 operands[1] = gen_lowpart (SImode, operands[1]);
7857 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
7860 ;; Since AND can be encoded with sign extended immediate, this is only
7861 ;; profitable when 7th bit is not set.
7863 [(set (match_operand 0 "register_operand")
7864 (and (match_operand 1 "general_operand")
7865 (match_operand 2 "const_int_operand")))
7866 (clobber (reg:CC FLAGS_REG))]
7868 && ANY_QI_REG_P (operands[0])
7869 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7870 && !(~INTVAL (operands[2]) & ~255)
7871 && !(INTVAL (operands[2]) & 128)
7872 && GET_MODE (operands[0]) != QImode"
7873 [(parallel [(set (strict_low_part (match_dup 0))
7874 (and:QI (match_dup 1)
7876 (clobber (reg:CC FLAGS_REG))])]
7878 operands[0] = gen_lowpart (QImode, operands[0]);
7879 operands[1] = gen_lowpart (QImode, operands[1]);
7880 operands[2] = gen_lowpart (QImode, operands[2]);
7883 ;; Logical inclusive and exclusive OR instructions
7885 ;; %%% This used to optimize known byte-wide and operations to memory.
7886 ;; If this is considered useful, it should be done with splitters.
7888 (define_expand "<code><mode>3"
7889 [(set (match_operand:SWIM 0 "nonimmediate_operand")
7890 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7891 (match_operand:SWIM 2 "<general_operand>")))]
7893 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
7895 (define_insn "*<code><mode>_1"
7896 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
7898 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
7899 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
7900 (clobber (reg:CC FLAGS_REG))]
7901 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7902 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7903 [(set_attr "type" "alu")
7904 (set_attr "mode" "<MODE>")])
7906 ;; %%% Potential partial reg stall on alternative 2. What to do?
7907 (define_insn "*<code>qi_1"
7908 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
7909 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7910 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
7911 (clobber (reg:CC FLAGS_REG))]
7912 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
7914 <logic>{b}\t{%2, %0|%0, %2}
7915 <logic>{b}\t{%2, %0|%0, %2}
7916 <logic>{l}\t{%k2, %k0|%k0, %k2}"
7917 [(set_attr "type" "alu")
7918 (set_attr "mode" "QI,QI,SI")])
7920 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7921 (define_insn "*<code>si_1_zext"
7922 [(set (match_operand:DI 0 "register_operand" "=r")
7924 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7925 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7926 (clobber (reg:CC FLAGS_REG))]
7927 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7928 "<logic>{l}\t{%2, %k0|%k0, %2}"
7929 [(set_attr "type" "alu")
7930 (set_attr "mode" "SI")])
7932 (define_insn "*<code>si_1_zext_imm"
7933 [(set (match_operand:DI 0 "register_operand" "=r")
7935 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
7936 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
7937 (clobber (reg:CC FLAGS_REG))]
7938 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7939 "<logic>{l}\t{%2, %k0|%k0, %2}"
7940 [(set_attr "type" "alu")
7941 (set_attr "mode" "SI")])
7943 (define_insn "*<code>qi_1_slp"
7944 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
7945 (any_or:QI (match_dup 0)
7946 (match_operand:QI 1 "general_operand" "qmn,qn")))
7947 (clobber (reg:CC FLAGS_REG))]
7948 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7949 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7950 "<logic>{b}\t{%1, %0|%0, %1}"
7951 [(set_attr "type" "alu1")
7952 (set_attr "mode" "QI")])
7954 (define_insn "*<code><mode>_2"
7955 [(set (reg FLAGS_REG)
7956 (compare (any_or:SWI
7957 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
7958 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
7960 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
7961 (any_or:SWI (match_dup 1) (match_dup 2)))]
7962 "ix86_match_ccmode (insn, CCNOmode)
7963 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7964 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7965 [(set_attr "type" "alu")
7966 (set_attr "mode" "<MODE>")])
7968 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7969 ;; ??? Special case for immediate operand is missing - it is tricky.
7970 (define_insn "*<code>si_2_zext"
7971 [(set (reg FLAGS_REG)
7972 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7973 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7975 (set (match_operand:DI 0 "register_operand" "=r")
7976 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
7977 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7978 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7979 "<logic>{l}\t{%2, %k0|%k0, %2}"
7980 [(set_attr "type" "alu")
7981 (set_attr "mode" "SI")])
7983 (define_insn "*<code>si_2_zext_imm"
7984 [(set (reg FLAGS_REG)
7986 (match_operand:SI 1 "nonimmediate_operand" "%0")
7987 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
7989 (set (match_operand:DI 0 "register_operand" "=r")
7990 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
7991 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7992 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7993 "<logic>{l}\t{%2, %k0|%k0, %2}"
7994 [(set_attr "type" "alu")
7995 (set_attr "mode" "SI")])
7997 (define_insn "*<code>qi_2_slp"
7998 [(set (reg FLAGS_REG)
7999 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8000 (match_operand:QI 1 "general_operand" "qmn,qn"))
8002 (set (strict_low_part (match_dup 0))
8003 (any_or:QI (match_dup 0) (match_dup 1)))]
8004 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8005 && ix86_match_ccmode (insn, CCNOmode)
8006 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8007 "<logic>{b}\t{%1, %0|%0, %1}"
8008 [(set_attr "type" "alu1")
8009 (set_attr "mode" "QI")])
8011 (define_insn "*<code><mode>_3"
8012 [(set (reg FLAGS_REG)
8013 (compare (any_or:SWI
8014 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8015 (match_operand:SWI 2 "<general_operand>" "<g>"))
8017 (clobber (match_scratch:SWI 0 "=<r>"))]
8018 "ix86_match_ccmode (insn, CCNOmode)
8019 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8020 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8021 [(set_attr "type" "alu")
8022 (set_attr "mode" "<MODE>")])
8024 (define_insn "*<code>qi_ext_0"
8025 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8030 (match_operand 1 "ext_register_operand" "0")
8033 (match_operand 2 "const_int_operand" "n")))
8034 (clobber (reg:CC FLAGS_REG))]
8035 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8036 "<logic>{b}\t{%2, %h0|%h0, %2}"
8037 [(set_attr "type" "alu")
8038 (set_attr "length_immediate" "1")
8039 (set_attr "modrm" "1")
8040 (set_attr "mode" "QI")])
8042 (define_insn "*<code>qi_ext_1"
8043 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8048 (match_operand 1 "ext_register_operand" "0,0")
8052 (match_operand:QI 2 "nonimmediate_x64nomem_operand" "Q,m"))))
8053 (clobber (reg:CC FLAGS_REG))]
8054 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8055 "<logic>{b}\t{%2, %h0|%h0, %2}"
8056 [(set_attr "isa" "*,nox64")
8057 (set_attr "type" "alu")
8058 (set_attr "length_immediate" "0")
8059 (set_attr "mode" "QI")])
8061 (define_insn "*<code>qi_ext_2"
8062 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8066 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8069 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8072 (clobber (reg:CC FLAGS_REG))]
8073 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8074 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8075 [(set_attr "type" "alu")
8076 (set_attr "length_immediate" "0")
8077 (set_attr "mode" "QI")])
8080 [(set (match_operand 0 "register_operand")
8081 (any_or (match_operand 1 "register_operand")
8082 (match_operand 2 "const_int_operand")))
8083 (clobber (reg:CC FLAGS_REG))]
8085 && QI_REG_P (operands[0])
8086 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8087 && !(INTVAL (operands[2]) & ~(255 << 8))
8088 && GET_MODE (operands[0]) != QImode"
8089 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8090 (any_or:SI (zero_extract:SI (match_dup 1)
8091 (const_int 8) (const_int 8))
8093 (clobber (reg:CC FLAGS_REG))])]
8095 operands[0] = gen_lowpart (SImode, operands[0]);
8096 operands[1] = gen_lowpart (SImode, operands[1]);
8097 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8100 ;; Since OR can be encoded with sign extended immediate, this is only
8101 ;; profitable when 7th bit is set.
8103 [(set (match_operand 0 "register_operand")
8104 (any_or (match_operand 1 "general_operand")
8105 (match_operand 2 "const_int_operand")))
8106 (clobber (reg:CC FLAGS_REG))]
8108 && ANY_QI_REG_P (operands[0])
8109 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8110 && !(INTVAL (operands[2]) & ~255)
8111 && (INTVAL (operands[2]) & 128)
8112 && GET_MODE (operands[0]) != QImode"
8113 [(parallel [(set (strict_low_part (match_dup 0))
8114 (any_or:QI (match_dup 1)
8116 (clobber (reg:CC FLAGS_REG))])]
8118 operands[0] = gen_lowpart (QImode, operands[0]);
8119 operands[1] = gen_lowpart (QImode, operands[1]);
8120 operands[2] = gen_lowpart (QImode, operands[2]);
8123 (define_expand "xorqi_cc_ext_1"
8125 (set (reg:CCNO FLAGS_REG)
8129 (match_operand 1 "ext_register_operand")
8132 (match_operand:QI 2 "const_int_operand"))
8134 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8144 (define_insn "*xorqi_cc_ext_1"
8145 [(set (reg FLAGS_REG)
8149 (match_operand 1 "ext_register_operand" "0,0")
8152 (match_operand:QI 2 "general_x64nomem_operand" "Qn,m"))
8154 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q,Q")
8163 "ix86_match_ccmode (insn, CCNOmode)"
8164 "xor{b}\t{%2, %h0|%h0, %2}"
8165 [(set_attr "isa" "*,nox64")
8166 (set_attr "type" "alu")
8167 (set_attr "modrm" "1")
8168 (set_attr "mode" "QI")])
8170 ;; Negation instructions
8172 (define_expand "neg<mode>2"
8173 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8174 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8176 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8178 (define_insn_and_split "*neg<dwi>2_doubleword"
8179 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8180 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8181 (clobber (reg:CC FLAGS_REG))]
8182 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8186 [(set (reg:CCZ FLAGS_REG)
8187 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8188 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8191 (plus:DWIH (match_dup 3)
8192 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8194 (clobber (reg:CC FLAGS_REG))])
8197 (neg:DWIH (match_dup 2)))
8198 (clobber (reg:CC FLAGS_REG))])]
8199 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8201 (define_insn "*neg<mode>2_1"
8202 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8203 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8204 (clobber (reg:CC FLAGS_REG))]
8205 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8206 "neg{<imodesuffix>}\t%0"
8207 [(set_attr "type" "negnot")
8208 (set_attr "mode" "<MODE>")])
8210 ;; Combine is quite creative about this pattern.
8211 (define_insn "*negsi2_1_zext"
8212 [(set (match_operand:DI 0 "register_operand" "=r")
8214 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8217 (clobber (reg:CC FLAGS_REG))]
8218 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8220 [(set_attr "type" "negnot")
8221 (set_attr "mode" "SI")])
8223 ;; The problem with neg is that it does not perform (compare x 0),
8224 ;; it really performs (compare 0 x), which leaves us with the zero
8225 ;; flag being the only useful item.
8227 (define_insn "*neg<mode>2_cmpz"
8228 [(set (reg:CCZ FLAGS_REG)
8230 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8232 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8233 (neg:SWI (match_dup 1)))]
8234 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8235 "neg{<imodesuffix>}\t%0"
8236 [(set_attr "type" "negnot")
8237 (set_attr "mode" "<MODE>")])
8239 (define_insn "*negsi2_cmpz_zext"
8240 [(set (reg:CCZ FLAGS_REG)
8244 (match_operand:DI 1 "register_operand" "0")
8248 (set (match_operand:DI 0 "register_operand" "=r")
8249 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8252 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8254 [(set_attr "type" "negnot")
8255 (set_attr "mode" "SI")])
8257 ;; Changing of sign for FP values is doable using integer unit too.
8259 (define_expand "<code><mode>2"
8260 [(set (match_operand:X87MODEF 0 "register_operand")
8261 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8262 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8263 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8265 (define_insn "*absneg<mode>2_mixed"
8266 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8267 (match_operator:MODEF 3 "absneg_operator"
8268 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8269 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8270 (clobber (reg:CC FLAGS_REG))]
8271 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8274 (define_insn "*absneg<mode>2_sse"
8275 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8276 (match_operator:MODEF 3 "absneg_operator"
8277 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8278 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8279 (clobber (reg:CC FLAGS_REG))]
8280 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8283 (define_insn "*absneg<mode>2_i387"
8284 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8285 (match_operator:X87MODEF 3 "absneg_operator"
8286 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8287 (use (match_operand 2))
8288 (clobber (reg:CC FLAGS_REG))]
8289 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8292 (define_expand "<code>tf2"
8293 [(set (match_operand:TF 0 "register_operand")
8294 (absneg:TF (match_operand:TF 1 "register_operand")))]
8296 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8298 (define_insn "*absnegtf2_sse"
8299 [(set (match_operand:TF 0 "register_operand" "=x,x")
8300 (match_operator:TF 3 "absneg_operator"
8301 [(match_operand:TF 1 "register_operand" "0,x")]))
8302 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8303 (clobber (reg:CC FLAGS_REG))]
8307 ;; Splitters for fp abs and neg.
8310 [(set (match_operand 0 "fp_register_operand")
8311 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8312 (use (match_operand 2))
8313 (clobber (reg:CC FLAGS_REG))]
8315 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8318 [(set (match_operand 0 "register_operand")
8319 (match_operator 3 "absneg_operator"
8320 [(match_operand 1 "register_operand")]))
8321 (use (match_operand 2 "nonimmediate_operand"))
8322 (clobber (reg:CC FLAGS_REG))]
8323 "reload_completed && SSE_REG_P (operands[0])"
8324 [(set (match_dup 0) (match_dup 3))]
8326 enum machine_mode mode = GET_MODE (operands[0]);
8327 enum machine_mode vmode = GET_MODE (operands[2]);
8330 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8331 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8332 if (operands_match_p (operands[0], operands[2]))
8335 operands[1] = operands[2];
8338 if (GET_CODE (operands[3]) == ABS)
8339 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8341 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8346 [(set (match_operand:SF 0 "register_operand")
8347 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8348 (use (match_operand:V4SF 2))
8349 (clobber (reg:CC FLAGS_REG))]
8351 [(parallel [(set (match_dup 0) (match_dup 1))
8352 (clobber (reg:CC FLAGS_REG))])]
8355 operands[0] = gen_lowpart (SImode, operands[0]);
8356 if (GET_CODE (operands[1]) == ABS)
8358 tmp = gen_int_mode (0x7fffffff, SImode);
8359 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8363 tmp = gen_int_mode (0x80000000, SImode);
8364 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8370 [(set (match_operand:DF 0 "register_operand")
8371 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8372 (use (match_operand 2))
8373 (clobber (reg:CC FLAGS_REG))]
8375 [(parallel [(set (match_dup 0) (match_dup 1))
8376 (clobber (reg:CC FLAGS_REG))])]
8381 tmp = gen_lowpart (DImode, operands[0]);
8382 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8385 if (GET_CODE (operands[1]) == ABS)
8388 tmp = gen_rtx_NOT (DImode, tmp);
8392 operands[0] = gen_highpart (SImode, operands[0]);
8393 if (GET_CODE (operands[1]) == ABS)
8395 tmp = gen_int_mode (0x7fffffff, SImode);
8396 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8400 tmp = gen_int_mode (0x80000000, SImode);
8401 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8408 [(set (match_operand:XF 0 "register_operand")
8409 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8410 (use (match_operand 2))
8411 (clobber (reg:CC FLAGS_REG))]
8413 [(parallel [(set (match_dup 0) (match_dup 1))
8414 (clobber (reg:CC FLAGS_REG))])]
8417 operands[0] = gen_rtx_REG (SImode,
8418 true_regnum (operands[0])
8419 + (TARGET_64BIT ? 1 : 2));
8420 if (GET_CODE (operands[1]) == ABS)
8422 tmp = GEN_INT (0x7fff);
8423 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8427 tmp = GEN_INT (0x8000);
8428 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8433 ;; Conditionalize these after reload. If they match before reload, we
8434 ;; lose the clobber and ability to use integer instructions.
8436 (define_insn "*<code><mode>2_1"
8437 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8438 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8440 && (reload_completed
8441 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8442 "f<absneg_mnemonic>"
8443 [(set_attr "type" "fsgn")
8444 (set_attr "mode" "<MODE>")])
8446 (define_insn "*<code>extendsfdf2"
8447 [(set (match_operand:DF 0 "register_operand" "=f")
8448 (absneg:DF (float_extend:DF
8449 (match_operand:SF 1 "register_operand" "0"))))]
8450 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8451 "f<absneg_mnemonic>"
8452 [(set_attr "type" "fsgn")
8453 (set_attr "mode" "DF")])
8455 (define_insn "*<code>extendsfxf2"
8456 [(set (match_operand:XF 0 "register_operand" "=f")
8457 (absneg:XF (float_extend:XF
8458 (match_operand:SF 1 "register_operand" "0"))))]
8460 "f<absneg_mnemonic>"
8461 [(set_attr "type" "fsgn")
8462 (set_attr "mode" "XF")])
8464 (define_insn "*<code>extenddfxf2"
8465 [(set (match_operand:XF 0 "register_operand" "=f")
8466 (absneg:XF (float_extend:XF
8467 (match_operand:DF 1 "register_operand" "0"))))]
8469 "f<absneg_mnemonic>"
8470 [(set_attr "type" "fsgn")
8471 (set_attr "mode" "XF")])
8473 ;; Copysign instructions
8475 (define_mode_iterator CSGNMODE [SF DF TF])
8476 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8478 (define_expand "copysign<mode>3"
8479 [(match_operand:CSGNMODE 0 "register_operand")
8480 (match_operand:CSGNMODE 1 "nonmemory_operand")
8481 (match_operand:CSGNMODE 2 "register_operand")]
8482 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8483 || (TARGET_SSE && (<MODE>mode == TFmode))"
8484 "ix86_expand_copysign (operands); DONE;")
8486 (define_insn_and_split "copysign<mode>3_const"
8487 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8489 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8490 (match_operand:CSGNMODE 2 "register_operand" "0")
8491 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8493 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8494 || (TARGET_SSE && (<MODE>mode == TFmode))"
8496 "&& reload_completed"
8498 "ix86_split_copysign_const (operands); DONE;")
8500 (define_insn "copysign<mode>3_var"
8501 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8503 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8504 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8505 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8506 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8508 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8509 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8510 || (TARGET_SSE && (<MODE>mode == TFmode))"
8514 [(set (match_operand:CSGNMODE 0 "register_operand")
8516 [(match_operand:CSGNMODE 2 "register_operand")
8517 (match_operand:CSGNMODE 3 "register_operand")
8518 (match_operand:<CSGNVMODE> 4)
8519 (match_operand:<CSGNVMODE> 5)]
8521 (clobber (match_scratch:<CSGNVMODE> 1))]
8522 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8523 || (TARGET_SSE && (<MODE>mode == TFmode)))
8524 && reload_completed"
8526 "ix86_split_copysign_var (operands); DONE;")
8528 ;; One complement instructions
8530 (define_expand "one_cmpl<mode>2"
8531 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8532 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
8534 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8536 (define_insn "*one_cmpl<mode>2_1"
8537 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8538 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8539 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8540 "not{<imodesuffix>}\t%0"
8541 [(set_attr "type" "negnot")
8542 (set_attr "mode" "<MODE>")])
8544 ;; %%% Potential partial reg stall on alternative 1. What to do?
8545 (define_insn "*one_cmplqi2_1"
8546 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8547 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8548 "ix86_unary_operator_ok (NOT, QImode, operands)"
8552 [(set_attr "type" "negnot")
8553 (set_attr "mode" "QI,SI")])
8555 ;; ??? Currently never generated - xor is used instead.
8556 (define_insn "*one_cmplsi2_1_zext"
8557 [(set (match_operand:DI 0 "register_operand" "=r")
8559 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8560 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8562 [(set_attr "type" "negnot")
8563 (set_attr "mode" "SI")])
8565 (define_insn "*one_cmpl<mode>2_2"
8566 [(set (reg FLAGS_REG)
8567 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8569 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8570 (not:SWI (match_dup 1)))]
8571 "ix86_match_ccmode (insn, CCNOmode)
8572 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8574 [(set_attr "type" "alu1")
8575 (set_attr "mode" "<MODE>")])
8578 [(set (match_operand 0 "flags_reg_operand")
8579 (match_operator 2 "compare_operator"
8580 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
8582 (set (match_operand:SWI 1 "nonimmediate_operand")
8583 (not:SWI (match_dup 3)))]
8584 "ix86_match_ccmode (insn, CCNOmode)"
8585 [(parallel [(set (match_dup 0)
8586 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8589 (xor:SWI (match_dup 3) (const_int -1)))])])
8591 ;; ??? Currently never generated - xor is used instead.
8592 (define_insn "*one_cmplsi2_2_zext"
8593 [(set (reg FLAGS_REG)
8594 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8596 (set (match_operand:DI 0 "register_operand" "=r")
8597 (zero_extend:DI (not:SI (match_dup 1))))]
8598 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8599 && ix86_unary_operator_ok (NOT, SImode, operands)"
8601 [(set_attr "type" "alu1")
8602 (set_attr "mode" "SI")])
8605 [(set (match_operand 0 "flags_reg_operand")
8606 (match_operator 2 "compare_operator"
8607 [(not:SI (match_operand:SI 3 "register_operand"))
8609 (set (match_operand:DI 1 "register_operand")
8610 (zero_extend:DI (not:SI (match_dup 3))))]
8611 "ix86_match_ccmode (insn, CCNOmode)"
8612 [(parallel [(set (match_dup 0)
8613 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8616 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8618 ;; Shift instructions
8620 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8621 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8622 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8623 ;; from the assembler input.
8625 ;; This instruction shifts the target reg/mem as usual, but instead of
8626 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8627 ;; is a left shift double, bits are taken from the high order bits of
8628 ;; reg, else if the insn is a shift right double, bits are taken from the
8629 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8630 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8632 ;; Since sh[lr]d does not change the `reg' operand, that is done
8633 ;; separately, making all shifts emit pairs of shift double and normal
8634 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8635 ;; support a 63 bit shift, each shift where the count is in a reg expands
8636 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8638 ;; If the shift count is a constant, we need never emit more than one
8639 ;; shift pair, instead using moves and sign extension for counts greater
8642 (define_expand "ashl<mode>3"
8643 [(set (match_operand:SDWIM 0 "<shift_operand>")
8644 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
8645 (match_operand:QI 2 "nonmemory_operand")))]
8647 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8649 (define_insn "*ashl<mode>3_doubleword"
8650 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8651 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8652 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8653 (clobber (reg:CC FLAGS_REG))]
8656 [(set_attr "type" "multi")])
8659 [(set (match_operand:DWI 0 "register_operand")
8660 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
8661 (match_operand:QI 2 "nonmemory_operand")))
8662 (clobber (reg:CC FLAGS_REG))]
8663 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8665 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8667 ;; By default we don't ask for a scratch register, because when DWImode
8668 ;; values are manipulated, registers are already at a premium. But if
8669 ;; we have one handy, we won't turn it away.
8672 [(match_scratch:DWIH 3 "r")
8673 (parallel [(set (match_operand:<DWI> 0 "register_operand")
8675 (match_operand:<DWI> 1 "nonmemory_operand")
8676 (match_operand:QI 2 "nonmemory_operand")))
8677 (clobber (reg:CC FLAGS_REG))])
8681 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
8683 (define_insn "x86_64_shld"
8684 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
8685 (ior:DI (ashift:DI (match_dup 0)
8686 (match_operand:QI 2 "nonmemory_operand" "Jc"))
8687 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8688 (minus:QI (const_int 64) (match_dup 2)))))
8689 (clobber (reg:CC FLAGS_REG))]
8691 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
8692 [(set_attr "type" "ishift")
8693 (set_attr "prefix_0f" "1")
8694 (set_attr "mode" "DI")
8695 (set_attr "athlon_decode" "vector")
8696 (set_attr "amdfam10_decode" "vector")
8697 (set_attr "bdver1_decode" "vector")])
8699 (define_insn "x86_shld"
8700 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
8701 (ior:SI (ashift:SI (match_dup 0)
8702 (match_operand:QI 2 "nonmemory_operand" "Ic"))
8703 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8704 (minus:QI (const_int 32) (match_dup 2)))))
8705 (clobber (reg:CC FLAGS_REG))]
8707 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
8708 [(set_attr "type" "ishift")
8709 (set_attr "prefix_0f" "1")
8710 (set_attr "mode" "SI")
8711 (set_attr "pent_pair" "np")
8712 (set_attr "athlon_decode" "vector")
8713 (set_attr "amdfam10_decode" "vector")
8714 (set_attr "bdver1_decode" "vector")])
8716 (define_expand "x86_shift<mode>_adj_1"
8717 [(set (reg:CCZ FLAGS_REG)
8718 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
8721 (set (match_operand:SWI48 0 "register_operand")
8722 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8723 (match_operand:SWI48 1 "register_operand")
8726 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8727 (match_operand:SWI48 3 "register_operand")
8730 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
8732 (define_expand "x86_shift<mode>_adj_2"
8733 [(use (match_operand:SWI48 0 "register_operand"))
8734 (use (match_operand:SWI48 1 "register_operand"))
8735 (use (match_operand:QI 2 "register_operand"))]
8738 rtx label = gen_label_rtx ();
8741 emit_insn (gen_testqi_ccz_1 (operands[2],
8742 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
8744 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
8745 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
8746 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
8747 gen_rtx_LABEL_REF (VOIDmode, label),
8749 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
8750 JUMP_LABEL (tmp) = label;
8752 emit_move_insn (operands[0], operands[1]);
8753 ix86_expand_clear (operands[1]);
8756 LABEL_NUSES (label) = 1;
8761 ;; Avoid useless masking of count operand.
8762 (define_insn "*ashl<mode>3_mask"
8763 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
8765 (match_operand:SWI48 1 "nonimmediate_operand" "0")
8768 (match_operand:SI 2 "register_operand" "c")
8769 (match_operand:SI 3 "const_int_operand" "n")) 0)))
8770 (clobber (reg:CC FLAGS_REG))]
8771 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
8772 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
8773 == GET_MODE_BITSIZE (<MODE>mode)-1"
8775 return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
8777 [(set_attr "type" "ishift")
8778 (set_attr "mode" "<MODE>")])
8780 (define_insn "*bmi2_ashl<mode>3_1"
8781 [(set (match_operand:SWI48 0 "register_operand" "=r")
8782 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
8783 (match_operand:SWI48 2 "register_operand" "r")))]
8785 "shlx\t{%2, %1, %0|%0, %1, %2}"
8786 [(set_attr "type" "ishiftx")
8787 (set_attr "mode" "<MODE>")])
8789 (define_insn "*ashl<mode>3_1"
8790 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
8791 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
8792 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
8793 (clobber (reg:CC FLAGS_REG))]
8794 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
8796 switch (get_attr_type (insn))
8803 gcc_assert (operands[2] == const1_rtx);
8804 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8805 return "add{<imodesuffix>}\t%0, %0";
8808 if (operands[2] == const1_rtx
8809 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
8810 return "sal{<imodesuffix>}\t%0";
8812 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
8815 [(set_attr "isa" "*,*,bmi2")
8817 (cond [(eq_attr "alternative" "1")
8818 (const_string "lea")
8819 (eq_attr "alternative" "2")
8820 (const_string "ishiftx")
8821 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
8822 (match_operand 0 "register_operand"))
8823 (match_operand 2 "const1_operand"))
8824 (const_string "alu")
8826 (const_string "ishift")))
8827 (set (attr "length_immediate")
8829 (ior (eq_attr "type" "alu")
8830 (and (eq_attr "type" "ishift")
8831 (and (match_operand 2 "const1_operand")
8832 (ior (match_test "TARGET_SHIFT1")
8833 (match_test "optimize_function_for_size_p (cfun)")))))
8835 (const_string "*")))
8836 (set_attr "mode" "<MODE>")])
8838 ;; Convert shift to the shiftx pattern to avoid flags dependency.
8840 [(set (match_operand:SWI48 0 "register_operand")
8841 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
8842 (match_operand:QI 2 "register_operand")))
8843 (clobber (reg:CC FLAGS_REG))]
8844 "TARGET_BMI2 && reload_completed"
8846 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
8847 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
8849 (define_insn "*bmi2_ashlsi3_1_zext"
8850 [(set (match_operand:DI 0 "register_operand" "=r")
8852 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
8853 (match_operand:SI 2 "register_operand" "r"))))]
8854 "TARGET_64BIT && TARGET_BMI2"
8855 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
8856 [(set_attr "type" "ishiftx")
8857 (set_attr "mode" "SI")])
8859 (define_insn "*ashlsi3_1_zext"
8860 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
8862 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
8863 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
8864 (clobber (reg:CC FLAGS_REG))]
8865 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
8867 switch (get_attr_type (insn))
8874 gcc_assert (operands[2] == const1_rtx);
8875 return "add{l}\t%k0, %k0";
8878 if (operands[2] == const1_rtx
8879 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
8880 return "sal{l}\t%k0";
8882 return "sal{l}\t{%2, %k0|%k0, %2}";
8885 [(set_attr "isa" "*,*,bmi2")
8887 (cond [(eq_attr "alternative" "1")
8888 (const_string "lea")
8889 (eq_attr "alternative" "2")
8890 (const_string "ishiftx")
8891 (and (match_test "TARGET_DOUBLE_WITH_ADD")
8892 (match_operand 2 "const1_operand"))
8893 (const_string "alu")
8895 (const_string "ishift")))
8896 (set (attr "length_immediate")
8898 (ior (eq_attr "type" "alu")
8899 (and (eq_attr "type" "ishift")
8900 (and (match_operand 2 "const1_operand")
8901 (ior (match_test "TARGET_SHIFT1")
8902 (match_test "optimize_function_for_size_p (cfun)")))))
8904 (const_string "*")))
8905 (set_attr "mode" "SI")])
8907 ;; Convert shift to the shiftx pattern to avoid flags dependency.
8909 [(set (match_operand:DI 0 "register_operand")
8911 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
8912 (match_operand:QI 2 "register_operand"))))
8913 (clobber (reg:CC FLAGS_REG))]
8914 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
8916 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
8917 "operands[2] = gen_lowpart (SImode, operands[2]);")
8919 (define_insn "*ashlhi3_1"
8920 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
8921 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
8922 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
8923 (clobber (reg:CC FLAGS_REG))]
8924 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
8926 switch (get_attr_type (insn))
8932 gcc_assert (operands[2] == const1_rtx);
8933 return "add{w}\t%0, %0";
8936 if (operands[2] == const1_rtx
8937 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
8938 return "sal{w}\t%0";
8940 return "sal{w}\t{%2, %0|%0, %2}";
8944 (cond [(eq_attr "alternative" "1")
8945 (const_string "lea")
8946 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
8947 (match_operand 0 "register_operand"))
8948 (match_operand 2 "const1_operand"))
8949 (const_string "alu")
8951 (const_string "ishift")))
8952 (set (attr "length_immediate")
8954 (ior (eq_attr "type" "alu")
8955 (and (eq_attr "type" "ishift")
8956 (and (match_operand 2 "const1_operand")
8957 (ior (match_test "TARGET_SHIFT1")
8958 (match_test "optimize_function_for_size_p (cfun)")))))
8960 (const_string "*")))
8961 (set_attr "mode" "HI,SI")])
8963 ;; %%% Potential partial reg stall on alternative 1. What to do?
8964 (define_insn "*ashlqi3_1"
8965 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
8966 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
8967 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
8968 (clobber (reg:CC FLAGS_REG))]
8969 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
8971 switch (get_attr_type (insn))
8977 gcc_assert (operands[2] == const1_rtx);
8978 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
8979 return "add{l}\t%k0, %k0";
8981 return "add{b}\t%0, %0";
8984 if (operands[2] == const1_rtx
8985 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
8987 if (get_attr_mode (insn) == MODE_SI)
8988 return "sal{l}\t%k0";
8990 return "sal{b}\t%0";
8994 if (get_attr_mode (insn) == MODE_SI)
8995 return "sal{l}\t{%2, %k0|%k0, %2}";
8997 return "sal{b}\t{%2, %0|%0, %2}";
9002 (cond [(eq_attr "alternative" "2")
9003 (const_string "lea")
9004 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9005 (match_operand 0 "register_operand"))
9006 (match_operand 2 "const1_operand"))
9007 (const_string "alu")
9009 (const_string "ishift")))
9010 (set (attr "length_immediate")
9012 (ior (eq_attr "type" "alu")
9013 (and (eq_attr "type" "ishift")
9014 (and (match_operand 2 "const1_operand")
9015 (ior (match_test "TARGET_SHIFT1")
9016 (match_test "optimize_function_for_size_p (cfun)")))))
9018 (const_string "*")))
9019 (set_attr "mode" "QI,SI,SI")])
9021 (define_insn "*ashlqi3_1_slp"
9022 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9023 (ashift:QI (match_dup 0)
9024 (match_operand:QI 1 "nonmemory_operand" "cI")))
9025 (clobber (reg:CC FLAGS_REG))]
9026 "(optimize_function_for_size_p (cfun)
9027 || !TARGET_PARTIAL_FLAG_REG_STALL
9028 || (operands[1] == const1_rtx
9030 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9032 switch (get_attr_type (insn))
9035 gcc_assert (operands[1] == const1_rtx);
9036 return "add{b}\t%0, %0";
9039 if (operands[1] == const1_rtx
9040 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9041 return "sal{b}\t%0";
9043 return "sal{b}\t{%1, %0|%0, %1}";
9047 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9048 (match_operand 0 "register_operand"))
9049 (match_operand 1 "const1_operand"))
9050 (const_string "alu")
9052 (const_string "ishift1")))
9053 (set (attr "length_immediate")
9055 (ior (eq_attr "type" "alu")
9056 (and (eq_attr "type" "ishift1")
9057 (and (match_operand 1 "const1_operand")
9058 (ior (match_test "TARGET_SHIFT1")
9059 (match_test "optimize_function_for_size_p (cfun)")))))
9061 (const_string "*")))
9062 (set_attr "mode" "QI")])
9064 ;; Convert ashift to the lea pattern to avoid flags dependency.
9066 [(set (match_operand 0 "register_operand")
9067 (ashift (match_operand 1 "index_register_operand")
9068 (match_operand:QI 2 "const_int_operand")))
9069 (clobber (reg:CC FLAGS_REG))]
9070 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9072 && true_regnum (operands[0]) != true_regnum (operands[1])"
9075 enum machine_mode mode = GET_MODE (operands[0]);
9078 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9081 operands[0] = gen_lowpart (mode, operands[0]);
9082 operands[1] = gen_lowpart (mode, operands[1]);
9085 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9087 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9089 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9093 ;; Convert ashift to the lea pattern to avoid flags dependency.
9095 [(set (match_operand:DI 0 "register_operand")
9097 (ashift:SI (match_operand:SI 1 "index_register_operand")
9098 (match_operand:QI 2 "const_int_operand"))))
9099 (clobber (reg:CC FLAGS_REG))]
9100 "TARGET_64BIT && reload_completed
9101 && true_regnum (operands[0]) != true_regnum (operands[1])"
9103 (zero_extend:DI (mult:SI (match_dup 1) (match_dup 2))))]
9105 operands[1] = gen_lowpart (SImode, operands[1]);
9106 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), SImode);
9109 ;; This pattern can't accept a variable shift count, since shifts by
9110 ;; zero don't affect the flags. We assume that shifts by constant
9111 ;; zero are optimized away.
9112 (define_insn "*ashl<mode>3_cmp"
9113 [(set (reg FLAGS_REG)
9115 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9116 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9118 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9119 (ashift:SWI (match_dup 1) (match_dup 2)))]
9120 "(optimize_function_for_size_p (cfun)
9121 || !TARGET_PARTIAL_FLAG_REG_STALL
9122 || (operands[2] == const1_rtx
9124 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9125 && ix86_match_ccmode (insn, CCGOCmode)
9126 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9128 switch (get_attr_type (insn))
9131 gcc_assert (operands[2] == const1_rtx);
9132 return "add{<imodesuffix>}\t%0, %0";
9135 if (operands[2] == const1_rtx
9136 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9137 return "sal{<imodesuffix>}\t%0";
9139 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9143 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9144 (match_operand 0 "register_operand"))
9145 (match_operand 2 "const1_operand"))
9146 (const_string "alu")
9148 (const_string "ishift")))
9149 (set (attr "length_immediate")
9151 (ior (eq_attr "type" "alu")
9152 (and (eq_attr "type" "ishift")
9153 (and (match_operand 2 "const1_operand")
9154 (ior (match_test "TARGET_SHIFT1")
9155 (match_test "optimize_function_for_size_p (cfun)")))))
9157 (const_string "*")))
9158 (set_attr "mode" "<MODE>")])
9160 (define_insn "*ashlsi3_cmp_zext"
9161 [(set (reg FLAGS_REG)
9163 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9164 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9166 (set (match_operand:DI 0 "register_operand" "=r")
9167 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9169 && (optimize_function_for_size_p (cfun)
9170 || !TARGET_PARTIAL_FLAG_REG_STALL
9171 || (operands[2] == const1_rtx
9173 || TARGET_DOUBLE_WITH_ADD)))
9174 && ix86_match_ccmode (insn, CCGOCmode)
9175 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9177 switch (get_attr_type (insn))
9180 gcc_assert (operands[2] == const1_rtx);
9181 return "add{l}\t%k0, %k0";
9184 if (operands[2] == const1_rtx
9185 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9186 return "sal{l}\t%k0";
9188 return "sal{l}\t{%2, %k0|%k0, %2}";
9192 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9193 (match_operand 2 "const1_operand"))
9194 (const_string "alu")
9196 (const_string "ishift")))
9197 (set (attr "length_immediate")
9199 (ior (eq_attr "type" "alu")
9200 (and (eq_attr "type" "ishift")
9201 (and (match_operand 2 "const1_operand")
9202 (ior (match_test "TARGET_SHIFT1")
9203 (match_test "optimize_function_for_size_p (cfun)")))))
9205 (const_string "*")))
9206 (set_attr "mode" "SI")])
9208 (define_insn "*ashl<mode>3_cconly"
9209 [(set (reg FLAGS_REG)
9211 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9212 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9214 (clobber (match_scratch:SWI 0 "=<r>"))]
9215 "(optimize_function_for_size_p (cfun)
9216 || !TARGET_PARTIAL_FLAG_REG_STALL
9217 || (operands[2] == const1_rtx
9219 || TARGET_DOUBLE_WITH_ADD)))
9220 && ix86_match_ccmode (insn, CCGOCmode)"
9222 switch (get_attr_type (insn))
9225 gcc_assert (operands[2] == const1_rtx);
9226 return "add{<imodesuffix>}\t%0, %0";
9229 if (operands[2] == const1_rtx
9230 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9231 return "sal{<imodesuffix>}\t%0";
9233 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9237 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9238 (match_operand 0 "register_operand"))
9239 (match_operand 2 "const1_operand"))
9240 (const_string "alu")
9242 (const_string "ishift")))
9243 (set (attr "length_immediate")
9245 (ior (eq_attr "type" "alu")
9246 (and (eq_attr "type" "ishift")
9247 (and (match_operand 2 "const1_operand")
9248 (ior (match_test "TARGET_SHIFT1")
9249 (match_test "optimize_function_for_size_p (cfun)")))))
9251 (const_string "*")))
9252 (set_attr "mode" "<MODE>")])
9254 ;; See comment above `ashl<mode>3' about how this works.
9256 (define_expand "<shift_insn><mode>3"
9257 [(set (match_operand:SDWIM 0 "<shift_operand>")
9258 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9259 (match_operand:QI 2 "nonmemory_operand")))]
9261 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9263 ;; Avoid useless masking of count operand.
9264 (define_insn "*<shift_insn><mode>3_mask"
9265 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9267 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9270 (match_operand:SI 2 "register_operand" "c")
9271 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9272 (clobber (reg:CC FLAGS_REG))]
9273 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9274 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9275 == GET_MODE_BITSIZE (<MODE>mode)-1"
9277 return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9279 [(set_attr "type" "ishift")
9280 (set_attr "mode" "<MODE>")])
9282 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9283 [(set (match_operand:DWI 0 "register_operand" "=r")
9284 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9285 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9286 (clobber (reg:CC FLAGS_REG))]
9289 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9291 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9292 [(set_attr "type" "multi")])
9294 ;; By default we don't ask for a scratch register, because when DWImode
9295 ;; values are manipulated, registers are already at a premium. But if
9296 ;; we have one handy, we won't turn it away.
9299 [(match_scratch:DWIH 3 "r")
9300 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9302 (match_operand:<DWI> 1 "register_operand")
9303 (match_operand:QI 2 "nonmemory_operand")))
9304 (clobber (reg:CC FLAGS_REG))])
9308 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9310 (define_insn "x86_64_shrd"
9311 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9312 (ior:DI (ashiftrt:DI (match_dup 0)
9313 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9314 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9315 (minus:QI (const_int 64) (match_dup 2)))))
9316 (clobber (reg:CC FLAGS_REG))]
9318 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9319 [(set_attr "type" "ishift")
9320 (set_attr "prefix_0f" "1")
9321 (set_attr "mode" "DI")
9322 (set_attr "athlon_decode" "vector")
9323 (set_attr "amdfam10_decode" "vector")
9324 (set_attr "bdver1_decode" "vector")])
9326 (define_insn "x86_shrd"
9327 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9328 (ior:SI (ashiftrt:SI (match_dup 0)
9329 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9330 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9331 (minus:QI (const_int 32) (match_dup 2)))))
9332 (clobber (reg:CC FLAGS_REG))]
9334 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9335 [(set_attr "type" "ishift")
9336 (set_attr "prefix_0f" "1")
9337 (set_attr "mode" "SI")
9338 (set_attr "pent_pair" "np")
9339 (set_attr "athlon_decode" "vector")
9340 (set_attr "amdfam10_decode" "vector")
9341 (set_attr "bdver1_decode" "vector")])
9343 (define_insn "ashrdi3_cvt"
9344 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9345 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9346 (match_operand:QI 2 "const_int_operand")))
9347 (clobber (reg:CC FLAGS_REG))]
9348 "TARGET_64BIT && INTVAL (operands[2]) == 63
9349 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9350 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9353 sar{q}\t{%2, %0|%0, %2}"
9354 [(set_attr "type" "imovx,ishift")
9355 (set_attr "prefix_0f" "0,*")
9356 (set_attr "length_immediate" "0,*")
9357 (set_attr "modrm" "0,1")
9358 (set_attr "mode" "DI")])
9360 (define_insn "ashrsi3_cvt"
9361 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9362 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9363 (match_operand:QI 2 "const_int_operand")))
9364 (clobber (reg:CC FLAGS_REG))]
9365 "INTVAL (operands[2]) == 31
9366 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9367 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9370 sar{l}\t{%2, %0|%0, %2}"
9371 [(set_attr "type" "imovx,ishift")
9372 (set_attr "prefix_0f" "0,*")
9373 (set_attr "length_immediate" "0,*")
9374 (set_attr "modrm" "0,1")
9375 (set_attr "mode" "SI")])
9377 (define_insn "*ashrsi3_cvt_zext"
9378 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9380 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9381 (match_operand:QI 2 "const_int_operand"))))
9382 (clobber (reg:CC FLAGS_REG))]
9383 "TARGET_64BIT && INTVAL (operands[2]) == 31
9384 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9385 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9388 sar{l}\t{%2, %k0|%k0, %2}"
9389 [(set_attr "type" "imovx,ishift")
9390 (set_attr "prefix_0f" "0,*")
9391 (set_attr "length_immediate" "0,*")
9392 (set_attr "modrm" "0,1")
9393 (set_attr "mode" "SI")])
9395 (define_expand "x86_shift<mode>_adj_3"
9396 [(use (match_operand:SWI48 0 "register_operand"))
9397 (use (match_operand:SWI48 1 "register_operand"))
9398 (use (match_operand:QI 2 "register_operand"))]
9401 rtx label = gen_label_rtx ();
9404 emit_insn (gen_testqi_ccz_1 (operands[2],
9405 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9407 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9408 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9409 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9410 gen_rtx_LABEL_REF (VOIDmode, label),
9412 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9413 JUMP_LABEL (tmp) = label;
9415 emit_move_insn (operands[0], operands[1]);
9416 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9417 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9419 LABEL_NUSES (label) = 1;
9424 (define_insn "*bmi2_<shift_insn><mode>3_1"
9425 [(set (match_operand:SWI48 0 "register_operand" "=r")
9426 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9427 (match_operand:SWI48 2 "register_operand" "r")))]
9429 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9430 [(set_attr "type" "ishiftx")
9431 (set_attr "mode" "<MODE>")])
9433 (define_insn "*<shift_insn><mode>3_1"
9434 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9436 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9437 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9438 (clobber (reg:CC FLAGS_REG))]
9439 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9441 switch (get_attr_type (insn))
9447 if (operands[2] == const1_rtx
9448 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9449 return "<shift>{<imodesuffix>}\t%0";
9451 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9454 [(set_attr "isa" "*,bmi2")
9455 (set_attr "type" "ishift,ishiftx")
9456 (set (attr "length_immediate")
9458 (and (match_operand 2 "const1_operand")
9459 (ior (match_test "TARGET_SHIFT1")
9460 (match_test "optimize_function_for_size_p (cfun)")))
9462 (const_string "*")))
9463 (set_attr "mode" "<MODE>")])
9465 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9467 [(set (match_operand:SWI48 0 "register_operand")
9468 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9469 (match_operand:QI 2 "register_operand")))
9470 (clobber (reg:CC FLAGS_REG))]
9471 "TARGET_BMI2 && reload_completed"
9473 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9474 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9476 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9477 [(set (match_operand:DI 0 "register_operand" "=r")
9479 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9480 (match_operand:SI 2 "register_operand" "r"))))]
9481 "TARGET_64BIT && TARGET_BMI2"
9482 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9483 [(set_attr "type" "ishiftx")
9484 (set_attr "mode" "SI")])
9486 (define_insn "*<shift_insn>si3_1_zext"
9487 [(set (match_operand:DI 0 "register_operand" "=r,r")
9489 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9490 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9491 (clobber (reg:CC FLAGS_REG))]
9492 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9494 switch (get_attr_type (insn))
9500 if (operands[2] == const1_rtx
9501 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9502 return "<shift>{l}\t%k0";
9504 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9507 [(set_attr "isa" "*,bmi2")
9508 (set_attr "type" "ishift,ishiftx")
9509 (set (attr "length_immediate")
9511 (and (match_operand 2 "const1_operand")
9512 (ior (match_test "TARGET_SHIFT1")
9513 (match_test "optimize_function_for_size_p (cfun)")))
9515 (const_string "*")))
9516 (set_attr "mode" "SI")])
9518 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9520 [(set (match_operand:DI 0 "register_operand")
9522 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
9523 (match_operand:QI 2 "register_operand"))))
9524 (clobber (reg:CC FLAGS_REG))]
9525 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9527 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9528 "operands[2] = gen_lowpart (SImode, operands[2]);")
9530 (define_insn "*<shift_insn><mode>3_1"
9531 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9533 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9534 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9535 (clobber (reg:CC FLAGS_REG))]
9536 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9538 if (operands[2] == const1_rtx
9539 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9540 return "<shift>{<imodesuffix>}\t%0";
9542 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9544 [(set_attr "type" "ishift")
9545 (set (attr "length_immediate")
9547 (and (match_operand 2 "const1_operand")
9548 (ior (match_test "TARGET_SHIFT1")
9549 (match_test "optimize_function_for_size_p (cfun)")))
9551 (const_string "*")))
9552 (set_attr "mode" "<MODE>")])
9554 (define_insn "*<shift_insn>qi3_1_slp"
9555 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9556 (any_shiftrt:QI (match_dup 0)
9557 (match_operand:QI 1 "nonmemory_operand" "cI")))
9558 (clobber (reg:CC FLAGS_REG))]
9559 "(optimize_function_for_size_p (cfun)
9560 || !TARGET_PARTIAL_REG_STALL
9561 || (operands[1] == const1_rtx
9564 if (operands[1] == const1_rtx
9565 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9566 return "<shift>{b}\t%0";
9568 return "<shift>{b}\t{%1, %0|%0, %1}";
9570 [(set_attr "type" "ishift1")
9571 (set (attr "length_immediate")
9573 (and (match_operand 1 "const1_operand")
9574 (ior (match_test "TARGET_SHIFT1")
9575 (match_test "optimize_function_for_size_p (cfun)")))
9577 (const_string "*")))
9578 (set_attr "mode" "QI")])
9580 ;; This pattern can't accept a variable shift count, since shifts by
9581 ;; zero don't affect the flags. We assume that shifts by constant
9582 ;; zero are optimized away.
9583 (define_insn "*<shift_insn><mode>3_cmp"
9584 [(set (reg FLAGS_REG)
9587 (match_operand:SWI 1 "nonimmediate_operand" "0")
9588 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9590 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9591 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9592 "(optimize_function_for_size_p (cfun)
9593 || !TARGET_PARTIAL_FLAG_REG_STALL
9594 || (operands[2] == const1_rtx
9596 && ix86_match_ccmode (insn, CCGOCmode)
9597 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9599 if (operands[2] == const1_rtx
9600 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9601 return "<shift>{<imodesuffix>}\t%0";
9603 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9605 [(set_attr "type" "ishift")
9606 (set (attr "length_immediate")
9608 (and (match_operand 2 "const1_operand")
9609 (ior (match_test "TARGET_SHIFT1")
9610 (match_test "optimize_function_for_size_p (cfun)")))
9612 (const_string "*")))
9613 (set_attr "mode" "<MODE>")])
9615 (define_insn "*<shift_insn>si3_cmp_zext"
9616 [(set (reg FLAGS_REG)
9618 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9619 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9621 (set (match_operand:DI 0 "register_operand" "=r")
9622 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9624 && (optimize_function_for_size_p (cfun)
9625 || !TARGET_PARTIAL_FLAG_REG_STALL
9626 || (operands[2] == const1_rtx
9628 && ix86_match_ccmode (insn, CCGOCmode)
9629 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9631 if (operands[2] == const1_rtx
9632 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9633 return "<shift>{l}\t%k0";
9635 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9637 [(set_attr "type" "ishift")
9638 (set (attr "length_immediate")
9640 (and (match_operand 2 "const1_operand")
9641 (ior (match_test "TARGET_SHIFT1")
9642 (match_test "optimize_function_for_size_p (cfun)")))
9644 (const_string "*")))
9645 (set_attr "mode" "SI")])
9647 (define_insn "*<shift_insn><mode>3_cconly"
9648 [(set (reg FLAGS_REG)
9651 (match_operand:SWI 1 "register_operand" "0")
9652 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9654 (clobber (match_scratch:SWI 0 "=<r>"))]
9655 "(optimize_function_for_size_p (cfun)
9656 || !TARGET_PARTIAL_FLAG_REG_STALL
9657 || (operands[2] == const1_rtx
9659 && ix86_match_ccmode (insn, CCGOCmode)"
9661 if (operands[2] == const1_rtx
9662 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9663 return "<shift>{<imodesuffix>}\t%0";
9665 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9667 [(set_attr "type" "ishift")
9668 (set (attr "length_immediate")
9670 (and (match_operand 2 "const1_operand")
9671 (ior (match_test "TARGET_SHIFT1")
9672 (match_test "optimize_function_for_size_p (cfun)")))
9674 (const_string "*")))
9675 (set_attr "mode" "<MODE>")])
9677 ;; Rotate instructions
9679 (define_expand "<rotate_insn>ti3"
9680 [(set (match_operand:TI 0 "register_operand")
9681 (any_rotate:TI (match_operand:TI 1 "register_operand")
9682 (match_operand:QI 2 "nonmemory_operand")))]
9685 if (const_1_to_63_operand (operands[2], VOIDmode))
9686 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
9687 (operands[0], operands[1], operands[2]));
9694 (define_expand "<rotate_insn>di3"
9695 [(set (match_operand:DI 0 "shiftdi_operand")
9696 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
9697 (match_operand:QI 2 "nonmemory_operand")))]
9701 ix86_expand_binary_operator (<CODE>, DImode, operands);
9702 else if (const_1_to_31_operand (operands[2], VOIDmode))
9703 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
9704 (operands[0], operands[1], operands[2]));
9711 (define_expand "<rotate_insn><mode>3"
9712 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
9713 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
9714 (match_operand:QI 2 "nonmemory_operand")))]
9716 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9718 ;; Avoid useless masking of count operand.
9719 (define_insn "*<rotate_insn><mode>3_mask"
9720 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9722 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9725 (match_operand:SI 2 "register_operand" "c")
9726 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9727 (clobber (reg:CC FLAGS_REG))]
9728 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9729 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9730 == GET_MODE_BITSIZE (<MODE>mode)-1"
9732 return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9734 [(set_attr "type" "rotate")
9735 (set_attr "mode" "<MODE>")])
9737 ;; Implement rotation using two double-precision
9738 ;; shift instructions and a scratch register.
9740 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
9741 [(set (match_operand:<DWI> 0 "register_operand" "=r")
9742 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
9743 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
9744 (clobber (reg:CC FLAGS_REG))
9745 (clobber (match_scratch:DWIH 3 "=&r"))]
9749 [(set (match_dup 3) (match_dup 4))
9752 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
9753 (lshiftrt:DWIH (match_dup 5)
9754 (minus:QI (match_dup 6) (match_dup 2)))))
9755 (clobber (reg:CC FLAGS_REG))])
9758 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
9759 (lshiftrt:DWIH (match_dup 3)
9760 (minus:QI (match_dup 6) (match_dup 2)))))
9761 (clobber (reg:CC FLAGS_REG))])]
9763 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
9765 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
9768 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
9769 [(set (match_operand:<DWI> 0 "register_operand" "=r")
9770 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
9771 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
9772 (clobber (reg:CC FLAGS_REG))
9773 (clobber (match_scratch:DWIH 3 "=&r"))]
9777 [(set (match_dup 3) (match_dup 4))
9780 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
9781 (ashift:DWIH (match_dup 5)
9782 (minus:QI (match_dup 6) (match_dup 2)))))
9783 (clobber (reg:CC FLAGS_REG))])
9786 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
9787 (ashift:DWIH (match_dup 3)
9788 (minus:QI (match_dup 6) (match_dup 2)))))
9789 (clobber (reg:CC FLAGS_REG))])]
9791 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
9793 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
9796 (define_insn "*bmi2_rorx<mode>3_1"
9797 [(set (match_operand:SWI48 0 "register_operand" "=r")
9798 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9799 (match_operand:QI 2 "immediate_operand" "<S>")))]
9801 "rorx\t{%2, %1, %0|%0, %1, %2}"
9802 [(set_attr "type" "rotatex")
9803 (set_attr "mode" "<MODE>")])
9805 (define_insn "*<rotate_insn><mode>3_1"
9806 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9808 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9809 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
9810 (clobber (reg:CC FLAGS_REG))]
9811 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9813 switch (get_attr_type (insn))
9819 if (operands[2] == const1_rtx
9820 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9821 return "<rotate>{<imodesuffix>}\t%0";
9823 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
9826 [(set_attr "isa" "*,bmi2")
9827 (set_attr "type" "rotate,rotatex")
9828 (set (attr "length_immediate")
9830 (and (eq_attr "type" "rotate")
9831 (and (match_operand 2 "const1_operand")
9832 (ior (match_test "TARGET_SHIFT1")
9833 (match_test "optimize_function_for_size_p (cfun)"))))
9835 (const_string "*")))
9836 (set_attr "mode" "<MODE>")])
9838 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
9840 [(set (match_operand:SWI48 0 "register_operand")
9841 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9842 (match_operand:QI 2 "immediate_operand")))
9843 (clobber (reg:CC FLAGS_REG))]
9844 "TARGET_BMI2 && reload_completed"
9846 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
9849 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
9853 [(set (match_operand:SWI48 0 "register_operand")
9854 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9855 (match_operand:QI 2 "immediate_operand")))
9856 (clobber (reg:CC FLAGS_REG))]
9857 "TARGET_BMI2 && reload_completed"
9859 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
9861 (define_insn "*bmi2_rorxsi3_1_zext"
9862 [(set (match_operand:DI 0 "register_operand" "=r")
9864 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9865 (match_operand:QI 2 "immediate_operand" "I"))))]
9866 "TARGET_64BIT && TARGET_BMI2"
9867 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
9868 [(set_attr "type" "rotatex")
9869 (set_attr "mode" "SI")])
9871 (define_insn "*<rotate_insn>si3_1_zext"
9872 [(set (match_operand:DI 0 "register_operand" "=r,r")
9874 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9875 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
9876 (clobber (reg:CC FLAGS_REG))]
9877 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9879 switch (get_attr_type (insn))
9885 if (operands[2] == const1_rtx
9886 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9887 return "<rotate>{l}\t%k0";
9889 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
9892 [(set_attr "isa" "*,bmi2")
9893 (set_attr "type" "rotate,rotatex")
9894 (set (attr "length_immediate")
9896 (and (eq_attr "type" "rotate")
9897 (and (match_operand 2 "const1_operand")
9898 (ior (match_test "TARGET_SHIFT1")
9899 (match_test "optimize_function_for_size_p (cfun)"))))
9901 (const_string "*")))
9902 (set_attr "mode" "SI")])
9904 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
9906 [(set (match_operand:DI 0 "register_operand")
9908 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
9909 (match_operand:QI 2 "immediate_operand"))))
9910 (clobber (reg:CC FLAGS_REG))]
9911 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9913 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
9916 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
9920 [(set (match_operand:DI 0 "register_operand")
9922 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
9923 (match_operand:QI 2 "immediate_operand"))))
9924 (clobber (reg:CC FLAGS_REG))]
9925 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9927 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
9929 (define_insn "*<rotate_insn><mode>3_1"
9930 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9931 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9932 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9933 (clobber (reg:CC FLAGS_REG))]
9934 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9936 if (operands[2] == const1_rtx
9937 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9938 return "<rotate>{<imodesuffix>}\t%0";
9940 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
9942 [(set_attr "type" "rotate")
9943 (set (attr "length_immediate")
9945 (and (match_operand 2 "const1_operand")
9946 (ior (match_test "TARGET_SHIFT1")
9947 (match_test "optimize_function_for_size_p (cfun)")))
9949 (const_string "*")))
9950 (set_attr "mode" "<MODE>")])
9952 (define_insn "*<rotate_insn>qi3_1_slp"
9953 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9954 (any_rotate:QI (match_dup 0)
9955 (match_operand:QI 1 "nonmemory_operand" "cI")))
9956 (clobber (reg:CC FLAGS_REG))]
9957 "(optimize_function_for_size_p (cfun)
9958 || !TARGET_PARTIAL_REG_STALL
9959 || (operands[1] == const1_rtx
9962 if (operands[1] == const1_rtx
9963 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9964 return "<rotate>{b}\t%0";
9966 return "<rotate>{b}\t{%1, %0|%0, %1}";
9968 [(set_attr "type" "rotate1")
9969 (set (attr "length_immediate")
9971 (and (match_operand 1 "const1_operand")
9972 (ior (match_test "TARGET_SHIFT1")
9973 (match_test "optimize_function_for_size_p (cfun)")))
9975 (const_string "*")))
9976 (set_attr "mode" "QI")])
9979 [(set (match_operand:HI 0 "register_operand")
9980 (any_rotate:HI (match_dup 0) (const_int 8)))
9981 (clobber (reg:CC FLAGS_REG))]
9983 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
9984 [(parallel [(set (strict_low_part (match_dup 0))
9985 (bswap:HI (match_dup 0)))
9986 (clobber (reg:CC FLAGS_REG))])])
9988 ;; Bit set / bit test instructions
9990 (define_expand "extv"
9991 [(set (match_operand:SI 0 "register_operand")
9992 (sign_extract:SI (match_operand:SI 1 "register_operand")
9993 (match_operand:SI 2 "const8_operand")
9994 (match_operand:SI 3 "const8_operand")))]
9997 /* Handle extractions from %ah et al. */
9998 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10001 /* From mips.md: extract_bit_field doesn't verify that our source
10002 matches the predicate, so check it again here. */
10003 if (! ext_register_operand (operands[1], VOIDmode))
10007 (define_expand "extzv"
10008 [(set (match_operand:SI 0 "register_operand")
10009 (zero_extract:SI (match_operand 1 "ext_register_operand")
10010 (match_operand:SI 2 "const8_operand")
10011 (match_operand:SI 3 "const8_operand")))]
10014 /* Handle extractions from %ah et al. */
10015 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10018 /* From mips.md: extract_bit_field doesn't verify that our source
10019 matches the predicate, so check it again here. */
10020 if (! ext_register_operand (operands[1], VOIDmode))
10024 (define_expand "insv"
10025 [(set (zero_extract (match_operand 0 "register_operand")
10026 (match_operand 1 "const_int_operand")
10027 (match_operand 2 "const_int_operand"))
10028 (match_operand 3 "register_operand"))]
10031 rtx (*gen_mov_insv_1) (rtx, rtx);
10033 if (ix86_expand_pinsr (operands))
10036 /* Handle insertions to %ah et al. */
10037 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10040 /* From mips.md: insert_bit_field doesn't verify that our source
10041 matches the predicate, so check it again here. */
10042 if (! ext_register_operand (operands[0], VOIDmode))
10045 gen_mov_insv_1 = (TARGET_64BIT
10046 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10048 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10052 ;; %%% bts, btr, btc, bt.
10053 ;; In general these instructions are *slow* when applied to memory,
10054 ;; since they enforce atomic operation. When applied to registers,
10055 ;; it depends on the cpu implementation. They're never faster than
10056 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10057 ;; no point. But in 64-bit, we can't hold the relevant immediates
10058 ;; within the instruction itself, so operating on bits in the high
10059 ;; 32-bits of a register becomes easier.
10061 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10062 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10063 ;; negdf respectively, so they can never be disabled entirely.
10065 (define_insn "*btsq"
10066 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10068 (match_operand:DI 1 "const_0_to_63_operand"))
10070 (clobber (reg:CC FLAGS_REG))]
10071 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10072 "bts{q}\t{%1, %0|%0, %1}"
10073 [(set_attr "type" "alu1")
10074 (set_attr "prefix_0f" "1")
10075 (set_attr "mode" "DI")])
10077 (define_insn "*btrq"
10078 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10080 (match_operand:DI 1 "const_0_to_63_operand"))
10082 (clobber (reg:CC FLAGS_REG))]
10083 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10084 "btr{q}\t{%1, %0|%0, %1}"
10085 [(set_attr "type" "alu1")
10086 (set_attr "prefix_0f" "1")
10087 (set_attr "mode" "DI")])
10089 (define_insn "*btcq"
10090 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10092 (match_operand:DI 1 "const_0_to_63_operand"))
10093 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10094 (clobber (reg:CC FLAGS_REG))]
10095 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10096 "btc{q}\t{%1, %0|%0, %1}"
10097 [(set_attr "type" "alu1")
10098 (set_attr "prefix_0f" "1")
10099 (set_attr "mode" "DI")])
10101 ;; Allow Nocona to avoid these instructions if a register is available.
10104 [(match_scratch:DI 2 "r")
10105 (parallel [(set (zero_extract:DI
10106 (match_operand:DI 0 "register_operand")
10108 (match_operand:DI 1 "const_0_to_63_operand"))
10110 (clobber (reg:CC FLAGS_REG))])]
10111 "TARGET_64BIT && !TARGET_USE_BT"
10114 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10117 if (HOST_BITS_PER_WIDE_INT >= 64)
10118 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10119 else if (i < HOST_BITS_PER_WIDE_INT)
10120 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10122 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10124 op1 = immed_double_const (lo, hi, DImode);
10127 emit_move_insn (operands[2], op1);
10131 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10136 [(match_scratch:DI 2 "r")
10137 (parallel [(set (zero_extract:DI
10138 (match_operand:DI 0 "register_operand")
10140 (match_operand:DI 1 "const_0_to_63_operand"))
10142 (clobber (reg:CC FLAGS_REG))])]
10143 "TARGET_64BIT && !TARGET_USE_BT"
10146 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10149 if (HOST_BITS_PER_WIDE_INT >= 64)
10150 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10151 else if (i < HOST_BITS_PER_WIDE_INT)
10152 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10154 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10156 op1 = immed_double_const (~lo, ~hi, DImode);
10159 emit_move_insn (operands[2], op1);
10163 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10168 [(match_scratch:DI 2 "r")
10169 (parallel [(set (zero_extract:DI
10170 (match_operand:DI 0 "register_operand")
10172 (match_operand:DI 1 "const_0_to_63_operand"))
10173 (not:DI (zero_extract:DI
10174 (match_dup 0) (const_int 1) (match_dup 1))))
10175 (clobber (reg:CC FLAGS_REG))])]
10176 "TARGET_64BIT && !TARGET_USE_BT"
10179 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10182 if (HOST_BITS_PER_WIDE_INT >= 64)
10183 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10184 else if (i < HOST_BITS_PER_WIDE_INT)
10185 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10187 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10189 op1 = immed_double_const (lo, hi, DImode);
10192 emit_move_insn (operands[2], op1);
10196 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10200 (define_insn "*bt<mode>"
10201 [(set (reg:CCC FLAGS_REG)
10203 (zero_extract:SWI48
10204 (match_operand:SWI48 0 "register_operand" "r")
10206 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10208 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10209 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10210 [(set_attr "type" "alu1")
10211 (set_attr "prefix_0f" "1")
10212 (set_attr "mode" "<MODE>")])
10214 ;; Store-flag instructions.
10216 ;; For all sCOND expanders, also expand the compare or test insn that
10217 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10219 (define_insn_and_split "*setcc_di_1"
10220 [(set (match_operand:DI 0 "register_operand" "=q")
10221 (match_operator:DI 1 "ix86_comparison_operator"
10222 [(reg FLAGS_REG) (const_int 0)]))]
10223 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10225 "&& reload_completed"
10226 [(set (match_dup 2) (match_dup 1))
10227 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10229 PUT_MODE (operands[1], QImode);
10230 operands[2] = gen_lowpart (QImode, operands[0]);
10233 (define_insn_and_split "*setcc_si_1_and"
10234 [(set (match_operand:SI 0 "register_operand" "=q")
10235 (match_operator:SI 1 "ix86_comparison_operator"
10236 [(reg FLAGS_REG) (const_int 0)]))
10237 (clobber (reg:CC FLAGS_REG))]
10238 "!TARGET_PARTIAL_REG_STALL
10239 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10241 "&& reload_completed"
10242 [(set (match_dup 2) (match_dup 1))
10243 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10244 (clobber (reg:CC FLAGS_REG))])]
10246 PUT_MODE (operands[1], QImode);
10247 operands[2] = gen_lowpart (QImode, operands[0]);
10250 (define_insn_and_split "*setcc_si_1_movzbl"
10251 [(set (match_operand:SI 0 "register_operand" "=q")
10252 (match_operator:SI 1 "ix86_comparison_operator"
10253 [(reg FLAGS_REG) (const_int 0)]))]
10254 "!TARGET_PARTIAL_REG_STALL
10255 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10257 "&& reload_completed"
10258 [(set (match_dup 2) (match_dup 1))
10259 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10261 PUT_MODE (operands[1], QImode);
10262 operands[2] = gen_lowpart (QImode, operands[0]);
10265 (define_insn "*setcc_qi"
10266 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10267 (match_operator:QI 1 "ix86_comparison_operator"
10268 [(reg FLAGS_REG) (const_int 0)]))]
10271 [(set_attr "type" "setcc")
10272 (set_attr "mode" "QI")])
10274 (define_insn "*setcc_qi_slp"
10275 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10276 (match_operator:QI 1 "ix86_comparison_operator"
10277 [(reg FLAGS_REG) (const_int 0)]))]
10280 [(set_attr "type" "setcc")
10281 (set_attr "mode" "QI")])
10283 ;; In general it is not safe to assume too much about CCmode registers,
10284 ;; so simplify-rtx stops when it sees a second one. Under certain
10285 ;; conditions this is safe on x86, so help combine not create
10292 [(set (match_operand:QI 0 "nonimmediate_operand")
10293 (ne:QI (match_operator 1 "ix86_comparison_operator"
10294 [(reg FLAGS_REG) (const_int 0)])
10297 [(set (match_dup 0) (match_dup 1))]
10298 "PUT_MODE (operands[1], QImode);")
10301 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10302 (ne:QI (match_operator 1 "ix86_comparison_operator"
10303 [(reg FLAGS_REG) (const_int 0)])
10306 [(set (match_dup 0) (match_dup 1))]
10307 "PUT_MODE (operands[1], QImode);")
10310 [(set (match_operand:QI 0 "nonimmediate_operand")
10311 (eq:QI (match_operator 1 "ix86_comparison_operator"
10312 [(reg FLAGS_REG) (const_int 0)])
10315 [(set (match_dup 0) (match_dup 1))]
10317 rtx new_op1 = copy_rtx (operands[1]);
10318 operands[1] = new_op1;
10319 PUT_MODE (new_op1, QImode);
10320 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10321 GET_MODE (XEXP (new_op1, 0))));
10323 /* Make sure that (a) the CCmode we have for the flags is strong
10324 enough for the reversed compare or (b) we have a valid FP compare. */
10325 if (! ix86_comparison_operator (new_op1, VOIDmode))
10330 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10331 (eq:QI (match_operator 1 "ix86_comparison_operator"
10332 [(reg FLAGS_REG) (const_int 0)])
10335 [(set (match_dup 0) (match_dup 1))]
10337 rtx new_op1 = copy_rtx (operands[1]);
10338 operands[1] = new_op1;
10339 PUT_MODE (new_op1, QImode);
10340 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10341 GET_MODE (XEXP (new_op1, 0))));
10343 /* Make sure that (a) the CCmode we have for the flags is strong
10344 enough for the reversed compare or (b) we have a valid FP compare. */
10345 if (! ix86_comparison_operator (new_op1, VOIDmode))
10349 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10350 ;; subsequent logical operations are used to imitate conditional moves.
10351 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10354 (define_insn "setcc_<mode>_sse"
10355 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10356 (match_operator:MODEF 3 "sse_comparison_operator"
10357 [(match_operand:MODEF 1 "register_operand" "0,x")
10358 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10359 "SSE_FLOAT_MODE_P (<MODE>mode)"
10361 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10362 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10363 [(set_attr "isa" "noavx,avx")
10364 (set_attr "type" "ssecmp")
10365 (set_attr "length_immediate" "1")
10366 (set_attr "prefix" "orig,vex")
10367 (set_attr "mode" "<MODE>")])
10369 ;; Basic conditional jump instructions.
10370 ;; We ignore the overflow flag for signed branch instructions.
10372 (define_insn "*jcc_1"
10374 (if_then_else (match_operator 1 "ix86_comparison_operator"
10375 [(reg FLAGS_REG) (const_int 0)])
10376 (label_ref (match_operand 0))
10380 [(set_attr "type" "ibr")
10381 (set_attr "modrm" "0")
10382 (set (attr "length")
10383 (if_then_else (and (ge (minus (match_dup 0) (pc))
10385 (lt (minus (match_dup 0) (pc))
10390 (define_insn "*jcc_2"
10392 (if_then_else (match_operator 1 "ix86_comparison_operator"
10393 [(reg FLAGS_REG) (const_int 0)])
10395 (label_ref (match_operand 0))))]
10398 [(set_attr "type" "ibr")
10399 (set_attr "modrm" "0")
10400 (set (attr "length")
10401 (if_then_else (and (ge (minus (match_dup 0) (pc))
10403 (lt (minus (match_dup 0) (pc))
10408 ;; In general it is not safe to assume too much about CCmode registers,
10409 ;; so simplify-rtx stops when it sees a second one. Under certain
10410 ;; conditions this is safe on x86, so help combine not create
10418 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10419 [(reg FLAGS_REG) (const_int 0)])
10421 (label_ref (match_operand 1))
10425 (if_then_else (match_dup 0)
10426 (label_ref (match_dup 1))
10428 "PUT_MODE (operands[0], VOIDmode);")
10432 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10433 [(reg FLAGS_REG) (const_int 0)])
10435 (label_ref (match_operand 1))
10439 (if_then_else (match_dup 0)
10440 (label_ref (match_dup 1))
10443 rtx new_op0 = copy_rtx (operands[0]);
10444 operands[0] = new_op0;
10445 PUT_MODE (new_op0, VOIDmode);
10446 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10447 GET_MODE (XEXP (new_op0, 0))));
10449 /* Make sure that (a) the CCmode we have for the flags is strong
10450 enough for the reversed compare or (b) we have a valid FP compare. */
10451 if (! ix86_comparison_operator (new_op0, VOIDmode))
10455 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10456 ;; pass generates from shift insn with QImode operand. Actually, the mode
10457 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10458 ;; appropriate modulo of the bit offset value.
10460 (define_insn_and_split "*jcc_bt<mode>"
10462 (if_then_else (match_operator 0 "bt_comparison_operator"
10463 [(zero_extract:SWI48
10464 (match_operand:SWI48 1 "register_operand" "r")
10467 (match_operand:QI 2 "register_operand" "r")))
10469 (label_ref (match_operand 3))
10471 (clobber (reg:CC FLAGS_REG))]
10472 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10475 [(set (reg:CCC FLAGS_REG)
10477 (zero_extract:SWI48
10483 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10484 (label_ref (match_dup 3))
10487 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10489 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10492 ;; Like *jcc_bt<mode>, but expect a SImode operand 2 instead of QImode
10493 ;; zero extended to SImode.
10494 (define_insn_and_split "*jcc_bt<mode>_1"
10496 (if_then_else (match_operator 0 "bt_comparison_operator"
10497 [(zero_extract:SWI48
10498 (match_operand:SWI48 1 "register_operand" "r")
10500 (match_operand:SI 2 "register_operand" "r"))
10502 (label_ref (match_operand 3))
10504 (clobber (reg:CC FLAGS_REG))]
10505 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10508 [(set (reg:CCC FLAGS_REG)
10510 (zero_extract:SWI48
10516 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10517 (label_ref (match_dup 3))
10520 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10522 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10525 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10526 ;; also for DImode, this is what combine produces.
10527 (define_insn_and_split "*jcc_bt<mode>_mask"
10529 (if_then_else (match_operator 0 "bt_comparison_operator"
10530 [(zero_extract:SWI48
10531 (match_operand:SWI48 1 "register_operand" "r")
10534 (match_operand:SI 2 "register_operand" "r")
10535 (match_operand:SI 3 "const_int_operand" "n")))])
10536 (label_ref (match_operand 4))
10538 (clobber (reg:CC FLAGS_REG))]
10539 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10540 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10541 == GET_MODE_BITSIZE (<MODE>mode)-1"
10544 [(set (reg:CCC FLAGS_REG)
10546 (zero_extract:SWI48
10552 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10553 (label_ref (match_dup 4))
10556 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10558 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10561 (define_insn_and_split "*jcc_btsi_1"
10563 (if_then_else (match_operator 0 "bt_comparison_operator"
10566 (match_operand:SI 1 "register_operand" "r")
10567 (match_operand:QI 2 "register_operand" "r"))
10570 (label_ref (match_operand 3))
10572 (clobber (reg:CC FLAGS_REG))]
10573 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10576 [(set (reg:CCC FLAGS_REG)
10584 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10585 (label_ref (match_dup 3))
10588 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10590 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10593 ;; avoid useless masking of bit offset operand
10594 (define_insn_and_split "*jcc_btsi_mask_1"
10597 (match_operator 0 "bt_comparison_operator"
10600 (match_operand:SI 1 "register_operand" "r")
10603 (match_operand:SI 2 "register_operand" "r")
10604 (match_operand:SI 3 "const_int_operand" "n")) 0))
10607 (label_ref (match_operand 4))
10609 (clobber (reg:CC FLAGS_REG))]
10610 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10611 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10614 [(set (reg:CCC FLAGS_REG)
10622 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10623 (label_ref (match_dup 4))
10625 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10627 ;; Define combination compare-and-branch fp compare instructions to help
10630 (define_insn "*jcc<mode>_0_i387"
10632 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
10633 [(match_operand:X87MODEF 1 "register_operand" "f")
10634 (match_operand:X87MODEF 2 "const0_operand")])
10635 (label_ref (match_operand 3))
10637 (clobber (reg:CCFP FPSR_REG))
10638 (clobber (reg:CCFP FLAGS_REG))
10639 (clobber (match_scratch:HI 4 "=a"))]
10640 "TARGET_80387 && !TARGET_CMOVE"
10643 (define_insn "*jcc<mode>_0_r_i387"
10645 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
10646 [(match_operand:X87MODEF 1 "register_operand" "f")
10647 (match_operand:X87MODEF 2 "const0_operand")])
10649 (label_ref (match_operand 3))))
10650 (clobber (reg:CCFP FPSR_REG))
10651 (clobber (reg:CCFP FLAGS_REG))
10652 (clobber (match_scratch:HI 4 "=a"))]
10653 "TARGET_80387 && !TARGET_CMOVE"
10656 (define_insn "*jccxf_i387"
10658 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
10659 [(match_operand:XF 1 "register_operand" "f")
10660 (match_operand:XF 2 "register_operand" "f")])
10661 (label_ref (match_operand 3))
10663 (clobber (reg:CCFP FPSR_REG))
10664 (clobber (reg:CCFP FLAGS_REG))
10665 (clobber (match_scratch:HI 4 "=a"))]
10666 "TARGET_80387 && !TARGET_CMOVE"
10669 (define_insn "*jccxf_r_i387"
10671 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
10672 [(match_operand:XF 1 "register_operand" "f")
10673 (match_operand:XF 2 "register_operand" "f")])
10675 (label_ref (match_operand 3))))
10676 (clobber (reg:CCFP FPSR_REG))
10677 (clobber (reg:CCFP FLAGS_REG))
10678 (clobber (match_scratch:HI 4 "=a"))]
10679 "TARGET_80387 && !TARGET_CMOVE"
10682 (define_insn "*jcc<mode>_i387"
10684 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
10685 [(match_operand:MODEF 1 "register_operand" "f")
10686 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
10687 (label_ref (match_operand 3))
10689 (clobber (reg:CCFP FPSR_REG))
10690 (clobber (reg:CCFP FLAGS_REG))
10691 (clobber (match_scratch:HI 4 "=a"))]
10692 "TARGET_80387 && !TARGET_CMOVE"
10695 (define_insn "*jcc<mode>_r_i387"
10697 (if_then_else (match_operator:CCFP 0 "ix86_fp_comparison_operator"
10698 [(match_operand:MODEF 1 "register_operand" "f")
10699 (match_operand:MODEF 2 "nonimmediate_operand" "fm")])
10701 (label_ref (match_operand 3))))
10702 (clobber (reg:CCFP FPSR_REG))
10703 (clobber (reg:CCFP FLAGS_REG))
10704 (clobber (match_scratch:HI 4 "=a"))]
10705 "TARGET_80387 && !TARGET_CMOVE"
10708 (define_insn "*jccu<mode>_i387"
10710 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
10711 [(match_operand:X87MODEF 1 "register_operand" "f")
10712 (match_operand:X87MODEF 2 "register_operand" "f")])
10713 (label_ref (match_operand 3))
10715 (clobber (reg:CCFP FPSR_REG))
10716 (clobber (reg:CCFP FLAGS_REG))
10717 (clobber (match_scratch:HI 4 "=a"))]
10718 "TARGET_80387 && !TARGET_CMOVE"
10721 (define_insn "*jccu<mode>_r_i387"
10723 (if_then_else (match_operator:CCFPU 0 "ix86_fp_comparison_operator"
10724 [(match_operand:X87MODEF 1 "register_operand" "f")
10725 (match_operand:X87MODEF 2 "register_operand" "f")])
10727 (label_ref (match_operand 3))))
10728 (clobber (reg:CCFP FPSR_REG))
10729 (clobber (reg:CCFP FLAGS_REG))
10730 (clobber (match_scratch:HI 4 "=a"))]
10731 "TARGET_80387 && !TARGET_CMOVE"
10736 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10737 [(match_operand:X87MODEF 1 "register_operand")
10738 (match_operand:X87MODEF 2 "nonimmediate_operand")])
10740 (match_operand 4)))
10741 (clobber (reg:CCFP FPSR_REG))
10742 (clobber (reg:CCFP FLAGS_REG))]
10743 "TARGET_80387 && !TARGET_CMOVE
10744 && reload_completed"
10747 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10748 operands[3], operands[4], NULL_RTX, NULL_RTX);
10754 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10755 [(match_operand:X87MODEF 1 "register_operand")
10756 (match_operand:X87MODEF 2 "general_operand")])
10758 (match_operand 4)))
10759 (clobber (reg:CCFP FPSR_REG))
10760 (clobber (reg:CCFP FLAGS_REG))
10761 (clobber (match_scratch:HI 5))]
10762 "TARGET_80387 && !TARGET_CMOVE
10763 && reload_completed"
10766 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10767 operands[3], operands[4], operands[5], NULL_RTX);
10771 ;; The order of operands in *jcc<fp>_<int>_i387 is forced by combine in
10772 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
10773 ;; with a precedence over other operators and is always put in the first
10774 ;; place. Swap condition and operands to match ficom instruction.
10776 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_i387"
10779 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
10780 [(match_operator:X87MODEF 1 "float_operator"
10781 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
10782 (match_operand:X87MODEF 3 "register_operand" "f,f")])
10783 (label_ref (match_operand 4))
10785 (clobber (reg:CCFP FPSR_REG))
10786 (clobber (reg:CCFP FLAGS_REG))
10787 (clobber (match_scratch:HI 5 "=a,a"))]
10788 "TARGET_80387 && !TARGET_CMOVE
10789 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
10790 || optimize_function_for_size_p (cfun))"
10793 (define_insn "*jcc<X87MODEF:mode>_<SWI24:mode>_r_i387"
10796 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
10797 [(match_operator:X87MODEF 1 "float_operator"
10798 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
10799 (match_operand:X87MODEF 3 "register_operand" "f,f")])
10801 (label_ref (match_operand 4))))
10802 (clobber (reg:CCFP FPSR_REG))
10803 (clobber (reg:CCFP FLAGS_REG))
10804 (clobber (match_scratch:HI 5 "=a,a"))]
10805 "TARGET_80387 && !TARGET_CMOVE
10806 && (TARGET_USE_<SWI24:MODE>MODE_FIOP
10807 || optimize_function_for_size_p (cfun))"
10813 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
10814 [(match_operator:X87MODEF 1 "float_operator"
10815 [(match_operand:SWI24 2 "memory_operand")])
10816 (match_operand:X87MODEF 3 "register_operand")])
10818 (match_operand 5)))
10819 (clobber (reg:CCFP FPSR_REG))
10820 (clobber (reg:CCFP FLAGS_REG))
10821 (clobber (match_scratch:HI 6))]
10822 "TARGET_80387 && !TARGET_CMOVE
10823 && reload_completed"
10826 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
10827 gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]),
10828 operands[4], operands[5], operands[6], NULL_RTX);
10832 ;; %%% Kill this when reload knows how to do it.
10836 (match_operator:CCFP 0 "ix86_swapped_fp_comparison_operator"
10837 [(match_operator:X87MODEF 1 "float_operator"
10838 [(match_operand:SWI24 2 "register_operand")])
10839 (match_operand:X87MODEF 3 "register_operand")])
10841 (match_operand 5)))
10842 (clobber (reg:CCFP FPSR_REG))
10843 (clobber (reg:CCFP FLAGS_REG))
10844 (clobber (match_scratch:HI 6))]
10845 "TARGET_80387 && !TARGET_CMOVE
10846 && reload_completed"
10849 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
10851 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])), operands[3],
10852 gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]),
10853 operands[4], operands[5], operands[6], operands[2]);
10857 ;; Unconditional and other jump instructions
10859 (define_insn "jump"
10861 (label_ref (match_operand 0)))]
10864 [(set_attr "type" "ibr")
10865 (set (attr "length")
10866 (if_then_else (and (ge (minus (match_dup 0) (pc))
10868 (lt (minus (match_dup 0) (pc))
10872 (set_attr "modrm" "0")])
10874 (define_expand "indirect_jump"
10875 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
10879 operands[0] = convert_memory_address (word_mode, operands[0]);
10882 (define_insn "*indirect_jump"
10883 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))]
10886 [(set_attr "type" "ibr")
10887 (set_attr "length_immediate" "0")])
10889 (define_expand "tablejump"
10890 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
10891 (use (label_ref (match_operand 1)))])]
10894 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
10895 relative. Convert the relative address to an absolute address. */
10899 enum rtx_code code;
10901 /* We can't use @GOTOFF for text labels on VxWorks;
10902 see gotoff_operand. */
10903 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
10907 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
10909 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
10913 op1 = pic_offset_table_rtx;
10918 op0 = pic_offset_table_rtx;
10922 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
10927 operands[0] = convert_memory_address (word_mode, operands[0]);
10930 (define_insn "*tablejump_1"
10931 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))
10932 (use (label_ref (match_operand 1)))]
10935 [(set_attr "type" "ibr")
10936 (set_attr "length_immediate" "0")])
10938 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
10941 [(set (reg FLAGS_REG) (match_operand 0))
10942 (set (match_operand:QI 1 "register_operand")
10943 (match_operator:QI 2 "ix86_comparison_operator"
10944 [(reg FLAGS_REG) (const_int 0)]))
10945 (set (match_operand 3 "q_regs_operand")
10946 (zero_extend (match_dup 1)))]
10947 "(peep2_reg_dead_p (3, operands[1])
10948 || operands_match_p (operands[1], operands[3]))
10949 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
10950 [(set (match_dup 4) (match_dup 0))
10951 (set (strict_low_part (match_dup 5))
10954 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
10955 operands[5] = gen_lowpart (QImode, operands[3]);
10956 ix86_expand_clear (operands[3]);
10960 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
10961 (match_operand 4)])
10962 (set (match_operand:QI 1 "register_operand")
10963 (match_operator:QI 2 "ix86_comparison_operator"
10964 [(reg FLAGS_REG) (const_int 0)]))
10965 (set (match_operand 3 "q_regs_operand")
10966 (zero_extend (match_dup 1)))]
10967 "(peep2_reg_dead_p (3, operands[1])
10968 || operands_match_p (operands[1], operands[3]))
10969 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
10970 [(parallel [(set (match_dup 5) (match_dup 0))
10972 (set (strict_low_part (match_dup 6))
10975 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
10976 operands[6] = gen_lowpart (QImode, operands[3]);
10977 ix86_expand_clear (operands[3]);
10980 ;; Similar, but match zero extend with andsi3.
10983 [(set (reg FLAGS_REG) (match_operand 0))
10984 (set (match_operand:QI 1 "register_operand")
10985 (match_operator:QI 2 "ix86_comparison_operator"
10986 [(reg FLAGS_REG) (const_int 0)]))
10987 (parallel [(set (match_operand:SI 3 "q_regs_operand")
10988 (and:SI (match_dup 3) (const_int 255)))
10989 (clobber (reg:CC FLAGS_REG))])]
10990 "REGNO (operands[1]) == REGNO (operands[3])
10991 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
10992 [(set (match_dup 4) (match_dup 0))
10993 (set (strict_low_part (match_dup 5))
10996 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
10997 operands[5] = gen_lowpart (QImode, operands[3]);
10998 ix86_expand_clear (operands[3]);
11002 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11003 (match_operand 4)])
11004 (set (match_operand:QI 1 "register_operand")
11005 (match_operator:QI 2 "ix86_comparison_operator"
11006 [(reg FLAGS_REG) (const_int 0)]))
11007 (parallel [(set (match_operand 3 "q_regs_operand")
11008 (zero_extend (match_dup 1)))
11009 (clobber (reg:CC FLAGS_REG))])]
11010 "(peep2_reg_dead_p (3, operands[1])
11011 || operands_match_p (operands[1], operands[3]))
11012 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11013 [(parallel [(set (match_dup 5) (match_dup 0))
11015 (set (strict_low_part (match_dup 6))
11018 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11019 operands[6] = gen_lowpart (QImode, operands[3]);
11020 ix86_expand_clear (operands[3]);
11023 ;; Call instructions.
11025 ;; The predicates normally associated with named expanders are not properly
11026 ;; checked for calls. This is a bug in the generic code, but it isn't that
11027 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11029 ;; P6 processors will jump to the address after the decrement when %esp
11030 ;; is used as a call operand, so they will execute return address as a code.
11031 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11033 ;; Register constraint for call instruction.
11034 (define_mode_attr c [(SI "l") (DI "r")])
11036 ;; Call subroutine returning no value.
11038 (define_expand "call"
11039 [(call (match_operand:QI 0)
11041 (use (match_operand 2))]
11044 ix86_expand_call (NULL, operands[0], operands[1],
11045 operands[2], NULL, false);
11049 (define_expand "sibcall"
11050 [(call (match_operand:QI 0)
11052 (use (match_operand 2))]
11055 ix86_expand_call (NULL, operands[0], operands[1],
11056 operands[2], NULL, true);
11060 (define_insn "*call"
11061 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11062 (match_operand 1))]
11063 "!SIBLING_CALL_P (insn)"
11064 "* return ix86_output_call_insn (insn, operands[0]);"
11065 [(set_attr "type" "call")])
11067 (define_insn "*call_rex64_ms_sysv"
11068 [(match_parallel 2 "call_rex64_ms_sysv_operation"
11069 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11071 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)])]
11072 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11073 "* return ix86_output_call_insn (insn, operands[0]);"
11074 [(set_attr "type" "call")])
11076 (define_insn "*sibcall"
11077 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11078 (match_operand 1))]
11079 "SIBLING_CALL_P (insn)"
11080 "* return ix86_output_call_insn (insn, operands[0]);"
11081 [(set_attr "type" "call")])
11083 (define_expand "call_pop"
11084 [(parallel [(call (match_operand:QI 0)
11085 (match_operand:SI 1))
11086 (set (reg:SI SP_REG)
11087 (plus:SI (reg:SI SP_REG)
11088 (match_operand:SI 3)))])]
11091 ix86_expand_call (NULL, operands[0], operands[1],
11092 operands[2], operands[3], false);
11096 (define_insn "*call_pop"
11097 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11099 (set (reg:SI SP_REG)
11100 (plus:SI (reg:SI SP_REG)
11101 (match_operand:SI 2 "immediate_operand" "i")))]
11102 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11103 "* return ix86_output_call_insn (insn, operands[0]);"
11104 [(set_attr "type" "call")])
11106 (define_insn "*sibcall_pop"
11107 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11109 (set (reg:SI SP_REG)
11110 (plus:SI (reg:SI SP_REG)
11111 (match_operand:SI 2 "immediate_operand" "i")))]
11112 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11113 "* return ix86_output_call_insn (insn, operands[0]);"
11114 [(set_attr "type" "call")])
11116 ;; Call subroutine, returning value in operand 0
11118 (define_expand "call_value"
11119 [(set (match_operand 0)
11120 (call (match_operand:QI 1)
11121 (match_operand 2)))
11122 (use (match_operand 3))]
11125 ix86_expand_call (operands[0], operands[1], operands[2],
11126 operands[3], NULL, false);
11130 (define_expand "sibcall_value"
11131 [(set (match_operand 0)
11132 (call (match_operand:QI 1)
11133 (match_operand 2)))
11134 (use (match_operand 3))]
11137 ix86_expand_call (operands[0], operands[1], operands[2],
11138 operands[3], NULL, true);
11142 (define_insn "*call_value"
11143 [(set (match_operand 0)
11144 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11145 (match_operand 2)))]
11146 "!SIBLING_CALL_P (insn)"
11147 "* return ix86_output_call_insn (insn, operands[1]);"
11148 [(set_attr "type" "callv")])
11150 (define_insn "*sibcall_value"
11151 [(set (match_operand 0)
11152 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11153 (match_operand 2)))]
11154 "SIBLING_CALL_P (insn)"
11155 "* return ix86_output_call_insn (insn, operands[1]);"
11156 [(set_attr "type" "callv")])
11158 (define_insn "*call_value_rex64_ms_sysv"
11159 [(match_parallel 3 "call_rex64_ms_sysv_operation"
11160 [(set (match_operand 0)
11161 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11162 (match_operand 2)))
11163 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)])]
11164 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11165 "* return ix86_output_call_insn (insn, operands[1]);"
11166 [(set_attr "type" "callv")])
11168 (define_expand "call_value_pop"
11169 [(parallel [(set (match_operand 0)
11170 (call (match_operand:QI 1)
11171 (match_operand:SI 2)))
11172 (set (reg:SI SP_REG)
11173 (plus:SI (reg:SI SP_REG)
11174 (match_operand:SI 4)))])]
11177 ix86_expand_call (operands[0], operands[1], operands[2],
11178 operands[3], operands[4], false);
11182 (define_insn "*call_value_pop"
11183 [(set (match_operand 0)
11184 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11185 (match_operand 2)))
11186 (set (reg:SI SP_REG)
11187 (plus:SI (reg:SI SP_REG)
11188 (match_operand:SI 3 "immediate_operand" "i")))]
11189 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11190 "* return ix86_output_call_insn (insn, operands[1]);"
11191 [(set_attr "type" "callv")])
11193 (define_insn "*sibcall_value_pop"
11194 [(set (match_operand 0)
11195 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11196 (match_operand 2)))
11197 (set (reg:SI SP_REG)
11198 (plus:SI (reg:SI SP_REG)
11199 (match_operand:SI 3 "immediate_operand" "i")))]
11200 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11201 "* return ix86_output_call_insn (insn, operands[1]);"
11202 [(set_attr "type" "callv")])
11204 ;; Call subroutine returning any type.
11206 (define_expand "untyped_call"
11207 [(parallel [(call (match_operand 0)
11210 (match_operand 2)])]
11215 /* In order to give reg-stack an easier job in validating two
11216 coprocessor registers as containing a possible return value,
11217 simply pretend the untyped call returns a complex long double
11220 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11221 and should have the default ABI. */
11223 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11224 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11225 operands[0], const0_rtx,
11226 GEN_INT ((TARGET_64BIT
11227 ? (ix86_abi == SYSV_ABI
11228 ? X86_64_SSE_REGPARM_MAX
11229 : X86_64_MS_SSE_REGPARM_MAX)
11230 : X86_32_SSE_REGPARM_MAX)
11234 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11236 rtx set = XVECEXP (operands[2], 0, i);
11237 emit_move_insn (SET_DEST (set), SET_SRC (set));
11240 /* The optimizer does not know that the call sets the function value
11241 registers we stored in the result block. We avoid problems by
11242 claiming that all hard registers are used and clobbered at this
11244 emit_insn (gen_blockage ());
11249 ;; Prologue and epilogue instructions
11251 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11252 ;; all of memory. This blocks insns from being moved across this point.
11254 (define_insn "blockage"
11255 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11258 [(set_attr "length" "0")])
11260 ;; Do not schedule instructions accessing memory across this point.
11262 (define_expand "memory_blockage"
11263 [(set (match_dup 0)
11264 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11267 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11268 MEM_VOLATILE_P (operands[0]) = 1;
11271 (define_insn "*memory_blockage"
11272 [(set (match_operand:BLK 0)
11273 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11276 [(set_attr "length" "0")])
11278 ;; As USE insns aren't meaningful after reload, this is used instead
11279 ;; to prevent deleting instructions setting registers for PIC code
11280 (define_insn "prologue_use"
11281 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
11284 [(set_attr "length" "0")])
11286 ;; Insn emitted into the body of a function to return from a function.
11287 ;; This is only done if the function's epilogue is known to be simple.
11288 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11290 (define_expand "return"
11292 "ix86_can_use_return_insn_p ()"
11294 if (crtl->args.pops_args)
11296 rtx popc = GEN_INT (crtl->args.pops_args);
11297 emit_jump_insn (gen_simple_return_pop_internal (popc));
11302 ;; We need to disable this for TARGET_SEH, as otherwise
11303 ;; shrink-wrapped prologue gets enabled too. This might exceed
11304 ;; the maximum size of prologue in unwind information.
11306 (define_expand "simple_return"
11310 if (crtl->args.pops_args)
11312 rtx popc = GEN_INT (crtl->args.pops_args);
11313 emit_jump_insn (gen_simple_return_pop_internal (popc));
11318 (define_insn "simple_return_internal"
11322 [(set_attr "length" "1")
11323 (set_attr "atom_unit" "jeu")
11324 (set_attr "length_immediate" "0")
11325 (set_attr "modrm" "0")])
11327 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11328 ;; instruction Athlon and K8 have.
11330 (define_insn "simple_return_internal_long"
11332 (unspec [(const_int 0)] UNSPEC_REP)]
11335 [(set_attr "length" "2")
11336 (set_attr "atom_unit" "jeu")
11337 (set_attr "length_immediate" "0")
11338 (set_attr "prefix_rep" "1")
11339 (set_attr "modrm" "0")])
11341 (define_insn "simple_return_pop_internal"
11343 (use (match_operand:SI 0 "const_int_operand"))]
11346 [(set_attr "length" "3")
11347 (set_attr "atom_unit" "jeu")
11348 (set_attr "length_immediate" "2")
11349 (set_attr "modrm" "0")])
11351 (define_insn "simple_return_indirect_internal"
11353 (use (match_operand:SI 0 "register_operand" "r"))]
11356 [(set_attr "type" "ibr")
11357 (set_attr "length_immediate" "0")])
11363 [(set_attr "length" "1")
11364 (set_attr "length_immediate" "0")
11365 (set_attr "modrm" "0")])
11367 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11368 (define_insn "nops"
11369 [(unspec_volatile [(match_operand 0 "const_int_operand")]
11373 int num = INTVAL (operands[0]);
11375 gcc_assert (IN_RANGE (num, 1, 8));
11378 fputs ("\tnop\n", asm_out_file);
11382 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11383 (set_attr "length_immediate" "0")
11384 (set_attr "modrm" "0")])
11386 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11387 ;; branch prediction penalty for the third jump in a 16-byte
11391 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
11394 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11395 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11397 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11398 The align insn is used to avoid 3 jump instructions in the row to improve
11399 branch prediction and the benefits hardly outweigh the cost of extra 8
11400 nops on the average inserted by full alignment pseudo operation. */
11404 [(set_attr "length" "16")])
11406 (define_expand "prologue"
11409 "ix86_expand_prologue (); DONE;")
11411 (define_insn "set_got"
11412 [(set (match_operand:SI 0 "register_operand" "=r")
11413 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11414 (clobber (reg:CC FLAGS_REG))]
11416 "* return output_set_got (operands[0], NULL_RTX);"
11417 [(set_attr "type" "multi")
11418 (set_attr "length" "12")])
11420 (define_insn "set_got_labelled"
11421 [(set (match_operand:SI 0 "register_operand" "=r")
11422 (unspec:SI [(label_ref (match_operand 1))]
11424 (clobber (reg:CC FLAGS_REG))]
11426 "* return output_set_got (operands[0], operands[1]);"
11427 [(set_attr "type" "multi")
11428 (set_attr "length" "12")])
11430 (define_insn "set_got_rex64"
11431 [(set (match_operand:DI 0 "register_operand" "=r")
11432 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11434 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11435 [(set_attr "type" "lea")
11436 (set_attr "length_address" "4")
11437 (set_attr "mode" "DI")])
11439 (define_insn "set_rip_rex64"
11440 [(set (match_operand:DI 0 "register_operand" "=r")
11441 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
11443 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11444 [(set_attr "type" "lea")
11445 (set_attr "length_address" "4")
11446 (set_attr "mode" "DI")])
11448 (define_insn "set_got_offset_rex64"
11449 [(set (match_operand:DI 0 "register_operand" "=r")
11451 [(label_ref (match_operand 1))]
11452 UNSPEC_SET_GOT_OFFSET))]
11454 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11455 [(set_attr "type" "imov")
11456 (set_attr "length_immediate" "0")
11457 (set_attr "length_address" "8")
11458 (set_attr "mode" "DI")])
11460 (define_expand "epilogue"
11463 "ix86_expand_epilogue (1); DONE;")
11465 (define_expand "sibcall_epilogue"
11468 "ix86_expand_epilogue (0); DONE;")
11470 (define_expand "eh_return"
11471 [(use (match_operand 0 "register_operand"))]
11474 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11476 /* Tricky bit: we write the address of the handler to which we will
11477 be returning into someone else's stack frame, one word below the
11478 stack address we wish to restore. */
11479 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11480 tmp = plus_constant (Pmode, tmp, -UNITS_PER_WORD);
11481 tmp = gen_rtx_MEM (Pmode, tmp);
11482 emit_move_insn (tmp, ra);
11484 emit_jump_insn (gen_eh_return_internal ());
11489 (define_insn_and_split "eh_return_internal"
11493 "epilogue_completed"
11495 "ix86_expand_epilogue (2); DONE;")
11497 (define_insn "leave"
11498 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11499 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11500 (clobber (mem:BLK (scratch)))]
11503 [(set_attr "type" "leave")])
11505 (define_insn "leave_rex64"
11506 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11507 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11508 (clobber (mem:BLK (scratch)))]
11511 [(set_attr "type" "leave")])
11513 ;; Handle -fsplit-stack.
11515 (define_expand "split_stack_prologue"
11519 ix86_expand_split_stack_prologue ();
11523 ;; In order to support the call/return predictor, we use a return
11524 ;; instruction which the middle-end doesn't see.
11525 (define_insn "split_stack_return"
11526 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
11527 UNSPECV_SPLIT_STACK_RETURN)]
11530 if (operands[0] == const0_rtx)
11535 [(set_attr "atom_unit" "jeu")
11536 (set_attr "modrm" "0")
11537 (set (attr "length")
11538 (if_then_else (match_operand:SI 0 "const0_operand")
11541 (set (attr "length_immediate")
11542 (if_then_else (match_operand:SI 0 "const0_operand")
11546 ;; If there are operand 0 bytes available on the stack, jump to
11549 (define_expand "split_stack_space_check"
11550 [(set (pc) (if_then_else
11551 (ltu (minus (reg SP_REG)
11552 (match_operand 0 "register_operand"))
11553 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11554 (label_ref (match_operand 1))
11558 rtx reg, size, limit;
11560 reg = gen_reg_rtx (Pmode);
11561 size = force_reg (Pmode, operands[0]);
11562 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11563 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11564 UNSPEC_STACK_CHECK);
11565 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11566 ix86_expand_branch (GEU, reg, limit, operands[1]);
11571 ;; Bit manipulation instructions.
11573 (define_expand "ffs<mode>2"
11574 [(set (match_dup 2) (const_int -1))
11575 (parallel [(set (match_dup 3) (match_dup 4))
11576 (set (match_operand:SWI48 0 "register_operand")
11578 (match_operand:SWI48 1 "nonimmediate_operand")))])
11579 (set (match_dup 0) (if_then_else:SWI48
11580 (eq (match_dup 3) (const_int 0))
11583 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11584 (clobber (reg:CC FLAGS_REG))])]
11587 enum machine_mode flags_mode;
11589 if (<MODE>mode == SImode && !TARGET_CMOVE)
11591 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11595 flags_mode = TARGET_BMI ? CCCmode : CCZmode;
11597 operands[2] = gen_reg_rtx (<MODE>mode);
11598 operands[3] = gen_rtx_REG (flags_mode, FLAGS_REG);
11599 operands[4] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
11602 (define_insn_and_split "ffssi2_no_cmove"
11603 [(set (match_operand:SI 0 "register_operand" "=r")
11604 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11605 (clobber (match_scratch:SI 2 "=&q"))
11606 (clobber (reg:CC FLAGS_REG))]
11609 "&& reload_completed"
11610 [(parallel [(set (match_dup 4) (match_dup 5))
11611 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11612 (set (strict_low_part (match_dup 3))
11613 (eq:QI (match_dup 4) (const_int 0)))
11614 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11615 (clobber (reg:CC FLAGS_REG))])
11616 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11617 (clobber (reg:CC FLAGS_REG))])
11618 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11619 (clobber (reg:CC FLAGS_REG))])]
11621 enum machine_mode flags_mode = TARGET_BMI ? CCCmode : CCZmode;
11623 operands[3] = gen_lowpart (QImode, operands[2]);
11624 operands[4] = gen_rtx_REG (flags_mode, FLAGS_REG);
11625 operands[5] = gen_rtx_COMPARE (flags_mode, operands[1], const0_rtx);
11627 ix86_expand_clear (operands[2]);
11630 (define_insn "*tzcnt<mode>_1"
11631 [(set (reg:CCC FLAGS_REG)
11632 (compare:CCC (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11634 (set (match_operand:SWI48 0 "register_operand" "=r")
11635 (ctz:SWI48 (match_dup 1)))]
11637 "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11638 [(set_attr "type" "alu1")
11639 (set_attr "prefix_0f" "1")
11640 (set_attr "prefix_rep" "1")
11641 (set_attr "btver2_decode" "double")
11642 (set_attr "mode" "<MODE>")])
11644 (define_insn "*bsf<mode>_1"
11645 [(set (reg:CCZ FLAGS_REG)
11646 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11648 (set (match_operand:SWI48 0 "register_operand" "=r")
11649 (ctz:SWI48 (match_dup 1)))]
11651 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11652 [(set_attr "type" "alu1")
11653 (set_attr "prefix_0f" "1")
11654 (set_attr "btver2_decode" "double")
11655 (set_attr "mode" "<MODE>")])
11657 (define_insn "ctz<mode>2"
11658 [(set (match_operand:SWI248 0 "register_operand" "=r")
11659 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11660 (clobber (reg:CC FLAGS_REG))]
11664 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11665 else if (optimize_function_for_size_p (cfun))
11667 else if (TARGET_GENERIC)
11668 /* tzcnt expands to 'rep bsf' and we can use it even if !TARGET_BMI. */
11669 return "rep%; bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
11671 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
11673 [(set_attr "type" "alu1")
11674 (set_attr "prefix_0f" "1")
11675 (set (attr "prefix_rep")
11677 (ior (match_test "TARGET_BMI")
11678 (and (not (match_test "optimize_function_for_size_p (cfun)"))
11679 (match_test "TARGET_GENERIC")))
11681 (const_string "0")))
11682 (set_attr "mode" "<MODE>")])
11684 (define_expand "clz<mode>2"
11686 [(set (match_operand:SWI248 0 "register_operand")
11689 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
11690 (clobber (reg:CC FLAGS_REG))])
11692 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
11693 (clobber (reg:CC FLAGS_REG))])]
11698 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
11701 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
11704 (define_insn "clz<mode>2_lzcnt"
11705 [(set (match_operand:SWI248 0 "register_operand" "=r")
11706 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11707 (clobber (reg:CC FLAGS_REG))]
11709 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
11710 [(set_attr "prefix_rep" "1")
11711 (set_attr "type" "bitmanip")
11712 (set_attr "mode" "<MODE>")])
11714 ;; BMI instructions.
11715 (define_insn "*bmi_andn_<mode>"
11716 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
11719 (match_operand:SWI48 1 "register_operand" "r,r"))
11720 (match_operand:SWI48 2 "nonimmediate_operand" "r,m")))
11721 (clobber (reg:CC FLAGS_REG))]
11723 "andn\t{%2, %1, %0|%0, %1, %2}"
11724 [(set_attr "type" "bitmanip")
11725 (set_attr "btver2_decode" "direct, double")
11726 (set_attr "mode" "<MODE>")])
11728 (define_insn "bmi_bextr_<mode>"
11729 [(set (match_operand:SWI48 0 "register_operand" "=r,r")
11730 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "r,m")
11731 (match_operand:SWI48 2 "register_operand" "r,r")]
11733 (clobber (reg:CC FLAGS_REG))]
11735 "bextr\t{%2, %1, %0|%0, %1, %2}"
11736 [(set_attr "type" "bitmanip")
11737 (set_attr "btver2_decode" "direct, double")
11738 (set_attr "mode" "<MODE>")])
11740 (define_insn "*bmi_blsi_<mode>"
11741 [(set (match_operand:SWI48 0 "register_operand" "=r")
11744 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
11746 (clobber (reg:CC FLAGS_REG))]
11748 "blsi\t{%1, %0|%0, %1}"
11749 [(set_attr "type" "bitmanip")
11750 (set_attr "btver2_decode" "double")
11751 (set_attr "mode" "<MODE>")])
11753 (define_insn "*bmi_blsmsk_<mode>"
11754 [(set (match_operand:SWI48 0 "register_operand" "=r")
11757 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11760 (clobber (reg:CC FLAGS_REG))]
11762 "blsmsk\t{%1, %0|%0, %1}"
11763 [(set_attr "type" "bitmanip")
11764 (set_attr "btver2_decode" "double")
11765 (set_attr "mode" "<MODE>")])
11767 (define_insn "*bmi_blsr_<mode>"
11768 [(set (match_operand:SWI48 0 "register_operand" "=r")
11771 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11774 (clobber (reg:CC FLAGS_REG))]
11776 "blsr\t{%1, %0|%0, %1}"
11777 [(set_attr "type" "bitmanip")
11778 (set_attr "btver2_decode" "double")
11779 (set_attr "mode" "<MODE>")])
11781 ;; BMI2 instructions.
11782 (define_insn "bmi2_bzhi_<mode>3"
11783 [(set (match_operand:SWI48 0 "register_operand" "=r")
11784 (and:SWI48 (lshiftrt:SWI48 (const_int -1)
11785 (match_operand:SWI48 2 "register_operand" "r"))
11786 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
11787 (clobber (reg:CC FLAGS_REG))]
11789 "bzhi\t{%2, %1, %0|%0, %1, %2}"
11790 [(set_attr "type" "bitmanip")
11791 (set_attr "prefix" "vex")
11792 (set_attr "mode" "<MODE>")])
11794 (define_insn "bmi2_pdep_<mode>3"
11795 [(set (match_operand:SWI48 0 "register_operand" "=r")
11796 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
11797 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
11800 "pdep\t{%2, %1, %0|%0, %1, %2}"
11801 [(set_attr "type" "bitmanip")
11802 (set_attr "prefix" "vex")
11803 (set_attr "mode" "<MODE>")])
11805 (define_insn "bmi2_pext_<mode>3"
11806 [(set (match_operand:SWI48 0 "register_operand" "=r")
11807 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
11808 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
11811 "pext\t{%2, %1, %0|%0, %1, %2}"
11812 [(set_attr "type" "bitmanip")
11813 (set_attr "prefix" "vex")
11814 (set_attr "mode" "<MODE>")])
11816 ;; TBM instructions.
11817 (define_insn "tbm_bextri_<mode>"
11818 [(set (match_operand:SWI48 0 "register_operand" "=r")
11819 (zero_extract:SWI48
11820 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11821 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
11822 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
11823 (clobber (reg:CC FLAGS_REG))]
11826 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
11827 return "bextr\t{%2, %1, %0|%0, %1, %2}";
11829 [(set_attr "type" "bitmanip")
11830 (set_attr "mode" "<MODE>")])
11832 (define_insn "*tbm_blcfill_<mode>"
11833 [(set (match_operand:SWI48 0 "register_operand" "=r")
11836 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11839 (clobber (reg:CC FLAGS_REG))]
11841 "blcfill\t{%1, %0|%0, %1}"
11842 [(set_attr "type" "bitmanip")
11843 (set_attr "mode" "<MODE>")])
11845 (define_insn "*tbm_blci_<mode>"
11846 [(set (match_operand:SWI48 0 "register_operand" "=r")
11850 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11853 (clobber (reg:CC FLAGS_REG))]
11855 "blci\t{%1, %0|%0, %1}"
11856 [(set_attr "type" "bitmanip")
11857 (set_attr "mode" "<MODE>")])
11859 (define_insn "*tbm_blcic_<mode>"
11860 [(set (match_operand:SWI48 0 "register_operand" "=r")
11863 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11867 (clobber (reg:CC FLAGS_REG))]
11869 "blcic\t{%1, %0|%0, %1}"
11870 [(set_attr "type" "bitmanip")
11871 (set_attr "mode" "<MODE>")])
11873 (define_insn "*tbm_blcmsk_<mode>"
11874 [(set (match_operand:SWI48 0 "register_operand" "=r")
11877 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11880 (clobber (reg:CC FLAGS_REG))]
11882 "blcmsk\t{%1, %0|%0, %1}"
11883 [(set_attr "type" "bitmanip")
11884 (set_attr "mode" "<MODE>")])
11886 (define_insn "*tbm_blcs_<mode>"
11887 [(set (match_operand:SWI48 0 "register_operand" "=r")
11890 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11893 (clobber (reg:CC FLAGS_REG))]
11895 "blcs\t{%1, %0|%0, %1}"
11896 [(set_attr "type" "bitmanip")
11897 (set_attr "mode" "<MODE>")])
11899 (define_insn "*tbm_blsfill_<mode>"
11900 [(set (match_operand:SWI48 0 "register_operand" "=r")
11903 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11906 (clobber (reg:CC FLAGS_REG))]
11908 "blsfill\t{%1, %0|%0, %1}"
11909 [(set_attr "type" "bitmanip")
11910 (set_attr "mode" "<MODE>")])
11912 (define_insn "*tbm_blsic_<mode>"
11913 [(set (match_operand:SWI48 0 "register_operand" "=r")
11916 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11920 (clobber (reg:CC FLAGS_REG))]
11922 "blsic\t{%1, %0|%0, %1}"
11923 [(set_attr "type" "bitmanip")
11924 (set_attr "mode" "<MODE>")])
11926 (define_insn "*tbm_t1mskc_<mode>"
11927 [(set (match_operand:SWI48 0 "register_operand" "=r")
11930 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11934 (clobber (reg:CC FLAGS_REG))]
11936 "t1mskc\t{%1, %0|%0, %1}"
11937 [(set_attr "type" "bitmanip")
11938 (set_attr "mode" "<MODE>")])
11940 (define_insn "*tbm_tzmsk_<mode>"
11941 [(set (match_operand:SWI48 0 "register_operand" "=r")
11944 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11948 (clobber (reg:CC FLAGS_REG))]
11950 "tzmsk\t{%1, %0|%0, %1}"
11951 [(set_attr "type" "bitmanip")
11952 (set_attr "mode" "<MODE>")])
11954 (define_insn "bsr_rex64"
11955 [(set (match_operand:DI 0 "register_operand" "=r")
11956 (minus:DI (const_int 63)
11957 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
11958 (clobber (reg:CC FLAGS_REG))]
11960 "bsr{q}\t{%1, %0|%0, %1}"
11961 [(set_attr "type" "alu1")
11962 (set_attr "prefix_0f" "1")
11963 (set_attr "mode" "DI")])
11966 [(set (match_operand:SI 0 "register_operand" "=r")
11967 (minus:SI (const_int 31)
11968 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
11969 (clobber (reg:CC FLAGS_REG))]
11971 "bsr{l}\t{%1, %0|%0, %1}"
11972 [(set_attr "type" "alu1")
11973 (set_attr "prefix_0f" "1")
11974 (set_attr "mode" "SI")])
11976 (define_insn "*bsrhi"
11977 [(set (match_operand:HI 0 "register_operand" "=r")
11978 (minus:HI (const_int 15)
11979 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
11980 (clobber (reg:CC FLAGS_REG))]
11982 "bsr{w}\t{%1, %0|%0, %1}"
11983 [(set_attr "type" "alu1")
11984 (set_attr "prefix_0f" "1")
11985 (set_attr "mode" "HI")])
11987 (define_insn "popcount<mode>2"
11988 [(set (match_operand:SWI248 0 "register_operand" "=r")
11990 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11991 (clobber (reg:CC FLAGS_REG))]
11995 return "popcnt\t{%1, %0|%0, %1}";
11997 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12000 [(set_attr "prefix_rep" "1")
12001 (set_attr "type" "bitmanip")
12002 (set_attr "mode" "<MODE>")])
12004 (define_insn "*popcount<mode>2_cmp"
12005 [(set (reg FLAGS_REG)
12008 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12010 (set (match_operand:SWI248 0 "register_operand" "=r")
12011 (popcount:SWI248 (match_dup 1)))]
12012 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12015 return "popcnt\t{%1, %0|%0, %1}";
12017 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12020 [(set_attr "prefix_rep" "1")
12021 (set_attr "type" "bitmanip")
12022 (set_attr "mode" "<MODE>")])
12024 (define_insn "*popcountsi2_cmp_zext"
12025 [(set (reg FLAGS_REG)
12027 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12029 (set (match_operand:DI 0 "register_operand" "=r")
12030 (zero_extend:DI(popcount:SI (match_dup 1))))]
12031 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12034 return "popcnt\t{%1, %0|%0, %1}";
12036 return "popcnt{l}\t{%1, %0|%0, %1}";
12039 [(set_attr "prefix_rep" "1")
12040 (set_attr "type" "bitmanip")
12041 (set_attr "mode" "SI")])
12043 (define_expand "bswapdi2"
12044 [(set (match_operand:DI 0 "register_operand")
12045 (bswap:DI (match_operand:DI 1 "nonimmediate_operand")))]
12049 operands[1] = force_reg (DImode, operands[1]);
12052 (define_expand "bswapsi2"
12053 [(set (match_operand:SI 0 "register_operand")
12054 (bswap:SI (match_operand:SI 1 "nonimmediate_operand")))]
12059 else if (TARGET_BSWAP)
12060 operands[1] = force_reg (SImode, operands[1]);
12063 rtx x = operands[0];
12065 emit_move_insn (x, operands[1]);
12066 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12067 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12068 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12073 (define_insn "*bswap<mode>2_movbe"
12074 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12075 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12077 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12080 movbe\t{%1, %0|%0, %1}
12081 movbe\t{%1, %0|%0, %1}"
12082 [(set_attr "type" "bitmanip,imov,imov")
12083 (set_attr "modrm" "0,1,1")
12084 (set_attr "prefix_0f" "*,1,1")
12085 (set_attr "prefix_extra" "*,1,1")
12086 (set_attr "mode" "<MODE>")])
12088 (define_insn "*bswap<mode>2"
12089 [(set (match_operand:SWI48 0 "register_operand" "=r")
12090 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12093 [(set_attr "type" "bitmanip")
12094 (set_attr "modrm" "0")
12095 (set_attr "mode" "<MODE>")])
12097 (define_insn "*bswaphi_lowpart_1"
12098 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12099 (bswap:HI (match_dup 0)))
12100 (clobber (reg:CC FLAGS_REG))]
12101 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12103 xchg{b}\t{%h0, %b0|%b0, %h0}
12104 rol{w}\t{$8, %0|%0, 8}"
12105 [(set_attr "length" "2,4")
12106 (set_attr "mode" "QI,HI")])
12108 (define_insn "bswaphi_lowpart"
12109 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12110 (bswap:HI (match_dup 0)))
12111 (clobber (reg:CC FLAGS_REG))]
12113 "rol{w}\t{$8, %0|%0, 8}"
12114 [(set_attr "length" "4")
12115 (set_attr "mode" "HI")])
12117 (define_expand "paritydi2"
12118 [(set (match_operand:DI 0 "register_operand")
12119 (parity:DI (match_operand:DI 1 "register_operand")))]
12122 rtx scratch = gen_reg_rtx (QImode);
12125 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12126 NULL_RTX, operands[1]));
12128 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12129 gen_rtx_REG (CCmode, FLAGS_REG),
12131 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12134 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12137 rtx tmp = gen_reg_rtx (SImode);
12139 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12140 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12145 (define_expand "paritysi2"
12146 [(set (match_operand:SI 0 "register_operand")
12147 (parity:SI (match_operand:SI 1 "register_operand")))]
12150 rtx scratch = gen_reg_rtx (QImode);
12153 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12155 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12156 gen_rtx_REG (CCmode, FLAGS_REG),
12158 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12160 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12164 (define_insn_and_split "paritydi2_cmp"
12165 [(set (reg:CC FLAGS_REG)
12166 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12168 (clobber (match_scratch:DI 0 "=r"))
12169 (clobber (match_scratch:SI 1 "=&r"))
12170 (clobber (match_scratch:HI 2 "=Q"))]
12173 "&& reload_completed"
12175 [(set (match_dup 1)
12176 (xor:SI (match_dup 1) (match_dup 4)))
12177 (clobber (reg:CC FLAGS_REG))])
12179 [(set (reg:CC FLAGS_REG)
12180 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12181 (clobber (match_dup 1))
12182 (clobber (match_dup 2))])]
12184 operands[4] = gen_lowpart (SImode, operands[3]);
12188 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12189 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12192 operands[1] = gen_highpart (SImode, operands[3]);
12195 (define_insn_and_split "paritysi2_cmp"
12196 [(set (reg:CC FLAGS_REG)
12197 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12199 (clobber (match_scratch:SI 0 "=r"))
12200 (clobber (match_scratch:HI 1 "=&Q"))]
12203 "&& reload_completed"
12205 [(set (match_dup 1)
12206 (xor:HI (match_dup 1) (match_dup 3)))
12207 (clobber (reg:CC FLAGS_REG))])
12209 [(set (reg:CC FLAGS_REG)
12210 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12211 (clobber (match_dup 1))])]
12213 operands[3] = gen_lowpart (HImode, operands[2]);
12215 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12216 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12219 (define_insn "*parityhi2_cmp"
12220 [(set (reg:CC FLAGS_REG)
12221 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12223 (clobber (match_scratch:HI 0 "=Q"))]
12225 "xor{b}\t{%h0, %b0|%b0, %h0}"
12226 [(set_attr "length" "2")
12227 (set_attr "mode" "HI")])
12230 ;; Thread-local storage patterns for ELF.
12232 ;; Note that these code sequences must appear exactly as shown
12233 ;; in order to allow linker relaxation.
12235 (define_insn "*tls_global_dynamic_32_gnu"
12236 [(set (match_operand:SI 0 "register_operand" "=a")
12238 [(match_operand:SI 1 "register_operand" "b")
12239 (match_operand 2 "tls_symbolic_operand")
12240 (match_operand 3 "constant_call_address_operand" "z")]
12242 (clobber (match_scratch:SI 4 "=d"))
12243 (clobber (match_scratch:SI 5 "=c"))
12244 (clobber (reg:CC FLAGS_REG))]
12245 "!TARGET_64BIT && TARGET_GNU_TLS"
12248 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12249 if (TARGET_SUN_TLS)
12250 #ifdef HAVE_AS_IX86_TLSGDPLT
12251 return "call\t%a2@tlsgdplt";
12253 return "call\t%p3@plt";
12255 return "call\t%P3";
12257 [(set_attr "type" "multi")
12258 (set_attr "length" "12")])
12260 (define_expand "tls_global_dynamic_32"
12262 [(set (match_operand:SI 0 "register_operand")
12263 (unspec:SI [(match_operand:SI 2 "register_operand")
12264 (match_operand 1 "tls_symbolic_operand")
12265 (match_operand 3 "constant_call_address_operand")]
12267 (clobber (match_scratch:SI 4))
12268 (clobber (match_scratch:SI 5))
12269 (clobber (reg:CC FLAGS_REG))])])
12271 (define_insn "*tls_global_dynamic_64_<mode>"
12272 [(set (match_operand:P 0 "register_operand" "=a")
12274 (mem:QI (match_operand 2 "constant_call_address_operand" "z"))
12275 (match_operand 3)))
12276 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12281 fputs (ASM_BYTE "0x66\n", asm_out_file);
12283 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12284 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12285 fputs ("\trex64\n", asm_out_file);
12286 if (TARGET_SUN_TLS)
12287 return "call\t%p2@plt";
12288 return "call\t%P2";
12290 [(set_attr "type" "multi")
12291 (set (attr "length")
12292 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12294 (define_expand "tls_global_dynamic_64_<mode>"
12296 [(set (match_operand:P 0 "register_operand")
12298 (mem:QI (match_operand 2 "constant_call_address_operand"))
12300 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12304 (define_insn "*tls_local_dynamic_base_32_gnu"
12305 [(set (match_operand:SI 0 "register_operand" "=a")
12307 [(match_operand:SI 1 "register_operand" "b")
12308 (match_operand 2 "constant_call_address_operand" "z")]
12309 UNSPEC_TLS_LD_BASE))
12310 (clobber (match_scratch:SI 3 "=d"))
12311 (clobber (match_scratch:SI 4 "=c"))
12312 (clobber (reg:CC FLAGS_REG))]
12313 "!TARGET_64BIT && TARGET_GNU_TLS"
12316 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12317 if (TARGET_SUN_TLS)
12318 #ifdef HAVE_AS_IX86_TLSLDMPLT
12319 return "call\t%&@tlsldmplt";
12321 return "call\t%p2@plt";
12323 return "call\t%P2";
12325 [(set_attr "type" "multi")
12326 (set_attr "length" "11")])
12328 (define_expand "tls_local_dynamic_base_32"
12330 [(set (match_operand:SI 0 "register_operand")
12332 [(match_operand:SI 1 "register_operand")
12333 (match_operand 2 "constant_call_address_operand")]
12334 UNSPEC_TLS_LD_BASE))
12335 (clobber (match_scratch:SI 3))
12336 (clobber (match_scratch:SI 4))
12337 (clobber (reg:CC FLAGS_REG))])])
12339 (define_insn "*tls_local_dynamic_base_64_<mode>"
12340 [(set (match_operand:P 0 "register_operand" "=a")
12342 (mem:QI (match_operand 1 "constant_call_address_operand" "z"))
12343 (match_operand 2)))
12344 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12348 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12349 if (TARGET_SUN_TLS)
12350 return "call\t%p1@plt";
12351 return "call\t%P1";
12353 [(set_attr "type" "multi")
12354 (set_attr "length" "12")])
12356 (define_expand "tls_local_dynamic_base_64_<mode>"
12358 [(set (match_operand:P 0 "register_operand")
12360 (mem:QI (match_operand 1 "constant_call_address_operand"))
12362 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12365 ;; Local dynamic of a single variable is a lose. Show combine how
12366 ;; to convert that back to global dynamic.
12368 (define_insn_and_split "*tls_local_dynamic_32_once"
12369 [(set (match_operand:SI 0 "register_operand" "=a")
12371 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12372 (match_operand 2 "constant_call_address_operand" "z")]
12373 UNSPEC_TLS_LD_BASE)
12374 (const:SI (unspec:SI
12375 [(match_operand 3 "tls_symbolic_operand")]
12377 (clobber (match_scratch:SI 4 "=d"))
12378 (clobber (match_scratch:SI 5 "=c"))
12379 (clobber (reg:CC FLAGS_REG))]
12384 [(set (match_dup 0)
12385 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12387 (clobber (match_dup 4))
12388 (clobber (match_dup 5))
12389 (clobber (reg:CC FLAGS_REG))])])
12391 ;; Segment register for the thread base ptr load
12392 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12394 ;; Load and add the thread base pointer from %<tp_seg>:0.
12395 (define_insn "*load_tp_x32"
12396 [(set (match_operand:SI 0 "register_operand" "=r")
12397 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12399 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12400 [(set_attr "type" "imov")
12401 (set_attr "modrm" "0")
12402 (set_attr "length" "7")
12403 (set_attr "memory" "load")
12404 (set_attr "imm_disp" "false")])
12406 (define_insn "*load_tp_x32_zext"
12407 [(set (match_operand:DI 0 "register_operand" "=r")
12408 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12410 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12411 [(set_attr "type" "imov")
12412 (set_attr "modrm" "0")
12413 (set_attr "length" "7")
12414 (set_attr "memory" "load")
12415 (set_attr "imm_disp" "false")])
12417 (define_insn "*load_tp_<mode>"
12418 [(set (match_operand:P 0 "register_operand" "=r")
12419 (unspec:P [(const_int 0)] UNSPEC_TP))]
12421 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12422 [(set_attr "type" "imov")
12423 (set_attr "modrm" "0")
12424 (set_attr "length" "7")
12425 (set_attr "memory" "load")
12426 (set_attr "imm_disp" "false")])
12428 (define_insn "*add_tp_x32"
12429 [(set (match_operand:SI 0 "register_operand" "=r")
12430 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12431 (match_operand:SI 1 "register_operand" "0")))
12432 (clobber (reg:CC FLAGS_REG))]
12434 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12435 [(set_attr "type" "alu")
12436 (set_attr "modrm" "0")
12437 (set_attr "length" "7")
12438 (set_attr "memory" "load")
12439 (set_attr "imm_disp" "false")])
12441 (define_insn "*add_tp_x32_zext"
12442 [(set (match_operand:DI 0 "register_operand" "=r")
12444 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12445 (match_operand:SI 1 "register_operand" "0"))))
12446 (clobber (reg:CC FLAGS_REG))]
12448 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12449 [(set_attr "type" "alu")
12450 (set_attr "modrm" "0")
12451 (set_attr "length" "7")
12452 (set_attr "memory" "load")
12453 (set_attr "imm_disp" "false")])
12455 (define_insn "*add_tp_<mode>"
12456 [(set (match_operand:P 0 "register_operand" "=r")
12457 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12458 (match_operand:P 1 "register_operand" "0")))
12459 (clobber (reg:CC FLAGS_REG))]
12461 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12462 [(set_attr "type" "alu")
12463 (set_attr "modrm" "0")
12464 (set_attr "length" "7")
12465 (set_attr "memory" "load")
12466 (set_attr "imm_disp" "false")])
12468 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12469 ;; %rax as destination of the initial executable code sequence.
12470 (define_insn "tls_initial_exec_64_sun"
12471 [(set (match_operand:DI 0 "register_operand" "=a")
12473 [(match_operand 1 "tls_symbolic_operand")]
12474 UNSPEC_TLS_IE_SUN))
12475 (clobber (reg:CC FLAGS_REG))]
12476 "TARGET_64BIT && TARGET_SUN_TLS"
12479 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12480 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12482 [(set_attr "type" "multi")])
12484 ;; GNU2 TLS patterns can be split.
12486 (define_expand "tls_dynamic_gnu2_32"
12487 [(set (match_dup 3)
12488 (plus:SI (match_operand:SI 2 "register_operand")
12490 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
12493 [(set (match_operand:SI 0 "register_operand")
12494 (unspec:SI [(match_dup 1) (match_dup 3)
12495 (match_dup 2) (reg:SI SP_REG)]
12497 (clobber (reg:CC FLAGS_REG))])]
12498 "!TARGET_64BIT && TARGET_GNU2_TLS"
12500 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12501 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12504 (define_insn "*tls_dynamic_gnu2_lea_32"
12505 [(set (match_operand:SI 0 "register_operand" "=r")
12506 (plus:SI (match_operand:SI 1 "register_operand" "b")
12508 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
12509 UNSPEC_TLSDESC))))]
12510 "!TARGET_64BIT && TARGET_GNU2_TLS"
12511 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
12512 [(set_attr "type" "lea")
12513 (set_attr "mode" "SI")
12514 (set_attr "length" "6")
12515 (set_attr "length_address" "4")])
12517 (define_insn "*tls_dynamic_gnu2_call_32"
12518 [(set (match_operand:SI 0 "register_operand" "=a")
12519 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
12520 (match_operand:SI 2 "register_operand" "0")
12521 ;; we have to make sure %ebx still points to the GOT
12522 (match_operand:SI 3 "register_operand" "b")
12525 (clobber (reg:CC FLAGS_REG))]
12526 "!TARGET_64BIT && TARGET_GNU2_TLS"
12527 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12528 [(set_attr "type" "call")
12529 (set_attr "length" "2")
12530 (set_attr "length_address" "0")])
12532 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12533 [(set (match_operand:SI 0 "register_operand" "=&a")
12535 (unspec:SI [(match_operand 3 "tls_modbase_operand")
12536 (match_operand:SI 4)
12537 (match_operand:SI 2 "register_operand" "b")
12540 (const:SI (unspec:SI
12541 [(match_operand 1 "tls_symbolic_operand")]
12543 (clobber (reg:CC FLAGS_REG))]
12544 "!TARGET_64BIT && TARGET_GNU2_TLS"
12547 [(set (match_dup 0) (match_dup 5))]
12549 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12550 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12553 (define_expand "tls_dynamic_gnu2_64"
12554 [(set (match_dup 2)
12555 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
12558 [(set (match_operand:DI 0 "register_operand")
12559 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12561 (clobber (reg:CC FLAGS_REG))])]
12562 "TARGET_64BIT && TARGET_GNU2_TLS"
12564 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12565 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12568 (define_insn "*tls_dynamic_gnu2_lea_64"
12569 [(set (match_operand:DI 0 "register_operand" "=r")
12570 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
12572 "TARGET_64BIT && TARGET_GNU2_TLS"
12573 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
12574 [(set_attr "type" "lea")
12575 (set_attr "mode" "DI")
12576 (set_attr "length" "7")
12577 (set_attr "length_address" "4")])
12579 (define_insn "*tls_dynamic_gnu2_call_64"
12580 [(set (match_operand:DI 0 "register_operand" "=a")
12581 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
12582 (match_operand:DI 2 "register_operand" "0")
12585 (clobber (reg:CC FLAGS_REG))]
12586 "TARGET_64BIT && TARGET_GNU2_TLS"
12587 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12588 [(set_attr "type" "call")
12589 (set_attr "length" "2")
12590 (set_attr "length_address" "0")])
12592 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12593 [(set (match_operand:DI 0 "register_operand" "=&a")
12595 (unspec:DI [(match_operand 2 "tls_modbase_operand")
12596 (match_operand:DI 3)
12599 (const:DI (unspec:DI
12600 [(match_operand 1 "tls_symbolic_operand")]
12602 (clobber (reg:CC FLAGS_REG))]
12603 "TARGET_64BIT && TARGET_GNU2_TLS"
12606 [(set (match_dup 0) (match_dup 4))]
12608 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12609 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12612 ;; These patterns match the binary 387 instructions for addM3, subM3,
12613 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12614 ;; SFmode. The first is the normal insn, the second the same insn but
12615 ;; with one operand a conversion, and the third the same insn but with
12616 ;; the other operand a conversion. The conversion may be SFmode or
12617 ;; SImode if the target mode DFmode, but only SImode if the target mode
12620 ;; Gcc is slightly more smart about handling normal two address instructions
12621 ;; so use special patterns for add and mull.
12623 (define_insn "*fop_<mode>_comm_mixed"
12624 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12625 (match_operator:MODEF 3 "binary_fp_operator"
12626 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12627 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12628 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12629 && COMMUTATIVE_ARITH_P (operands[3])
12630 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12631 "* return output_387_binary_op (insn, operands);"
12632 [(set (attr "type")
12633 (if_then_else (eq_attr "alternative" "1,2")
12634 (if_then_else (match_operand:MODEF 3 "mult_operator")
12635 (const_string "ssemul")
12636 (const_string "sseadd"))
12637 (if_then_else (match_operand:MODEF 3 "mult_operator")
12638 (const_string "fmul")
12639 (const_string "fop"))))
12640 (set_attr "isa" "*,noavx,avx")
12641 (set_attr "prefix" "orig,orig,vex")
12642 (set_attr "mode" "<MODE>")])
12644 (define_insn "*fop_<mode>_comm_sse"
12645 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12646 (match_operator:MODEF 3 "binary_fp_operator"
12647 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12648 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12649 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12650 && COMMUTATIVE_ARITH_P (operands[3])
12651 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12652 "* return output_387_binary_op (insn, operands);"
12653 [(set (attr "type")
12654 (if_then_else (match_operand:MODEF 3 "mult_operator")
12655 (const_string "ssemul")
12656 (const_string "sseadd")))
12657 (set_attr "isa" "noavx,avx")
12658 (set_attr "prefix" "orig,vex")
12659 (set_attr "mode" "<MODE>")])
12661 (define_insn "*fop_<mode>_comm_i387"
12662 [(set (match_operand:MODEF 0 "register_operand" "=f")
12663 (match_operator:MODEF 3 "binary_fp_operator"
12664 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12665 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12666 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12667 && COMMUTATIVE_ARITH_P (operands[3])
12668 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12669 "* return output_387_binary_op (insn, operands);"
12670 [(set (attr "type")
12671 (if_then_else (match_operand:MODEF 3 "mult_operator")
12672 (const_string "fmul")
12673 (const_string "fop")))
12674 (set_attr "mode" "<MODE>")])
12676 (define_insn "*fop_<mode>_1_mixed"
12677 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
12678 (match_operator:MODEF 3 "binary_fp_operator"
12679 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
12680 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
12681 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12682 && !COMMUTATIVE_ARITH_P (operands[3])
12683 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12684 "* return output_387_binary_op (insn, operands);"
12685 [(set (attr "type")
12686 (cond [(and (eq_attr "alternative" "2,3")
12687 (match_operand:MODEF 3 "mult_operator"))
12688 (const_string "ssemul")
12689 (and (eq_attr "alternative" "2,3")
12690 (match_operand:MODEF 3 "div_operator"))
12691 (const_string "ssediv")
12692 (eq_attr "alternative" "2,3")
12693 (const_string "sseadd")
12694 (match_operand:MODEF 3 "mult_operator")
12695 (const_string "fmul")
12696 (match_operand:MODEF 3 "div_operator")
12697 (const_string "fdiv")
12699 (const_string "fop")))
12700 (set_attr "isa" "*,*,noavx,avx")
12701 (set_attr "prefix" "orig,orig,orig,vex")
12702 (set_attr "mode" "<MODE>")])
12704 (define_insn "*rcpsf2_sse"
12705 [(set (match_operand:SF 0 "register_operand" "=x")
12706 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12709 "%vrcpss\t{%1, %d0|%d0, %1}"
12710 [(set_attr "type" "sse")
12711 (set_attr "atom_sse_attr" "rcp")
12712 (set_attr "btver2_sse_attr" "rcp")
12713 (set_attr "prefix" "maybe_vex")
12714 (set_attr "mode" "SF")])
12716 (define_insn "*fop_<mode>_1_sse"
12717 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12718 (match_operator:MODEF 3 "binary_fp_operator"
12719 [(match_operand:MODEF 1 "register_operand" "0,x")
12720 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12721 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12722 && !COMMUTATIVE_ARITH_P (operands[3])"
12723 "* return output_387_binary_op (insn, operands);"
12724 [(set (attr "type")
12725 (cond [(match_operand:MODEF 3 "mult_operator")
12726 (const_string "ssemul")
12727 (match_operand:MODEF 3 "div_operator")
12728 (const_string "ssediv")
12730 (const_string "sseadd")))
12731 (set_attr "isa" "noavx,avx")
12732 (set_attr "prefix" "orig,vex")
12733 (set_attr "mode" "<MODE>")])
12735 ;; This pattern is not fully shadowed by the pattern above.
12736 (define_insn "*fop_<mode>_1_i387"
12737 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12738 (match_operator:MODEF 3 "binary_fp_operator"
12739 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
12740 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
12741 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12742 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
12743 && !COMMUTATIVE_ARITH_P (operands[3])
12744 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12745 "* return output_387_binary_op (insn, operands);"
12746 [(set (attr "type")
12747 (cond [(match_operand:MODEF 3 "mult_operator")
12748 (const_string "fmul")
12749 (match_operand:MODEF 3 "div_operator")
12750 (const_string "fdiv")
12752 (const_string "fop")))
12753 (set_attr "mode" "<MODE>")])
12755 ;; ??? Add SSE splitters for these!
12756 (define_insn "*fop_<MODEF:mode>_2_i387"
12757 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12758 (match_operator:MODEF 3 "binary_fp_operator"
12760 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
12761 (match_operand:MODEF 2 "register_operand" "0,0")]))]
12762 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
12763 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12764 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12765 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12766 [(set (attr "type")
12767 (cond [(match_operand:MODEF 3 "mult_operator")
12768 (const_string "fmul")
12769 (match_operand:MODEF 3 "div_operator")
12770 (const_string "fdiv")
12772 (const_string "fop")))
12773 (set_attr "fp_int_src" "true")
12774 (set_attr "mode" "<SWI24:MODE>")])
12776 (define_insn "*fop_<MODEF:mode>_3_i387"
12777 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
12778 (match_operator:MODEF 3 "binary_fp_operator"
12779 [(match_operand:MODEF 1 "register_operand" "0,0")
12781 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
12782 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
12783 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
12784 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12785 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12786 [(set (attr "type")
12787 (cond [(match_operand:MODEF 3 "mult_operator")
12788 (const_string "fmul")
12789 (match_operand:MODEF 3 "div_operator")
12790 (const_string "fdiv")
12792 (const_string "fop")))
12793 (set_attr "fp_int_src" "true")
12794 (set_attr "mode" "<MODE>")])
12796 (define_insn "*fop_df_4_i387"
12797 [(set (match_operand:DF 0 "register_operand" "=f,f")
12798 (match_operator:DF 3 "binary_fp_operator"
12800 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
12801 (match_operand:DF 2 "register_operand" "0,f")]))]
12802 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12803 && !(TARGET_SSE2 && TARGET_SSE_MATH)
12804 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12805 "* return output_387_binary_op (insn, operands);"
12806 [(set (attr "type")
12807 (cond [(match_operand:DF 3 "mult_operator")
12808 (const_string "fmul")
12809 (match_operand:DF 3 "div_operator")
12810 (const_string "fdiv")
12812 (const_string "fop")))
12813 (set_attr "mode" "SF")])
12815 (define_insn "*fop_df_5_i387"
12816 [(set (match_operand:DF 0 "register_operand" "=f,f")
12817 (match_operator:DF 3 "binary_fp_operator"
12818 [(match_operand:DF 1 "register_operand" "0,f")
12820 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12821 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12822 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12823 "* return output_387_binary_op (insn, operands);"
12824 [(set (attr "type")
12825 (cond [(match_operand:DF 3 "mult_operator")
12826 (const_string "fmul")
12827 (match_operand:DF 3 "div_operator")
12828 (const_string "fdiv")
12830 (const_string "fop")))
12831 (set_attr "mode" "SF")])
12833 (define_insn "*fop_df_6_i387"
12834 [(set (match_operand:DF 0 "register_operand" "=f,f")
12835 (match_operator:DF 3 "binary_fp_operator"
12837 (match_operand:SF 1 "register_operand" "0,f"))
12839 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
12840 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
12841 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
12842 "* return output_387_binary_op (insn, operands);"
12843 [(set (attr "type")
12844 (cond [(match_operand:DF 3 "mult_operator")
12845 (const_string "fmul")
12846 (match_operand:DF 3 "div_operator")
12847 (const_string "fdiv")
12849 (const_string "fop")))
12850 (set_attr "mode" "SF")])
12852 (define_insn "*fop_xf_comm_i387"
12853 [(set (match_operand:XF 0 "register_operand" "=f")
12854 (match_operator:XF 3 "binary_fp_operator"
12855 [(match_operand:XF 1 "register_operand" "%0")
12856 (match_operand:XF 2 "register_operand" "f")]))]
12858 && COMMUTATIVE_ARITH_P (operands[3])"
12859 "* return output_387_binary_op (insn, operands);"
12860 [(set (attr "type")
12861 (if_then_else (match_operand:XF 3 "mult_operator")
12862 (const_string "fmul")
12863 (const_string "fop")))
12864 (set_attr "mode" "XF")])
12866 (define_insn "*fop_xf_1_i387"
12867 [(set (match_operand:XF 0 "register_operand" "=f,f")
12868 (match_operator:XF 3 "binary_fp_operator"
12869 [(match_operand:XF 1 "register_operand" "0,f")
12870 (match_operand:XF 2 "register_operand" "f,0")]))]
12872 && !COMMUTATIVE_ARITH_P (operands[3])"
12873 "* return output_387_binary_op (insn, operands);"
12874 [(set (attr "type")
12875 (cond [(match_operand:XF 3 "mult_operator")
12876 (const_string "fmul")
12877 (match_operand:XF 3 "div_operator")
12878 (const_string "fdiv")
12880 (const_string "fop")))
12881 (set_attr "mode" "XF")])
12883 (define_insn "*fop_xf_2_i387"
12884 [(set (match_operand:XF 0 "register_operand" "=f,f")
12885 (match_operator:XF 3 "binary_fp_operator"
12887 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
12888 (match_operand:XF 2 "register_operand" "0,0")]))]
12889 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12890 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12891 [(set (attr "type")
12892 (cond [(match_operand:XF 3 "mult_operator")
12893 (const_string "fmul")
12894 (match_operand:XF 3 "div_operator")
12895 (const_string "fdiv")
12897 (const_string "fop")))
12898 (set_attr "fp_int_src" "true")
12899 (set_attr "mode" "<MODE>")])
12901 (define_insn "*fop_xf_3_i387"
12902 [(set (match_operand:XF 0 "register_operand" "=f,f")
12903 (match_operator:XF 3 "binary_fp_operator"
12904 [(match_operand:XF 1 "register_operand" "0,0")
12906 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
12907 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
12908 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
12909 [(set (attr "type")
12910 (cond [(match_operand:XF 3 "mult_operator")
12911 (const_string "fmul")
12912 (match_operand:XF 3 "div_operator")
12913 (const_string "fdiv")
12915 (const_string "fop")))
12916 (set_attr "fp_int_src" "true")
12917 (set_attr "mode" "<MODE>")])
12919 (define_insn "*fop_xf_4_i387"
12920 [(set (match_operand:XF 0 "register_operand" "=f,f")
12921 (match_operator:XF 3 "binary_fp_operator"
12923 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
12924 (match_operand:XF 2 "register_operand" "0,f")]))]
12926 "* return output_387_binary_op (insn, operands);"
12927 [(set (attr "type")
12928 (cond [(match_operand:XF 3 "mult_operator")
12929 (const_string "fmul")
12930 (match_operand:XF 3 "div_operator")
12931 (const_string "fdiv")
12933 (const_string "fop")))
12934 (set_attr "mode" "<MODE>")])
12936 (define_insn "*fop_xf_5_i387"
12937 [(set (match_operand:XF 0 "register_operand" "=f,f")
12938 (match_operator:XF 3 "binary_fp_operator"
12939 [(match_operand:XF 1 "register_operand" "0,f")
12941 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12943 "* return output_387_binary_op (insn, operands);"
12944 [(set (attr "type")
12945 (cond [(match_operand:XF 3 "mult_operator")
12946 (const_string "fmul")
12947 (match_operand:XF 3 "div_operator")
12948 (const_string "fdiv")
12950 (const_string "fop")))
12951 (set_attr "mode" "<MODE>")])
12953 (define_insn "*fop_xf_6_i387"
12954 [(set (match_operand:XF 0 "register_operand" "=f,f")
12955 (match_operator:XF 3 "binary_fp_operator"
12957 (match_operand:MODEF 1 "register_operand" "0,f"))
12959 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
12961 "* return output_387_binary_op (insn, operands);"
12962 [(set (attr "type")
12963 (cond [(match_operand:XF 3 "mult_operator")
12964 (const_string "fmul")
12965 (match_operand:XF 3 "div_operator")
12966 (const_string "fdiv")
12968 (const_string "fop")))
12969 (set_attr "mode" "<MODE>")])
12972 [(set (match_operand 0 "register_operand")
12973 (match_operator 3 "binary_fp_operator"
12974 [(float (match_operand:SWI24 1 "register_operand"))
12975 (match_operand 2 "register_operand")]))]
12977 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12978 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
12981 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
12982 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
12983 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
12984 gen_rtx_fmt_ee (GET_CODE (operands[3]),
12985 GET_MODE (operands[3]),
12988 ix86_free_from_memory (GET_MODE (operands[1]));
12993 [(set (match_operand 0 "register_operand")
12994 (match_operator 3 "binary_fp_operator"
12995 [(match_operand 1 "register_operand")
12996 (float (match_operand:SWI24 2 "register_operand"))]))]
12998 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
12999 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13002 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13003 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13004 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13005 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13006 GET_MODE (operands[3]),
13009 ix86_free_from_memory (GET_MODE (operands[2]));
13013 ;; FPU special functions.
13015 ;; This pattern implements a no-op XFmode truncation for
13016 ;; all fancy i386 XFmode math functions.
13018 (define_insn "truncxf<mode>2_i387_noop_unspec"
13019 [(set (match_operand:MODEF 0 "register_operand" "=f")
13020 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13021 UNSPEC_TRUNC_NOOP))]
13022 "TARGET_USE_FANCY_MATH_387"
13023 "* return output_387_reg_move (insn, operands);"
13024 [(set_attr "type" "fmov")
13025 (set_attr "mode" "<MODE>")])
13027 (define_insn "sqrtxf2"
13028 [(set (match_operand:XF 0 "register_operand" "=f")
13029 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13030 "TARGET_USE_FANCY_MATH_387"
13032 [(set_attr "type" "fpspc")
13033 (set_attr "mode" "XF")
13034 (set_attr "athlon_decode" "direct")
13035 (set_attr "amdfam10_decode" "direct")
13036 (set_attr "bdver1_decode" "direct")])
13038 (define_insn "sqrt_extend<mode>xf2_i387"
13039 [(set (match_operand:XF 0 "register_operand" "=f")
13042 (match_operand:MODEF 1 "register_operand" "0"))))]
13043 "TARGET_USE_FANCY_MATH_387"
13045 [(set_attr "type" "fpspc")
13046 (set_attr "mode" "XF")
13047 (set_attr "athlon_decode" "direct")
13048 (set_attr "amdfam10_decode" "direct")
13049 (set_attr "bdver1_decode" "direct")])
13051 (define_insn "*rsqrtsf2_sse"
13052 [(set (match_operand:SF 0 "register_operand" "=x")
13053 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13056 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13057 [(set_attr "type" "sse")
13058 (set_attr "atom_sse_attr" "rcp")
13059 (set_attr "btver2_sse_attr" "rcp")
13060 (set_attr "prefix" "maybe_vex")
13061 (set_attr "mode" "SF")])
13063 (define_expand "rsqrtsf2"
13064 [(set (match_operand:SF 0 "register_operand")
13065 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
13069 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13073 (define_insn "*sqrt<mode>2_sse"
13074 [(set (match_operand:MODEF 0 "register_operand" "=x")
13076 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13077 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13078 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13079 [(set_attr "type" "sse")
13080 (set_attr "atom_sse_attr" "sqrt")
13081 (set_attr "btver2_sse_attr" "sqrt")
13082 (set_attr "prefix" "maybe_vex")
13083 (set_attr "mode" "<MODE>")
13084 (set_attr "athlon_decode" "*")
13085 (set_attr "amdfam10_decode" "*")
13086 (set_attr "bdver1_decode" "*")])
13088 (define_expand "sqrt<mode>2"
13089 [(set (match_operand:MODEF 0 "register_operand")
13091 (match_operand:MODEF 1 "nonimmediate_operand")))]
13092 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13093 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13095 if (<MODE>mode == SFmode
13097 && TARGET_RECIP_SQRT
13098 && !optimize_function_for_size_p (cfun)
13099 && flag_finite_math_only && !flag_trapping_math
13100 && flag_unsafe_math_optimizations)
13102 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13106 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13108 rtx op0 = gen_reg_rtx (XFmode);
13109 rtx op1 = force_reg (<MODE>mode, operands[1]);
13111 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13112 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13117 (define_insn "fpremxf4_i387"
13118 [(set (match_operand:XF 0 "register_operand" "=f")
13119 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13120 (match_operand:XF 3 "register_operand" "1")]
13122 (set (match_operand:XF 1 "register_operand" "=u")
13123 (unspec:XF [(match_dup 2) (match_dup 3)]
13125 (set (reg:CCFP FPSR_REG)
13126 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13128 "TARGET_USE_FANCY_MATH_387"
13130 [(set_attr "type" "fpspc")
13131 (set_attr "mode" "XF")])
13133 (define_expand "fmodxf3"
13134 [(use (match_operand:XF 0 "register_operand"))
13135 (use (match_operand:XF 1 "general_operand"))
13136 (use (match_operand:XF 2 "general_operand"))]
13137 "TARGET_USE_FANCY_MATH_387"
13139 rtx label = gen_label_rtx ();
13141 rtx op1 = gen_reg_rtx (XFmode);
13142 rtx op2 = gen_reg_rtx (XFmode);
13144 emit_move_insn (op2, operands[2]);
13145 emit_move_insn (op1, operands[1]);
13147 emit_label (label);
13148 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13149 ix86_emit_fp_unordered_jump (label);
13150 LABEL_NUSES (label) = 1;
13152 emit_move_insn (operands[0], op1);
13156 (define_expand "fmod<mode>3"
13157 [(use (match_operand:MODEF 0 "register_operand"))
13158 (use (match_operand:MODEF 1 "general_operand"))
13159 (use (match_operand:MODEF 2 "general_operand"))]
13160 "TARGET_USE_FANCY_MATH_387"
13162 rtx (*gen_truncxf) (rtx, rtx);
13164 rtx label = gen_label_rtx ();
13166 rtx op1 = gen_reg_rtx (XFmode);
13167 rtx op2 = gen_reg_rtx (XFmode);
13169 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13170 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13172 emit_label (label);
13173 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13174 ix86_emit_fp_unordered_jump (label);
13175 LABEL_NUSES (label) = 1;
13177 /* Truncate the result properly for strict SSE math. */
13178 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13179 && !TARGET_MIX_SSE_I387)
13180 gen_truncxf = gen_truncxf<mode>2;
13182 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13184 emit_insn (gen_truncxf (operands[0], op1));
13188 (define_insn "fprem1xf4_i387"
13189 [(set (match_operand:XF 0 "register_operand" "=f")
13190 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13191 (match_operand:XF 3 "register_operand" "1")]
13193 (set (match_operand:XF 1 "register_operand" "=u")
13194 (unspec:XF [(match_dup 2) (match_dup 3)]
13196 (set (reg:CCFP FPSR_REG)
13197 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13199 "TARGET_USE_FANCY_MATH_387"
13201 [(set_attr "type" "fpspc")
13202 (set_attr "mode" "XF")])
13204 (define_expand "remainderxf3"
13205 [(use (match_operand:XF 0 "register_operand"))
13206 (use (match_operand:XF 1 "general_operand"))
13207 (use (match_operand:XF 2 "general_operand"))]
13208 "TARGET_USE_FANCY_MATH_387"
13210 rtx label = gen_label_rtx ();
13212 rtx op1 = gen_reg_rtx (XFmode);
13213 rtx op2 = gen_reg_rtx (XFmode);
13215 emit_move_insn (op2, operands[2]);
13216 emit_move_insn (op1, operands[1]);
13218 emit_label (label);
13219 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13220 ix86_emit_fp_unordered_jump (label);
13221 LABEL_NUSES (label) = 1;
13223 emit_move_insn (operands[0], op1);
13227 (define_expand "remainder<mode>3"
13228 [(use (match_operand:MODEF 0 "register_operand"))
13229 (use (match_operand:MODEF 1 "general_operand"))
13230 (use (match_operand:MODEF 2 "general_operand"))]
13231 "TARGET_USE_FANCY_MATH_387"
13233 rtx (*gen_truncxf) (rtx, rtx);
13235 rtx label = gen_label_rtx ();
13237 rtx op1 = gen_reg_rtx (XFmode);
13238 rtx op2 = gen_reg_rtx (XFmode);
13240 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13241 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13243 emit_label (label);
13245 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13246 ix86_emit_fp_unordered_jump (label);
13247 LABEL_NUSES (label) = 1;
13249 /* Truncate the result properly for strict SSE math. */
13250 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13251 && !TARGET_MIX_SSE_I387)
13252 gen_truncxf = gen_truncxf<mode>2;
13254 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13256 emit_insn (gen_truncxf (operands[0], op1));
13260 (define_int_iterator SINCOS
13264 (define_int_attr sincos
13265 [(UNSPEC_SIN "sin")
13266 (UNSPEC_COS "cos")])
13268 (define_insn "*<sincos>xf2_i387"
13269 [(set (match_operand:XF 0 "register_operand" "=f")
13270 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13272 "TARGET_USE_FANCY_MATH_387
13273 && flag_unsafe_math_optimizations"
13275 [(set_attr "type" "fpspc")
13276 (set_attr "mode" "XF")])
13278 (define_insn "*<sincos>_extend<mode>xf2_i387"
13279 [(set (match_operand:XF 0 "register_operand" "=f")
13280 (unspec:XF [(float_extend:XF
13281 (match_operand:MODEF 1 "register_operand" "0"))]
13283 "TARGET_USE_FANCY_MATH_387
13284 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13285 || TARGET_MIX_SSE_I387)
13286 && flag_unsafe_math_optimizations"
13288 [(set_attr "type" "fpspc")
13289 (set_attr "mode" "XF")])
13291 ;; When sincos pattern is defined, sin and cos builtin functions will be
13292 ;; expanded to sincos pattern with one of its outputs left unused.
13293 ;; CSE pass will figure out if two sincos patterns can be combined,
13294 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13295 ;; depending on the unused output.
13297 (define_insn "sincosxf3"
13298 [(set (match_operand:XF 0 "register_operand" "=f")
13299 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13300 UNSPEC_SINCOS_COS))
13301 (set (match_operand:XF 1 "register_operand" "=u")
13302 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13303 "TARGET_USE_FANCY_MATH_387
13304 && flag_unsafe_math_optimizations"
13306 [(set_attr "type" "fpspc")
13307 (set_attr "mode" "XF")])
13310 [(set (match_operand:XF 0 "register_operand")
13311 (unspec:XF [(match_operand:XF 2 "register_operand")]
13312 UNSPEC_SINCOS_COS))
13313 (set (match_operand:XF 1 "register_operand")
13314 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13315 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13316 && can_create_pseudo_p ()"
13317 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13320 [(set (match_operand:XF 0 "register_operand")
13321 (unspec:XF [(match_operand:XF 2 "register_operand")]
13322 UNSPEC_SINCOS_COS))
13323 (set (match_operand:XF 1 "register_operand")
13324 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13325 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13326 && can_create_pseudo_p ()"
13327 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13329 (define_insn "sincos_extend<mode>xf3_i387"
13330 [(set (match_operand:XF 0 "register_operand" "=f")
13331 (unspec:XF [(float_extend:XF
13332 (match_operand:MODEF 2 "register_operand" "0"))]
13333 UNSPEC_SINCOS_COS))
13334 (set (match_operand:XF 1 "register_operand" "=u")
13335 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13336 "TARGET_USE_FANCY_MATH_387
13337 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13338 || TARGET_MIX_SSE_I387)
13339 && flag_unsafe_math_optimizations"
13341 [(set_attr "type" "fpspc")
13342 (set_attr "mode" "XF")])
13345 [(set (match_operand:XF 0 "register_operand")
13346 (unspec:XF [(float_extend:XF
13347 (match_operand:MODEF 2 "register_operand"))]
13348 UNSPEC_SINCOS_COS))
13349 (set (match_operand:XF 1 "register_operand")
13350 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13351 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13352 && can_create_pseudo_p ()"
13353 [(set (match_dup 1)
13354 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13357 [(set (match_operand:XF 0 "register_operand")
13358 (unspec:XF [(float_extend:XF
13359 (match_operand:MODEF 2 "register_operand"))]
13360 UNSPEC_SINCOS_COS))
13361 (set (match_operand:XF 1 "register_operand")
13362 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13363 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13364 && can_create_pseudo_p ()"
13365 [(set (match_dup 0)
13366 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13368 (define_expand "sincos<mode>3"
13369 [(use (match_operand:MODEF 0 "register_operand"))
13370 (use (match_operand:MODEF 1 "register_operand"))
13371 (use (match_operand:MODEF 2 "register_operand"))]
13372 "TARGET_USE_FANCY_MATH_387
13373 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13374 || TARGET_MIX_SSE_I387)
13375 && flag_unsafe_math_optimizations"
13377 rtx op0 = gen_reg_rtx (XFmode);
13378 rtx op1 = gen_reg_rtx (XFmode);
13380 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13381 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13382 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13386 (define_insn "fptanxf4_i387"
13387 [(set (match_operand:XF 0 "register_operand" "=f")
13388 (match_operand:XF 3 "const_double_operand" "F"))
13389 (set (match_operand:XF 1 "register_operand" "=u")
13390 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13392 "TARGET_USE_FANCY_MATH_387
13393 && flag_unsafe_math_optimizations
13394 && standard_80387_constant_p (operands[3]) == 2"
13396 [(set_attr "type" "fpspc")
13397 (set_attr "mode" "XF")])
13399 (define_insn "fptan_extend<mode>xf4_i387"
13400 [(set (match_operand:MODEF 0 "register_operand" "=f")
13401 (match_operand:MODEF 3 "const_double_operand" "F"))
13402 (set (match_operand:XF 1 "register_operand" "=u")
13403 (unspec:XF [(float_extend:XF
13404 (match_operand:MODEF 2 "register_operand" "0"))]
13406 "TARGET_USE_FANCY_MATH_387
13407 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13408 || TARGET_MIX_SSE_I387)
13409 && flag_unsafe_math_optimizations
13410 && standard_80387_constant_p (operands[3]) == 2"
13412 [(set_attr "type" "fpspc")
13413 (set_attr "mode" "XF")])
13415 (define_expand "tanxf2"
13416 [(use (match_operand:XF 0 "register_operand"))
13417 (use (match_operand:XF 1 "register_operand"))]
13418 "TARGET_USE_FANCY_MATH_387
13419 && flag_unsafe_math_optimizations"
13421 rtx one = gen_reg_rtx (XFmode);
13422 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13424 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13428 (define_expand "tan<mode>2"
13429 [(use (match_operand:MODEF 0 "register_operand"))
13430 (use (match_operand:MODEF 1 "register_operand"))]
13431 "TARGET_USE_FANCY_MATH_387
13432 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13433 || TARGET_MIX_SSE_I387)
13434 && flag_unsafe_math_optimizations"
13436 rtx op0 = gen_reg_rtx (XFmode);
13438 rtx one = gen_reg_rtx (<MODE>mode);
13439 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13441 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13442 operands[1], op2));
13443 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13447 (define_insn "*fpatanxf3_i387"
13448 [(set (match_operand:XF 0 "register_operand" "=f")
13449 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13450 (match_operand:XF 2 "register_operand" "u")]
13452 (clobber (match_scratch:XF 3 "=2"))]
13453 "TARGET_USE_FANCY_MATH_387
13454 && flag_unsafe_math_optimizations"
13456 [(set_attr "type" "fpspc")
13457 (set_attr "mode" "XF")])
13459 (define_insn "fpatan_extend<mode>xf3_i387"
13460 [(set (match_operand:XF 0 "register_operand" "=f")
13461 (unspec:XF [(float_extend:XF
13462 (match_operand:MODEF 1 "register_operand" "0"))
13464 (match_operand:MODEF 2 "register_operand" "u"))]
13466 (clobber (match_scratch:XF 3 "=2"))]
13467 "TARGET_USE_FANCY_MATH_387
13468 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13469 || TARGET_MIX_SSE_I387)
13470 && flag_unsafe_math_optimizations"
13472 [(set_attr "type" "fpspc")
13473 (set_attr "mode" "XF")])
13475 (define_expand "atan2xf3"
13476 [(parallel [(set (match_operand:XF 0 "register_operand")
13477 (unspec:XF [(match_operand:XF 2 "register_operand")
13478 (match_operand:XF 1 "register_operand")]
13480 (clobber (match_scratch:XF 3))])]
13481 "TARGET_USE_FANCY_MATH_387
13482 && flag_unsafe_math_optimizations")
13484 (define_expand "atan2<mode>3"
13485 [(use (match_operand:MODEF 0 "register_operand"))
13486 (use (match_operand:MODEF 1 "register_operand"))
13487 (use (match_operand:MODEF 2 "register_operand"))]
13488 "TARGET_USE_FANCY_MATH_387
13489 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13490 || TARGET_MIX_SSE_I387)
13491 && flag_unsafe_math_optimizations"
13493 rtx op0 = gen_reg_rtx (XFmode);
13495 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13496 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13500 (define_expand "atanxf2"
13501 [(parallel [(set (match_operand:XF 0 "register_operand")
13502 (unspec:XF [(match_dup 2)
13503 (match_operand:XF 1 "register_operand")]
13505 (clobber (match_scratch:XF 3))])]
13506 "TARGET_USE_FANCY_MATH_387
13507 && flag_unsafe_math_optimizations"
13509 operands[2] = gen_reg_rtx (XFmode);
13510 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13513 (define_expand "atan<mode>2"
13514 [(use (match_operand:MODEF 0 "register_operand"))
13515 (use (match_operand:MODEF 1 "register_operand"))]
13516 "TARGET_USE_FANCY_MATH_387
13517 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13518 || TARGET_MIX_SSE_I387)
13519 && flag_unsafe_math_optimizations"
13521 rtx op0 = gen_reg_rtx (XFmode);
13523 rtx op2 = gen_reg_rtx (<MODE>mode);
13524 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13526 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13527 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13531 (define_expand "asinxf2"
13532 [(set (match_dup 2)
13533 (mult:XF (match_operand:XF 1 "register_operand")
13535 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13536 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13537 (parallel [(set (match_operand:XF 0 "register_operand")
13538 (unspec:XF [(match_dup 5) (match_dup 1)]
13540 (clobber (match_scratch:XF 6))])]
13541 "TARGET_USE_FANCY_MATH_387
13542 && flag_unsafe_math_optimizations"
13546 if (optimize_insn_for_size_p ())
13549 for (i = 2; i < 6; i++)
13550 operands[i] = gen_reg_rtx (XFmode);
13552 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13555 (define_expand "asin<mode>2"
13556 [(use (match_operand:MODEF 0 "register_operand"))
13557 (use (match_operand:MODEF 1 "general_operand"))]
13558 "TARGET_USE_FANCY_MATH_387
13559 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13560 || TARGET_MIX_SSE_I387)
13561 && flag_unsafe_math_optimizations"
13563 rtx op0 = gen_reg_rtx (XFmode);
13564 rtx op1 = gen_reg_rtx (XFmode);
13566 if (optimize_insn_for_size_p ())
13569 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13570 emit_insn (gen_asinxf2 (op0, op1));
13571 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13575 (define_expand "acosxf2"
13576 [(set (match_dup 2)
13577 (mult:XF (match_operand:XF 1 "register_operand")
13579 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13580 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13581 (parallel [(set (match_operand:XF 0 "register_operand")
13582 (unspec:XF [(match_dup 1) (match_dup 5)]
13584 (clobber (match_scratch:XF 6))])]
13585 "TARGET_USE_FANCY_MATH_387
13586 && flag_unsafe_math_optimizations"
13590 if (optimize_insn_for_size_p ())
13593 for (i = 2; i < 6; i++)
13594 operands[i] = gen_reg_rtx (XFmode);
13596 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13599 (define_expand "acos<mode>2"
13600 [(use (match_operand:MODEF 0 "register_operand"))
13601 (use (match_operand:MODEF 1 "general_operand"))]
13602 "TARGET_USE_FANCY_MATH_387
13603 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13604 || TARGET_MIX_SSE_I387)
13605 && flag_unsafe_math_optimizations"
13607 rtx op0 = gen_reg_rtx (XFmode);
13608 rtx op1 = gen_reg_rtx (XFmode);
13610 if (optimize_insn_for_size_p ())
13613 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13614 emit_insn (gen_acosxf2 (op0, op1));
13615 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13619 (define_insn "fyl2xxf3_i387"
13620 [(set (match_operand:XF 0 "register_operand" "=f")
13621 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13622 (match_operand:XF 2 "register_operand" "u")]
13624 (clobber (match_scratch:XF 3 "=2"))]
13625 "TARGET_USE_FANCY_MATH_387
13626 && flag_unsafe_math_optimizations"
13628 [(set_attr "type" "fpspc")
13629 (set_attr "mode" "XF")])
13631 (define_insn "fyl2x_extend<mode>xf3_i387"
13632 [(set (match_operand:XF 0 "register_operand" "=f")
13633 (unspec:XF [(float_extend:XF
13634 (match_operand:MODEF 1 "register_operand" "0"))
13635 (match_operand:XF 2 "register_operand" "u")]
13637 (clobber (match_scratch:XF 3 "=2"))]
13638 "TARGET_USE_FANCY_MATH_387
13639 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13640 || TARGET_MIX_SSE_I387)
13641 && flag_unsafe_math_optimizations"
13643 [(set_attr "type" "fpspc")
13644 (set_attr "mode" "XF")])
13646 (define_expand "logxf2"
13647 [(parallel [(set (match_operand:XF 0 "register_operand")
13648 (unspec:XF [(match_operand:XF 1 "register_operand")
13649 (match_dup 2)] UNSPEC_FYL2X))
13650 (clobber (match_scratch:XF 3))])]
13651 "TARGET_USE_FANCY_MATH_387
13652 && flag_unsafe_math_optimizations"
13654 operands[2] = gen_reg_rtx (XFmode);
13655 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13658 (define_expand "log<mode>2"
13659 [(use (match_operand:MODEF 0 "register_operand"))
13660 (use (match_operand:MODEF 1 "register_operand"))]
13661 "TARGET_USE_FANCY_MATH_387
13662 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13663 || TARGET_MIX_SSE_I387)
13664 && flag_unsafe_math_optimizations"
13666 rtx op0 = gen_reg_rtx (XFmode);
13668 rtx op2 = gen_reg_rtx (XFmode);
13669 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13671 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13672 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13676 (define_expand "log10xf2"
13677 [(parallel [(set (match_operand:XF 0 "register_operand")
13678 (unspec:XF [(match_operand:XF 1 "register_operand")
13679 (match_dup 2)] UNSPEC_FYL2X))
13680 (clobber (match_scratch:XF 3))])]
13681 "TARGET_USE_FANCY_MATH_387
13682 && flag_unsafe_math_optimizations"
13684 operands[2] = gen_reg_rtx (XFmode);
13685 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13688 (define_expand "log10<mode>2"
13689 [(use (match_operand:MODEF 0 "register_operand"))
13690 (use (match_operand:MODEF 1 "register_operand"))]
13691 "TARGET_USE_FANCY_MATH_387
13692 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13693 || TARGET_MIX_SSE_I387)
13694 && flag_unsafe_math_optimizations"
13696 rtx op0 = gen_reg_rtx (XFmode);
13698 rtx op2 = gen_reg_rtx (XFmode);
13699 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
13701 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13702 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13706 (define_expand "log2xf2"
13707 [(parallel [(set (match_operand:XF 0 "register_operand")
13708 (unspec:XF [(match_operand:XF 1 "register_operand")
13709 (match_dup 2)] UNSPEC_FYL2X))
13710 (clobber (match_scratch:XF 3))])]
13711 "TARGET_USE_FANCY_MATH_387
13712 && flag_unsafe_math_optimizations"
13714 operands[2] = gen_reg_rtx (XFmode);
13715 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13718 (define_expand "log2<mode>2"
13719 [(use (match_operand:MODEF 0 "register_operand"))
13720 (use (match_operand:MODEF 1 "register_operand"))]
13721 "TARGET_USE_FANCY_MATH_387
13722 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13723 || TARGET_MIX_SSE_I387)
13724 && flag_unsafe_math_optimizations"
13726 rtx op0 = gen_reg_rtx (XFmode);
13728 rtx op2 = gen_reg_rtx (XFmode);
13729 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
13731 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13732 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13736 (define_insn "fyl2xp1xf3_i387"
13737 [(set (match_operand:XF 0 "register_operand" "=f")
13738 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13739 (match_operand:XF 2 "register_operand" "u")]
13741 (clobber (match_scratch:XF 3 "=2"))]
13742 "TARGET_USE_FANCY_MATH_387
13743 && flag_unsafe_math_optimizations"
13745 [(set_attr "type" "fpspc")
13746 (set_attr "mode" "XF")])
13748 (define_insn "fyl2xp1_extend<mode>xf3_i387"
13749 [(set (match_operand:XF 0 "register_operand" "=f")
13750 (unspec:XF [(float_extend:XF
13751 (match_operand:MODEF 1 "register_operand" "0"))
13752 (match_operand:XF 2 "register_operand" "u")]
13754 (clobber (match_scratch:XF 3 "=2"))]
13755 "TARGET_USE_FANCY_MATH_387
13756 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13757 || TARGET_MIX_SSE_I387)
13758 && flag_unsafe_math_optimizations"
13760 [(set_attr "type" "fpspc")
13761 (set_attr "mode" "XF")])
13763 (define_expand "log1pxf2"
13764 [(use (match_operand:XF 0 "register_operand"))
13765 (use (match_operand:XF 1 "register_operand"))]
13766 "TARGET_USE_FANCY_MATH_387
13767 && flag_unsafe_math_optimizations"
13769 if (optimize_insn_for_size_p ())
13772 ix86_emit_i387_log1p (operands[0], operands[1]);
13776 (define_expand "log1p<mode>2"
13777 [(use (match_operand:MODEF 0 "register_operand"))
13778 (use (match_operand:MODEF 1 "register_operand"))]
13779 "TARGET_USE_FANCY_MATH_387
13780 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13781 || TARGET_MIX_SSE_I387)
13782 && flag_unsafe_math_optimizations"
13786 if (optimize_insn_for_size_p ())
13789 op0 = gen_reg_rtx (XFmode);
13791 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
13793 ix86_emit_i387_log1p (op0, operands[1]);
13794 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13798 (define_insn "fxtractxf3_i387"
13799 [(set (match_operand:XF 0 "register_operand" "=f")
13800 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13801 UNSPEC_XTRACT_FRACT))
13802 (set (match_operand:XF 1 "register_operand" "=u")
13803 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
13804 "TARGET_USE_FANCY_MATH_387
13805 && flag_unsafe_math_optimizations"
13807 [(set_attr "type" "fpspc")
13808 (set_attr "mode" "XF")])
13810 (define_insn "fxtract_extend<mode>xf3_i387"
13811 [(set (match_operand:XF 0 "register_operand" "=f")
13812 (unspec:XF [(float_extend:XF
13813 (match_operand:MODEF 2 "register_operand" "0"))]
13814 UNSPEC_XTRACT_FRACT))
13815 (set (match_operand:XF 1 "register_operand" "=u")
13816 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
13817 "TARGET_USE_FANCY_MATH_387
13818 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13819 || TARGET_MIX_SSE_I387)
13820 && flag_unsafe_math_optimizations"
13822 [(set_attr "type" "fpspc")
13823 (set_attr "mode" "XF")])
13825 (define_expand "logbxf2"
13826 [(parallel [(set (match_dup 2)
13827 (unspec:XF [(match_operand:XF 1 "register_operand")]
13828 UNSPEC_XTRACT_FRACT))
13829 (set (match_operand:XF 0 "register_operand")
13830 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
13831 "TARGET_USE_FANCY_MATH_387
13832 && flag_unsafe_math_optimizations"
13833 "operands[2] = gen_reg_rtx (XFmode);")
13835 (define_expand "logb<mode>2"
13836 [(use (match_operand:MODEF 0 "register_operand"))
13837 (use (match_operand:MODEF 1 "register_operand"))]
13838 "TARGET_USE_FANCY_MATH_387
13839 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13840 || TARGET_MIX_SSE_I387)
13841 && flag_unsafe_math_optimizations"
13843 rtx op0 = gen_reg_rtx (XFmode);
13844 rtx op1 = gen_reg_rtx (XFmode);
13846 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13847 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
13851 (define_expand "ilogbxf2"
13852 [(use (match_operand:SI 0 "register_operand"))
13853 (use (match_operand:XF 1 "register_operand"))]
13854 "TARGET_USE_FANCY_MATH_387
13855 && flag_unsafe_math_optimizations"
13859 if (optimize_insn_for_size_p ())
13862 op0 = gen_reg_rtx (XFmode);
13863 op1 = gen_reg_rtx (XFmode);
13865 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
13866 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13870 (define_expand "ilogb<mode>2"
13871 [(use (match_operand:SI 0 "register_operand"))
13872 (use (match_operand:MODEF 1 "register_operand"))]
13873 "TARGET_USE_FANCY_MATH_387
13874 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13875 || TARGET_MIX_SSE_I387)
13876 && flag_unsafe_math_optimizations"
13880 if (optimize_insn_for_size_p ())
13883 op0 = gen_reg_rtx (XFmode);
13884 op1 = gen_reg_rtx (XFmode);
13886 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
13887 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
13891 (define_insn "*f2xm1xf2_i387"
13892 [(set (match_operand:XF 0 "register_operand" "=f")
13893 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
13895 "TARGET_USE_FANCY_MATH_387
13896 && flag_unsafe_math_optimizations"
13898 [(set_attr "type" "fpspc")
13899 (set_attr "mode" "XF")])
13901 (define_insn "*fscalexf4_i387"
13902 [(set (match_operand:XF 0 "register_operand" "=f")
13903 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13904 (match_operand:XF 3 "register_operand" "1")]
13905 UNSPEC_FSCALE_FRACT))
13906 (set (match_operand:XF 1 "register_operand" "=u")
13907 (unspec:XF [(match_dup 2) (match_dup 3)]
13908 UNSPEC_FSCALE_EXP))]
13909 "TARGET_USE_FANCY_MATH_387
13910 && flag_unsafe_math_optimizations"
13912 [(set_attr "type" "fpspc")
13913 (set_attr "mode" "XF")])
13915 (define_expand "expNcorexf3"
13916 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
13917 (match_operand:XF 2 "register_operand")))
13918 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
13919 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
13920 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
13921 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
13922 (parallel [(set (match_operand:XF 0 "register_operand")
13923 (unspec:XF [(match_dup 8) (match_dup 4)]
13924 UNSPEC_FSCALE_FRACT))
13926 (unspec:XF [(match_dup 8) (match_dup 4)]
13927 UNSPEC_FSCALE_EXP))])]
13928 "TARGET_USE_FANCY_MATH_387
13929 && flag_unsafe_math_optimizations"
13933 if (optimize_insn_for_size_p ())
13936 for (i = 3; i < 10; i++)
13937 operands[i] = gen_reg_rtx (XFmode);
13939 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
13942 (define_expand "expxf2"
13943 [(use (match_operand:XF 0 "register_operand"))
13944 (use (match_operand:XF 1 "register_operand"))]
13945 "TARGET_USE_FANCY_MATH_387
13946 && flag_unsafe_math_optimizations"
13950 if (optimize_insn_for_size_p ())
13953 op2 = gen_reg_rtx (XFmode);
13954 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
13956 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
13960 (define_expand "exp<mode>2"
13961 [(use (match_operand:MODEF 0 "register_operand"))
13962 (use (match_operand:MODEF 1 "general_operand"))]
13963 "TARGET_USE_FANCY_MATH_387
13964 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13965 || TARGET_MIX_SSE_I387)
13966 && flag_unsafe_math_optimizations"
13970 if (optimize_insn_for_size_p ())
13973 op0 = gen_reg_rtx (XFmode);
13974 op1 = gen_reg_rtx (XFmode);
13976 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13977 emit_insn (gen_expxf2 (op0, op1));
13978 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13982 (define_expand "exp10xf2"
13983 [(use (match_operand:XF 0 "register_operand"))
13984 (use (match_operand:XF 1 "register_operand"))]
13985 "TARGET_USE_FANCY_MATH_387
13986 && flag_unsafe_math_optimizations"
13990 if (optimize_insn_for_size_p ())
13993 op2 = gen_reg_rtx (XFmode);
13994 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
13996 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14000 (define_expand "exp10<mode>2"
14001 [(use (match_operand:MODEF 0 "register_operand"))
14002 (use (match_operand:MODEF 1 "general_operand"))]
14003 "TARGET_USE_FANCY_MATH_387
14004 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14005 || TARGET_MIX_SSE_I387)
14006 && flag_unsafe_math_optimizations"
14010 if (optimize_insn_for_size_p ())
14013 op0 = gen_reg_rtx (XFmode);
14014 op1 = gen_reg_rtx (XFmode);
14016 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14017 emit_insn (gen_exp10xf2 (op0, op1));
14018 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14022 (define_expand "exp2xf2"
14023 [(use (match_operand:XF 0 "register_operand"))
14024 (use (match_operand:XF 1 "register_operand"))]
14025 "TARGET_USE_FANCY_MATH_387
14026 && flag_unsafe_math_optimizations"
14030 if (optimize_insn_for_size_p ())
14033 op2 = gen_reg_rtx (XFmode);
14034 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14036 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14040 (define_expand "exp2<mode>2"
14041 [(use (match_operand:MODEF 0 "register_operand"))
14042 (use (match_operand:MODEF 1 "general_operand"))]
14043 "TARGET_USE_FANCY_MATH_387
14044 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14045 || TARGET_MIX_SSE_I387)
14046 && flag_unsafe_math_optimizations"
14050 if (optimize_insn_for_size_p ())
14053 op0 = gen_reg_rtx (XFmode);
14054 op1 = gen_reg_rtx (XFmode);
14056 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14057 emit_insn (gen_exp2xf2 (op0, op1));
14058 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14062 (define_expand "expm1xf2"
14063 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14065 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14066 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14067 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14068 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14069 (parallel [(set (match_dup 7)
14070 (unspec:XF [(match_dup 6) (match_dup 4)]
14071 UNSPEC_FSCALE_FRACT))
14073 (unspec:XF [(match_dup 6) (match_dup 4)]
14074 UNSPEC_FSCALE_EXP))])
14075 (parallel [(set (match_dup 10)
14076 (unspec:XF [(match_dup 9) (match_dup 8)]
14077 UNSPEC_FSCALE_FRACT))
14078 (set (match_dup 11)
14079 (unspec:XF [(match_dup 9) (match_dup 8)]
14080 UNSPEC_FSCALE_EXP))])
14081 (set (match_dup 12) (minus:XF (match_dup 10)
14082 (float_extend:XF (match_dup 13))))
14083 (set (match_operand:XF 0 "register_operand")
14084 (plus:XF (match_dup 12) (match_dup 7)))]
14085 "TARGET_USE_FANCY_MATH_387
14086 && flag_unsafe_math_optimizations"
14090 if (optimize_insn_for_size_p ())
14093 for (i = 2; i < 13; i++)
14094 operands[i] = gen_reg_rtx (XFmode);
14097 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14099 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14102 (define_expand "expm1<mode>2"
14103 [(use (match_operand:MODEF 0 "register_operand"))
14104 (use (match_operand:MODEF 1 "general_operand"))]
14105 "TARGET_USE_FANCY_MATH_387
14106 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14107 || TARGET_MIX_SSE_I387)
14108 && flag_unsafe_math_optimizations"
14112 if (optimize_insn_for_size_p ())
14115 op0 = gen_reg_rtx (XFmode);
14116 op1 = gen_reg_rtx (XFmode);
14118 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14119 emit_insn (gen_expm1xf2 (op0, op1));
14120 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14124 (define_expand "ldexpxf3"
14125 [(set (match_dup 3)
14126 (float:XF (match_operand:SI 2 "register_operand")))
14127 (parallel [(set (match_operand:XF 0 " register_operand")
14128 (unspec:XF [(match_operand:XF 1 "register_operand")
14130 UNSPEC_FSCALE_FRACT))
14132 (unspec:XF [(match_dup 1) (match_dup 3)]
14133 UNSPEC_FSCALE_EXP))])]
14134 "TARGET_USE_FANCY_MATH_387
14135 && flag_unsafe_math_optimizations"
14137 if (optimize_insn_for_size_p ())
14140 operands[3] = gen_reg_rtx (XFmode);
14141 operands[4] = gen_reg_rtx (XFmode);
14144 (define_expand "ldexp<mode>3"
14145 [(use (match_operand:MODEF 0 "register_operand"))
14146 (use (match_operand:MODEF 1 "general_operand"))
14147 (use (match_operand:SI 2 "register_operand"))]
14148 "TARGET_USE_FANCY_MATH_387
14149 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14150 || TARGET_MIX_SSE_I387)
14151 && flag_unsafe_math_optimizations"
14155 if (optimize_insn_for_size_p ())
14158 op0 = gen_reg_rtx (XFmode);
14159 op1 = gen_reg_rtx (XFmode);
14161 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14162 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14163 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14167 (define_expand "scalbxf3"
14168 [(parallel [(set (match_operand:XF 0 " register_operand")
14169 (unspec:XF [(match_operand:XF 1 "register_operand")
14170 (match_operand:XF 2 "register_operand")]
14171 UNSPEC_FSCALE_FRACT))
14173 (unspec:XF [(match_dup 1) (match_dup 2)]
14174 UNSPEC_FSCALE_EXP))])]
14175 "TARGET_USE_FANCY_MATH_387
14176 && flag_unsafe_math_optimizations"
14178 if (optimize_insn_for_size_p ())
14181 operands[3] = gen_reg_rtx (XFmode);
14184 (define_expand "scalb<mode>3"
14185 [(use (match_operand:MODEF 0 "register_operand"))
14186 (use (match_operand:MODEF 1 "general_operand"))
14187 (use (match_operand:MODEF 2 "general_operand"))]
14188 "TARGET_USE_FANCY_MATH_387
14189 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14190 || TARGET_MIX_SSE_I387)
14191 && flag_unsafe_math_optimizations"
14195 if (optimize_insn_for_size_p ())
14198 op0 = gen_reg_rtx (XFmode);
14199 op1 = gen_reg_rtx (XFmode);
14200 op2 = gen_reg_rtx (XFmode);
14202 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14203 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14204 emit_insn (gen_scalbxf3 (op0, op1, op2));
14205 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14209 (define_expand "significandxf2"
14210 [(parallel [(set (match_operand:XF 0 "register_operand")
14211 (unspec:XF [(match_operand:XF 1 "register_operand")]
14212 UNSPEC_XTRACT_FRACT))
14214 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14215 "TARGET_USE_FANCY_MATH_387
14216 && flag_unsafe_math_optimizations"
14217 "operands[2] = gen_reg_rtx (XFmode);")
14219 (define_expand "significand<mode>2"
14220 [(use (match_operand:MODEF 0 "register_operand"))
14221 (use (match_operand:MODEF 1 "register_operand"))]
14222 "TARGET_USE_FANCY_MATH_387
14223 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14224 || TARGET_MIX_SSE_I387)
14225 && flag_unsafe_math_optimizations"
14227 rtx op0 = gen_reg_rtx (XFmode);
14228 rtx op1 = gen_reg_rtx (XFmode);
14230 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14231 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14236 (define_insn "sse4_1_round<mode>2"
14237 [(set (match_operand:MODEF 0 "register_operand" "=x")
14238 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14239 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14242 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14243 [(set_attr "type" "ssecvt")
14244 (set_attr "prefix_extra" "1")
14245 (set_attr "prefix" "maybe_vex")
14246 (set_attr "mode" "<MODE>")])
14248 (define_insn "rintxf2"
14249 [(set (match_operand:XF 0 "register_operand" "=f")
14250 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14252 "TARGET_USE_FANCY_MATH_387
14253 && flag_unsafe_math_optimizations"
14255 [(set_attr "type" "fpspc")
14256 (set_attr "mode" "XF")])
14258 (define_expand "rint<mode>2"
14259 [(use (match_operand:MODEF 0 "register_operand"))
14260 (use (match_operand:MODEF 1 "register_operand"))]
14261 "(TARGET_USE_FANCY_MATH_387
14262 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14263 || TARGET_MIX_SSE_I387)
14264 && flag_unsafe_math_optimizations)
14265 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14266 && !flag_trapping_math)"
14268 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14269 && !flag_trapping_math)
14272 emit_insn (gen_sse4_1_round<mode>2
14273 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14274 else if (optimize_insn_for_size_p ())
14277 ix86_expand_rint (operands[0], operands[1]);
14281 rtx op0 = gen_reg_rtx (XFmode);
14282 rtx op1 = gen_reg_rtx (XFmode);
14284 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14285 emit_insn (gen_rintxf2 (op0, op1));
14287 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14292 (define_expand "round<mode>2"
14293 [(match_operand:X87MODEF 0 "register_operand")
14294 (match_operand:X87MODEF 1 "nonimmediate_operand")]
14295 "(TARGET_USE_FANCY_MATH_387
14296 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14297 || TARGET_MIX_SSE_I387)
14298 && flag_unsafe_math_optimizations)
14299 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14300 && !flag_trapping_math && !flag_rounding_math)"
14302 if (optimize_insn_for_size_p ())
14305 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14306 && !flag_trapping_math && !flag_rounding_math)
14310 operands[1] = force_reg (<MODE>mode, operands[1]);
14311 ix86_expand_round_sse4 (operands[0], operands[1]);
14313 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14314 ix86_expand_round (operands[0], operands[1]);
14316 ix86_expand_rounddf_32 (operands[0], operands[1]);
14320 operands[1] = force_reg (<MODE>mode, operands[1]);
14321 ix86_emit_i387_round (operands[0], operands[1]);
14326 (define_insn_and_split "*fistdi2_1"
14327 [(set (match_operand:DI 0 "nonimmediate_operand")
14328 (unspec:DI [(match_operand:XF 1 "register_operand")]
14330 "TARGET_USE_FANCY_MATH_387
14331 && can_create_pseudo_p ()"
14336 if (memory_operand (operands[0], VOIDmode))
14337 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14340 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14341 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14346 [(set_attr "type" "fpspc")
14347 (set_attr "mode" "DI")])
14349 (define_insn "fistdi2"
14350 [(set (match_operand:DI 0 "memory_operand" "=m")
14351 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14353 (clobber (match_scratch:XF 2 "=&1f"))]
14354 "TARGET_USE_FANCY_MATH_387"
14355 "* return output_fix_trunc (insn, operands, false);"
14356 [(set_attr "type" "fpspc")
14357 (set_attr "mode" "DI")])
14359 (define_insn "fistdi2_with_temp"
14360 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14361 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14363 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14364 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14365 "TARGET_USE_FANCY_MATH_387"
14367 [(set_attr "type" "fpspc")
14368 (set_attr "mode" "DI")])
14371 [(set (match_operand:DI 0 "register_operand")
14372 (unspec:DI [(match_operand:XF 1 "register_operand")]
14374 (clobber (match_operand:DI 2 "memory_operand"))
14375 (clobber (match_scratch 3))]
14377 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14378 (clobber (match_dup 3))])
14379 (set (match_dup 0) (match_dup 2))])
14382 [(set (match_operand:DI 0 "memory_operand")
14383 (unspec:DI [(match_operand:XF 1 "register_operand")]
14385 (clobber (match_operand:DI 2 "memory_operand"))
14386 (clobber (match_scratch 3))]
14388 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14389 (clobber (match_dup 3))])])
14391 (define_insn_and_split "*fist<mode>2_1"
14392 [(set (match_operand:SWI24 0 "register_operand")
14393 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14395 "TARGET_USE_FANCY_MATH_387
14396 && can_create_pseudo_p ()"
14401 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14402 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14406 [(set_attr "type" "fpspc")
14407 (set_attr "mode" "<MODE>")])
14409 (define_insn "fist<mode>2"
14410 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14411 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14413 "TARGET_USE_FANCY_MATH_387"
14414 "* return output_fix_trunc (insn, operands, false);"
14415 [(set_attr "type" "fpspc")
14416 (set_attr "mode" "<MODE>")])
14418 (define_insn "fist<mode>2_with_temp"
14419 [(set (match_operand:SWI24 0 "register_operand" "=r")
14420 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14422 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14423 "TARGET_USE_FANCY_MATH_387"
14425 [(set_attr "type" "fpspc")
14426 (set_attr "mode" "<MODE>")])
14429 [(set (match_operand:SWI24 0 "register_operand")
14430 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14432 (clobber (match_operand:SWI24 2 "memory_operand"))]
14434 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14435 (set (match_dup 0) (match_dup 2))])
14438 [(set (match_operand:SWI24 0 "memory_operand")
14439 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14441 (clobber (match_operand:SWI24 2 "memory_operand"))]
14443 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14445 (define_expand "lrintxf<mode>2"
14446 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
14447 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
14449 "TARGET_USE_FANCY_MATH_387")
14451 (define_expand "lrint<MODEF:mode><SWI48:mode>2"
14452 [(set (match_operand:SWI48 0 "nonimmediate_operand")
14453 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
14454 UNSPEC_FIX_NOTRUNC))]
14455 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH")
14457 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14458 [(match_operand:SWI248x 0 "nonimmediate_operand")
14459 (match_operand:X87MODEF 1 "register_operand")]
14460 "(TARGET_USE_FANCY_MATH_387
14461 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14462 || TARGET_MIX_SSE_I387)
14463 && flag_unsafe_math_optimizations)
14464 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14465 && <SWI248x:MODE>mode != HImode
14466 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14467 && !flag_trapping_math && !flag_rounding_math)"
14469 if (optimize_insn_for_size_p ())
14472 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14473 && <SWI248x:MODE>mode != HImode
14474 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14475 && !flag_trapping_math && !flag_rounding_math)
14476 ix86_expand_lround (operands[0], operands[1]);
14478 ix86_emit_i387_round (operands[0], operands[1]);
14482 (define_int_iterator FRNDINT_ROUNDING
14483 [UNSPEC_FRNDINT_FLOOR
14484 UNSPEC_FRNDINT_CEIL
14485 UNSPEC_FRNDINT_TRUNC])
14487 (define_int_iterator FIST_ROUNDING
14491 ;; Base name for define_insn
14492 (define_int_attr rounding_insn
14493 [(UNSPEC_FRNDINT_FLOOR "floor")
14494 (UNSPEC_FRNDINT_CEIL "ceil")
14495 (UNSPEC_FRNDINT_TRUNC "btrunc")
14496 (UNSPEC_FIST_FLOOR "floor")
14497 (UNSPEC_FIST_CEIL "ceil")])
14499 (define_int_attr rounding
14500 [(UNSPEC_FRNDINT_FLOOR "floor")
14501 (UNSPEC_FRNDINT_CEIL "ceil")
14502 (UNSPEC_FRNDINT_TRUNC "trunc")
14503 (UNSPEC_FIST_FLOOR "floor")
14504 (UNSPEC_FIST_CEIL "ceil")])
14506 (define_int_attr ROUNDING
14507 [(UNSPEC_FRNDINT_FLOOR "FLOOR")
14508 (UNSPEC_FRNDINT_CEIL "CEIL")
14509 (UNSPEC_FRNDINT_TRUNC "TRUNC")
14510 (UNSPEC_FIST_FLOOR "FLOOR")
14511 (UNSPEC_FIST_CEIL "CEIL")])
14513 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14514 (define_insn_and_split "frndintxf2_<rounding>"
14515 [(set (match_operand:XF 0 "register_operand")
14516 (unspec:XF [(match_operand:XF 1 "register_operand")]
14518 (clobber (reg:CC FLAGS_REG))]
14519 "TARGET_USE_FANCY_MATH_387
14520 && flag_unsafe_math_optimizations
14521 && can_create_pseudo_p ()"
14526 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
14528 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14529 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
14531 emit_insn (gen_frndintxf2_<rounding>_i387 (operands[0], operands[1],
14532 operands[2], operands[3]));
14535 [(set_attr "type" "frndint")
14536 (set_attr "i387_cw" "<rounding>")
14537 (set_attr "mode" "XF")])
14539 (define_insn "frndintxf2_<rounding>_i387"
14540 [(set (match_operand:XF 0 "register_operand" "=f")
14541 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14543 (use (match_operand:HI 2 "memory_operand" "m"))
14544 (use (match_operand:HI 3 "memory_operand" "m"))]
14545 "TARGET_USE_FANCY_MATH_387
14546 && flag_unsafe_math_optimizations"
14547 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14548 [(set_attr "type" "frndint")
14549 (set_attr "i387_cw" "<rounding>")
14550 (set_attr "mode" "XF")])
14552 (define_expand "<rounding_insn>xf2"
14553 [(parallel [(set (match_operand:XF 0 "register_operand")
14554 (unspec:XF [(match_operand:XF 1 "register_operand")]
14556 (clobber (reg:CC FLAGS_REG))])]
14557 "TARGET_USE_FANCY_MATH_387
14558 && flag_unsafe_math_optimizations
14559 && !optimize_insn_for_size_p ()")
14561 (define_expand "<rounding_insn><mode>2"
14562 [(parallel [(set (match_operand:MODEF 0 "register_operand")
14563 (unspec:MODEF [(match_operand:MODEF 1 "register_operand")]
14565 (clobber (reg:CC FLAGS_REG))])]
14566 "(TARGET_USE_FANCY_MATH_387
14567 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14568 || TARGET_MIX_SSE_I387)
14569 && flag_unsafe_math_optimizations)
14570 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14571 && !flag_trapping_math)"
14573 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14574 && !flag_trapping_math)
14577 emit_insn (gen_sse4_1_round<mode>2
14578 (operands[0], operands[1], GEN_INT (ROUND_<ROUNDING>)));
14579 else if (optimize_insn_for_size_p ())
14581 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14583 if (ROUND_<ROUNDING> == ROUND_FLOOR)
14584 ix86_expand_floorceil (operands[0], operands[1], true);
14585 else if (ROUND_<ROUNDING> == ROUND_CEIL)
14586 ix86_expand_floorceil (operands[0], operands[1], false);
14587 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
14588 ix86_expand_trunc (operands[0], operands[1]);
14590 gcc_unreachable ();
14594 if (ROUND_<ROUNDING> == ROUND_FLOOR)
14595 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
14596 else if (ROUND_<ROUNDING> == ROUND_CEIL)
14597 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
14598 else if (ROUND_<ROUNDING> == ROUND_TRUNC)
14599 ix86_expand_truncdf_32 (operands[0], operands[1]);
14601 gcc_unreachable ();
14608 if (optimize_insn_for_size_p ())
14611 op0 = gen_reg_rtx (XFmode);
14612 op1 = gen_reg_rtx (XFmode);
14613 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14614 emit_insn (gen_frndintxf2_<rounding> (op0, op1));
14616 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14621 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14622 (define_insn_and_split "frndintxf2_mask_pm"
14623 [(set (match_operand:XF 0 "register_operand")
14624 (unspec:XF [(match_operand:XF 1 "register_operand")]
14625 UNSPEC_FRNDINT_MASK_PM))
14626 (clobber (reg:CC FLAGS_REG))]
14627 "TARGET_USE_FANCY_MATH_387
14628 && flag_unsafe_math_optimizations
14629 && can_create_pseudo_p ()"
14634 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
14636 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14637 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
14639 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
14640 operands[2], operands[3]));
14643 [(set_attr "type" "frndint")
14644 (set_attr "i387_cw" "mask_pm")
14645 (set_attr "mode" "XF")])
14647 (define_insn "frndintxf2_mask_pm_i387"
14648 [(set (match_operand:XF 0 "register_operand" "=f")
14649 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14650 UNSPEC_FRNDINT_MASK_PM))
14651 (use (match_operand:HI 2 "memory_operand" "m"))
14652 (use (match_operand:HI 3 "memory_operand" "m"))]
14653 "TARGET_USE_FANCY_MATH_387
14654 && flag_unsafe_math_optimizations"
14655 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
14656 [(set_attr "type" "frndint")
14657 (set_attr "i387_cw" "mask_pm")
14658 (set_attr "mode" "XF")])
14660 (define_expand "nearbyintxf2"
14661 [(parallel [(set (match_operand:XF 0 "register_operand")
14662 (unspec:XF [(match_operand:XF 1 "register_operand")]
14663 UNSPEC_FRNDINT_MASK_PM))
14664 (clobber (reg:CC FLAGS_REG))])]
14665 "TARGET_USE_FANCY_MATH_387
14666 && flag_unsafe_math_optimizations")
14668 (define_expand "nearbyint<mode>2"
14669 [(use (match_operand:MODEF 0 "register_operand"))
14670 (use (match_operand:MODEF 1 "register_operand"))]
14671 "TARGET_USE_FANCY_MATH_387
14672 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14673 || TARGET_MIX_SSE_I387)
14674 && flag_unsafe_math_optimizations"
14676 rtx op0 = gen_reg_rtx (XFmode);
14677 rtx op1 = gen_reg_rtx (XFmode);
14679 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14680 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
14682 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14686 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14687 (define_insn_and_split "*fist<mode>2_<rounding>_1"
14688 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
14689 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
14691 (clobber (reg:CC FLAGS_REG))]
14692 "TARGET_USE_FANCY_MATH_387
14693 && flag_unsafe_math_optimizations
14694 && can_create_pseudo_p ()"
14699 ix86_optimize_mode_switching[I387_<ROUNDING>] = 1;
14701 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14702 operands[3] = assign_386_stack_local (HImode, SLOT_CW_<ROUNDING>);
14703 if (memory_operand (operands[0], VOIDmode))
14704 emit_insn (gen_fist<mode>2_<rounding> (operands[0], operands[1],
14705 operands[2], operands[3]));
14708 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14709 emit_insn (gen_fist<mode>2_<rounding>_with_temp
14710 (operands[0], operands[1], operands[2],
14711 operands[3], operands[4]));
14715 [(set_attr "type" "fistp")
14716 (set_attr "i387_cw" "<rounding>")
14717 (set_attr "mode" "<MODE>")])
14719 (define_insn "fistdi2_<rounding>"
14720 [(set (match_operand:DI 0 "memory_operand" "=m")
14721 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14723 (use (match_operand:HI 2 "memory_operand" "m"))
14724 (use (match_operand:HI 3 "memory_operand" "m"))
14725 (clobber (match_scratch:XF 4 "=&1f"))]
14726 "TARGET_USE_FANCY_MATH_387
14727 && flag_unsafe_math_optimizations"
14728 "* return output_fix_trunc (insn, operands, false);"
14729 [(set_attr "type" "fistp")
14730 (set_attr "i387_cw" "<rounding>")
14731 (set_attr "mode" "DI")])
14733 (define_insn "fistdi2_<rounding>_with_temp"
14734 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14735 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14737 (use (match_operand:HI 2 "memory_operand" "m,m"))
14738 (use (match_operand:HI 3 "memory_operand" "m,m"))
14739 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14740 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14741 "TARGET_USE_FANCY_MATH_387
14742 && flag_unsafe_math_optimizations"
14744 [(set_attr "type" "fistp")
14745 (set_attr "i387_cw" "<rounding>")
14746 (set_attr "mode" "DI")])
14749 [(set (match_operand:DI 0 "register_operand")
14750 (unspec:DI [(match_operand:XF 1 "register_operand")]
14752 (use (match_operand:HI 2 "memory_operand"))
14753 (use (match_operand:HI 3 "memory_operand"))
14754 (clobber (match_operand:DI 4 "memory_operand"))
14755 (clobber (match_scratch 5))]
14757 [(parallel [(set (match_dup 4)
14758 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
14759 (use (match_dup 2))
14760 (use (match_dup 3))
14761 (clobber (match_dup 5))])
14762 (set (match_dup 0) (match_dup 4))])
14765 [(set (match_operand:DI 0 "memory_operand")
14766 (unspec:DI [(match_operand:XF 1 "register_operand")]
14768 (use (match_operand:HI 2 "memory_operand"))
14769 (use (match_operand:HI 3 "memory_operand"))
14770 (clobber (match_operand:DI 4 "memory_operand"))
14771 (clobber (match_scratch 5))]
14773 [(parallel [(set (match_dup 0)
14774 (unspec:DI [(match_dup 1)] FIST_ROUNDING))
14775 (use (match_dup 2))
14776 (use (match_dup 3))
14777 (clobber (match_dup 5))])])
14779 (define_insn "fist<mode>2_<rounding>"
14780 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14781 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14783 (use (match_operand:HI 2 "memory_operand" "m"))
14784 (use (match_operand:HI 3 "memory_operand" "m"))]
14785 "TARGET_USE_FANCY_MATH_387
14786 && flag_unsafe_math_optimizations"
14787 "* return output_fix_trunc (insn, operands, false);"
14788 [(set_attr "type" "fistp")
14789 (set_attr "i387_cw" "<rounding>")
14790 (set_attr "mode" "<MODE>")])
14792 (define_insn "fist<mode>2_<rounding>_with_temp"
14793 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
14794 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
14796 (use (match_operand:HI 2 "memory_operand" "m,m"))
14797 (use (match_operand:HI 3 "memory_operand" "m,m"))
14798 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
14799 "TARGET_USE_FANCY_MATH_387
14800 && flag_unsafe_math_optimizations"
14802 [(set_attr "type" "fistp")
14803 (set_attr "i387_cw" "<rounding>")
14804 (set_attr "mode" "<MODE>")])
14807 [(set (match_operand:SWI24 0 "register_operand")
14808 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14810 (use (match_operand:HI 2 "memory_operand"))
14811 (use (match_operand:HI 3 "memory_operand"))
14812 (clobber (match_operand:SWI24 4 "memory_operand"))]
14814 [(parallel [(set (match_dup 4)
14815 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
14816 (use (match_dup 2))
14817 (use (match_dup 3))])
14818 (set (match_dup 0) (match_dup 4))])
14821 [(set (match_operand:SWI24 0 "memory_operand")
14822 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14824 (use (match_operand:HI 2 "memory_operand"))
14825 (use (match_operand:HI 3 "memory_operand"))
14826 (clobber (match_operand:SWI24 4 "memory_operand"))]
14828 [(parallel [(set (match_dup 0)
14829 (unspec:SWI24 [(match_dup 1)] FIST_ROUNDING))
14830 (use (match_dup 2))
14831 (use (match_dup 3))])])
14833 (define_expand "l<rounding_insn>xf<mode>2"
14834 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
14835 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
14837 (clobber (reg:CC FLAGS_REG))])]
14838 "TARGET_USE_FANCY_MATH_387
14839 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
14840 && flag_unsafe_math_optimizations")
14842 (define_expand "l<rounding_insn><MODEF:mode><SWI48:mode>2"
14843 [(parallel [(set (match_operand:SWI48 0 "nonimmediate_operand")
14844 (unspec:SWI48 [(match_operand:MODEF 1 "register_operand")]
14846 (clobber (reg:CC FLAGS_REG))])]
14847 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14848 && !flag_trapping_math"
14850 if (TARGET_64BIT && optimize_insn_for_size_p ())
14853 if (ROUND_<ROUNDING> == ROUND_FLOOR)
14854 ix86_expand_lfloorceil (operands[0], operands[1], true);
14855 else if (ROUND_<ROUNDING> == ROUND_CEIL)
14856 ix86_expand_lfloorceil (operands[0], operands[1], false);
14858 gcc_unreachable ();
14863 (define_insn "fxam<mode>2_i387"
14864 [(set (match_operand:HI 0 "register_operand" "=a")
14866 [(match_operand:X87MODEF 1 "register_operand" "f")]
14868 "TARGET_USE_FANCY_MATH_387"
14869 "fxam\n\tfnstsw\t%0"
14870 [(set_attr "type" "multi")
14871 (set_attr "length" "4")
14872 (set_attr "unit" "i387")
14873 (set_attr "mode" "<MODE>")])
14875 (define_insn_and_split "fxam<mode>2_i387_with_temp"
14876 [(set (match_operand:HI 0 "register_operand")
14878 [(match_operand:MODEF 1 "memory_operand")]
14880 "TARGET_USE_FANCY_MATH_387
14881 && can_create_pseudo_p ()"
14884 [(set (match_dup 2)(match_dup 1))
14886 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
14888 operands[2] = gen_reg_rtx (<MODE>mode);
14890 MEM_VOLATILE_P (operands[1]) = 1;
14892 [(set_attr "type" "multi")
14893 (set_attr "unit" "i387")
14894 (set_attr "mode" "<MODE>")])
14896 (define_expand "isinfxf2"
14897 [(use (match_operand:SI 0 "register_operand"))
14898 (use (match_operand:XF 1 "register_operand"))]
14899 "TARGET_USE_FANCY_MATH_387
14900 && TARGET_C99_FUNCTIONS"
14902 rtx mask = GEN_INT (0x45);
14903 rtx val = GEN_INT (0x05);
14907 rtx scratch = gen_reg_rtx (HImode);
14908 rtx res = gen_reg_rtx (QImode);
14910 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
14912 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
14913 emit_insn (gen_cmpqi_ext_3 (scratch, val));
14914 cond = gen_rtx_fmt_ee (EQ, QImode,
14915 gen_rtx_REG (CCmode, FLAGS_REG),
14917 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
14918 emit_insn (gen_zero_extendqisi2 (operands[0], res));
14922 (define_expand "isinf<mode>2"
14923 [(use (match_operand:SI 0 "register_operand"))
14924 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
14925 "TARGET_USE_FANCY_MATH_387
14926 && TARGET_C99_FUNCTIONS
14927 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
14929 rtx mask = GEN_INT (0x45);
14930 rtx val = GEN_INT (0x05);
14934 rtx scratch = gen_reg_rtx (HImode);
14935 rtx res = gen_reg_rtx (QImode);
14937 /* Remove excess precision by forcing value through memory. */
14938 if (memory_operand (operands[1], VOIDmode))
14939 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
14942 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14944 emit_move_insn (temp, operands[1]);
14945 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
14948 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
14949 emit_insn (gen_cmpqi_ext_3 (scratch, val));
14950 cond = gen_rtx_fmt_ee (EQ, QImode,
14951 gen_rtx_REG (CCmode, FLAGS_REG),
14953 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
14954 emit_insn (gen_zero_extendqisi2 (operands[0], res));
14958 (define_expand "signbitxf2"
14959 [(use (match_operand:SI 0 "register_operand"))
14960 (use (match_operand:XF 1 "register_operand"))]
14961 "TARGET_USE_FANCY_MATH_387"
14963 rtx scratch = gen_reg_rtx (HImode);
14965 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
14966 emit_insn (gen_andsi3 (operands[0],
14967 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
14971 (define_insn "movmsk_df"
14972 [(set (match_operand:SI 0 "register_operand" "=r")
14974 [(match_operand:DF 1 "register_operand" "x")]
14976 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
14977 "%vmovmskpd\t{%1, %0|%0, %1}"
14978 [(set_attr "type" "ssemov")
14979 (set_attr "prefix" "maybe_vex")
14980 (set_attr "mode" "DF")])
14982 ;; Use movmskpd in SSE mode to avoid store forwarding stall
14983 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
14984 (define_expand "signbitdf2"
14985 [(use (match_operand:SI 0 "register_operand"))
14986 (use (match_operand:DF 1 "register_operand"))]
14987 "TARGET_USE_FANCY_MATH_387
14988 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
14990 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
14992 emit_insn (gen_movmsk_df (operands[0], operands[1]));
14993 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
14997 rtx scratch = gen_reg_rtx (HImode);
14999 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15000 emit_insn (gen_andsi3 (operands[0],
15001 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15006 (define_expand "signbitsf2"
15007 [(use (match_operand:SI 0 "register_operand"))
15008 (use (match_operand:SF 1 "register_operand"))]
15009 "TARGET_USE_FANCY_MATH_387
15010 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15012 rtx scratch = gen_reg_rtx (HImode);
15014 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15015 emit_insn (gen_andsi3 (operands[0],
15016 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15020 ;; Block operation instructions
15023 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15026 [(set_attr "length" "1")
15027 (set_attr "length_immediate" "0")
15028 (set_attr "modrm" "0")])
15030 (define_expand "movmem<mode>"
15031 [(use (match_operand:BLK 0 "memory_operand"))
15032 (use (match_operand:BLK 1 "memory_operand"))
15033 (use (match_operand:SWI48 2 "nonmemory_operand"))
15034 (use (match_operand:SWI48 3 "const_int_operand"))
15035 (use (match_operand:SI 4 "const_int_operand"))
15036 (use (match_operand:SI 5 "const_int_operand"))]
15039 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15040 operands[4], operands[5]))
15046 ;; Most CPUs don't like single string operations
15047 ;; Handle this case here to simplify previous expander.
15049 (define_expand "strmov"
15050 [(set (match_dup 4) (match_operand 3 "memory_operand"))
15051 (set (match_operand 1 "memory_operand") (match_dup 4))
15052 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
15053 (clobber (reg:CC FLAGS_REG))])
15054 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
15055 (clobber (reg:CC FLAGS_REG))])]
15058 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15060 /* If .md ever supports :P for Pmode, these can be directly
15061 in the pattern above. */
15062 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15063 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15065 /* Can't use this if the user has appropriated esi or edi. */
15066 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15067 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15069 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15070 operands[2], operands[3],
15071 operands[5], operands[6]));
15075 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15078 (define_expand "strmov_singleop"
15079 [(parallel [(set (match_operand 1 "memory_operand")
15080 (match_operand 3 "memory_operand"))
15081 (set (match_operand 0 "register_operand")
15083 (set (match_operand 2 "register_operand")
15084 (match_operand 5))])]
15086 "ix86_current_function_needs_cld = 1;")
15088 (define_insn "*strmovdi_rex_1"
15089 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15090 (mem:DI (match_operand:P 3 "register_operand" "1")))
15091 (set (match_operand:P 0 "register_operand" "=D")
15092 (plus:P (match_dup 2)
15094 (set (match_operand:P 1 "register_operand" "=S")
15095 (plus:P (match_dup 3)
15098 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15100 [(set_attr "type" "str")
15101 (set_attr "memory" "both")
15102 (set_attr "mode" "DI")])
15104 (define_insn "*strmovsi_1"
15105 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15106 (mem:SI (match_operand:P 3 "register_operand" "1")))
15107 (set (match_operand:P 0 "register_operand" "=D")
15108 (plus:P (match_dup 2)
15110 (set (match_operand:P 1 "register_operand" "=S")
15111 (plus:P (match_dup 3)
15113 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15115 [(set_attr "type" "str")
15116 (set_attr "memory" "both")
15117 (set_attr "mode" "SI")])
15119 (define_insn "*strmovhi_1"
15120 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15121 (mem:HI (match_operand:P 3 "register_operand" "1")))
15122 (set (match_operand:P 0 "register_operand" "=D")
15123 (plus:P (match_dup 2)
15125 (set (match_operand:P 1 "register_operand" "=S")
15126 (plus:P (match_dup 3)
15128 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15130 [(set_attr "type" "str")
15131 (set_attr "memory" "both")
15132 (set_attr "mode" "HI")])
15134 (define_insn "*strmovqi_1"
15135 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15136 (mem:QI (match_operand:P 3 "register_operand" "1")))
15137 (set (match_operand:P 0 "register_operand" "=D")
15138 (plus:P (match_dup 2)
15140 (set (match_operand:P 1 "register_operand" "=S")
15141 (plus:P (match_dup 3)
15143 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15145 [(set_attr "type" "str")
15146 (set_attr "memory" "both")
15147 (set (attr "prefix_rex")
15149 (match_test "<P:MODE>mode == DImode")
15151 (const_string "*")))
15152 (set_attr "mode" "QI")])
15154 (define_expand "rep_mov"
15155 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
15156 (set (match_operand 0 "register_operand")
15158 (set (match_operand 2 "register_operand")
15160 (set (match_operand 1 "memory_operand")
15161 (match_operand 3 "memory_operand"))
15162 (use (match_dup 4))])]
15164 "ix86_current_function_needs_cld = 1;")
15166 (define_insn "*rep_movdi_rex64"
15167 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15168 (set (match_operand:P 0 "register_operand" "=D")
15169 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15171 (match_operand:P 3 "register_operand" "0")))
15172 (set (match_operand:P 1 "register_operand" "=S")
15173 (plus:P (ashift:P (match_dup 5) (const_int 3))
15174 (match_operand:P 4 "register_operand" "1")))
15175 (set (mem:BLK (match_dup 3))
15176 (mem:BLK (match_dup 4)))
15177 (use (match_dup 5))]
15179 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15181 [(set_attr "type" "str")
15182 (set_attr "prefix_rep" "1")
15183 (set_attr "memory" "both")
15184 (set_attr "mode" "DI")])
15186 (define_insn "*rep_movsi"
15187 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15188 (set (match_operand:P 0 "register_operand" "=D")
15189 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15191 (match_operand:P 3 "register_operand" "0")))
15192 (set (match_operand:P 1 "register_operand" "=S")
15193 (plus:P (ashift:P (match_dup 5) (const_int 2))
15194 (match_operand:P 4 "register_operand" "1")))
15195 (set (mem:BLK (match_dup 3))
15196 (mem:BLK (match_dup 4)))
15197 (use (match_dup 5))]
15198 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15199 "%^rep{%;} movs{l|d}"
15200 [(set_attr "type" "str")
15201 (set_attr "prefix_rep" "1")
15202 (set_attr "memory" "both")
15203 (set_attr "mode" "SI")])
15205 (define_insn "*rep_movqi"
15206 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15207 (set (match_operand:P 0 "register_operand" "=D")
15208 (plus:P (match_operand:P 3 "register_operand" "0")
15209 (match_operand:P 5 "register_operand" "2")))
15210 (set (match_operand:P 1 "register_operand" "=S")
15211 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15212 (set (mem:BLK (match_dup 3))
15213 (mem:BLK (match_dup 4)))
15214 (use (match_dup 5))]
15215 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15217 [(set_attr "type" "str")
15218 (set_attr "prefix_rep" "1")
15219 (set_attr "memory" "both")
15220 (set_attr "mode" "QI")])
15222 (define_expand "setmem<mode>"
15223 [(use (match_operand:BLK 0 "memory_operand"))
15224 (use (match_operand:SWI48 1 "nonmemory_operand"))
15225 (use (match_operand:QI 2 "nonmemory_operand"))
15226 (use (match_operand 3 "const_int_operand"))
15227 (use (match_operand:SI 4 "const_int_operand"))
15228 (use (match_operand:SI 5 "const_int_operand"))]
15231 if (ix86_expand_setmem (operands[0], operands[1],
15232 operands[2], operands[3],
15233 operands[4], operands[5]))
15239 ;; Most CPUs don't like single string operations
15240 ;; Handle this case here to simplify previous expander.
15242 (define_expand "strset"
15243 [(set (match_operand 1 "memory_operand")
15244 (match_operand 2 "register_operand"))
15245 (parallel [(set (match_operand 0 "register_operand")
15247 (clobber (reg:CC FLAGS_REG))])]
15250 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15251 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15253 /* If .md ever supports :P for Pmode, this can be directly
15254 in the pattern above. */
15255 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15256 GEN_INT (GET_MODE_SIZE (GET_MODE
15258 /* Can't use this if the user has appropriated eax or edi. */
15259 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15260 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15262 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15268 (define_expand "strset_singleop"
15269 [(parallel [(set (match_operand 1 "memory_operand")
15270 (match_operand 2 "register_operand"))
15271 (set (match_operand 0 "register_operand")
15273 (unspec [(const_int 0)] UNSPEC_STOS)])]
15275 "ix86_current_function_needs_cld = 1;")
15277 (define_insn "*strsetdi_rex_1"
15278 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
15279 (match_operand:DI 2 "register_operand" "a"))
15280 (set (match_operand:P 0 "register_operand" "=D")
15281 (plus:P (match_dup 1)
15283 (unspec [(const_int 0)] UNSPEC_STOS)]
15285 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15287 [(set_attr "type" "str")
15288 (set_attr "memory" "store")
15289 (set_attr "mode" "DI")])
15291 (define_insn "*strsetsi_1"
15292 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15293 (match_operand:SI 2 "register_operand" "a"))
15294 (set (match_operand:P 0 "register_operand" "=D")
15295 (plus:P (match_dup 1)
15297 (unspec [(const_int 0)] UNSPEC_STOS)]
15298 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15300 [(set_attr "type" "str")
15301 (set_attr "memory" "store")
15302 (set_attr "mode" "SI")])
15304 (define_insn "*strsethi_1"
15305 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15306 (match_operand:HI 2 "register_operand" "a"))
15307 (set (match_operand:P 0 "register_operand" "=D")
15308 (plus:P (match_dup 1)
15310 (unspec [(const_int 0)] UNSPEC_STOS)]
15311 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15313 [(set_attr "type" "str")
15314 (set_attr "memory" "store")
15315 (set_attr "mode" "HI")])
15317 (define_insn "*strsetqi_1"
15318 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15319 (match_operand:QI 2 "register_operand" "a"))
15320 (set (match_operand:P 0 "register_operand" "=D")
15321 (plus:P (match_dup 1)
15323 (unspec [(const_int 0)] UNSPEC_STOS)]
15324 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15326 [(set_attr "type" "str")
15327 (set_attr "memory" "store")
15328 (set (attr "prefix_rex")
15330 (match_test "<P:MODE>mode == DImode")
15332 (const_string "*")))
15333 (set_attr "mode" "QI")])
15335 (define_expand "rep_stos"
15336 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
15337 (set (match_operand 0 "register_operand")
15339 (set (match_operand 2 "memory_operand") (const_int 0))
15340 (use (match_operand 3 "register_operand"))
15341 (use (match_dup 1))])]
15343 "ix86_current_function_needs_cld = 1;")
15345 (define_insn "*rep_stosdi_rex64"
15346 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15347 (set (match_operand:P 0 "register_operand" "=D")
15348 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15350 (match_operand:P 3 "register_operand" "0")))
15351 (set (mem:BLK (match_dup 3))
15353 (use (match_operand:DI 2 "register_operand" "a"))
15354 (use (match_dup 4))]
15356 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15358 [(set_attr "type" "str")
15359 (set_attr "prefix_rep" "1")
15360 (set_attr "memory" "store")
15361 (set_attr "mode" "DI")])
15363 (define_insn "*rep_stossi"
15364 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15365 (set (match_operand:P 0 "register_operand" "=D")
15366 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15368 (match_operand:P 3 "register_operand" "0")))
15369 (set (mem:BLK (match_dup 3))
15371 (use (match_operand:SI 2 "register_operand" "a"))
15372 (use (match_dup 4))]
15373 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15374 "%^rep{%;} stos{l|d}"
15375 [(set_attr "type" "str")
15376 (set_attr "prefix_rep" "1")
15377 (set_attr "memory" "store")
15378 (set_attr "mode" "SI")])
15380 (define_insn "*rep_stosqi"
15381 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15382 (set (match_operand:P 0 "register_operand" "=D")
15383 (plus:P (match_operand:P 3 "register_operand" "0")
15384 (match_operand:P 4 "register_operand" "1")))
15385 (set (mem:BLK (match_dup 3))
15387 (use (match_operand:QI 2 "register_operand" "a"))
15388 (use (match_dup 4))]
15389 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15391 [(set_attr "type" "str")
15392 (set_attr "prefix_rep" "1")
15393 (set_attr "memory" "store")
15394 (set (attr "prefix_rex")
15396 (match_test "<P:MODE>mode == DImode")
15398 (const_string "*")))
15399 (set_attr "mode" "QI")])
15401 (define_expand "cmpstrnsi"
15402 [(set (match_operand:SI 0 "register_operand")
15403 (compare:SI (match_operand:BLK 1 "general_operand")
15404 (match_operand:BLK 2 "general_operand")))
15405 (use (match_operand 3 "general_operand"))
15406 (use (match_operand 4 "immediate_operand"))]
15409 rtx addr1, addr2, out, outlow, count, countreg, align;
15411 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
15414 /* Can't use this if the user has appropriated ecx, esi or edi. */
15415 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
15420 out = gen_reg_rtx (SImode);
15422 addr1 = copy_addr_to_reg (XEXP (operands[1], 0));
15423 addr2 = copy_addr_to_reg (XEXP (operands[2], 0));
15424 if (addr1 != XEXP (operands[1], 0))
15425 operands[1] = replace_equiv_address_nv (operands[1], addr1);
15426 if (addr2 != XEXP (operands[2], 0))
15427 operands[2] = replace_equiv_address_nv (operands[2], addr2);
15429 count = operands[3];
15430 countreg = ix86_zero_extend_to_Pmode (count);
15432 /* %%% Iff we are testing strict equality, we can use known alignment
15433 to good advantage. This may be possible with combine, particularly
15434 once cc0 is dead. */
15435 align = operands[4];
15437 if (CONST_INT_P (count))
15439 if (INTVAL (count) == 0)
15441 emit_move_insn (operands[0], const0_rtx);
15444 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
15445 operands[1], operands[2]));
15449 rtx (*gen_cmp) (rtx, rtx);
15451 gen_cmp = (TARGET_64BIT
15452 ? gen_cmpdi_1 : gen_cmpsi_1);
15454 emit_insn (gen_cmp (countreg, countreg));
15455 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
15456 operands[1], operands[2]));
15459 outlow = gen_lowpart (QImode, out);
15460 emit_insn (gen_cmpintqi (outlow));
15461 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
15463 if (operands[0] != out)
15464 emit_move_insn (operands[0], out);
15469 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
15471 (define_expand "cmpintqi"
15472 [(set (match_dup 1)
15473 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15475 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15476 (parallel [(set (match_operand:QI 0 "register_operand")
15477 (minus:QI (match_dup 1)
15479 (clobber (reg:CC FLAGS_REG))])]
15482 operands[1] = gen_reg_rtx (QImode);
15483 operands[2] = gen_reg_rtx (QImode);
15486 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
15487 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
15489 (define_expand "cmpstrnqi_nz_1"
15490 [(parallel [(set (reg:CC FLAGS_REG)
15491 (compare:CC (match_operand 4 "memory_operand")
15492 (match_operand 5 "memory_operand")))
15493 (use (match_operand 2 "register_operand"))
15494 (use (match_operand:SI 3 "immediate_operand"))
15495 (clobber (match_operand 0 "register_operand"))
15496 (clobber (match_operand 1 "register_operand"))
15497 (clobber (match_dup 2))])]
15499 "ix86_current_function_needs_cld = 1;")
15501 (define_insn "*cmpstrnqi_nz_1"
15502 [(set (reg:CC FLAGS_REG)
15503 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15504 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
15505 (use (match_operand:P 6 "register_operand" "2"))
15506 (use (match_operand:SI 3 "immediate_operand" "i"))
15507 (clobber (match_operand:P 0 "register_operand" "=S"))
15508 (clobber (match_operand:P 1 "register_operand" "=D"))
15509 (clobber (match_operand:P 2 "register_operand" "=c"))]
15510 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15512 [(set_attr "type" "str")
15513 (set_attr "mode" "QI")
15514 (set (attr "prefix_rex")
15516 (match_test "<P:MODE>mode == DImode")
15518 (const_string "*")))
15519 (set_attr "prefix_rep" "1")])
15521 ;; The same, but the count is not known to not be zero.
15523 (define_expand "cmpstrnqi_1"
15524 [(parallel [(set (reg:CC FLAGS_REG)
15525 (if_then_else:CC (ne (match_operand 2 "register_operand")
15527 (compare:CC (match_operand 4 "memory_operand")
15528 (match_operand 5 "memory_operand"))
15530 (use (match_operand:SI 3 "immediate_operand"))
15531 (use (reg:CC FLAGS_REG))
15532 (clobber (match_operand 0 "register_operand"))
15533 (clobber (match_operand 1 "register_operand"))
15534 (clobber (match_dup 2))])]
15536 "ix86_current_function_needs_cld = 1;")
15538 (define_insn "*cmpstrnqi_1"
15539 [(set (reg:CC FLAGS_REG)
15540 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
15542 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
15543 (mem:BLK (match_operand:P 5 "register_operand" "1")))
15545 (use (match_operand:SI 3 "immediate_operand" "i"))
15546 (use (reg:CC FLAGS_REG))
15547 (clobber (match_operand:P 0 "register_operand" "=S"))
15548 (clobber (match_operand:P 1 "register_operand" "=D"))
15549 (clobber (match_operand:P 2 "register_operand" "=c"))]
15550 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15552 [(set_attr "type" "str")
15553 (set_attr "mode" "QI")
15554 (set (attr "prefix_rex")
15556 (match_test "<P:MODE>mode == DImode")
15558 (const_string "*")))
15559 (set_attr "prefix_rep" "1")])
15561 (define_expand "strlen<mode>"
15562 [(set (match_operand:P 0 "register_operand")
15563 (unspec:P [(match_operand:BLK 1 "general_operand")
15564 (match_operand:QI 2 "immediate_operand")
15565 (match_operand 3 "immediate_operand")]
15569 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
15575 (define_expand "strlenqi_1"
15576 [(parallel [(set (match_operand 0 "register_operand")
15578 (clobber (match_operand 1 "register_operand"))
15579 (clobber (reg:CC FLAGS_REG))])]
15581 "ix86_current_function_needs_cld = 1;")
15583 (define_insn "*strlenqi_1"
15584 [(set (match_operand:P 0 "register_operand" "=&c")
15585 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
15586 (match_operand:QI 2 "register_operand" "a")
15587 (match_operand:P 3 "immediate_operand" "i")
15588 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
15589 (clobber (match_operand:P 1 "register_operand" "=D"))
15590 (clobber (reg:CC FLAGS_REG))]
15591 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15592 "%^repnz{%;} scasb"
15593 [(set_attr "type" "str")
15594 (set_attr "mode" "QI")
15595 (set (attr "prefix_rex")
15597 (match_test "<P:MODE>mode == DImode")
15599 (const_string "*")))
15600 (set_attr "prefix_rep" "1")])
15602 ;; Peephole optimizations to clean up after cmpstrn*. This should be
15603 ;; handled in combine, but it is not currently up to the task.
15604 ;; When used for their truth value, the cmpstrn* expanders generate
15613 ;; The intermediate three instructions are unnecessary.
15615 ;; This one handles cmpstrn*_nz_1...
15618 (set (reg:CC FLAGS_REG)
15619 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
15620 (mem:BLK (match_operand 5 "register_operand"))))
15621 (use (match_operand 6 "register_operand"))
15622 (use (match_operand:SI 3 "immediate_operand"))
15623 (clobber (match_operand 0 "register_operand"))
15624 (clobber (match_operand 1 "register_operand"))
15625 (clobber (match_operand 2 "register_operand"))])
15626 (set (match_operand:QI 7 "register_operand")
15627 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15628 (set (match_operand:QI 8 "register_operand")
15629 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15630 (set (reg FLAGS_REG)
15631 (compare (match_dup 7) (match_dup 8)))
15633 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15635 (set (reg:CC FLAGS_REG)
15636 (compare:CC (mem:BLK (match_dup 4))
15637 (mem:BLK (match_dup 5))))
15638 (use (match_dup 6))
15639 (use (match_dup 3))
15640 (clobber (match_dup 0))
15641 (clobber (match_dup 1))
15642 (clobber (match_dup 2))])])
15644 ;; ...and this one handles cmpstrn*_1.
15647 (set (reg:CC FLAGS_REG)
15648 (if_then_else:CC (ne (match_operand 6 "register_operand")
15650 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
15651 (mem:BLK (match_operand 5 "register_operand")))
15653 (use (match_operand:SI 3 "immediate_operand"))
15654 (use (reg:CC FLAGS_REG))
15655 (clobber (match_operand 0 "register_operand"))
15656 (clobber (match_operand 1 "register_operand"))
15657 (clobber (match_operand 2 "register_operand"))])
15658 (set (match_operand:QI 7 "register_operand")
15659 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
15660 (set (match_operand:QI 8 "register_operand")
15661 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
15662 (set (reg FLAGS_REG)
15663 (compare (match_dup 7) (match_dup 8)))
15665 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
15667 (set (reg:CC FLAGS_REG)
15668 (if_then_else:CC (ne (match_dup 6)
15670 (compare:CC (mem:BLK (match_dup 4))
15671 (mem:BLK (match_dup 5)))
15673 (use (match_dup 3))
15674 (use (reg:CC FLAGS_REG))
15675 (clobber (match_dup 0))
15676 (clobber (match_dup 1))
15677 (clobber (match_dup 2))])])
15679 ;; Conditional move instructions.
15681 (define_expand "mov<mode>cc"
15682 [(set (match_operand:SWIM 0 "register_operand")
15683 (if_then_else:SWIM (match_operand 1 "comparison_operator")
15684 (match_operand:SWIM 2 "<general_operand>")
15685 (match_operand:SWIM 3 "<general_operand>")))]
15687 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
15689 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
15690 ;; the register first winds up with `sbbl $0,reg', which is also weird.
15691 ;; So just document what we're doing explicitly.
15693 (define_expand "x86_mov<mode>cc_0_m1"
15695 [(set (match_operand:SWI48 0 "register_operand")
15696 (if_then_else:SWI48
15697 (match_operator:SWI48 2 "ix86_carry_flag_operator"
15698 [(match_operand 1 "flags_reg_operand")
15702 (clobber (reg:CC FLAGS_REG))])])
15704 (define_insn "*x86_mov<mode>cc_0_m1"
15705 [(set (match_operand:SWI48 0 "register_operand" "=r")
15706 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15707 [(reg FLAGS_REG) (const_int 0)])
15710 (clobber (reg:CC FLAGS_REG))]
15712 "sbb{<imodesuffix>}\t%0, %0"
15713 ; Since we don't have the proper number of operands for an alu insn,
15714 ; fill in all the blanks.
15715 [(set_attr "type" "alu")
15716 (set_attr "use_carry" "1")
15717 (set_attr "pent_pair" "pu")
15718 (set_attr "memory" "none")
15719 (set_attr "imm_disp" "false")
15720 (set_attr "mode" "<MODE>")
15721 (set_attr "length_immediate" "0")])
15723 (define_insn "*x86_mov<mode>cc_0_m1_se"
15724 [(set (match_operand:SWI48 0 "register_operand" "=r")
15725 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15726 [(reg FLAGS_REG) (const_int 0)])
15729 (clobber (reg:CC FLAGS_REG))]
15731 "sbb{<imodesuffix>}\t%0, %0"
15732 [(set_attr "type" "alu")
15733 (set_attr "use_carry" "1")
15734 (set_attr "pent_pair" "pu")
15735 (set_attr "memory" "none")
15736 (set_attr "imm_disp" "false")
15737 (set_attr "mode" "<MODE>")
15738 (set_attr "length_immediate" "0")])
15740 (define_insn "*x86_mov<mode>cc_0_m1_neg"
15741 [(set (match_operand:SWI48 0 "register_operand" "=r")
15742 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
15743 [(reg FLAGS_REG) (const_int 0)])))
15744 (clobber (reg:CC FLAGS_REG))]
15746 "sbb{<imodesuffix>}\t%0, %0"
15747 [(set_attr "type" "alu")
15748 (set_attr "use_carry" "1")
15749 (set_attr "pent_pair" "pu")
15750 (set_attr "memory" "none")
15751 (set_attr "imm_disp" "false")
15752 (set_attr "mode" "<MODE>")
15753 (set_attr "length_immediate" "0")])
15755 (define_insn "*mov<mode>cc_noc"
15756 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
15757 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
15758 [(reg FLAGS_REG) (const_int 0)])
15759 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
15760 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
15761 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
15763 cmov%O2%C1\t{%2, %0|%0, %2}
15764 cmov%O2%c1\t{%3, %0|%0, %3}"
15765 [(set_attr "type" "icmov")
15766 (set_attr "mode" "<MODE>")])
15768 ;; Don't do conditional moves with memory inputs. This splitter helps
15769 ;; register starved x86_32 by forcing inputs into registers before reload.
15771 [(set (match_operand:SWI248 0 "register_operand")
15772 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
15773 [(reg FLAGS_REG) (const_int 0)])
15774 (match_operand:SWI248 2 "nonimmediate_operand")
15775 (match_operand:SWI248 3 "nonimmediate_operand")))]
15776 "!TARGET_64BIT && TARGET_CMOVE
15777 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
15778 && (MEM_P (operands[2]) || MEM_P (operands[3]))
15779 && can_create_pseudo_p ()
15780 && optimize_insn_for_speed_p ()"
15781 [(set (match_dup 0)
15782 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 3)))]
15784 if (MEM_P (operands[2]))
15785 operands[2] = force_reg (<MODE>mode, operands[2]);
15786 if (MEM_P (operands[3]))
15787 operands[3] = force_reg (<MODE>mode, operands[3]);
15790 (define_insn "*movqicc_noc"
15791 [(set (match_operand:QI 0 "register_operand" "=r,r")
15792 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
15793 [(reg FLAGS_REG) (const_int 0)])
15794 (match_operand:QI 2 "register_operand" "r,0")
15795 (match_operand:QI 3 "register_operand" "0,r")))]
15796 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
15798 [(set_attr "type" "icmov")
15799 (set_attr "mode" "QI")])
15802 [(set (match_operand:SWI12 0 "register_operand")
15803 (if_then_else:SWI12 (match_operator 1 "ix86_comparison_operator"
15804 [(reg FLAGS_REG) (const_int 0)])
15805 (match_operand:SWI12 2 "register_operand")
15806 (match_operand:SWI12 3 "register_operand")))]
15807 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
15808 && reload_completed"
15809 [(set (match_dup 0)
15810 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
15812 operands[0] = gen_lowpart (SImode, operands[0]);
15813 operands[2] = gen_lowpart (SImode, operands[2]);
15814 operands[3] = gen_lowpart (SImode, operands[3]);
15817 ;; Don't do conditional moves with memory inputs
15819 [(match_scratch:SWI248 2 "r")
15820 (set (match_operand:SWI248 0 "register_operand")
15821 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
15822 [(reg FLAGS_REG) (const_int 0)])
15824 (match_operand:SWI248 3 "memory_operand")))]
15825 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
15826 && optimize_insn_for_speed_p ()"
15827 [(set (match_dup 2) (match_dup 3))
15829 (if_then_else:SWI248 (match_dup 1) (match_dup 0) (match_dup 2)))])
15832 [(match_scratch:SWI248 2 "r")
15833 (set (match_operand:SWI248 0 "register_operand")
15834 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
15835 [(reg FLAGS_REG) (const_int 0)])
15836 (match_operand:SWI248 3 "memory_operand")
15838 "TARGET_CMOVE && TARGET_AVOID_MEM_OPND_FOR_CMOVE
15839 && optimize_insn_for_speed_p ()"
15840 [(set (match_dup 2) (match_dup 3))
15842 (if_then_else:SWI248 (match_dup 1) (match_dup 2) (match_dup 0)))])
15844 (define_expand "mov<mode>cc"
15845 [(set (match_operand:X87MODEF 0 "register_operand")
15846 (if_then_else:X87MODEF
15847 (match_operand 1 "comparison_operator")
15848 (match_operand:X87MODEF 2 "register_operand")
15849 (match_operand:X87MODEF 3 "register_operand")))]
15850 "(TARGET_80387 && TARGET_CMOVE)
15851 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15852 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
15854 (define_insn "*movxfcc_1"
15855 [(set (match_operand:XF 0 "register_operand" "=f,f")
15856 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
15857 [(reg FLAGS_REG) (const_int 0)])
15858 (match_operand:XF 2 "register_operand" "f,0")
15859 (match_operand:XF 3 "register_operand" "0,f")))]
15860 "TARGET_80387 && TARGET_CMOVE"
15862 fcmov%F1\t{%2, %0|%0, %2}
15863 fcmov%f1\t{%3, %0|%0, %3}"
15864 [(set_attr "type" "fcmov")
15865 (set_attr "mode" "XF")])
15867 (define_insn "*movdfcc_1"
15868 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r,r ,r")
15869 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
15870 [(reg FLAGS_REG) (const_int 0)])
15871 (match_operand:DF 2 "nonimmediate_operand"
15873 (match_operand:DF 3 "nonimmediate_operand"
15874 "0 ,f,0 ,rm,0, rm")))]
15875 "TARGET_80387 && TARGET_CMOVE
15876 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
15878 fcmov%F1\t{%2, %0|%0, %2}
15879 fcmov%f1\t{%3, %0|%0, %3}
15882 cmov%O2%C1\t{%2, %0|%0, %2}
15883 cmov%O2%c1\t{%3, %0|%0, %3}"
15884 [(set_attr "isa" "*,*,nox64,nox64,x64,x64")
15885 (set_attr "type" "fcmov,fcmov,multi,multi,icmov,icmov")
15886 (set_attr "mode" "DF,DF,DI,DI,DI,DI")])
15889 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
15890 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
15891 [(reg FLAGS_REG) (const_int 0)])
15892 (match_operand:DF 2 "nonimmediate_operand")
15893 (match_operand:DF 3 "nonimmediate_operand")))]
15894 "!TARGET_64BIT && reload_completed"
15895 [(set (match_dup 2)
15896 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
15898 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
15900 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
15901 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
15904 (define_insn "*movsfcc_1_387"
15905 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
15906 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
15907 [(reg FLAGS_REG) (const_int 0)])
15908 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
15909 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
15910 "TARGET_80387 && TARGET_CMOVE
15911 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
15913 fcmov%F1\t{%2, %0|%0, %2}
15914 fcmov%f1\t{%3, %0|%0, %3}
15915 cmov%O2%C1\t{%2, %0|%0, %2}
15916 cmov%O2%c1\t{%3, %0|%0, %3}"
15917 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
15918 (set_attr "mode" "SF,SF,SI,SI")])
15920 ;; Don't do conditional moves with memory inputs. This splitter helps
15921 ;; register starved x86_32 by forcing inputs into registers before reload.
15923 [(set (match_operand:MODEF 0 "register_operand")
15924 (if_then_else:MODEF (match_operator 1 "ix86_comparison_operator"
15925 [(reg FLAGS_REG) (const_int 0)])
15926 (match_operand:MODEF 2 "nonimmediate_operand")
15927 (match_operand:MODEF 3 "nonimmediate_operand")))]
15928 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
15929 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
15930 && (MEM_P (operands[2]) || MEM_P (operands[3]))
15931 && can_create_pseudo_p ()
15932 && optimize_insn_for_speed_p ()"
15933 [(set (match_dup 0)
15934 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 3)))]
15936 if (MEM_P (operands[2]))
15937 operands[2] = force_reg (<MODE>mode, operands[2]);
15938 if (MEM_P (operands[3]))
15939 operands[3] = force_reg (<MODE>mode, operands[3]);
15942 ;; Don't do conditional moves with memory inputs
15944 [(match_scratch:MODEF 2 "r")
15945 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
15946 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
15947 [(reg FLAGS_REG) (const_int 0)])
15949 (match_operand:MODEF 3 "memory_operand")))]
15950 "(<MODE>mode != DFmode || TARGET_64BIT)
15951 && TARGET_80387 && TARGET_CMOVE
15952 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
15953 && optimize_insn_for_speed_p ()"
15954 [(set (match_dup 2) (match_dup 3))
15956 (if_then_else:MODEF (match_dup 1) (match_dup 0) (match_dup 2)))])
15959 [(match_scratch:MODEF 2 "r")
15960 (set (match_operand:MODEF 0 "register_and_not_any_fp_reg_operand")
15961 (if_then_else:MODEF (match_operator 1 "fcmov_comparison_operator"
15962 [(reg FLAGS_REG) (const_int 0)])
15963 (match_operand:MODEF 3 "memory_operand")
15965 "(<MODE>mode != DFmode || TARGET_64BIT)
15966 && TARGET_80387 && TARGET_CMOVE
15967 && TARGET_AVOID_MEM_OPND_FOR_CMOVE
15968 && optimize_insn_for_speed_p ()"
15969 [(set (match_dup 2) (match_dup 3))
15971 (if_then_else:MODEF (match_dup 1) (match_dup 2) (match_dup 0)))])
15973 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
15974 ;; the scalar versions to have only XMM registers as operands.
15976 ;; XOP conditional move
15977 (define_insn "*xop_pcmov_<mode>"
15978 [(set (match_operand:MODEF 0 "register_operand" "=x")
15979 (if_then_else:MODEF
15980 (match_operand:MODEF 1 "register_operand" "x")
15981 (match_operand:MODEF 2 "register_operand" "x")
15982 (match_operand:MODEF 3 "register_operand" "x")))]
15984 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
15985 [(set_attr "type" "sse4arg")])
15987 ;; These versions of the min/max patterns are intentionally ignorant of
15988 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
15989 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
15990 ;; are undefined in this condition, we're certain this is correct.
15992 (define_insn "<code><mode>3"
15993 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
15995 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
15996 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
15997 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15999 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16000 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16001 [(set_attr "isa" "noavx,avx")
16002 (set_attr "prefix" "orig,vex")
16003 (set_attr "type" "sseadd")
16004 (set_attr "mode" "<MODE>")])
16006 ;; These versions of the min/max patterns implement exactly the operations
16007 ;; min = (op1 < op2 ? op1 : op2)
16008 ;; max = (!(op1 < op2) ? op1 : op2)
16009 ;; Their operands are not commutative, and thus they may be used in the
16010 ;; presence of -0.0 and NaN.
16012 (define_int_iterator IEEE_MAXMIN
16016 (define_int_attr ieee_maxmin
16017 [(UNSPEC_IEEE_MAX "max")
16018 (UNSPEC_IEEE_MIN "min")])
16020 (define_insn "*ieee_s<ieee_maxmin><mode>3"
16021 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16023 [(match_operand:MODEF 1 "register_operand" "0,x")
16024 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16026 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16028 <ieee_maxmin><ssemodesuffix>\t{%2, %0|%0, %2}
16029 v<ieee_maxmin><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16030 [(set_attr "isa" "noavx,avx")
16031 (set_attr "prefix" "orig,vex")
16032 (set_attr "type" "sseadd")
16033 (set_attr "mode" "<MODE>")])
16035 ;; Make two stack loads independent:
16037 ;; fld %st(0) -> fld bb
16038 ;; fmul bb fmul %st(1), %st
16040 ;; Actually we only match the last two instructions for simplicity.
16042 [(set (match_operand 0 "fp_register_operand")
16043 (match_operand 1 "fp_register_operand"))
16045 (match_operator 2 "binary_fp_operator"
16047 (match_operand 3 "memory_operand")]))]
16048 "REGNO (operands[0]) != REGNO (operands[1])"
16049 [(set (match_dup 0) (match_dup 3))
16050 (set (match_dup 0) (match_dup 4))]
16052 ;; The % modifier is not operational anymore in peephole2's, so we have to
16053 ;; swap the operands manually in the case of addition and multiplication.
16057 if (COMMUTATIVE_ARITH_P (operands[2]))
16058 op0 = operands[0], op1 = operands[1];
16060 op0 = operands[1], op1 = operands[0];
16062 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16063 GET_MODE (operands[2]),
16067 ;; Conditional addition patterns
16068 (define_expand "add<mode>cc"
16069 [(match_operand:SWI 0 "register_operand")
16070 (match_operand 1 "ordered_comparison_operator")
16071 (match_operand:SWI 2 "register_operand")
16072 (match_operand:SWI 3 "const_int_operand")]
16074 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16076 ;; Misc patterns (?)
16078 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16079 ;; Otherwise there will be nothing to keep
16081 ;; [(set (reg ebp) (reg esp))]
16082 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16083 ;; (clobber (eflags)]
16084 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16086 ;; in proper program order.
16088 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16089 [(set (match_operand:P 0 "register_operand" "=r,r")
16090 (plus:P (match_operand:P 1 "register_operand" "0,r")
16091 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16092 (clobber (reg:CC FLAGS_REG))
16093 (clobber (mem:BLK (scratch)))]
16096 switch (get_attr_type (insn))
16099 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16102 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16103 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16104 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16106 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16109 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16110 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16113 [(set (attr "type")
16114 (cond [(and (eq_attr "alternative" "0")
16115 (not (match_test "TARGET_OPT_AGU")))
16116 (const_string "alu")
16117 (match_operand:<MODE> 2 "const0_operand")
16118 (const_string "imov")
16120 (const_string "lea")))
16121 (set (attr "length_immediate")
16122 (cond [(eq_attr "type" "imov")
16124 (and (eq_attr "type" "alu")
16125 (match_operand 2 "const128_operand"))
16128 (const_string "*")))
16129 (set_attr "mode" "<MODE>")])
16131 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16132 [(set (match_operand:P 0 "register_operand" "=r")
16133 (minus:P (match_operand:P 1 "register_operand" "0")
16134 (match_operand:P 2 "register_operand" "r")))
16135 (clobber (reg:CC FLAGS_REG))
16136 (clobber (mem:BLK (scratch)))]
16138 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16139 [(set_attr "type" "alu")
16140 (set_attr "mode" "<MODE>")])
16142 (define_insn "allocate_stack_worker_probe_<mode>"
16143 [(set (match_operand:P 0 "register_operand" "=a")
16144 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16145 UNSPECV_STACK_PROBE))
16146 (clobber (reg:CC FLAGS_REG))]
16147 "ix86_target_stack_probe ()"
16148 "call\t___chkstk_ms"
16149 [(set_attr "type" "multi")
16150 (set_attr "length" "5")])
16152 (define_expand "allocate_stack"
16153 [(match_operand 0 "register_operand")
16154 (match_operand 1 "general_operand")]
16155 "ix86_target_stack_probe ()"
16159 #ifndef CHECK_STACK_LIMIT
16160 #define CHECK_STACK_LIMIT 0
16163 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16164 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16168 rtx (*insn) (rtx, rtx);
16170 x = copy_to_mode_reg (Pmode, operands[1]);
16172 insn = (TARGET_64BIT
16173 ? gen_allocate_stack_worker_probe_di
16174 : gen_allocate_stack_worker_probe_si);
16176 emit_insn (insn (x, x));
16179 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16180 stack_pointer_rtx, 0, OPTAB_DIRECT);
16182 if (x != stack_pointer_rtx)
16183 emit_move_insn (stack_pointer_rtx, x);
16185 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16189 ;; Use IOR for stack probes, this is shorter.
16190 (define_expand "probe_stack"
16191 [(match_operand 0 "memory_operand")]
16194 rtx (*gen_ior3) (rtx, rtx, rtx);
16196 gen_ior3 = (GET_MODE (operands[0]) == DImode
16197 ? gen_iordi3 : gen_iorsi3);
16199 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16203 (define_insn "adjust_stack_and_probe<mode>"
16204 [(set (match_operand:P 0 "register_operand" "=r")
16205 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16206 UNSPECV_PROBE_STACK_RANGE))
16207 (set (reg:P SP_REG)
16208 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16209 (clobber (reg:CC FLAGS_REG))
16210 (clobber (mem:BLK (scratch)))]
16212 "* return output_adjust_stack_and_probe (operands[0]);"
16213 [(set_attr "type" "multi")])
16215 (define_insn "probe_stack_range<mode>"
16216 [(set (match_operand:P 0 "register_operand" "=r")
16217 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16218 (match_operand:P 2 "const_int_operand" "n")]
16219 UNSPECV_PROBE_STACK_RANGE))
16220 (clobber (reg:CC FLAGS_REG))]
16222 "* return output_probe_stack_range (operands[0], operands[2]);"
16223 [(set_attr "type" "multi")])
16225 (define_expand "builtin_setjmp_receiver"
16226 [(label_ref (match_operand 0))]
16227 "!TARGET_64BIT && flag_pic"
16233 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16234 rtx label_rtx = gen_label_rtx ();
16235 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16236 xops[0] = xops[1] = picreg;
16237 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16238 ix86_expand_binary_operator (MINUS, SImode, xops);
16242 emit_insn (gen_set_got (pic_offset_table_rtx));
16246 (define_insn_and_split "nonlocal_goto_receiver"
16247 [(unspec_volatile [(const_int 0)] UNSPECV_NLGR)]
16248 "TARGET_MACHO && !TARGET_64BIT && flag_pic"
16250 "&& reload_completed"
16253 if (crtl->uses_pic_offset_table)
16256 rtx label_rtx = gen_label_rtx ();
16259 /* Get a new pic base. */
16260 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16261 /* Correct this with the offset from the new to the old. */
16262 xops[0] = xops[1] = pic_offset_table_rtx;
16263 label_rtx = gen_rtx_LABEL_REF (SImode, label_rtx);
16264 tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, label_rtx),
16265 UNSPEC_MACHOPIC_OFFSET);
16266 xops[2] = gen_rtx_CONST (Pmode, tmp);
16267 ix86_expand_binary_operator (MINUS, SImode, xops);
16270 /* No pic reg restore needed. */
16271 emit_note (NOTE_INSN_DELETED);
16276 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16279 [(set (match_operand 0 "register_operand")
16280 (match_operator 3 "promotable_binary_operator"
16281 [(match_operand 1 "register_operand")
16282 (match_operand 2 "aligned_operand")]))
16283 (clobber (reg:CC FLAGS_REG))]
16284 "! TARGET_PARTIAL_REG_STALL && reload_completed
16285 && ((GET_MODE (operands[0]) == HImode
16286 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16287 /* ??? next two lines just !satisfies_constraint_K (...) */
16288 || !CONST_INT_P (operands[2])
16289 || satisfies_constraint_K (operands[2])))
16290 || (GET_MODE (operands[0]) == QImode
16291 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16292 [(parallel [(set (match_dup 0)
16293 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16294 (clobber (reg:CC FLAGS_REG))])]
16296 operands[0] = gen_lowpart (SImode, operands[0]);
16297 operands[1] = gen_lowpart (SImode, operands[1]);
16298 if (GET_CODE (operands[3]) != ASHIFT)
16299 operands[2] = gen_lowpart (SImode, operands[2]);
16300 PUT_MODE (operands[3], SImode);
16303 ; Promote the QImode tests, as i386 has encoding of the AND
16304 ; instruction with 32-bit sign-extended immediate and thus the
16305 ; instruction size is unchanged, except in the %eax case for
16306 ; which it is increased by one byte, hence the ! optimize_size.
16308 [(set (match_operand 0 "flags_reg_operand")
16309 (match_operator 2 "compare_operator"
16310 [(and (match_operand 3 "aligned_operand")
16311 (match_operand 4 "const_int_operand"))
16313 (set (match_operand 1 "register_operand")
16314 (and (match_dup 3) (match_dup 4)))]
16315 "! TARGET_PARTIAL_REG_STALL && reload_completed
16316 && optimize_insn_for_speed_p ()
16317 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16318 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16319 /* Ensure that the operand will remain sign-extended immediate. */
16320 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16321 [(parallel [(set (match_dup 0)
16322 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16325 (and:SI (match_dup 3) (match_dup 4)))])]
16328 = gen_int_mode (INTVAL (operands[4])
16329 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16330 operands[1] = gen_lowpart (SImode, operands[1]);
16331 operands[3] = gen_lowpart (SImode, operands[3]);
16334 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16335 ; the TEST instruction with 32-bit sign-extended immediate and thus
16336 ; the instruction size would at least double, which is not what we
16337 ; want even with ! optimize_size.
16339 [(set (match_operand 0 "flags_reg_operand")
16340 (match_operator 1 "compare_operator"
16341 [(and (match_operand:HI 2 "aligned_operand")
16342 (match_operand:HI 3 "const_int_operand"))
16344 "! TARGET_PARTIAL_REG_STALL && reload_completed
16345 && ! TARGET_FAST_PREFIX
16346 && optimize_insn_for_speed_p ()
16347 /* Ensure that the operand will remain sign-extended immediate. */
16348 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16349 [(set (match_dup 0)
16350 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16354 = gen_int_mode (INTVAL (operands[3])
16355 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16356 operands[2] = gen_lowpart (SImode, operands[2]);
16360 [(set (match_operand 0 "register_operand")
16361 (neg (match_operand 1 "register_operand")))
16362 (clobber (reg:CC FLAGS_REG))]
16363 "! TARGET_PARTIAL_REG_STALL && reload_completed
16364 && (GET_MODE (operands[0]) == HImode
16365 || (GET_MODE (operands[0]) == QImode
16366 && (TARGET_PROMOTE_QImode
16367 || optimize_insn_for_size_p ())))"
16368 [(parallel [(set (match_dup 0)
16369 (neg:SI (match_dup 1)))
16370 (clobber (reg:CC FLAGS_REG))])]
16372 operands[0] = gen_lowpart (SImode, operands[0]);
16373 operands[1] = gen_lowpart (SImode, operands[1]);
16377 [(set (match_operand 0 "register_operand")
16378 (not (match_operand 1 "register_operand")))]
16379 "! TARGET_PARTIAL_REG_STALL && reload_completed
16380 && (GET_MODE (operands[0]) == HImode
16381 || (GET_MODE (operands[0]) == QImode
16382 && (TARGET_PROMOTE_QImode
16383 || optimize_insn_for_size_p ())))"
16384 [(set (match_dup 0)
16385 (not:SI (match_dup 1)))]
16387 operands[0] = gen_lowpart (SImode, operands[0]);
16388 operands[1] = gen_lowpart (SImode, operands[1]);
16391 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16392 ;; transform a complex memory operation into two memory to register operations.
16394 ;; Don't push memory operands
16396 [(set (match_operand:SWI 0 "push_operand")
16397 (match_operand:SWI 1 "memory_operand"))
16398 (match_scratch:SWI 2 "<r>")]
16399 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16400 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16401 [(set (match_dup 2) (match_dup 1))
16402 (set (match_dup 0) (match_dup 2))])
16404 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16407 [(set (match_operand:SF 0 "push_operand")
16408 (match_operand:SF 1 "memory_operand"))
16409 (match_scratch:SF 2 "r")]
16410 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16411 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16412 [(set (match_dup 2) (match_dup 1))
16413 (set (match_dup 0) (match_dup 2))])
16415 ;; Don't move an immediate directly to memory when the instruction
16416 ;; gets too big, or if LCP stalls are a problem for 16-bit moves.
16418 [(match_scratch:SWI124 1 "<r>")
16419 (set (match_operand:SWI124 0 "memory_operand")
16421 "optimize_insn_for_speed_p ()
16422 && ((<MODE>mode == HImode
16423 && TARGET_LCP_STALL)
16424 || (!TARGET_USE_MOV0
16425 && TARGET_SPLIT_LONG_MOVES
16426 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))
16427 && peep2_regno_dead_p (0, FLAGS_REG)"
16428 [(parallel [(set (match_dup 2) (const_int 0))
16429 (clobber (reg:CC FLAGS_REG))])
16430 (set (match_dup 0) (match_dup 1))]
16431 "operands[2] = gen_lowpart (SImode, operands[1]);")
16434 [(match_scratch:SWI124 2 "<r>")
16435 (set (match_operand:SWI124 0 "memory_operand")
16436 (match_operand:SWI124 1 "immediate_operand"))]
16437 "optimize_insn_for_speed_p ()
16438 && ((<MODE>mode == HImode
16439 && TARGET_LCP_STALL)
16440 || (TARGET_SPLIT_LONG_MOVES
16441 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn))"
16442 [(set (match_dup 2) (match_dup 1))
16443 (set (match_dup 0) (match_dup 2))])
16445 ;; Don't compare memory with zero, load and use a test instead.
16447 [(set (match_operand 0 "flags_reg_operand")
16448 (match_operator 1 "compare_operator"
16449 [(match_operand:SI 2 "memory_operand")
16451 (match_scratch:SI 3 "r")]
16452 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16453 [(set (match_dup 3) (match_dup 2))
16454 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16456 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16457 ;; Don't split NOTs with a displacement operand, because resulting XOR
16458 ;; will not be pairable anyway.
16460 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16461 ;; represented using a modRM byte. The XOR replacement is long decoded,
16462 ;; so this split helps here as well.
16464 ;; Note: Can't do this as a regular split because we can't get proper
16465 ;; lifetime information then.
16468 [(set (match_operand:SWI124 0 "nonimmediate_operand")
16469 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
16470 "optimize_insn_for_speed_p ()
16471 && ((TARGET_NOT_UNPAIRABLE
16472 && (!MEM_P (operands[0])
16473 || !memory_displacement_operand (operands[0], <MODE>mode)))
16474 || (TARGET_NOT_VECTORMODE
16475 && long_memory_operand (operands[0], <MODE>mode)))
16476 && peep2_regno_dead_p (0, FLAGS_REG)"
16477 [(parallel [(set (match_dup 0)
16478 (xor:SWI124 (match_dup 1) (const_int -1)))
16479 (clobber (reg:CC FLAGS_REG))])])
16481 ;; Non pairable "test imm, reg" instructions can be translated to
16482 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16483 ;; byte opcode instead of two, have a short form for byte operands),
16484 ;; so do it for other CPUs as well. Given that the value was dead,
16485 ;; this should not create any new dependencies. Pass on the sub-word
16486 ;; versions if we're concerned about partial register stalls.
16489 [(set (match_operand 0 "flags_reg_operand")
16490 (match_operator 1 "compare_operator"
16491 [(and:SI (match_operand:SI 2 "register_operand")
16492 (match_operand:SI 3 "immediate_operand"))
16494 "ix86_match_ccmode (insn, CCNOmode)
16495 && (true_regnum (operands[2]) != AX_REG
16496 || satisfies_constraint_K (operands[3]))
16497 && peep2_reg_dead_p (1, operands[2])"
16499 [(set (match_dup 0)
16500 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16503 (and:SI (match_dup 2) (match_dup 3)))])])
16505 ;; We don't need to handle HImode case, because it will be promoted to SImode
16506 ;; on ! TARGET_PARTIAL_REG_STALL
16509 [(set (match_operand 0 "flags_reg_operand")
16510 (match_operator 1 "compare_operator"
16511 [(and:QI (match_operand:QI 2 "register_operand")
16512 (match_operand:QI 3 "immediate_operand"))
16514 "! TARGET_PARTIAL_REG_STALL
16515 && ix86_match_ccmode (insn, CCNOmode)
16516 && true_regnum (operands[2]) != AX_REG
16517 && peep2_reg_dead_p (1, operands[2])"
16519 [(set (match_dup 0)
16520 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
16523 (and:QI (match_dup 2) (match_dup 3)))])])
16526 [(set (match_operand 0 "flags_reg_operand")
16527 (match_operator 1 "compare_operator"
16530 (match_operand 2 "ext_register_operand")
16533 (match_operand 3 "const_int_operand"))
16535 "! TARGET_PARTIAL_REG_STALL
16536 && ix86_match_ccmode (insn, CCNOmode)
16537 && true_regnum (operands[2]) != AX_REG
16538 && peep2_reg_dead_p (1, operands[2])"
16539 [(parallel [(set (match_dup 0)
16548 (set (zero_extract:SI (match_dup 2)
16556 (match_dup 3)))])])
16558 ;; Don't do logical operations with memory inputs.
16560 [(match_scratch:SI 2 "r")
16561 (parallel [(set (match_operand:SI 0 "register_operand")
16562 (match_operator:SI 3 "arith_or_logical_operator"
16564 (match_operand:SI 1 "memory_operand")]))
16565 (clobber (reg:CC FLAGS_REG))])]
16566 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
16567 [(set (match_dup 2) (match_dup 1))
16568 (parallel [(set (match_dup 0)
16569 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
16570 (clobber (reg:CC FLAGS_REG))])])
16573 [(match_scratch:SI 2 "r")
16574 (parallel [(set (match_operand:SI 0 "register_operand")
16575 (match_operator:SI 3 "arith_or_logical_operator"
16576 [(match_operand:SI 1 "memory_operand")
16578 (clobber (reg:CC FLAGS_REG))])]
16579 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
16580 [(set (match_dup 2) (match_dup 1))
16581 (parallel [(set (match_dup 0)
16582 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
16583 (clobber (reg:CC FLAGS_REG))])])
16585 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
16586 ;; refers to the destination of the load!
16589 [(set (match_operand:SI 0 "register_operand")
16590 (match_operand:SI 1 "register_operand"))
16591 (parallel [(set (match_dup 0)
16592 (match_operator:SI 3 "commutative_operator"
16594 (match_operand:SI 2 "memory_operand")]))
16595 (clobber (reg:CC FLAGS_REG))])]
16596 "REGNO (operands[0]) != REGNO (operands[1])
16597 && GENERAL_REGNO_P (REGNO (operands[0]))
16598 && GENERAL_REGNO_P (REGNO (operands[1]))"
16599 [(set (match_dup 0) (match_dup 4))
16600 (parallel [(set (match_dup 0)
16601 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
16602 (clobber (reg:CC FLAGS_REG))])]
16603 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
16606 [(set (match_operand 0 "register_operand")
16607 (match_operand 1 "register_operand"))
16609 (match_operator 3 "commutative_operator"
16611 (match_operand 2 "memory_operand")]))]
16612 "REGNO (operands[0]) != REGNO (operands[1])
16613 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
16614 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
16615 [(set (match_dup 0) (match_dup 2))
16617 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
16619 ; Don't do logical operations with memory outputs
16621 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
16622 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
16623 ; the same decoder scheduling characteristics as the original.
16626 [(match_scratch:SI 2 "r")
16627 (parallel [(set (match_operand:SI 0 "memory_operand")
16628 (match_operator:SI 3 "arith_or_logical_operator"
16630 (match_operand:SI 1 "nonmemory_operand")]))
16631 (clobber (reg:CC FLAGS_REG))])]
16632 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16633 /* Do not split stack checking probes. */
16634 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16635 [(set (match_dup 2) (match_dup 0))
16636 (parallel [(set (match_dup 2)
16637 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
16638 (clobber (reg:CC FLAGS_REG))])
16639 (set (match_dup 0) (match_dup 2))])
16642 [(match_scratch:SI 2 "r")
16643 (parallel [(set (match_operand:SI 0 "memory_operand")
16644 (match_operator:SI 3 "arith_or_logical_operator"
16645 [(match_operand:SI 1 "nonmemory_operand")
16647 (clobber (reg:CC FLAGS_REG))])]
16648 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16649 /* Do not split stack checking probes. */
16650 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
16651 [(set (match_dup 2) (match_dup 0))
16652 (parallel [(set (match_dup 2)
16653 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16654 (clobber (reg:CC FLAGS_REG))])
16655 (set (match_dup 0) (match_dup 2))])
16657 ;; Attempt to use arith or logical operations with memory outputs with
16658 ;; setting of flags.
16660 [(set (match_operand:SWI 0 "register_operand")
16661 (match_operand:SWI 1 "memory_operand"))
16662 (parallel [(set (match_dup 0)
16663 (match_operator:SWI 3 "plusminuslogic_operator"
16665 (match_operand:SWI 2 "<nonmemory_operand>")]))
16666 (clobber (reg:CC FLAGS_REG))])
16667 (set (match_dup 1) (match_dup 0))
16668 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16669 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16670 && peep2_reg_dead_p (4, operands[0])
16671 && !reg_overlap_mentioned_p (operands[0], operands[1])
16672 && !reg_overlap_mentioned_p (operands[0], operands[2])
16673 && (<MODE>mode != QImode
16674 || immediate_operand (operands[2], QImode)
16675 || q_regs_operand (operands[2], QImode))
16676 && ix86_match_ccmode (peep2_next_insn (3),
16677 (GET_CODE (operands[3]) == PLUS
16678 || GET_CODE (operands[3]) == MINUS)
16679 ? CCGOCmode : CCNOmode)"
16680 [(parallel [(set (match_dup 4) (match_dup 5))
16681 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
16682 (match_dup 2)]))])]
16684 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
16685 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16686 copy_rtx (operands[1]),
16687 copy_rtx (operands[2]));
16688 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
16689 operands[5], const0_rtx);
16693 [(parallel [(set (match_operand:SWI 0 "register_operand")
16694 (match_operator:SWI 2 "plusminuslogic_operator"
16696 (match_operand:SWI 1 "memory_operand")]))
16697 (clobber (reg:CC FLAGS_REG))])
16698 (set (match_dup 1) (match_dup 0))
16699 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16700 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16701 && GET_CODE (operands[2]) != MINUS
16702 && peep2_reg_dead_p (3, operands[0])
16703 && !reg_overlap_mentioned_p (operands[0], operands[1])
16704 && ix86_match_ccmode (peep2_next_insn (2),
16705 GET_CODE (operands[2]) == PLUS
16706 ? CCGOCmode : CCNOmode)"
16707 [(parallel [(set (match_dup 3) (match_dup 4))
16708 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
16709 (match_dup 0)]))])]
16711 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
16712 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
16713 copy_rtx (operands[1]),
16714 copy_rtx (operands[0]));
16715 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
16716 operands[4], const0_rtx);
16720 [(set (match_operand:SWI12 0 "register_operand")
16721 (match_operand:SWI12 1 "memory_operand"))
16722 (parallel [(set (match_operand:SI 4 "register_operand")
16723 (match_operator:SI 3 "plusminuslogic_operator"
16725 (match_operand:SI 2 "nonmemory_operand")]))
16726 (clobber (reg:CC FLAGS_REG))])
16727 (set (match_dup 1) (match_dup 0))
16728 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
16729 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
16730 && REG_P (operands[0]) && REG_P (operands[4])
16731 && REGNO (operands[0]) == REGNO (operands[4])
16732 && peep2_reg_dead_p (4, operands[0])
16733 && (<MODE>mode != QImode
16734 || immediate_operand (operands[2], SImode)
16735 || q_regs_operand (operands[2], SImode))
16736 && !reg_overlap_mentioned_p (operands[0], operands[1])
16737 && !reg_overlap_mentioned_p (operands[0], operands[2])
16738 && ix86_match_ccmode (peep2_next_insn (3),
16739 (GET_CODE (operands[3]) == PLUS
16740 || GET_CODE (operands[3]) == MINUS)
16741 ? CCGOCmode : CCNOmode)"
16742 [(parallel [(set (match_dup 4) (match_dup 5))
16743 (set (match_dup 1) (match_dup 6))])]
16745 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
16746 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
16747 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16748 copy_rtx (operands[1]), operands[2]);
16749 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
16750 operands[5], const0_rtx);
16751 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
16752 copy_rtx (operands[1]),
16753 copy_rtx (operands[2]));
16756 ;; Attempt to always use XOR for zeroing registers.
16758 [(set (match_operand 0 "register_operand")
16759 (match_operand 1 "const0_operand"))]
16760 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
16761 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16762 && GENERAL_REG_P (operands[0])
16763 && peep2_regno_dead_p (0, FLAGS_REG)"
16764 [(parallel [(set (match_dup 0) (const_int 0))
16765 (clobber (reg:CC FLAGS_REG))])]
16766 "operands[0] = gen_lowpart (word_mode, operands[0]);")
16769 [(set (strict_low_part (match_operand 0 "register_operand"))
16771 "(GET_MODE (operands[0]) == QImode
16772 || GET_MODE (operands[0]) == HImode)
16773 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
16774 && peep2_regno_dead_p (0, FLAGS_REG)"
16775 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
16776 (clobber (reg:CC FLAGS_REG))])])
16778 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
16780 [(set (match_operand:SWI248 0 "register_operand")
16782 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
16783 && peep2_regno_dead_p (0, FLAGS_REG)"
16784 [(parallel [(set (match_dup 0) (const_int -1))
16785 (clobber (reg:CC FLAGS_REG))])]
16787 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
16788 operands[0] = gen_lowpart (SImode, operands[0]);
16791 ;; Attempt to convert simple lea to add/shift.
16792 ;; These can be created by move expanders.
16793 ;; Disable PLUS peepholes on TARGET_OPT_AGU, since all
16794 ;; relevant lea instructions were already split.
16797 [(set (match_operand:SWI48 0 "register_operand")
16798 (plus:SWI48 (match_dup 0)
16799 (match_operand:SWI48 1 "<nonmemory_operand>")))]
16801 && peep2_regno_dead_p (0, FLAGS_REG)"
16802 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
16803 (clobber (reg:CC FLAGS_REG))])])
16806 [(set (match_operand:SWI48 0 "register_operand")
16807 (plus:SWI48 (match_operand:SWI48 1 "<nonmemory_operand>")
16810 && peep2_regno_dead_p (0, FLAGS_REG)"
16811 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
16812 (clobber (reg:CC FLAGS_REG))])])
16815 [(set (match_operand:DI 0 "register_operand")
16817 (plus:SI (match_operand:SI 1 "register_operand")
16818 (match_operand:SI 2 "nonmemory_operand"))))]
16819 "TARGET_64BIT && !TARGET_OPT_AGU
16820 && REGNO (operands[0]) == REGNO (operands[1])
16821 && peep2_regno_dead_p (0, FLAGS_REG)"
16822 [(parallel [(set (match_dup 0)
16823 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))
16824 (clobber (reg:CC FLAGS_REG))])])
16827 [(set (match_operand:DI 0 "register_operand")
16829 (plus:SI (match_operand:SI 1 "nonmemory_operand")
16830 (match_operand:SI 2 "register_operand"))))]
16831 "TARGET_64BIT && !TARGET_OPT_AGU
16832 && REGNO (operands[0]) == REGNO (operands[2])
16833 && peep2_regno_dead_p (0, FLAGS_REG)"
16834 [(parallel [(set (match_dup 0)
16835 (zero_extend:DI (plus:SI (match_dup 2) (match_dup 1))))
16836 (clobber (reg:CC FLAGS_REG))])])
16839 [(set (match_operand:SWI48 0 "register_operand")
16840 (mult:SWI48 (match_dup 0)
16841 (match_operand:SWI48 1 "const_int_operand")))]
16842 "exact_log2 (INTVAL (operands[1])) >= 0
16843 && peep2_regno_dead_p (0, FLAGS_REG)"
16844 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 1)))
16845 (clobber (reg:CC FLAGS_REG))])]
16846 "operands[1] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
16849 [(set (match_operand:DI 0 "register_operand")
16851 (mult:SI (match_operand:SI 1 "register_operand")
16852 (match_operand:SI 2 "const_int_operand"))))]
16854 && exact_log2 (INTVAL (operands[2])) >= 0
16855 && REGNO (operands[0]) == REGNO (operands[1])
16856 && peep2_regno_dead_p (0, FLAGS_REG)"
16857 [(parallel [(set (match_dup 0)
16858 (zero_extend (ashift:SI (match_dup 1) (match_dup 2))))
16859 (clobber (reg:CC FLAGS_REG))])]
16860 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
16862 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
16863 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
16864 ;; On many CPUs it is also faster, since special hardware to avoid esp
16865 ;; dependencies is present.
16867 ;; While some of these conversions may be done using splitters, we use
16868 ;; peepholes in order to allow combine_stack_adjustments pass to see
16869 ;; nonobfuscated RTL.
16871 ;; Convert prologue esp subtractions to push.
16872 ;; We need register to push. In order to keep verify_flow_info happy we have
16874 ;; - use scratch and clobber it in order to avoid dependencies
16875 ;; - use already live register
16876 ;; We can't use the second way right now, since there is no reliable way how to
16877 ;; verify that given register is live. First choice will also most likely in
16878 ;; fewer dependencies. On the place of esp adjustments it is very likely that
16879 ;; call clobbered registers are dead. We may want to use base pointer as an
16880 ;; alternative when no register is available later.
16883 [(match_scratch:W 1 "r")
16884 (parallel [(set (reg:P SP_REG)
16885 (plus:P (reg:P SP_REG)
16886 (match_operand:P 0 "const_int_operand")))
16887 (clobber (reg:CC FLAGS_REG))
16888 (clobber (mem:BLK (scratch)))])]
16889 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16890 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
16891 [(clobber (match_dup 1))
16892 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16893 (clobber (mem:BLK (scratch)))])])
16896 [(match_scratch:W 1 "r")
16897 (parallel [(set (reg:P SP_REG)
16898 (plus:P (reg:P SP_REG)
16899 (match_operand:P 0 "const_int_operand")))
16900 (clobber (reg:CC FLAGS_REG))
16901 (clobber (mem:BLK (scratch)))])]
16902 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16903 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
16904 [(clobber (match_dup 1))
16905 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16906 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16907 (clobber (mem:BLK (scratch)))])])
16909 ;; Convert esp subtractions to push.
16911 [(match_scratch:W 1 "r")
16912 (parallel [(set (reg:P SP_REG)
16913 (plus:P (reg:P SP_REG)
16914 (match_operand:P 0 "const_int_operand")))
16915 (clobber (reg:CC FLAGS_REG))])]
16916 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
16917 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
16918 [(clobber (match_dup 1))
16919 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
16922 [(match_scratch:W 1 "r")
16923 (parallel [(set (reg:P SP_REG)
16924 (plus:P (reg:P SP_REG)
16925 (match_operand:P 0 "const_int_operand")))
16926 (clobber (reg:CC FLAGS_REG))])]
16927 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
16928 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
16929 [(clobber (match_dup 1))
16930 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
16931 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
16933 ;; Convert epilogue deallocator to pop.
16935 [(match_scratch:W 1 "r")
16936 (parallel [(set (reg:P SP_REG)
16937 (plus:P (reg:P SP_REG)
16938 (match_operand:P 0 "const_int_operand")))
16939 (clobber (reg:CC FLAGS_REG))
16940 (clobber (mem:BLK (scratch)))])]
16941 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
16942 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
16943 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
16944 (clobber (mem:BLK (scratch)))])])
16946 ;; Two pops case is tricky, since pop causes dependency
16947 ;; on destination register. We use two registers if available.
16949 [(match_scratch:W 1 "r")
16950 (match_scratch:W 2 "r")
16951 (parallel [(set (reg:P SP_REG)
16952 (plus:P (reg:P SP_REG)
16953 (match_operand:P 0 "const_int_operand")))
16954 (clobber (reg:CC FLAGS_REG))
16955 (clobber (mem:BLK (scratch)))])]
16956 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
16957 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
16958 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
16959 (clobber (mem:BLK (scratch)))])
16960 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
16963 [(match_scratch:W 1 "r")
16964 (parallel [(set (reg:P SP_REG)
16965 (plus:P (reg:P SP_REG)
16966 (match_operand:P 0 "const_int_operand")))
16967 (clobber (reg:CC FLAGS_REG))
16968 (clobber (mem:BLK (scratch)))])]
16969 "optimize_insn_for_size_p ()
16970 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
16971 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
16972 (clobber (mem:BLK (scratch)))])
16973 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
16975 ;; Convert esp additions to pop.
16977 [(match_scratch:W 1 "r")
16978 (parallel [(set (reg:P SP_REG)
16979 (plus:P (reg:P SP_REG)
16980 (match_operand:P 0 "const_int_operand")))
16981 (clobber (reg:CC FLAGS_REG))])]
16982 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
16983 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
16985 ;; Two pops case is tricky, since pop causes dependency
16986 ;; on destination register. We use two registers if available.
16988 [(match_scratch:W 1 "r")
16989 (match_scratch:W 2 "r")
16990 (parallel [(set (reg:P SP_REG)
16991 (plus:P (reg:P SP_REG)
16992 (match_operand:P 0 "const_int_operand")))
16993 (clobber (reg:CC FLAGS_REG))])]
16994 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
16995 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
16996 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
16999 [(match_scratch:W 1 "r")
17000 (parallel [(set (reg:P SP_REG)
17001 (plus:P (reg:P SP_REG)
17002 (match_operand:P 0 "const_int_operand")))
17003 (clobber (reg:CC FLAGS_REG))])]
17004 "optimize_insn_for_size_p ()
17005 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17006 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17007 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17009 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17010 ;; required and register dies. Similarly for 128 to -128.
17012 [(set (match_operand 0 "flags_reg_operand")
17013 (match_operator 1 "compare_operator"
17014 [(match_operand 2 "register_operand")
17015 (match_operand 3 "const_int_operand")]))]
17016 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17017 && incdec_operand (operands[3], GET_MODE (operands[3])))
17018 || (!TARGET_FUSE_CMP_AND_BRANCH
17019 && INTVAL (operands[3]) == 128))
17020 && ix86_match_ccmode (insn, CCGCmode)
17021 && peep2_reg_dead_p (1, operands[2])"
17022 [(parallel [(set (match_dup 0)
17023 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17024 (clobber (match_dup 2))])])
17026 ;; Convert imul by three, five and nine into lea
17029 [(set (match_operand:SWI48 0 "register_operand")
17030 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
17031 (match_operand:SWI48 2 "const359_operand")))
17032 (clobber (reg:CC FLAGS_REG))])]
17033 "!TARGET_PARTIAL_REG_STALL
17034 || <MODE>mode == SImode
17035 || optimize_function_for_size_p (cfun)"
17036 [(set (match_dup 0)
17037 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17039 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17043 [(set (match_operand:SWI48 0 "register_operand")
17044 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17045 (match_operand:SWI48 2 "const359_operand")))
17046 (clobber (reg:CC FLAGS_REG))])]
17047 "optimize_insn_for_speed_p ()
17048 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17049 [(set (match_dup 0) (match_dup 1))
17051 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17053 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17055 ;; imul $32bit_imm, mem, reg is vector decoded, while
17056 ;; imul $32bit_imm, reg, reg is direct decoded.
17058 [(match_scratch:SWI48 3 "r")
17059 (parallel [(set (match_operand:SWI48 0 "register_operand")
17060 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
17061 (match_operand:SWI48 2 "immediate_operand")))
17062 (clobber (reg:CC FLAGS_REG))])]
17063 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17064 && !satisfies_constraint_K (operands[2])"
17065 [(set (match_dup 3) (match_dup 1))
17066 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17067 (clobber (reg:CC FLAGS_REG))])])
17070 [(match_scratch:SI 3 "r")
17071 (parallel [(set (match_operand:DI 0 "register_operand")
17073 (mult:SI (match_operand:SI 1 "memory_operand")
17074 (match_operand:SI 2 "immediate_operand"))))
17075 (clobber (reg:CC FLAGS_REG))])]
17077 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17078 && !satisfies_constraint_K (operands[2])"
17079 [(set (match_dup 3) (match_dup 1))
17080 (parallel [(set (match_dup 0)
17081 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17082 (clobber (reg:CC FLAGS_REG))])])
17084 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17085 ;; Convert it into imul reg, reg
17086 ;; It would be better to force assembler to encode instruction using long
17087 ;; immediate, but there is apparently no way to do so.
17089 [(parallel [(set (match_operand:SWI248 0 "register_operand")
17091 (match_operand:SWI248 1 "nonimmediate_operand")
17092 (match_operand:SWI248 2 "const_int_operand")))
17093 (clobber (reg:CC FLAGS_REG))])
17094 (match_scratch:SWI248 3 "r")]
17095 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17096 && satisfies_constraint_K (operands[2])"
17097 [(set (match_dup 3) (match_dup 2))
17098 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17099 (clobber (reg:CC FLAGS_REG))])]
17101 if (!rtx_equal_p (operands[0], operands[1]))
17102 emit_move_insn (operands[0], operands[1]);
17105 ;; After splitting up read-modify operations, array accesses with memory
17106 ;; operands might end up in form:
17108 ;; movl 4(%esp), %edx
17110 ;; instead of pre-splitting:
17112 ;; addl 4(%esp), %eax
17114 ;; movl 4(%esp), %edx
17115 ;; leal (%edx,%eax,4), %eax
17118 [(match_scratch:W 5 "r")
17119 (parallel [(set (match_operand 0 "register_operand")
17120 (ashift (match_operand 1 "register_operand")
17121 (match_operand 2 "const_int_operand")))
17122 (clobber (reg:CC FLAGS_REG))])
17123 (parallel [(set (match_operand 3 "register_operand")
17124 (plus (match_dup 0)
17125 (match_operand 4 "x86_64_general_operand")))
17126 (clobber (reg:CC FLAGS_REG))])]
17127 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17128 /* Validate MODE for lea. */
17129 && ((!TARGET_PARTIAL_REG_STALL
17130 && (GET_MODE (operands[0]) == QImode
17131 || GET_MODE (operands[0]) == HImode))
17132 || GET_MODE (operands[0]) == SImode
17133 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17134 && (rtx_equal_p (operands[0], operands[3])
17135 || peep2_reg_dead_p (2, operands[0]))
17136 /* We reorder load and the shift. */
17137 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17138 [(set (match_dup 5) (match_dup 4))
17139 (set (match_dup 0) (match_dup 1))]
17141 enum machine_mode op1mode = GET_MODE (operands[1]);
17142 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17143 int scale = 1 << INTVAL (operands[2]);
17144 rtx index = gen_lowpart (word_mode, operands[1]);
17145 rtx base = gen_lowpart (word_mode, operands[5]);
17146 rtx dest = gen_lowpart (mode, operands[3]);
17148 operands[1] = gen_rtx_PLUS (word_mode, base,
17149 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
17150 operands[5] = base;
17151 if (mode != word_mode)
17152 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17153 if (op1mode != word_mode)
17154 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17155 operands[0] = dest;
17158 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17159 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17160 ;; caught for use by garbage collectors and the like. Using an insn that
17161 ;; maps to SIGILL makes it more likely the program will rightfully die.
17162 ;; Keeping with tradition, "6" is in honor of #UD.
17163 (define_insn "trap"
17164 [(trap_if (const_int 1) (const_int 6))]
17166 { return ASM_SHORT "0x0b0f"; }
17167 [(set_attr "length" "2")])
17169 (define_expand "prefetch"
17170 [(prefetch (match_operand 0 "address_operand")
17171 (match_operand:SI 1 "const_int_operand")
17172 (match_operand:SI 2 "const_int_operand"))]
17173 "TARGET_PREFETCH_SSE || TARGET_PRFCHW"
17175 bool write = INTVAL (operands[1]) != 0;
17176 int locality = INTVAL (operands[2]);
17178 gcc_assert (IN_RANGE (locality, 0, 3));
17180 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17181 supported by SSE counterpart or the SSE prefetch is not available
17182 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17184 if (TARGET_PRFCHW && (write || !TARGET_PREFETCH_SSE))
17185 operands[2] = GEN_INT (3);
17187 operands[1] = const0_rtx;
17190 (define_insn "*prefetch_sse"
17191 [(prefetch (match_operand 0 "address_operand" "p")
17193 (match_operand:SI 1 "const_int_operand"))]
17194 "TARGET_PREFETCH_SSE"
17196 static const char * const patterns[4] = {
17197 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17200 int locality = INTVAL (operands[1]);
17201 gcc_assert (IN_RANGE (locality, 0, 3));
17203 return patterns[locality];
17205 [(set_attr "type" "sse")
17206 (set_attr "atom_sse_attr" "prefetch")
17207 (set (attr "length_address")
17208 (symbol_ref "memory_address_length (operands[0], false)"))
17209 (set_attr "memory" "none")])
17211 (define_insn "*prefetch_3dnow"
17212 [(prefetch (match_operand 0 "address_operand" "p")
17213 (match_operand:SI 1 "const_int_operand" "n")
17217 if (INTVAL (operands[1]) == 0)
17218 return "prefetch\t%a0";
17220 return "prefetchw\t%a0";
17222 [(set_attr "type" "mmx")
17223 (set (attr "length_address")
17224 (symbol_ref "memory_address_length (operands[0], false)"))
17225 (set_attr "memory" "none")])
17227 (define_expand "stack_protect_set"
17228 [(match_operand 0 "memory_operand")
17229 (match_operand 1 "memory_operand")]
17230 "TARGET_SSP_TLS_GUARD"
17232 rtx (*insn)(rtx, rtx);
17234 #ifdef TARGET_THREAD_SSP_OFFSET
17235 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17236 insn = (TARGET_LP64
17237 ? gen_stack_tls_protect_set_di
17238 : gen_stack_tls_protect_set_si);
17240 insn = (TARGET_LP64
17241 ? gen_stack_protect_set_di
17242 : gen_stack_protect_set_si);
17245 emit_insn (insn (operands[0], operands[1]));
17249 (define_insn "stack_protect_set_<mode>"
17250 [(set (match_operand:PTR 0 "memory_operand" "=m")
17251 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17253 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17254 (clobber (reg:CC FLAGS_REG))]
17255 "TARGET_SSP_TLS_GUARD"
17256 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17257 [(set_attr "type" "multi")])
17259 (define_insn "stack_tls_protect_set_<mode>"
17260 [(set (match_operand:PTR 0 "memory_operand" "=m")
17261 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17262 UNSPEC_SP_TLS_SET))
17263 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17264 (clobber (reg:CC FLAGS_REG))]
17266 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17267 [(set_attr "type" "multi")])
17269 (define_expand "stack_protect_test"
17270 [(match_operand 0 "memory_operand")
17271 (match_operand 1 "memory_operand")
17273 "TARGET_SSP_TLS_GUARD"
17275 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17277 rtx (*insn)(rtx, rtx, rtx);
17279 #ifdef TARGET_THREAD_SSP_OFFSET
17280 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17281 insn = (TARGET_LP64
17282 ? gen_stack_tls_protect_test_di
17283 : gen_stack_tls_protect_test_si);
17285 insn = (TARGET_LP64
17286 ? gen_stack_protect_test_di
17287 : gen_stack_protect_test_si);
17290 emit_insn (insn (flags, operands[0], operands[1]));
17292 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17293 flags, const0_rtx, operands[2]));
17297 (define_insn "stack_protect_test_<mode>"
17298 [(set (match_operand:CCZ 0 "flags_reg_operand")
17299 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17300 (match_operand:PTR 2 "memory_operand" "m")]
17302 (clobber (match_scratch:PTR 3 "=&r"))]
17303 "TARGET_SSP_TLS_GUARD"
17304 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17305 [(set_attr "type" "multi")])
17307 (define_insn "stack_tls_protect_test_<mode>"
17308 [(set (match_operand:CCZ 0 "flags_reg_operand")
17309 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17310 (match_operand:PTR 2 "const_int_operand" "i")]
17311 UNSPEC_SP_TLS_TEST))
17312 (clobber (match_scratch:PTR 3 "=r"))]
17314 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17315 [(set_attr "type" "multi")])
17317 (define_insn "sse4_2_crc32<mode>"
17318 [(set (match_operand:SI 0 "register_operand" "=r")
17320 [(match_operand:SI 1 "register_operand" "0")
17321 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17323 "TARGET_SSE4_2 || TARGET_CRC32"
17324 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17325 [(set_attr "type" "sselog1")
17326 (set_attr "prefix_rep" "1")
17327 (set_attr "prefix_extra" "1")
17328 (set (attr "prefix_data16")
17329 (if_then_else (match_operand:HI 2)
17331 (const_string "*")))
17332 (set (attr "prefix_rex")
17333 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
17335 (const_string "*")))
17336 (set_attr "mode" "SI")])
17338 (define_insn "sse4_2_crc32di"
17339 [(set (match_operand:DI 0 "register_operand" "=r")
17341 [(match_operand:DI 1 "register_operand" "0")
17342 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17344 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17345 "crc32{q}\t{%2, %0|%0, %2}"
17346 [(set_attr "type" "sselog1")
17347 (set_attr "prefix_rep" "1")
17348 (set_attr "prefix_extra" "1")
17349 (set_attr "mode" "DI")])
17351 (define_insn "rdpmc"
17352 [(set (match_operand:DI 0 "register_operand" "=A")
17353 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17357 [(set_attr "type" "other")
17358 (set_attr "length" "2")])
17360 (define_insn "rdpmc_rex64"
17361 [(set (match_operand:DI 0 "register_operand" "=a")
17362 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17364 (set (match_operand:DI 1 "register_operand" "=d")
17365 (unspec_volatile:DI [(match_dup 2)] UNSPECV_RDPMC))]
17368 [(set_attr "type" "other")
17369 (set_attr "length" "2")])
17371 (define_insn "rdtsc"
17372 [(set (match_operand:DI 0 "register_operand" "=A")
17373 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17376 [(set_attr "type" "other")
17377 (set_attr "length" "2")])
17379 (define_insn "rdtsc_rex64"
17380 [(set (match_operand:DI 0 "register_operand" "=a")
17381 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17382 (set (match_operand:DI 1 "register_operand" "=d")
17383 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17386 [(set_attr "type" "other")
17387 (set_attr "length" "2")])
17389 (define_insn "rdtscp"
17390 [(set (match_operand:DI 0 "register_operand" "=A")
17391 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17392 (set (match_operand:SI 1 "register_operand" "=c")
17393 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17396 [(set_attr "type" "other")
17397 (set_attr "length" "3")])
17399 (define_insn "rdtscp_rex64"
17400 [(set (match_operand:DI 0 "register_operand" "=a")
17401 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17402 (set (match_operand:DI 1 "register_operand" "=d")
17403 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17404 (set (match_operand:SI 2 "register_operand" "=c")
17405 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17408 [(set_attr "type" "other")
17409 (set_attr "length" "3")])
17411 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17413 ;; FXSR, XSAVE and XSAVEOPT instructions
17415 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17417 (define_insn "fxsave"
17418 [(set (match_operand:BLK 0 "memory_operand" "=m")
17419 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE))]
17422 [(set_attr "type" "other")
17423 (set_attr "memory" "store")
17424 (set (attr "length")
17425 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17427 (define_insn "fxsave64"
17428 [(set (match_operand:BLK 0 "memory_operand" "=m")
17429 (unspec_volatile:BLK [(const_int 0)] UNSPECV_FXSAVE64))]
17430 "TARGET_64BIT && TARGET_FXSR"
17432 [(set_attr "type" "other")
17433 (set_attr "memory" "store")
17434 (set (attr "length")
17435 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17437 (define_insn "fxrstor"
17438 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
17442 [(set_attr "type" "other")
17443 (set_attr "memory" "load")
17444 (set (attr "length")
17445 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17447 (define_insn "fxrstor64"
17448 [(unspec_volatile [(match_operand:BLK 0 "memory_operand" "m")]
17449 UNSPECV_FXRSTOR64)]
17450 "TARGET_64BIT && TARGET_FXSR"
17452 [(set_attr "type" "other")
17453 (set_attr "memory" "load")
17454 (set (attr "length")
17455 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17457 (define_int_iterator ANY_XSAVE
17459 (UNSPECV_XSAVEOPT "TARGET_XSAVEOPT")])
17461 (define_int_iterator ANY_XSAVE64
17463 (UNSPECV_XSAVEOPT64 "TARGET_XSAVEOPT")])
17465 (define_int_attr xsave
17466 [(UNSPECV_XSAVE "xsave")
17467 (UNSPECV_XSAVE64 "xsave64")
17468 (UNSPECV_XSAVEOPT "xsaveopt")
17469 (UNSPECV_XSAVEOPT64 "xsaveopt64")])
17471 (define_insn "<xsave>"
17472 [(set (match_operand:BLK 0 "memory_operand" "=m")
17473 (unspec_volatile:BLK
17474 [(match_operand:DI 1 "register_operand" "A")]
17476 "!TARGET_64BIT && TARGET_XSAVE"
17478 [(set_attr "type" "other")
17479 (set_attr "memory" "store")
17480 (set (attr "length")
17481 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17483 (define_insn "<xsave>_rex64"
17484 [(set (match_operand:BLK 0 "memory_operand" "=m")
17485 (unspec_volatile:BLK
17486 [(match_operand:SI 1 "register_operand" "a")
17487 (match_operand:SI 2 "register_operand" "d")]
17489 "TARGET_64BIT && TARGET_XSAVE"
17491 [(set_attr "type" "other")
17492 (set_attr "memory" "store")
17493 (set (attr "length")
17494 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17496 (define_insn "<xsave>"
17497 [(set (match_operand:BLK 0 "memory_operand" "=m")
17498 (unspec_volatile:BLK
17499 [(match_operand:SI 1 "register_operand" "a")
17500 (match_operand:SI 2 "register_operand" "d")]
17502 "TARGET_64BIT && TARGET_XSAVE"
17504 [(set_attr "type" "other")
17505 (set_attr "memory" "store")
17506 (set (attr "length")
17507 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17509 (define_insn "xrstor"
17510 [(unspec_volatile:BLK
17511 [(match_operand:BLK 0 "memory_operand" "m")
17512 (match_operand:DI 1 "register_operand" "A")]
17514 "!TARGET_64BIT && TARGET_XSAVE"
17516 [(set_attr "type" "other")
17517 (set_attr "memory" "load")
17518 (set (attr "length")
17519 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17521 (define_insn "xrstor_rex64"
17522 [(unspec_volatile:BLK
17523 [(match_operand:BLK 0 "memory_operand" "m")
17524 (match_operand:SI 1 "register_operand" "a")
17525 (match_operand:SI 2 "register_operand" "d")]
17527 "TARGET_64BIT && TARGET_XSAVE"
17529 [(set_attr "type" "other")
17530 (set_attr "memory" "load")
17531 (set (attr "length")
17532 (symbol_ref "ix86_attr_length_address_default (insn) + 3"))])
17534 (define_insn "xrstor64"
17535 [(unspec_volatile:BLK
17536 [(match_operand:BLK 0 "memory_operand" "m")
17537 (match_operand:SI 1 "register_operand" "a")
17538 (match_operand:SI 2 "register_operand" "d")]
17540 "TARGET_64BIT && TARGET_XSAVE"
17542 [(set_attr "type" "other")
17543 (set_attr "memory" "load")
17544 (set (attr "length")
17545 (symbol_ref "ix86_attr_length_address_default (insn) + 4"))])
17547 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17549 ;; LWP instructions
17551 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17553 (define_expand "lwp_llwpcb"
17554 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17555 UNSPECV_LLWP_INTRINSIC)]
17558 (define_insn "*lwp_llwpcb<mode>1"
17559 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17560 UNSPECV_LLWP_INTRINSIC)]
17563 [(set_attr "type" "lwp")
17564 (set_attr "mode" "<MODE>")
17565 (set_attr "length" "5")])
17567 (define_expand "lwp_slwpcb"
17568 [(set (match_operand 0 "register_operand" "=r")
17569 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17574 insn = (Pmode == DImode
17576 : gen_lwp_slwpcbsi);
17578 emit_insn (insn (operands[0]));
17582 (define_insn "lwp_slwpcb<mode>"
17583 [(set (match_operand:P 0 "register_operand" "=r")
17584 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17587 [(set_attr "type" "lwp")
17588 (set_attr "mode" "<MODE>")
17589 (set_attr "length" "5")])
17591 (define_expand "lwp_lwpval<mode>3"
17592 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
17593 (match_operand:SI 2 "nonimmediate_operand" "rm")
17594 (match_operand:SI 3 "const_int_operand" "i")]
17595 UNSPECV_LWPVAL_INTRINSIC)]
17597 ;; Avoid unused variable warning.
17598 "(void) operands[0];")
17600 (define_insn "*lwp_lwpval<mode>3_1"
17601 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
17602 (match_operand:SI 1 "nonimmediate_operand" "rm")
17603 (match_operand:SI 2 "const_int_operand" "i")]
17604 UNSPECV_LWPVAL_INTRINSIC)]
17606 "lwpval\t{%2, %1, %0|%0, %1, %2}"
17607 [(set_attr "type" "lwp")
17608 (set_attr "mode" "<MODE>")
17609 (set (attr "length")
17610 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17612 (define_expand "lwp_lwpins<mode>3"
17613 [(set (reg:CCC FLAGS_REG)
17614 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
17615 (match_operand:SI 2 "nonimmediate_operand" "rm")
17616 (match_operand:SI 3 "const_int_operand" "i")]
17617 UNSPECV_LWPINS_INTRINSIC))
17618 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
17619 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
17622 (define_insn "*lwp_lwpins<mode>3_1"
17623 [(set (reg:CCC FLAGS_REG)
17624 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
17625 (match_operand:SI 1 "nonimmediate_operand" "rm")
17626 (match_operand:SI 2 "const_int_operand" "i")]
17627 UNSPECV_LWPINS_INTRINSIC))]
17629 "lwpins\t{%2, %1, %0|%0, %1, %2}"
17630 [(set_attr "type" "lwp")
17631 (set_attr "mode" "<MODE>")
17632 (set (attr "length")
17633 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
17635 (define_int_iterator RDFSGSBASE
17639 (define_int_iterator WRFSGSBASE
17643 (define_int_attr fsgs
17644 [(UNSPECV_RDFSBASE "fs")
17645 (UNSPECV_RDGSBASE "gs")
17646 (UNSPECV_WRFSBASE "fs")
17647 (UNSPECV_WRGSBASE "gs")])
17649 (define_insn "rd<fsgs>base<mode>"
17650 [(set (match_operand:SWI48 0 "register_operand" "=r")
17651 (unspec_volatile:SWI48 [(const_int 0)] RDFSGSBASE))]
17652 "TARGET_64BIT && TARGET_FSGSBASE"
17654 [(set_attr "type" "other")
17655 (set_attr "prefix_extra" "2")])
17657 (define_insn "wr<fsgs>base<mode>"
17658 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
17660 "TARGET_64BIT && TARGET_FSGSBASE"
17662 [(set_attr "type" "other")
17663 (set_attr "prefix_extra" "2")])
17665 (define_insn "rdrand<mode>_1"
17666 [(set (match_operand:SWI248 0 "register_operand" "=r")
17667 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
17668 (set (reg:CCC FLAGS_REG)
17669 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
17672 [(set_attr "type" "other")
17673 (set_attr "prefix_extra" "1")])
17675 (define_insn "rdseed<mode>_1"
17676 [(set (match_operand:SWI248 0 "register_operand" "=r")
17677 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDSEED))
17678 (set (reg:CCC FLAGS_REG)
17679 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDSEED))]
17682 [(set_attr "type" "other")
17683 (set_attr "prefix_extra" "1")])
17685 (define_expand "pause"
17686 [(set (match_dup 0)
17687 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
17690 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
17691 MEM_VOLATILE_P (operands[0]) = 1;
17694 ;; Use "rep; nop", instead of "pause", to support older assemblers.
17695 ;; They have the same encoding.
17696 (define_insn "*pause"
17697 [(set (match_operand:BLK 0)
17698 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
17701 [(set_attr "length" "2")
17702 (set_attr "memory" "unknown")])
17704 (define_expand "xbegin"
17705 [(set (match_operand:SI 0 "register_operand")
17706 (unspec_volatile:SI [(const_int 0)] UNSPECV_XBEGIN))]
17709 rtx label = gen_label_rtx ();
17711 /* xbegin is emitted as jump_insn, so reload won't be able
17712 to reload its operand. Force the value into AX hard register. */
17713 rtx ax_reg = gen_rtx_REG (SImode, AX_REG);
17714 emit_move_insn (ax_reg, constm1_rtx);
17716 emit_jump_insn (gen_xbegin_1 (ax_reg, label));
17718 emit_label (label);
17719 LABEL_NUSES (label) = 1;
17721 emit_move_insn (operands[0], ax_reg);
17726 (define_insn "xbegin_1"
17728 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
17730 (label_ref (match_operand 1))
17732 (set (match_operand:SI 0 "register_operand" "+a")
17733 (unspec_volatile:SI [(match_dup 0)] UNSPECV_XBEGIN))]
17736 [(set_attr "type" "other")
17737 (set_attr "length" "6")])
17739 (define_insn "xend"
17740 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
17743 [(set_attr "type" "other")
17744 (set_attr "length" "3")])
17746 (define_insn "xabort"
17747 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
17751 [(set_attr "type" "other")
17752 (set_attr "length" "3")])
17754 (define_expand "xtest"
17755 [(set (match_operand:QI 0 "register_operand")
17756 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
17759 emit_insn (gen_xtest_1 ());
17761 ix86_expand_setcc (operands[0], NE,
17762 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
17766 (define_insn "xtest_1"
17767 [(set (reg:CCZ FLAGS_REG)
17768 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
17771 [(set_attr "type" "other")
17772 (set_attr "length" "3")])
17776 (include "sync.md")