1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>. */
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;; The special asm out single letter directives following a '%' are:
30 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; F,f -- likewise, but for floating-point.
34 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
36 ;; R -- print the prefix for register names.
37 ;; z -- print the opcode suffix for the size of the current operand.
38 ;; Z -- likewise, with special suffixes for x87 instructions.
39 ;; * -- print a star (in certain assembler syntax)
40 ;; A -- print an absolute memory reference.
41 ;; E -- print address with DImode register names if TARGET_64BIT.
42 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
43 ;; s -- print a shift double count, followed by the assemblers argument
45 ;; b -- print the QImode name of the register for the indicated operand.
46 ;; %b0 would print %al if operands[0] is reg 0.
47 ;; w -- likewise, print the HImode name of the register.
48 ;; k -- likewise, print the SImode name of the register.
49 ;; q -- likewise, print the DImode name of the register.
50 ;; x -- likewise, print the V4SFmode name of the register.
51 ;; t -- likewise, print the V8SFmode name of the register.
52 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
53 ;; y -- print "st(0)" instead of "st" as a register.
54 ;; d -- print duplicated register operand for AVX instruction.
55 ;; D -- print condition for SSE cmp instruction.
56 ;; P -- if PIC, print an @PLT suffix.
57 ;; p -- print raw symbol name.
58 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
59 ;; & -- print some in-use local-dynamic symbol name.
60 ;; H -- print a memory address offset by 8; used for sse high-parts
61 ;; Y -- print condition for XOP pcom* instruction.
62 ;; + -- print a branch hint as 'cs' or 'ds' prefix
63 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
64 ;; @ -- print a segment register of thread base pointer load
66 (define_c_enum "unspec" [
67 ;; Relocation specifiers
78 UNSPEC_MACHOPIC_OFFSET
86 UNSPEC_MEMORY_BLOCKAGE
96 ;; Other random patterns
105 UNSPEC_LD_MPIC ; load_macho_picbase
107 UNSPEC_DIV_ALREADY_SPLIT
108 UNSPEC_MS_TO_SYSV_CALL
109 UNSPEC_CALL_NEEDS_VZEROUPPER
114 ;; For SSE/MMX support:
122 ;; Generic math support
124 UNSPEC_IEEE_MIN ; not commutative
125 UNSPEC_IEEE_MAX ; not commutative
127 ;; x87 Floating point
143 UNSPEC_FRNDINT_MASK_PM
147 ;; x87 Double output FP
182 (define_c_enum "unspecv" [
185 UNSPECV_PROBE_STACK_RANGE
188 UNSPECV_SPLIT_STACK_RETURN
194 UNSPECV_LLWP_INTRINSIC
195 UNSPECV_SLWP_INTRINSIC
196 UNSPECV_LWPVAL_INTRINSIC
197 UNSPECV_LWPINS_INTRINSIC
203 ;; For RDRAND support
207 ;; Constants to represent rounding modes in the ROUND instruction
216 ;; Constants to represent pcomtrue/pcomfalse variants
226 ;; Constants used in the XOP pperm instruction
228 [(PPERM_SRC 0x00) /* copy source */
229 (PPERM_INVERT 0x20) /* invert source */
230 (PPERM_REVERSE 0x40) /* bit reverse source */
231 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
232 (PPERM_ZERO 0x80) /* all 0's */
233 (PPERM_ONES 0xa0) /* all 1's */
234 (PPERM_SIGN 0xc0) /* propagate sign bit */
235 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
236 (PPERM_SRC1 0x00) /* use first source byte */
237 (PPERM_SRC2 0x10) /* use second source byte */
240 ;; Registers by name.
293 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
296 ;; In C guard expressions, put expressions which may be compile-time
297 ;; constants first. This allows for better optimization. For
298 ;; example, write "TARGET_64BIT && reload_completed", not
299 ;; "reload_completed && TARGET_64BIT".
303 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
304 atom,generic64,amdfam10,bdver1,bdver2,btver1"
305 (const (symbol_ref "ix86_schedule")))
307 ;; A basic instruction type. Refinements due to arguments to be
308 ;; provided in other attributes.
311 alu,alu1,negnot,imov,imovx,lea,
312 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,imul,imulx,idiv,
313 icmp,test,ibr,setcc,icmov,
314 push,pop,call,callv,leave,
316 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
317 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
318 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
319 ssemuladd,sse4arg,lwp,
320 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
321 (const_string "other"))
323 ;; Main data type used by the insn
325 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
326 (const_string "unknown"))
328 ;; The CPU unit operations uses.
329 (define_attr "unit" "integer,i387,sse,mmx,unknown"
330 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
331 (const_string "i387")
332 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
333 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
334 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
336 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
338 (eq_attr "type" "other")
339 (const_string "unknown")]
340 (const_string "integer")))
342 ;; The (bounding maximum) length of an instruction immediate.
343 (define_attr "length_immediate" ""
344 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
347 (eq_attr "unit" "i387,sse,mmx")
349 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
350 rotate,rotatex,rotate1,imul,icmp,push,pop")
351 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
352 (eq_attr "type" "imov,test")
353 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
354 (eq_attr "type" "call")
355 (if_then_else (match_operand 0 "constant_call_address_operand" "")
358 (eq_attr "type" "callv")
359 (if_then_else (match_operand 1 "constant_call_address_operand" "")
362 ;; We don't know the size before shorten_branches. Expect
363 ;; the instruction to fit for better scheduling.
364 (eq_attr "type" "ibr")
367 (symbol_ref "/* Update immediate_length and other attributes! */
368 gcc_unreachable (),1")))
370 ;; The (bounding maximum) length of an instruction address.
371 (define_attr "length_address" ""
372 (cond [(eq_attr "type" "str,other,multi,fxch")
374 (and (eq_attr "type" "call")
375 (match_operand 0 "constant_call_address_operand" ""))
377 (and (eq_attr "type" "callv")
378 (match_operand 1 "constant_call_address_operand" ""))
381 (symbol_ref "ix86_attr_length_address_default (insn)")))
383 ;; Set when length prefix is used.
384 (define_attr "prefix_data16" ""
385 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
387 (eq_attr "mode" "HI")
389 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
394 ;; Set when string REP prefix is used.
395 (define_attr "prefix_rep" ""
396 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
398 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
403 ;; Set when 0f opcode prefix is used.
404 (define_attr "prefix_0f" ""
406 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
407 (eq_attr "unit" "sse,mmx"))
411 ;; Set when REX opcode prefix is used.
412 (define_attr "prefix_rex" ""
413 (cond [(not (match_test "TARGET_64BIT"))
415 (and (eq_attr "mode" "DI")
416 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
417 (eq_attr "unit" "!mmx")))
419 (and (eq_attr "mode" "QI")
420 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
422 (match_test "x86_extended_reg_mentioned_p (insn)")
424 (and (eq_attr "type" "imovx")
425 (match_operand:QI 1 "ext_QIreg_operand" ""))
430 ;; There are also additional prefixes in 3DNOW, SSSE3.
431 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
432 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
433 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
434 (define_attr "prefix_extra" ""
435 (cond [(eq_attr "type" "ssemuladd,sse4arg")
437 (eq_attr "type" "sseiadd1,ssecvt1")
442 ;; Prefix used: original, VEX or maybe VEX.
443 (define_attr "prefix" "orig,vex,maybe_vex"
444 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
446 (const_string "orig")))
448 ;; VEX W bit is used.
449 (define_attr "prefix_vex_w" "" (const_int 0))
451 ;; The length of VEX prefix
452 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
453 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
454 ;; still prefix_0f 1, with prefix_extra 1.
455 (define_attr "length_vex" ""
456 (if_then_else (and (eq_attr "prefix_0f" "1")
457 (eq_attr "prefix_extra" "0"))
458 (if_then_else (eq_attr "prefix_vex_w" "1")
459 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
460 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
461 (if_then_else (eq_attr "prefix_vex_w" "1")
462 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
463 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
465 ;; Set when modrm byte is used.
466 (define_attr "modrm" ""
467 (cond [(eq_attr "type" "str,leave")
469 (eq_attr "unit" "i387")
471 (and (eq_attr "type" "incdec")
472 (and (not (match_test "TARGET_64BIT"))
473 (ior (match_operand:SI 1 "register_operand" "")
474 (match_operand:HI 1 "register_operand" ""))))
476 (and (eq_attr "type" "push")
477 (not (match_operand 1 "memory_operand" "")))
479 (and (eq_attr "type" "pop")
480 (not (match_operand 0 "memory_operand" "")))
482 (and (eq_attr "type" "imov")
483 (and (not (eq_attr "mode" "DI"))
484 (ior (and (match_operand 0 "register_operand" "")
485 (match_operand 1 "immediate_operand" ""))
486 (ior (and (match_operand 0 "ax_reg_operand" "")
487 (match_operand 1 "memory_displacement_only_operand" ""))
488 (and (match_operand 0 "memory_displacement_only_operand" "")
489 (match_operand 1 "ax_reg_operand" ""))))))
491 (and (eq_attr "type" "call")
492 (match_operand 0 "constant_call_address_operand" ""))
494 (and (eq_attr "type" "callv")
495 (match_operand 1 "constant_call_address_operand" ""))
497 (and (eq_attr "type" "alu,alu1,icmp,test")
498 (match_operand 0 "ax_reg_operand" ""))
499 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
503 ;; The (bounding maximum) length of an instruction in bytes.
504 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
505 ;; Later we may want to split them and compute proper length as for
507 (define_attr "length" ""
508 (cond [(eq_attr "type" "other,multi,fistp,frndint")
510 (eq_attr "type" "fcmp")
512 (eq_attr "unit" "i387")
514 (plus (attr "prefix_data16")
515 (attr "length_address")))
516 (ior (eq_attr "prefix" "vex")
517 (and (eq_attr "prefix" "maybe_vex")
518 (match_test "TARGET_AVX")))
519 (plus (attr "length_vex")
520 (plus (attr "length_immediate")
522 (attr "length_address"))))]
523 (plus (plus (attr "modrm")
524 (plus (attr "prefix_0f")
525 (plus (attr "prefix_rex")
526 (plus (attr "prefix_extra")
528 (plus (attr "prefix_rep")
529 (plus (attr "prefix_data16")
530 (plus (attr "length_immediate")
531 (attr "length_address")))))))
533 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
534 ;; `store' if there is a simple memory reference therein, or `unknown'
535 ;; if the instruction is complex.
537 (define_attr "memory" "none,load,store,both,unknown"
538 (cond [(eq_attr "type" "other,multi,str,lwp")
539 (const_string "unknown")
540 (eq_attr "type" "lea,fcmov,fpspc")
541 (const_string "none")
542 (eq_attr "type" "fistp,leave")
543 (const_string "both")
544 (eq_attr "type" "frndint")
545 (const_string "load")
546 (eq_attr "type" "push")
547 (if_then_else (match_operand 1 "memory_operand" "")
548 (const_string "both")
549 (const_string "store"))
550 (eq_attr "type" "pop")
551 (if_then_else (match_operand 0 "memory_operand" "")
552 (const_string "both")
553 (const_string "load"))
554 (eq_attr "type" "setcc")
555 (if_then_else (match_operand 0 "memory_operand" "")
556 (const_string "store")
557 (const_string "none"))
558 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
559 (if_then_else (ior (match_operand 0 "memory_operand" "")
560 (match_operand 1 "memory_operand" ""))
561 (const_string "load")
562 (const_string "none"))
563 (eq_attr "type" "ibr")
564 (if_then_else (match_operand 0 "memory_operand" "")
565 (const_string "load")
566 (const_string "none"))
567 (eq_attr "type" "call")
568 (if_then_else (match_operand 0 "constant_call_address_operand" "")
569 (const_string "none")
570 (const_string "load"))
571 (eq_attr "type" "callv")
572 (if_then_else (match_operand 1 "constant_call_address_operand" "")
573 (const_string "none")
574 (const_string "load"))
575 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
576 (match_operand 1 "memory_operand" ""))
577 (const_string "both")
578 (and (match_operand 0 "memory_operand" "")
579 (match_operand 1 "memory_operand" ""))
580 (const_string "both")
581 (match_operand 0 "memory_operand" "")
582 (const_string "store")
583 (match_operand 1 "memory_operand" "")
584 (const_string "load")
586 "!alu1,negnot,ishift1,
587 imov,imovx,icmp,test,bitmanip,
589 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
590 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
591 (match_operand 2 "memory_operand" ""))
592 (const_string "load")
593 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
594 (match_operand 3 "memory_operand" ""))
595 (const_string "load")
597 (const_string "none")))
599 ;; Indicates if an instruction has both an immediate and a displacement.
601 (define_attr "imm_disp" "false,true,unknown"
602 (cond [(eq_attr "type" "other,multi")
603 (const_string "unknown")
604 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
605 (and (match_operand 0 "memory_displacement_operand" "")
606 (match_operand 1 "immediate_operand" "")))
607 (const_string "true")
608 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
609 (and (match_operand 0 "memory_displacement_operand" "")
610 (match_operand 2 "immediate_operand" "")))
611 (const_string "true")
613 (const_string "false")))
615 ;; Indicates if an FP operation has an integer source.
617 (define_attr "fp_int_src" "false,true"
618 (const_string "false"))
620 ;; Defines rounding mode of an FP operation.
622 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
623 (const_string "any"))
625 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
626 (define_attr "use_carry" "0,1" (const_string "0"))
628 ;; Define attribute to indicate unaligned ssemov insns
629 (define_attr "movu" "0,1" (const_string "0"))
631 ;; Used to control the "enabled" attribute on a per-instruction basis.
632 (define_attr "isa" "base,sse2,sse2_noavx,sse3,sse4,sse4_noavx,noavx,avx,
634 (const_string "base"))
636 (define_attr "enabled" ""
637 (cond [(eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
638 (eq_attr "isa" "sse2_noavx")
639 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
640 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
641 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
642 (eq_attr "isa" "sse4_noavx")
643 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
644 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
645 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
646 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
647 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
648 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
652 ;; Describe a user's asm statement.
653 (define_asm_attributes
654 [(set_attr "length" "128")
655 (set_attr "type" "multi")])
657 (define_code_iterator plusminus [plus minus])
659 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
661 ;; Base name for define_insn
662 (define_code_attr plusminus_insn
663 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
664 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
666 ;; Base name for insn mnemonic.
667 (define_code_attr plusminus_mnemonic
668 [(plus "add") (ss_plus "adds") (us_plus "addus")
669 (minus "sub") (ss_minus "subs") (us_minus "subus")])
670 (define_code_attr plusminus_carry_mnemonic
671 [(plus "adc") (minus "sbb")])
673 ;; Mark commutative operators as such in constraints.
674 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
675 (minus "") (ss_minus "") (us_minus "")])
677 ;; Mapping of max and min
678 (define_code_iterator maxmin [smax smin umax umin])
680 ;; Mapping of signed max and min
681 (define_code_iterator smaxmin [smax smin])
683 ;; Mapping of unsigned max and min
684 (define_code_iterator umaxmin [umax umin])
686 ;; Base name for integer and FP insn mnemonic
687 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
688 (umax "maxu") (umin "minu")])
689 (define_code_attr maxmin_float [(smax "max") (smin "min")])
691 ;; Mapping of logic operators
692 (define_code_iterator any_logic [and ior xor])
693 (define_code_iterator any_or [ior xor])
695 ;; Base name for insn mnemonic.
696 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
698 ;; Mapping of logic-shift operators
699 (define_code_iterator any_lshift [ashift lshiftrt])
701 ;; Mapping of shift-right operators
702 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
704 ;; Base name for define_insn
705 (define_code_attr shift_insn
706 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
708 ;; Base name for insn mnemonic.
709 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
710 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
712 ;; Mapping of rotate operators
713 (define_code_iterator any_rotate [rotate rotatert])
715 ;; Base name for define_insn
716 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
718 ;; Base name for insn mnemonic.
719 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
721 ;; Mapping of abs neg operators
722 (define_code_iterator absneg [abs neg])
724 ;; Base name for x87 insn mnemonic.
725 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
727 ;; Used in signed and unsigned widening multiplications.
728 (define_code_iterator any_extend [sign_extend zero_extend])
730 ;; Prefix for insn menmonic.
731 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
733 ;; Prefix for define_insn
734 (define_code_attr u [(sign_extend "") (zero_extend "u")])
735 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
737 ;; All integer modes.
738 (define_mode_iterator SWI1248x [QI HI SI DI])
740 ;; All integer modes without QImode.
741 (define_mode_iterator SWI248x [HI SI DI])
743 ;; All integer modes without QImode and HImode.
744 (define_mode_iterator SWI48x [SI DI])
746 ;; All integer modes without SImode and DImode.
747 (define_mode_iterator SWI12 [QI HI])
749 ;; All integer modes without DImode.
750 (define_mode_iterator SWI124 [QI HI SI])
752 ;; All integer modes without QImode and DImode.
753 (define_mode_iterator SWI24 [HI SI])
755 ;; Single word integer modes.
756 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
758 ;; Single word integer modes without QImode.
759 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
761 ;; Single word integer modes without QImode and HImode.
762 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
764 ;; All math-dependant single and double word integer modes.
765 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
766 (HI "TARGET_HIMODE_MATH")
767 SI DI (TI "TARGET_64BIT")])
769 ;; Math-dependant single word integer modes.
770 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
771 (HI "TARGET_HIMODE_MATH")
772 SI (DI "TARGET_64BIT")])
774 ;; Math-dependant integer modes without DImode.
775 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
776 (HI "TARGET_HIMODE_MATH")
779 ;; Math-dependant single word integer modes without QImode.
780 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
781 SI (DI "TARGET_64BIT")])
783 ;; Double word integer modes.
784 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
785 (TI "TARGET_64BIT")])
787 ;; Double word integer modes as mode attribute.
788 (define_mode_attr DWI [(SI "DI") (DI "TI")])
789 (define_mode_attr dwi [(SI "di") (DI "ti")])
791 ;; Half mode for double word integer modes.
792 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
793 (DI "TARGET_64BIT")])
795 ;; Instruction suffix for integer modes.
796 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
798 ;; Pointer size prefix for integer modes (Intel asm dialect)
799 (define_mode_attr iptrsize [(QI "BYTE")
804 ;; Register class for integer modes.
805 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
807 ;; Immediate operand constraint for integer modes.
808 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
810 ;; General operand constraint for word modes.
811 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
813 ;; Immediate operand constraint for double integer modes.
814 (define_mode_attr di [(SI "nF") (DI "e")])
816 ;; Immediate operand constraint for shifts.
817 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
819 ;; General operand predicate for integer modes.
820 (define_mode_attr general_operand
821 [(QI "general_operand")
822 (HI "general_operand")
823 (SI "x86_64_general_operand")
824 (DI "x86_64_general_operand")
825 (TI "x86_64_general_operand")])
827 ;; General sign/zero extend operand predicate for integer modes.
828 (define_mode_attr general_szext_operand
829 [(QI "general_operand")
830 (HI "general_operand")
831 (SI "x86_64_szext_general_operand")
832 (DI "x86_64_szext_general_operand")])
834 ;; Immediate operand predicate for integer modes.
835 (define_mode_attr immediate_operand
836 [(QI "immediate_operand")
837 (HI "immediate_operand")
838 (SI "x86_64_immediate_operand")
839 (DI "x86_64_immediate_operand")])
841 ;; Nonmemory operand predicate for integer modes.
842 (define_mode_attr nonmemory_operand
843 [(QI "nonmemory_operand")
844 (HI "nonmemory_operand")
845 (SI "x86_64_nonmemory_operand")
846 (DI "x86_64_nonmemory_operand")])
848 ;; Operand predicate for shifts.
849 (define_mode_attr shift_operand
850 [(QI "nonimmediate_operand")
851 (HI "nonimmediate_operand")
852 (SI "nonimmediate_operand")
853 (DI "shiftdi_operand")
854 (TI "register_operand")])
856 ;; Operand predicate for shift argument.
857 (define_mode_attr shift_immediate_operand
858 [(QI "const_1_to_31_operand")
859 (HI "const_1_to_31_operand")
860 (SI "const_1_to_31_operand")
861 (DI "const_1_to_63_operand")])
863 ;; Input operand predicate for arithmetic left shifts.
864 (define_mode_attr ashl_input_operand
865 [(QI "nonimmediate_operand")
866 (HI "nonimmediate_operand")
867 (SI "nonimmediate_operand")
868 (DI "ashldi_input_operand")
869 (TI "reg_or_pm1_operand")])
871 ;; SSE and x87 SFmode and DFmode floating point modes
872 (define_mode_iterator MODEF [SF DF])
874 ;; All x87 floating point modes
875 (define_mode_iterator X87MODEF [SF DF XF])
877 ;; SSE instruction suffix for various modes
878 (define_mode_attr ssemodesuffix
880 (V8SF "ps") (V4DF "pd")
881 (V4SF "ps") (V2DF "pd")
882 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
883 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
885 ;; SSE vector suffix for floating point modes
886 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
888 ;; SSE vector mode corresponding to a scalar mode
889 (define_mode_attr ssevecmode
890 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
892 ;; Instruction suffix for REX 64bit operators.
893 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
895 ;; This mode iterator allows :P to be used for patterns that operate on
896 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
897 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
899 ;; This mode iterator allows :PTR to be used for patterns that operate on
900 ;; ptr_mode sized quantities.
901 (define_mode_iterator PTR
902 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
904 ;; Scheduling descriptions
906 (include "pentium.md")
909 (include "athlon.md")
910 (include "bdver1.md")
916 ;; Operand and operator predicates and constraints
918 (include "predicates.md")
919 (include "constraints.md")
922 ;; Compare and branch/compare and store instructions.
924 (define_expand "cbranch<mode>4"
925 [(set (reg:CC FLAGS_REG)
926 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
927 (match_operand:SDWIM 2 "<general_operand>" "")))
928 (set (pc) (if_then_else
929 (match_operator 0 "ordered_comparison_operator"
930 [(reg:CC FLAGS_REG) (const_int 0)])
931 (label_ref (match_operand 3 "" ""))
935 if (MEM_P (operands[1]) && MEM_P (operands[2]))
936 operands[1] = force_reg (<MODE>mode, operands[1]);
937 ix86_expand_branch (GET_CODE (operands[0]),
938 operands[1], operands[2], operands[3]);
942 (define_expand "cstore<mode>4"
943 [(set (reg:CC FLAGS_REG)
944 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
945 (match_operand:SWIM 3 "<general_operand>" "")))
946 (set (match_operand:QI 0 "register_operand" "")
947 (match_operator 1 "ordered_comparison_operator"
948 [(reg:CC FLAGS_REG) (const_int 0)]))]
951 if (MEM_P (operands[2]) && MEM_P (operands[3]))
952 operands[2] = force_reg (<MODE>mode, operands[2]);
953 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
954 operands[2], operands[3]);
958 (define_expand "cmp<mode>_1"
959 [(set (reg:CC FLAGS_REG)
960 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
961 (match_operand:SWI48 1 "<general_operand>" "")))])
963 (define_insn "*cmp<mode>_ccno_1"
964 [(set (reg FLAGS_REG)
965 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
966 (match_operand:SWI 1 "const0_operand" "")))]
967 "ix86_match_ccmode (insn, CCNOmode)"
969 test{<imodesuffix>}\t%0, %0
970 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
971 [(set_attr "type" "test,icmp")
972 (set_attr "length_immediate" "0,1")
973 (set_attr "mode" "<MODE>")])
975 (define_insn "*cmp<mode>_1"
976 [(set (reg FLAGS_REG)
977 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
978 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
979 "ix86_match_ccmode (insn, CCmode)"
980 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
981 [(set_attr "type" "icmp")
982 (set_attr "mode" "<MODE>")])
984 (define_insn "*cmp<mode>_minus_1"
985 [(set (reg FLAGS_REG)
987 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
988 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
990 "ix86_match_ccmode (insn, CCGOCmode)"
991 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
992 [(set_attr "type" "icmp")
993 (set_attr "mode" "<MODE>")])
995 (define_insn "*cmpqi_ext_1"
996 [(set (reg FLAGS_REG)
998 (match_operand:QI 0 "general_operand" "Qm")
1001 (match_operand 1 "ext_register_operand" "Q")
1003 (const_int 8)) 0)))]
1004 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1005 "cmp{b}\t{%h1, %0|%0, %h1}"
1006 [(set_attr "type" "icmp")
1007 (set_attr "mode" "QI")])
1009 (define_insn "*cmpqi_ext_1_rex64"
1010 [(set (reg FLAGS_REG)
1012 (match_operand:QI 0 "register_operand" "Q")
1015 (match_operand 1 "ext_register_operand" "Q")
1017 (const_int 8)) 0)))]
1018 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1019 "cmp{b}\t{%h1, %0|%0, %h1}"
1020 [(set_attr "type" "icmp")
1021 (set_attr "mode" "QI")])
1023 (define_insn "*cmpqi_ext_2"
1024 [(set (reg FLAGS_REG)
1028 (match_operand 0 "ext_register_operand" "Q")
1031 (match_operand:QI 1 "const0_operand" "")))]
1032 "ix86_match_ccmode (insn, CCNOmode)"
1034 [(set_attr "type" "test")
1035 (set_attr "length_immediate" "0")
1036 (set_attr "mode" "QI")])
1038 (define_expand "cmpqi_ext_3"
1039 [(set (reg:CC FLAGS_REG)
1043 (match_operand 0 "ext_register_operand" "")
1046 (match_operand:QI 1 "immediate_operand" "")))])
1048 (define_insn "*cmpqi_ext_3_insn"
1049 [(set (reg FLAGS_REG)
1053 (match_operand 0 "ext_register_operand" "Q")
1056 (match_operand:QI 1 "general_operand" "Qmn")))]
1057 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1058 "cmp{b}\t{%1, %h0|%h0, %1}"
1059 [(set_attr "type" "icmp")
1060 (set_attr "modrm" "1")
1061 (set_attr "mode" "QI")])
1063 (define_insn "*cmpqi_ext_3_insn_rex64"
1064 [(set (reg FLAGS_REG)
1068 (match_operand 0 "ext_register_operand" "Q")
1071 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1072 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1073 "cmp{b}\t{%1, %h0|%h0, %1}"
1074 [(set_attr "type" "icmp")
1075 (set_attr "modrm" "1")
1076 (set_attr "mode" "QI")])
1078 (define_insn "*cmpqi_ext_4"
1079 [(set (reg FLAGS_REG)
1083 (match_operand 0 "ext_register_operand" "Q")
1088 (match_operand 1 "ext_register_operand" "Q")
1090 (const_int 8)) 0)))]
1091 "ix86_match_ccmode (insn, CCmode)"
1092 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1093 [(set_attr "type" "icmp")
1094 (set_attr "mode" "QI")])
1096 ;; These implement float point compares.
1097 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1098 ;; which would allow mix and match FP modes on the compares. Which is what
1099 ;; the old patterns did, but with many more of them.
1101 (define_expand "cbranchxf4"
1102 [(set (reg:CC FLAGS_REG)
1103 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1104 (match_operand:XF 2 "nonmemory_operand" "")))
1105 (set (pc) (if_then_else
1106 (match_operator 0 "ix86_fp_comparison_operator"
1109 (label_ref (match_operand 3 "" ""))
1113 ix86_expand_branch (GET_CODE (operands[0]),
1114 operands[1], operands[2], operands[3]);
1118 (define_expand "cstorexf4"
1119 [(set (reg:CC FLAGS_REG)
1120 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1121 (match_operand:XF 3 "nonmemory_operand" "")))
1122 (set (match_operand:QI 0 "register_operand" "")
1123 (match_operator 1 "ix86_fp_comparison_operator"
1128 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1129 operands[2], operands[3]);
1133 (define_expand "cbranch<mode>4"
1134 [(set (reg:CC FLAGS_REG)
1135 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1136 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1137 (set (pc) (if_then_else
1138 (match_operator 0 "ix86_fp_comparison_operator"
1141 (label_ref (match_operand 3 "" ""))
1143 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1145 ix86_expand_branch (GET_CODE (operands[0]),
1146 operands[1], operands[2], operands[3]);
1150 (define_expand "cstore<mode>4"
1151 [(set (reg:CC FLAGS_REG)
1152 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1153 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1154 (set (match_operand:QI 0 "register_operand" "")
1155 (match_operator 1 "ix86_fp_comparison_operator"
1158 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1160 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1161 operands[2], operands[3]);
1165 (define_expand "cbranchcc4"
1166 [(set (pc) (if_then_else
1167 (match_operator 0 "comparison_operator"
1168 [(match_operand 1 "flags_reg_operand" "")
1169 (match_operand 2 "const0_operand" "")])
1170 (label_ref (match_operand 3 "" ""))
1174 ix86_expand_branch (GET_CODE (operands[0]),
1175 operands[1], operands[2], operands[3]);
1179 (define_expand "cstorecc4"
1180 [(set (match_operand:QI 0 "register_operand" "")
1181 (match_operator 1 "comparison_operator"
1182 [(match_operand 2 "flags_reg_operand" "")
1183 (match_operand 3 "const0_operand" "")]))]
1186 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1187 operands[2], operands[3]);
1192 ;; FP compares, step 1:
1193 ;; Set the FP condition codes.
1195 ;; CCFPmode compare with exceptions
1196 ;; CCFPUmode compare with no exceptions
1198 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1199 ;; used to manage the reg stack popping would not be preserved.
1201 (define_insn "*cmpfp_0"
1202 [(set (match_operand:HI 0 "register_operand" "=a")
1205 (match_operand 1 "register_operand" "f")
1206 (match_operand 2 "const0_operand" ""))]
1208 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1209 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1210 "* return output_fp_compare (insn, operands, false, false);"
1211 [(set_attr "type" "multi")
1212 (set_attr "unit" "i387")
1214 (cond [(match_operand:SF 1 "" "")
1216 (match_operand:DF 1 "" "")
1219 (const_string "XF")))])
1221 (define_insn_and_split "*cmpfp_0_cc"
1222 [(set (reg:CCFP FLAGS_REG)
1224 (match_operand 1 "register_operand" "f")
1225 (match_operand 2 "const0_operand" "")))
1226 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1227 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1228 && TARGET_SAHF && !TARGET_CMOVE
1229 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1231 "&& reload_completed"
1234 [(compare:CCFP (match_dup 1)(match_dup 2))]
1236 (set (reg:CC FLAGS_REG)
1237 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1239 [(set_attr "type" "multi")
1240 (set_attr "unit" "i387")
1242 (cond [(match_operand:SF 1 "" "")
1244 (match_operand:DF 1 "" "")
1247 (const_string "XF")))])
1249 (define_insn "*cmpfp_xf"
1250 [(set (match_operand:HI 0 "register_operand" "=a")
1253 (match_operand:XF 1 "register_operand" "f")
1254 (match_operand:XF 2 "register_operand" "f"))]
1257 "* return output_fp_compare (insn, operands, false, false);"
1258 [(set_attr "type" "multi")
1259 (set_attr "unit" "i387")
1260 (set_attr "mode" "XF")])
1262 (define_insn_and_split "*cmpfp_xf_cc"
1263 [(set (reg:CCFP FLAGS_REG)
1265 (match_operand:XF 1 "register_operand" "f")
1266 (match_operand:XF 2 "register_operand" "f")))
1267 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1269 && TARGET_SAHF && !TARGET_CMOVE"
1271 "&& reload_completed"
1274 [(compare:CCFP (match_dup 1)(match_dup 2))]
1276 (set (reg:CC FLAGS_REG)
1277 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1279 [(set_attr "type" "multi")
1280 (set_attr "unit" "i387")
1281 (set_attr "mode" "XF")])
1283 (define_insn "*cmpfp_<mode>"
1284 [(set (match_operand:HI 0 "register_operand" "=a")
1287 (match_operand:MODEF 1 "register_operand" "f")
1288 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1291 "* return output_fp_compare (insn, operands, false, false);"
1292 [(set_attr "type" "multi")
1293 (set_attr "unit" "i387")
1294 (set_attr "mode" "<MODE>")])
1296 (define_insn_and_split "*cmpfp_<mode>_cc"
1297 [(set (reg:CCFP FLAGS_REG)
1299 (match_operand:MODEF 1 "register_operand" "f")
1300 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1301 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1303 && TARGET_SAHF && !TARGET_CMOVE"
1305 "&& reload_completed"
1308 [(compare:CCFP (match_dup 1)(match_dup 2))]
1310 (set (reg:CC FLAGS_REG)
1311 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1313 [(set_attr "type" "multi")
1314 (set_attr "unit" "i387")
1315 (set_attr "mode" "<MODE>")])
1317 (define_insn "*cmpfp_u"
1318 [(set (match_operand:HI 0 "register_operand" "=a")
1321 (match_operand 1 "register_operand" "f")
1322 (match_operand 2 "register_operand" "f"))]
1324 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1325 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1326 "* return output_fp_compare (insn, operands, false, true);"
1327 [(set_attr "type" "multi")
1328 (set_attr "unit" "i387")
1330 (cond [(match_operand:SF 1 "" "")
1332 (match_operand:DF 1 "" "")
1335 (const_string "XF")))])
1337 (define_insn_and_split "*cmpfp_u_cc"
1338 [(set (reg:CCFPU FLAGS_REG)
1340 (match_operand 1 "register_operand" "f")
1341 (match_operand 2 "register_operand" "f")))
1342 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1343 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1344 && TARGET_SAHF && !TARGET_CMOVE
1345 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1347 "&& reload_completed"
1350 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1352 (set (reg:CC FLAGS_REG)
1353 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1355 [(set_attr "type" "multi")
1356 (set_attr "unit" "i387")
1358 (cond [(match_operand:SF 1 "" "")
1360 (match_operand:DF 1 "" "")
1363 (const_string "XF")))])
1365 (define_insn "*cmpfp_<mode>"
1366 [(set (match_operand:HI 0 "register_operand" "=a")
1369 (match_operand 1 "register_operand" "f")
1370 (match_operator 3 "float_operator"
1371 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1373 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1374 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1375 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1376 "* return output_fp_compare (insn, operands, false, false);"
1377 [(set_attr "type" "multi")
1378 (set_attr "unit" "i387")
1379 (set_attr "fp_int_src" "true")
1380 (set_attr "mode" "<MODE>")])
1382 (define_insn_and_split "*cmpfp_<mode>_cc"
1383 [(set (reg:CCFP FLAGS_REG)
1385 (match_operand 1 "register_operand" "f")
1386 (match_operator 3 "float_operator"
1387 [(match_operand:SWI24 2 "memory_operand" "m")])))
1388 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1389 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1390 && TARGET_SAHF && !TARGET_CMOVE
1391 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1392 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1394 "&& reload_completed"
1399 (match_op_dup 3 [(match_dup 2)]))]
1401 (set (reg:CC FLAGS_REG)
1402 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1404 [(set_attr "type" "multi")
1405 (set_attr "unit" "i387")
1406 (set_attr "fp_int_src" "true")
1407 (set_attr "mode" "<MODE>")])
1409 ;; FP compares, step 2
1410 ;; Move the fpsw to ax.
1412 (define_insn "x86_fnstsw_1"
1413 [(set (match_operand:HI 0 "register_operand" "=a")
1414 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1417 [(set (attr "length")
1418 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1419 (set_attr "mode" "SI")
1420 (set_attr "unit" "i387")])
1422 ;; FP compares, step 3
1423 ;; Get ax into flags, general case.
1425 (define_insn "x86_sahf_1"
1426 [(set (reg:CC FLAGS_REG)
1427 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1431 #ifndef HAVE_AS_IX86_SAHF
1433 return ASM_BYTE "0x9e";
1438 [(set_attr "length" "1")
1439 (set_attr "athlon_decode" "vector")
1440 (set_attr "amdfam10_decode" "direct")
1441 (set_attr "bdver1_decode" "direct")
1442 (set_attr "mode" "SI")])
1444 ;; Pentium Pro can do steps 1 through 3 in one go.
1445 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1446 ;; (these i387 instructions set flags directly)
1447 (define_insn "*cmpfp_i_mixed"
1448 [(set (reg:CCFP FLAGS_REG)
1449 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1450 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1451 "TARGET_MIX_SSE_I387
1452 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1453 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1454 "* return output_fp_compare (insn, operands, true, false);"
1455 [(set_attr "type" "fcmp,ssecomi")
1456 (set_attr "prefix" "orig,maybe_vex")
1458 (if_then_else (match_operand:SF 1 "" "")
1460 (const_string "DF")))
1461 (set (attr "prefix_rep")
1462 (if_then_else (eq_attr "type" "ssecomi")
1464 (const_string "*")))
1465 (set (attr "prefix_data16")
1466 (cond [(eq_attr "type" "fcmp")
1468 (eq_attr "mode" "DF")
1471 (const_string "0")))
1472 (set_attr "athlon_decode" "vector")
1473 (set_attr "amdfam10_decode" "direct")
1474 (set_attr "bdver1_decode" "double")])
1476 (define_insn "*cmpfp_i_sse"
1477 [(set (reg:CCFP FLAGS_REG)
1478 (compare:CCFP (match_operand 0 "register_operand" "x")
1479 (match_operand 1 "nonimmediate_operand" "xm")))]
1481 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1482 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1483 "* return output_fp_compare (insn, operands, true, false);"
1484 [(set_attr "type" "ssecomi")
1485 (set_attr "prefix" "maybe_vex")
1487 (if_then_else (match_operand:SF 1 "" "")
1489 (const_string "DF")))
1490 (set_attr "prefix_rep" "0")
1491 (set (attr "prefix_data16")
1492 (if_then_else (eq_attr "mode" "DF")
1494 (const_string "0")))
1495 (set_attr "athlon_decode" "vector")
1496 (set_attr "amdfam10_decode" "direct")
1497 (set_attr "bdver1_decode" "double")])
1499 (define_insn "*cmpfp_i_i387"
1500 [(set (reg:CCFP FLAGS_REG)
1501 (compare:CCFP (match_operand 0 "register_operand" "f")
1502 (match_operand 1 "register_operand" "f")))]
1503 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1505 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1506 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1507 "* return output_fp_compare (insn, operands, true, false);"
1508 [(set_attr "type" "fcmp")
1510 (cond [(match_operand:SF 1 "" "")
1512 (match_operand:DF 1 "" "")
1515 (const_string "XF")))
1516 (set_attr "athlon_decode" "vector")
1517 (set_attr "amdfam10_decode" "direct")
1518 (set_attr "bdver1_decode" "double")])
1520 (define_insn "*cmpfp_iu_mixed"
1521 [(set (reg:CCFPU FLAGS_REG)
1522 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1523 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1524 "TARGET_MIX_SSE_I387
1525 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1526 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1527 "* return output_fp_compare (insn, operands, true, true);"
1528 [(set_attr "type" "fcmp,ssecomi")
1529 (set_attr "prefix" "orig,maybe_vex")
1531 (if_then_else (match_operand:SF 1 "" "")
1533 (const_string "DF")))
1534 (set (attr "prefix_rep")
1535 (if_then_else (eq_attr "type" "ssecomi")
1537 (const_string "*")))
1538 (set (attr "prefix_data16")
1539 (cond [(eq_attr "type" "fcmp")
1541 (eq_attr "mode" "DF")
1544 (const_string "0")))
1545 (set_attr "athlon_decode" "vector")
1546 (set_attr "amdfam10_decode" "direct")
1547 (set_attr "bdver1_decode" "double")])
1549 (define_insn "*cmpfp_iu_sse"
1550 [(set (reg:CCFPU FLAGS_REG)
1551 (compare:CCFPU (match_operand 0 "register_operand" "x")
1552 (match_operand 1 "nonimmediate_operand" "xm")))]
1554 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1555 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1556 "* return output_fp_compare (insn, operands, true, true);"
1557 [(set_attr "type" "ssecomi")
1558 (set_attr "prefix" "maybe_vex")
1560 (if_then_else (match_operand:SF 1 "" "")
1562 (const_string "DF")))
1563 (set_attr "prefix_rep" "0")
1564 (set (attr "prefix_data16")
1565 (if_then_else (eq_attr "mode" "DF")
1567 (const_string "0")))
1568 (set_attr "athlon_decode" "vector")
1569 (set_attr "amdfam10_decode" "direct")
1570 (set_attr "bdver1_decode" "double")])
1572 (define_insn "*cmpfp_iu_387"
1573 [(set (reg:CCFPU FLAGS_REG)
1574 (compare:CCFPU (match_operand 0 "register_operand" "f")
1575 (match_operand 1 "register_operand" "f")))]
1576 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1578 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1579 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1580 "* return output_fp_compare (insn, operands, true, true);"
1581 [(set_attr "type" "fcmp")
1583 (cond [(match_operand:SF 1 "" "")
1585 (match_operand:DF 1 "" "")
1588 (const_string "XF")))
1589 (set_attr "athlon_decode" "vector")
1590 (set_attr "amdfam10_decode" "direct")
1591 (set_attr "bdver1_decode" "direct")])
1593 ;; Push/pop instructions.
1595 (define_insn "*push<mode>2"
1596 [(set (match_operand:DWI 0 "push_operand" "=<")
1597 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1600 [(set_attr "type" "multi")
1601 (set_attr "mode" "<MODE>")])
1604 [(set (match_operand:TI 0 "push_operand" "")
1605 (match_operand:TI 1 "general_operand" ""))]
1606 "TARGET_64BIT && reload_completed
1607 && !SSE_REG_P (operands[1])"
1609 "ix86_split_long_move (operands); DONE;")
1611 (define_insn "*pushdi2_rex64"
1612 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1613 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1618 [(set_attr "type" "push,multi")
1619 (set_attr "mode" "DI")])
1621 ;; Convert impossible pushes of immediate to existing instructions.
1622 ;; First try to get scratch register and go through it. In case this
1623 ;; fails, push sign extended lower part first and then overwrite
1624 ;; upper part by 32bit move.
1626 [(match_scratch:DI 2 "r")
1627 (set (match_operand:DI 0 "push_operand" "")
1628 (match_operand:DI 1 "immediate_operand" ""))]
1629 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1630 && !x86_64_immediate_operand (operands[1], DImode)"
1631 [(set (match_dup 2) (match_dup 1))
1632 (set (match_dup 0) (match_dup 2))])
1634 ;; We need to define this as both peepholer and splitter for case
1635 ;; peephole2 pass is not run.
1636 ;; "&& 1" is needed to keep it from matching the previous pattern.
1638 [(set (match_operand:DI 0 "push_operand" "")
1639 (match_operand:DI 1 "immediate_operand" ""))]
1640 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1641 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1642 [(set (match_dup 0) (match_dup 1))
1643 (set (match_dup 2) (match_dup 3))]
1645 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1647 operands[1] = gen_lowpart (DImode, operands[2]);
1648 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1653 [(set (match_operand:DI 0 "push_operand" "")
1654 (match_operand:DI 1 "immediate_operand" ""))]
1655 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1656 ? epilogue_completed : reload_completed)
1657 && !symbolic_operand (operands[1], DImode)
1658 && !x86_64_immediate_operand (operands[1], DImode)"
1659 [(set (match_dup 0) (match_dup 1))
1660 (set (match_dup 2) (match_dup 3))]
1662 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1664 operands[1] = gen_lowpart (DImode, operands[2]);
1665 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1670 [(set (match_operand:DI 0 "push_operand" "")
1671 (match_operand:DI 1 "general_operand" ""))]
1672 "!TARGET_64BIT && reload_completed
1673 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1675 "ix86_split_long_move (operands); DONE;")
1677 (define_insn "*pushsi2"
1678 [(set (match_operand:SI 0 "push_operand" "=<")
1679 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1682 [(set_attr "type" "push")
1683 (set_attr "mode" "SI")])
1685 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1686 ;; "push a byte/word". But actually we use pushl, which has the effect
1687 ;; of rounding the amount pushed up to a word.
1689 ;; For TARGET_64BIT we always round up to 8 bytes.
1690 (define_insn "*push<mode>2_rex64"
1691 [(set (match_operand:SWI124 0 "push_operand" "=X")
1692 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1695 [(set_attr "type" "push")
1696 (set_attr "mode" "DI")])
1698 (define_insn "*push<mode>2"
1699 [(set (match_operand:SWI12 0 "push_operand" "=X")
1700 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1703 [(set_attr "type" "push")
1704 (set_attr "mode" "SI")])
1706 (define_insn "*push<mode>2_prologue"
1707 [(set (match_operand:P 0 "push_operand" "=<")
1708 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1709 (clobber (mem:BLK (scratch)))]
1711 "push{<imodesuffix>}\t%1"
1712 [(set_attr "type" "push")
1713 (set_attr "mode" "<MODE>")])
1715 (define_insn "*pop<mode>1"
1716 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1717 (match_operand:P 1 "pop_operand" ">"))]
1719 "pop{<imodesuffix>}\t%0"
1720 [(set_attr "type" "pop")
1721 (set_attr "mode" "<MODE>")])
1723 (define_insn "*pop<mode>1_epilogue"
1724 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1725 (match_operand:P 1 "pop_operand" ">"))
1726 (clobber (mem:BLK (scratch)))]
1728 "pop{<imodesuffix>}\t%0"
1729 [(set_attr "type" "pop")
1730 (set_attr "mode" "<MODE>")])
1732 ;; Move instructions.
1734 (define_expand "movoi"
1735 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1736 (match_operand:OI 1 "general_operand" ""))]
1738 "ix86_expand_move (OImode, operands); DONE;")
1740 (define_expand "movti"
1741 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1742 (match_operand:TI 1 "nonimmediate_operand" ""))]
1743 "TARGET_64BIT || TARGET_SSE"
1746 ix86_expand_move (TImode, operands);
1747 else if (push_operand (operands[0], TImode))
1748 ix86_expand_push (TImode, operands[1]);
1750 ix86_expand_vector_move (TImode, operands);
1754 ;; This expands to what emit_move_complex would generate if we didn't
1755 ;; have a movti pattern. Having this avoids problems with reload on
1756 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1757 ;; to have around all the time.
1758 (define_expand "movcdi"
1759 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1760 (match_operand:CDI 1 "general_operand" ""))]
1763 if (push_operand (operands[0], CDImode))
1764 emit_move_complex_push (CDImode, operands[0], operands[1]);
1766 emit_move_complex_parts (operands[0], operands[1]);
1770 (define_expand "mov<mode>"
1771 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1772 (match_operand:SWI1248x 1 "general_operand" ""))]
1774 "ix86_expand_move (<MODE>mode, operands); DONE;")
1776 (define_insn "*mov<mode>_xor"
1777 [(set (match_operand:SWI48 0 "register_operand" "=r")
1778 (match_operand:SWI48 1 "const0_operand" ""))
1779 (clobber (reg:CC FLAGS_REG))]
1782 [(set_attr "type" "alu1")
1783 (set_attr "mode" "SI")
1784 (set_attr "length_immediate" "0")])
1786 (define_insn "*mov<mode>_or"
1787 [(set (match_operand:SWI48 0 "register_operand" "=r")
1788 (match_operand:SWI48 1 "const_int_operand" ""))
1789 (clobber (reg:CC FLAGS_REG))]
1791 && operands[1] == constm1_rtx"
1792 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1793 [(set_attr "type" "alu1")
1794 (set_attr "mode" "<MODE>")
1795 (set_attr "length_immediate" "1")])
1797 (define_insn "*movoi_internal_avx"
1798 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1799 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1800 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1802 switch (which_alternative)
1805 return standard_sse_constant_opcode (insn, operands[1]);
1808 if (misaligned_operand (operands[0], OImode)
1809 || misaligned_operand (operands[1], OImode))
1810 return "vmovdqu\t{%1, %0|%0, %1}";
1812 return "vmovdqa\t{%1, %0|%0, %1}";
1817 [(set_attr "type" "sselog1,ssemov,ssemov")
1818 (set_attr "prefix" "vex")
1819 (set_attr "mode" "OI")])
1821 (define_insn "*movti_internal_rex64"
1822 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,m")
1823 (match_operand:TI 1 "general_operand" "riFo,re,C,xm,x"))]
1824 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1826 switch (which_alternative)
1832 return standard_sse_constant_opcode (insn, operands[1]);
1835 /* TDmode values are passed as TImode on the stack. Moving them
1836 to stack may result in unaligned memory access. */
1837 if (misaligned_operand (operands[0], TImode)
1838 || misaligned_operand (operands[1], TImode))
1840 if (get_attr_mode (insn) == MODE_V4SF)
1841 return "%vmovups\t{%1, %0|%0, %1}";
1843 return "%vmovdqu\t{%1, %0|%0, %1}";
1847 if (get_attr_mode (insn) == MODE_V4SF)
1848 return "%vmovaps\t{%1, %0|%0, %1}";
1850 return "%vmovdqa\t{%1, %0|%0, %1}";
1856 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1857 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1859 (cond [(eq_attr "alternative" "2,3")
1861 (match_test "optimize_function_for_size_p (cfun)")
1862 (const_string "V4SF")
1863 (const_string "TI"))
1864 (eq_attr "alternative" "4")
1866 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
1867 (match_test "optimize_function_for_size_p (cfun)"))
1868 (const_string "V4SF")
1869 (const_string "TI"))]
1870 (const_string "DI")))])
1873 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1874 (match_operand:TI 1 "general_operand" ""))]
1876 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1878 "ix86_split_long_move (operands); DONE;")
1880 (define_insn "*movti_internal_sse"
1881 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1882 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1883 "TARGET_SSE && !TARGET_64BIT
1884 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1886 switch (which_alternative)
1889 return standard_sse_constant_opcode (insn, operands[1]);
1892 /* TDmode values are passed as TImode on the stack. Moving them
1893 to stack may result in unaligned memory access. */
1894 if (misaligned_operand (operands[0], TImode)
1895 || misaligned_operand (operands[1], TImode))
1897 if (get_attr_mode (insn) == MODE_V4SF)
1898 return "%vmovups\t{%1, %0|%0, %1}";
1900 return "%vmovdqu\t{%1, %0|%0, %1}";
1904 if (get_attr_mode (insn) == MODE_V4SF)
1905 return "%vmovaps\t{%1, %0|%0, %1}";
1907 return "%vmovdqa\t{%1, %0|%0, %1}";
1913 [(set_attr "type" "sselog1,ssemov,ssemov")
1914 (set_attr "prefix" "maybe_vex")
1916 (cond [(ior (not (match_test "TARGET_SSE2"))
1917 (match_test "optimize_function_for_size_p (cfun)"))
1918 (const_string "V4SF")
1919 (and (eq_attr "alternative" "2")
1920 (match_test "TARGET_SSE_TYPELESS_STORES"))
1921 (const_string "V4SF")]
1922 (const_string "TI")))])
1924 (define_insn "*movdi_internal_rex64"
1925 [(set (match_operand:DI 0 "nonimmediate_operand"
1926 "=r,r ,r,m ,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1927 (match_operand:DI 1 "general_operand"
1928 "Z ,rem,i,re,C ,*y ,m ,*Ym,r ,C ,*x,*x,m ,*Yi,r ,*Ym,*x"))]
1929 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1931 switch (get_attr_type (insn))
1934 if (SSE_REG_P (operands[0]))
1935 return "movq2dq\t{%1, %0|%0, %1}";
1937 return "movdq2q\t{%1, %0|%0, %1}";
1940 if (get_attr_mode (insn) == MODE_TI)
1941 return "%vmovdqa\t{%1, %0|%0, %1}";
1942 /* Handle broken assemblers that require movd instead of movq. */
1943 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1944 return "%vmovd\t{%1, %0|%0, %1}";
1946 return "%vmovq\t{%1, %0|%0, %1}";
1949 /* Handle broken assemblers that require movd instead of movq. */
1950 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1951 return "movd\t{%1, %0|%0, %1}";
1953 return "movq\t{%1, %0|%0, %1}";
1956 return standard_sse_constant_opcode (insn, operands[1]);
1959 return "pxor\t%0, %0";
1962 return "lea{q}\t{%E1, %0|%0, %E1}";
1965 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1966 if (get_attr_mode (insn) == MODE_SI)
1967 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1968 else if (which_alternative == 2)
1969 return "movabs{q}\t{%1, %0|%0, %1}";
1970 else if (ix86_use_lea_for_mov (insn, operands))
1971 return "lea{q}\t{%E1, %0|%0, %E1}";
1973 return "mov{q}\t{%1, %0|%0, %1}";
1977 (cond [(eq_attr "alternative" "4")
1978 (const_string "mmx")
1979 (eq_attr "alternative" "5,6,7,8")
1980 (const_string "mmxmov")
1981 (eq_attr "alternative" "9")
1982 (const_string "sselog1")
1983 (eq_attr "alternative" "10,11,12,13,14")
1984 (const_string "ssemov")
1985 (eq_attr "alternative" "15,16")
1986 (const_string "ssecvt")
1987 (match_operand 1 "pic_32bit_operand" "")
1988 (const_string "lea")
1990 (const_string "imov")))
1993 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
1995 (const_string "*")))
1996 (set (attr "length_immediate")
1998 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2000 (const_string "*")))
2001 (set (attr "prefix_rex")
2002 (if_then_else (eq_attr "alternative" "7,8")
2004 (const_string "*")))
2005 (set (attr "prefix_data16")
2006 (if_then_else (eq_attr "alternative" "10")
2008 (const_string "*")))
2009 (set (attr "prefix")
2010 (if_then_else (eq_attr "alternative" "11,12,13,14,15")
2011 (const_string "maybe_vex")
2012 (const_string "orig")))
2013 (set_attr "mode" "SI,DI,DI,DI,DI,DI,DI,DI,DI,TI,DI,TI,DI,DI,DI,DI,DI")])
2015 ;; Reload patterns to support multi-word load/store
2016 ;; with non-offsetable address.
2017 (define_expand "reload_noff_store"
2018 [(parallel [(match_operand 0 "memory_operand" "=m")
2019 (match_operand 1 "register_operand" "r")
2020 (match_operand:DI 2 "register_operand" "=&r")])]
2023 rtx mem = operands[0];
2024 rtx addr = XEXP (mem, 0);
2026 emit_move_insn (operands[2], addr);
2027 mem = replace_equiv_address_nv (mem, operands[2]);
2029 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
2033 (define_expand "reload_noff_load"
2034 [(parallel [(match_operand 0 "register_operand" "=r")
2035 (match_operand 1 "memory_operand" "m")
2036 (match_operand:DI 2 "register_operand" "=r")])]
2039 rtx mem = operands[1];
2040 rtx addr = XEXP (mem, 0);
2042 emit_move_insn (operands[2], addr);
2043 mem = replace_equiv_address_nv (mem, operands[2]);
2045 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
2049 (define_insn "*movdi_internal"
2050 [(set (match_operand:DI 0 "nonimmediate_operand"
2051 "=r ,o ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym")
2052 (match_operand:DI 1 "general_operand"
2053 "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))]
2054 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2056 switch (get_attr_type (insn))
2059 if (SSE_REG_P (operands[0]))
2060 return "movq2dq\t{%1, %0|%0, %1}";
2062 return "movdq2q\t{%1, %0|%0, %1}";
2065 switch (get_attr_mode (insn))
2068 return "%vmovdqa\t{%1, %0|%0, %1}";
2070 return "%vmovq\t{%1, %0|%0, %1}";
2072 return "movaps\t{%1, %0|%0, %1}";
2074 return "movlps\t{%1, %0|%0, %1}";
2080 return "movq\t{%1, %0|%0, %1}";
2083 return standard_sse_constant_opcode (insn, operands[1]);
2086 return "pxor\t%0, %0";
2096 (cond [(eq_attr "alternative" "5,6,7,8,13,14")
2097 (const_string "sse2")
2098 (eq_attr "alternative" "9,10,11,12")
2099 (const_string "noavx")
2101 (const_string "*")))
2103 (cond [(eq_attr "alternative" "0,1")
2104 (const_string "multi")
2105 (eq_attr "alternative" "2")
2106 (const_string "mmx")
2107 (eq_attr "alternative" "3,4")
2108 (const_string "mmxmov")
2109 (eq_attr "alternative" "5,9")
2110 (const_string "sselog1")
2111 (eq_attr "alternative" "13,14")
2112 (const_string "ssecvt")
2114 (const_string "ssemov")))
2115 (set (attr "prefix")
2116 (if_then_else (eq_attr "alternative" "5,6,7,8")
2117 (const_string "maybe_vex")
2118 (const_string "orig")))
2119 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")])
2122 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2123 (match_operand:DI 1 "general_operand" ""))]
2124 "!TARGET_64BIT && reload_completed
2125 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2126 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2128 "ix86_split_long_move (operands); DONE;")
2130 (define_insn "*movsi_internal"
2131 [(set (match_operand:SI 0 "nonimmediate_operand"
2132 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2133 (match_operand:SI 1 "general_operand"
2134 "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2135 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2137 switch (get_attr_type (insn))
2140 return standard_sse_constant_opcode (insn, operands[1]);
2143 switch (get_attr_mode (insn))
2146 return "%vmovdqa\t{%1, %0|%0, %1}";
2148 return "%vmovaps\t{%1, %0|%0, %1}";
2150 return "%vmovd\t{%1, %0|%0, %1}";
2152 return "%vmovss\t{%1, %0|%0, %1}";
2158 return "pxor\t%0, %0";
2161 if (get_attr_mode (insn) == MODE_DI)
2162 return "movq\t{%1, %0|%0, %1}";
2163 return "movd\t{%1, %0|%0, %1}";
2166 return "lea{l}\t{%E1, %0|%0, %E1}";
2169 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2170 if (ix86_use_lea_for_mov (insn, operands))
2171 return "lea{l}\t{%E1, %0|%0, %E1}";
2173 return "mov{l}\t{%1, %0|%0, %1}";
2177 (cond [(eq_attr "alternative" "2")
2178 (const_string "mmx")
2179 (eq_attr "alternative" "3,4,5")
2180 (const_string "mmxmov")
2181 (eq_attr "alternative" "6")
2182 (const_string "sselog1")
2183 (eq_attr "alternative" "7,8,9,10,11")
2184 (const_string "ssemov")
2185 (match_operand 1 "pic_32bit_operand" "")
2186 (const_string "lea")
2188 (const_string "imov")))
2189 (set (attr "prefix")
2190 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2191 (const_string "orig")
2192 (const_string "maybe_vex")))
2193 (set (attr "prefix_data16")
2194 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2196 (const_string "*")))
2198 (cond [(eq_attr "alternative" "2,3")
2200 (eq_attr "alternative" "6,7")
2202 (not (match_test "TARGET_SSE2"))
2203 (const_string "V4SF")
2204 (const_string "TI"))
2205 (and (eq_attr "alternative" "8,9,10,11")
2206 (not (match_test "TARGET_SSE2")))
2209 (const_string "SI")))])
2211 (define_insn "*movhi_internal"
2212 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2213 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2214 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2216 switch (get_attr_type (insn))
2219 /* movzwl is faster than movw on p2 due to partial word stalls,
2220 though not as fast as an aligned movl. */
2221 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2223 if (get_attr_mode (insn) == MODE_SI)
2224 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2226 return "mov{w}\t{%1, %0|%0, %1}";
2230 (cond [(match_test "optimize_function_for_size_p (cfun)")
2231 (const_string "imov")
2232 (and (eq_attr "alternative" "0")
2233 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2234 (not (match_test "TARGET_HIMODE_MATH"))))
2235 (const_string "imov")
2236 (and (eq_attr "alternative" "1,2")
2237 (match_operand:HI 1 "aligned_operand" ""))
2238 (const_string "imov")
2239 (and (match_test "TARGET_MOVX")
2240 (eq_attr "alternative" "0,2"))
2241 (const_string "imovx")
2243 (const_string "imov")))
2245 (cond [(eq_attr "type" "imovx")
2247 (and (eq_attr "alternative" "1,2")
2248 (match_operand:HI 1 "aligned_operand" ""))
2250 (and (eq_attr "alternative" "0")
2251 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2252 (not (match_test "TARGET_HIMODE_MATH"))))
2255 (const_string "HI")))])
2257 ;; Situation is quite tricky about when to choose full sized (SImode) move
2258 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2259 ;; partial register dependency machines (such as AMD Athlon), where QImode
2260 ;; moves issue extra dependency and for partial register stalls machines
2261 ;; that don't use QImode patterns (and QImode move cause stall on the next
2264 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2265 ;; register stall machines with, where we use QImode instructions, since
2266 ;; partial register stall can be caused there. Then we use movzx.
2267 (define_insn "*movqi_internal"
2268 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2269 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2270 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2272 switch (get_attr_type (insn))
2275 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2276 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2278 if (get_attr_mode (insn) == MODE_SI)
2279 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2281 return "mov{b}\t{%1, %0|%0, %1}";
2285 (cond [(and (eq_attr "alternative" "5")
2286 (not (match_operand:QI 1 "aligned_operand" "")))
2287 (const_string "imovx")
2288 (match_test "optimize_function_for_size_p (cfun)")
2289 (const_string "imov")
2290 (and (eq_attr "alternative" "3")
2291 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2292 (not (match_test "TARGET_QIMODE_MATH"))))
2293 (const_string "imov")
2294 (eq_attr "alternative" "3,5")
2295 (const_string "imovx")
2296 (and (match_test "TARGET_MOVX")
2297 (eq_attr "alternative" "2"))
2298 (const_string "imovx")
2300 (const_string "imov")))
2302 (cond [(eq_attr "alternative" "3,4,5")
2304 (eq_attr "alternative" "6")
2306 (eq_attr "type" "imovx")
2308 (and (eq_attr "type" "imov")
2309 (and (eq_attr "alternative" "0,1")
2310 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2311 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2312 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2314 ;; Avoid partial register stalls when not using QImode arithmetic
2315 (and (eq_attr "type" "imov")
2316 (and (eq_attr "alternative" "0,1")
2317 (and (match_test "TARGET_PARTIAL_REG_STALL")
2318 (not (match_test "TARGET_QIMODE_MATH")))))
2321 (const_string "QI")))])
2323 ;; Stores and loads of ax to arbitrary constant address.
2324 ;; We fake an second form of instruction to force reload to load address
2325 ;; into register when rax is not available
2326 (define_insn "*movabs<mode>_1"
2327 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2328 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2329 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2331 movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1}
2332 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2333 [(set_attr "type" "imov")
2334 (set_attr "modrm" "0,*")
2335 (set_attr "length_address" "8,0")
2336 (set_attr "length_immediate" "0,*")
2337 (set_attr "memory" "store")
2338 (set_attr "mode" "<MODE>")])
2340 (define_insn "*movabs<mode>_2"
2341 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2342 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2343 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2345 movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]}
2346 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2347 [(set_attr "type" "imov")
2348 (set_attr "modrm" "0,*")
2349 (set_attr "length_address" "8,0")
2350 (set_attr "length_immediate" "0")
2351 (set_attr "memory" "load")
2352 (set_attr "mode" "<MODE>")])
2354 (define_insn "*swap<mode>"
2355 [(set (match_operand:SWI48 0 "register_operand" "+r")
2356 (match_operand:SWI48 1 "register_operand" "+r"))
2360 "xchg{<imodesuffix>}\t%1, %0"
2361 [(set_attr "type" "imov")
2362 (set_attr "mode" "<MODE>")
2363 (set_attr "pent_pair" "np")
2364 (set_attr "athlon_decode" "vector")
2365 (set_attr "amdfam10_decode" "double")
2366 (set_attr "bdver1_decode" "double")])
2368 (define_insn "*swap<mode>_1"
2369 [(set (match_operand:SWI12 0 "register_operand" "+r")
2370 (match_operand:SWI12 1 "register_operand" "+r"))
2373 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2375 [(set_attr "type" "imov")
2376 (set_attr "mode" "SI")
2377 (set_attr "pent_pair" "np")
2378 (set_attr "athlon_decode" "vector")
2379 (set_attr "amdfam10_decode" "double")
2380 (set_attr "bdver1_decode" "double")])
2382 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2383 ;; is disabled for AMDFAM10
2384 (define_insn "*swap<mode>_2"
2385 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2386 (match_operand:SWI12 1 "register_operand" "+<r>"))
2389 "TARGET_PARTIAL_REG_STALL"
2390 "xchg{<imodesuffix>}\t%1, %0"
2391 [(set_attr "type" "imov")
2392 (set_attr "mode" "<MODE>")
2393 (set_attr "pent_pair" "np")
2394 (set_attr "athlon_decode" "vector")])
2396 (define_expand "movstrict<mode>"
2397 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2398 (match_operand:SWI12 1 "general_operand" ""))]
2401 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2403 if (GET_CODE (operands[0]) == SUBREG
2404 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2406 /* Don't generate memory->memory moves, go through a register */
2407 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2408 operands[1] = force_reg (<MODE>mode, operands[1]);
2411 (define_insn "*movstrict<mode>_1"
2412 [(set (strict_low_part
2413 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2414 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2415 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2416 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2417 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2418 [(set_attr "type" "imov")
2419 (set_attr "mode" "<MODE>")])
2421 (define_insn "*movstrict<mode>_xor"
2422 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2423 (match_operand:SWI12 1 "const0_operand" ""))
2424 (clobber (reg:CC FLAGS_REG))]
2426 "xor{<imodesuffix>}\t%0, %0"
2427 [(set_attr "type" "alu1")
2428 (set_attr "mode" "<MODE>")
2429 (set_attr "length_immediate" "0")])
2431 (define_insn "*mov<mode>_extv_1"
2432 [(set (match_operand:SWI24 0 "register_operand" "=R")
2433 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2437 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2438 [(set_attr "type" "imovx")
2439 (set_attr "mode" "SI")])
2441 (define_insn "*movqi_extv_1_rex64"
2442 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2443 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2448 switch (get_attr_type (insn))
2451 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2453 return "mov{b}\t{%h1, %0|%0, %h1}";
2457 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2458 (match_test "TARGET_MOVX"))
2459 (const_string "imovx")
2460 (const_string "imov")))
2462 (if_then_else (eq_attr "type" "imovx")
2464 (const_string "QI")))])
2466 (define_insn "*movqi_extv_1"
2467 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2468 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2473 switch (get_attr_type (insn))
2476 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2478 return "mov{b}\t{%h1, %0|%0, %h1}";
2482 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2483 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2484 (match_test "TARGET_MOVX")))
2485 (const_string "imovx")
2486 (const_string "imov")))
2488 (if_then_else (eq_attr "type" "imovx")
2490 (const_string "QI")))])
2492 (define_insn "*mov<mode>_extzv_1"
2493 [(set (match_operand:SWI48 0 "register_operand" "=R")
2494 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2498 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2499 [(set_attr "type" "imovx")
2500 (set_attr "mode" "SI")])
2502 (define_insn "*movqi_extzv_2_rex64"
2503 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2505 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2510 switch (get_attr_type (insn))
2513 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2515 return "mov{b}\t{%h1, %0|%0, %h1}";
2519 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2520 (match_test "TARGET_MOVX"))
2521 (const_string "imovx")
2522 (const_string "imov")))
2524 (if_then_else (eq_attr "type" "imovx")
2526 (const_string "QI")))])
2528 (define_insn "*movqi_extzv_2"
2529 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2531 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2536 switch (get_attr_type (insn))
2539 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2541 return "mov{b}\t{%h1, %0|%0, %h1}";
2545 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2546 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2547 (match_test "TARGET_MOVX")))
2548 (const_string "imovx")
2549 (const_string "imov")))
2551 (if_then_else (eq_attr "type" "imovx")
2553 (const_string "QI")))])
2555 (define_expand "mov<mode>_insv_1"
2556 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2559 (match_operand:SWI48 1 "nonmemory_operand" ""))])
2561 (define_insn "*mov<mode>_insv_1_rex64"
2562 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2565 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2568 if (CONST_INT_P (operands[1]))
2569 operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2570 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2572 [(set_attr "type" "imov")
2573 (set_attr "mode" "QI")])
2575 (define_insn "*movsi_insv_1"
2576 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2579 (match_operand:SI 1 "general_operand" "Qmn"))]
2582 if (CONST_INT_P (operands[1]))
2583 operands[1] = simplify_gen_subreg (QImode, operands[1], SImode, 0);
2584 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2586 [(set_attr "type" "imov")
2587 (set_attr "mode" "QI")])
2589 (define_insn "*movqi_insv_2"
2590 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2593 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2596 "mov{b}\t{%h1, %h0|%h0, %h1}"
2597 [(set_attr "type" "imov")
2598 (set_attr "mode" "QI")])
2600 ;; Floating point push instructions.
2602 (define_insn "*pushtf"
2603 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2604 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2607 /* This insn should be already split before reg-stack. */
2610 [(set_attr "type" "multi")
2611 (set_attr "unit" "sse,*,*")
2612 (set_attr "mode" "TF,SI,SI")])
2614 ;; %%% Kill this when call knows how to work this out.
2616 [(set (match_operand:TF 0 "push_operand" "")
2617 (match_operand:TF 1 "sse_reg_operand" ""))]
2618 "TARGET_SSE2 && reload_completed"
2619 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2620 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2622 (define_insn "*pushxf"
2623 [(set (match_operand:XF 0 "push_operand" "=<,<")
2624 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2625 "optimize_function_for_speed_p (cfun)"
2627 /* This insn should be already split before reg-stack. */
2630 [(set_attr "type" "multi")
2631 (set_attr "unit" "i387,*")
2632 (set_attr "mode" "XF,SI")])
2634 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2635 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2636 ;; Pushing using integer instructions is longer except for constants
2637 ;; and direct memory references (assuming that any given constant is pushed
2638 ;; only once, but this ought to be handled elsewhere).
2640 (define_insn "*pushxf_nointeger"
2641 [(set (match_operand:XF 0 "push_operand" "=<,<")
2642 (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2643 "optimize_function_for_size_p (cfun)"
2645 /* This insn should be already split before reg-stack. */
2648 [(set_attr "type" "multi")
2649 (set_attr "unit" "i387,*")
2650 (set_attr "mode" "XF,SI")])
2652 ;; %%% Kill this when call knows how to work this out.
2654 [(set (match_operand:XF 0 "push_operand" "")
2655 (match_operand:XF 1 "fp_register_operand" ""))]
2657 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2658 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2659 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2661 (define_insn "*pushdf_rex64"
2662 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2663 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
2666 /* This insn should be already split before reg-stack. */
2669 [(set_attr "type" "multi")
2670 (set_attr "unit" "i387,*,*")
2671 (set_attr "mode" "DF,DI,DF")])
2673 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2674 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2675 ;; On the average, pushdf using integers can be still shorter.
2677 (define_insn "*pushdf"
2678 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2679 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
2682 /* This insn should be already split before reg-stack. */
2685 [(set_attr "isa" "*,*,sse2")
2686 (set_attr "type" "multi")
2687 (set_attr "unit" "i387,*,*")
2688 (set_attr "mode" "DF,DI,DF")])
2690 ;; %%% Kill this when call knows how to work this out.
2692 [(set (match_operand:DF 0 "push_operand" "")
2693 (match_operand:DF 1 "any_fp_register_operand" ""))]
2695 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2696 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2698 (define_insn "*pushsf_rex64"
2699 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2700 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2703 /* Anything else should be already split before reg-stack. */
2704 gcc_assert (which_alternative == 1);
2705 return "push{q}\t%q1";
2707 [(set_attr "type" "multi,push,multi")
2708 (set_attr "unit" "i387,*,*")
2709 (set_attr "mode" "SF,DI,SF")])
2711 (define_insn "*pushsf"
2712 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2713 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2716 /* Anything else should be already split before reg-stack. */
2717 gcc_assert (which_alternative == 1);
2718 return "push{l}\t%1";
2720 [(set_attr "type" "multi,push,multi")
2721 (set_attr "unit" "i387,*,*")
2722 (set_attr "mode" "SF,SI,SF")])
2724 ;; %%% Kill this when call knows how to work this out.
2726 [(set (match_operand:SF 0 "push_operand" "")
2727 (match_operand:SF 1 "any_fp_register_operand" ""))]
2729 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2730 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2731 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2734 [(set (match_operand:SF 0 "push_operand" "")
2735 (match_operand:SF 1 "memory_operand" ""))]
2737 && (operands[2] = find_constant_src (insn))"
2738 [(set (match_dup 0) (match_dup 2))])
2741 [(set (match_operand 0 "push_operand" "")
2742 (match_operand 1 "general_operand" ""))]
2744 && (GET_MODE (operands[0]) == TFmode
2745 || GET_MODE (operands[0]) == XFmode
2746 || GET_MODE (operands[0]) == DFmode)
2747 && !ANY_FP_REG_P (operands[1])"
2749 "ix86_split_long_move (operands); DONE;")
2751 ;; Floating point move instructions.
2753 (define_expand "movtf"
2754 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2755 (match_operand:TF 1 "nonimmediate_operand" ""))]
2756 "TARGET_64BIT || TARGET_SSE2"
2758 ix86_expand_move (TFmode, operands);
2762 (define_expand "mov<mode>"
2763 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2764 (match_operand:X87MODEF 1 "general_operand" ""))]
2766 "ix86_expand_move (<MODE>mode, operands); DONE;")
2768 (define_insn "*movtf_internal_rex64"
2769 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o")
2770 (match_operand:TF 1 "general_operand" "xm,x,C,*roF,*r"))]
2771 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2772 && (!can_create_pseudo_p ()
2773 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2774 || GET_CODE (operands[1]) != CONST_DOUBLE
2775 || (optimize_function_for_size_p (cfun)
2776 && standard_sse_constant_p (operands[1])
2777 && !memory_operand (operands[0], TFmode))
2778 || (!TARGET_MEMORY_MISMATCH_STALL
2779 && memory_operand (operands[0], TFmode)))"
2781 switch (which_alternative)
2785 /* Handle misaligned load/store since we
2786 don't have movmisaligntf pattern. */
2787 if (misaligned_operand (operands[0], TFmode)
2788 || misaligned_operand (operands[1], TFmode))
2790 if (get_attr_mode (insn) == MODE_V4SF)
2791 return "%vmovups\t{%1, %0|%0, %1}";
2793 return "%vmovdqu\t{%1, %0|%0, %1}";
2797 if (get_attr_mode (insn) == MODE_V4SF)
2798 return "%vmovaps\t{%1, %0|%0, %1}";
2800 return "%vmovdqa\t{%1, %0|%0, %1}";
2804 return standard_sse_constant_opcode (insn, operands[1]);
2814 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2815 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2817 (cond [(eq_attr "alternative" "0,2")
2819 (match_test "optimize_function_for_size_p (cfun)")
2820 (const_string "V4SF")
2821 (const_string "TI"))
2822 (eq_attr "alternative" "1")
2824 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
2825 (match_test "optimize_function_for_size_p (cfun)"))
2826 (const_string "V4SF")
2827 (const_string "TI"))]
2828 (const_string "DI")))])
2830 (define_insn "*movtf_internal_sse2"
2831 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x")
2832 (match_operand:TF 1 "general_operand" "xm,x,C"))]
2833 "TARGET_SSE2 && !TARGET_64BIT
2834 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2835 && (!can_create_pseudo_p ()
2836 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2837 || GET_CODE (operands[1]) != CONST_DOUBLE
2838 || (optimize_function_for_size_p (cfun)
2839 && standard_sse_constant_p (operands[1])
2840 && !memory_operand (operands[0], TFmode))
2841 || (!TARGET_MEMORY_MISMATCH_STALL
2842 && memory_operand (operands[0], TFmode)))"
2844 switch (which_alternative)
2848 /* Handle misaligned load/store since we
2849 don't have movmisaligntf pattern. */
2850 if (misaligned_operand (operands[0], TFmode)
2851 || misaligned_operand (operands[1], TFmode))
2853 if (get_attr_mode (insn) == MODE_V4SF)
2854 return "%vmovups\t{%1, %0|%0, %1}";
2856 return "%vmovdqu\t{%1, %0|%0, %1}";
2860 if (get_attr_mode (insn) == MODE_V4SF)
2861 return "%vmovaps\t{%1, %0|%0, %1}";
2863 return "%vmovdqa\t{%1, %0|%0, %1}";
2867 return standard_sse_constant_opcode (insn, operands[1]);
2873 [(set_attr "type" "ssemov,ssemov,sselog1")
2874 (set_attr "prefix" "maybe_vex")
2876 (cond [(eq_attr "alternative" "0,2")
2878 (match_test "optimize_function_for_size_p (cfun)")
2879 (const_string "V4SF")
2880 (const_string "TI"))
2881 (eq_attr "alternative" "1")
2883 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
2884 (match_test "optimize_function_for_size_p (cfun)"))
2885 (const_string "V4SF")
2886 (const_string "TI"))]
2887 (const_string "DI")))])
2889 (define_insn "*movxf_internal_rex64"
2890 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2891 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,Yx*rC"))]
2892 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2893 && (!can_create_pseudo_p ()
2894 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2895 || GET_CODE (operands[1]) != CONST_DOUBLE
2896 || (optimize_function_for_size_p (cfun)
2897 && standard_80387_constant_p (operands[1]) > 0
2898 && !memory_operand (operands[0], XFmode))
2899 || (!TARGET_MEMORY_MISMATCH_STALL
2900 && memory_operand (operands[0], XFmode)))"
2902 switch (which_alternative)
2906 return output_387_reg_move (insn, operands);
2909 return standard_80387_constant_opcode (operands[1]);
2919 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2920 (set_attr "mode" "XF,XF,XF,SI,SI")])
2922 ;; Possible store forwarding (partial memory) stall in alternative 4.
2923 (define_insn "*movxf_internal"
2924 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2925 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,Yx*rF"))]
2926 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2927 && (!can_create_pseudo_p ()
2928 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2929 || GET_CODE (operands[1]) != CONST_DOUBLE
2930 || (optimize_function_for_size_p (cfun)
2931 && standard_80387_constant_p (operands[1]) > 0
2932 && !memory_operand (operands[0], XFmode))
2933 || (!TARGET_MEMORY_MISMATCH_STALL
2934 && memory_operand (operands[0], XFmode)))"
2936 switch (which_alternative)
2940 return output_387_reg_move (insn, operands);
2943 return standard_80387_constant_opcode (operands[1]);
2953 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2954 (set_attr "mode" "XF,XF,XF,SI,SI")])
2956 (define_insn "*movdf_internal_rex64"
2957 [(set (match_operand:DF 0 "nonimmediate_operand"
2958 "=?Yf*f,?m ,?Yf*f,?r,?m,?r,?r,x,x,x,m,Yi,r ")
2959 (match_operand:DF 1 "general_operand"
2960 "Yf*fm ,Yf*f ,G ,rm,rC,C ,F ,C,x,m,x,r ,Yi"))]
2961 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2962 && (!can_create_pseudo_p ()
2963 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2964 || GET_CODE (operands[1]) != CONST_DOUBLE
2965 || (optimize_function_for_size_p (cfun)
2966 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2967 && standard_80387_constant_p (operands[1]) > 0)
2968 || (TARGET_SSE2 && TARGET_SSE_MATH
2969 && standard_sse_constant_p (operands[1]))))
2970 || memory_operand (operands[0], DFmode))"
2972 switch (which_alternative)
2976 return output_387_reg_move (insn, operands);
2979 return standard_80387_constant_opcode (operands[1]);
2983 return "mov{q}\t{%1, %0|%0, %1}";
2986 return "mov{l}\t{%1, %k0|%k0, %1}";
2989 return "movabs{q}\t{%1, %0|%0, %1}";
2992 return standard_sse_constant_opcode (insn, operands[1]);
2997 switch (get_attr_mode (insn))
3000 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3001 return "%vmovapd\t{%1, %0|%0, %1}";
3003 return "%vmovaps\t{%1, %0|%0, %1}";
3006 return "%vmovq\t{%1, %0|%0, %1}";
3008 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3009 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3010 return "%vmovsd\t{%1, %0|%0, %1}";
3012 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3014 return "%vmovlps\t{%1, %d0|%d0, %1}";
3021 /* Handle broken assemblers that require movd instead of movq. */
3022 return "%vmovd\t{%1, %0|%0, %1}";
3029 (cond [(eq_attr "alternative" "0,1,2")
3030 (const_string "fmov")
3031 (eq_attr "alternative" "3,4,5,6")
3032 (const_string "imov")
3033 (eq_attr "alternative" "7")
3034 (const_string "sselog1")
3036 (const_string "ssemov")))
3039 (and (eq_attr "alternative" "6") (eq_attr "type" "imov"))
3041 (const_string "*")))
3042 (set (attr "length_immediate")
3044 (and (eq_attr "alternative" "6") (eq_attr "type" "imov"))
3046 (const_string "*")))
3047 (set (attr "prefix")
3048 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3049 (const_string "orig")
3050 (const_string "maybe_vex")))
3051 (set (attr "prefix_data16")
3052 (if_then_else (eq_attr "mode" "V1DF")
3054 (const_string "*")))
3056 (cond [(eq_attr "alternative" "0,1,2")
3058 (eq_attr "alternative" "3,4,6,11,12")
3060 (eq_attr "alternative" "5")
3063 /* xorps is one byte shorter. */
3064 (eq_attr "alternative" "7")
3065 (cond [(match_test "optimize_function_for_size_p (cfun)")
3066 (const_string "V4SF")
3067 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3070 (const_string "V2DF"))
3072 /* For architectures resolving dependencies on
3073 whole SSE registers use APD move to break dependency
3074 chains, otherwise use short move to avoid extra work.
3076 movaps encodes one byte shorter. */
3077 (eq_attr "alternative" "8")
3079 [(match_test "optimize_function_for_size_p (cfun)")
3080 (const_string "V4SF")
3081 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3082 (const_string "V2DF")
3084 (const_string "DF"))
3085 /* For architectures resolving dependencies on register
3086 parts we may avoid extra work to zero out upper part
3088 (eq_attr "alternative" "9")
3090 (match_test "TARGET_SSE_SPLIT_REGS")
3091 (const_string "V1DF")
3092 (const_string "DF"))
3094 (const_string "DF")))])
3096 ;; Possible store forwarding (partial memory) stall in alternative 4.
3097 (define_insn "*movdf_internal"
3098 [(set (match_operand:DF 0 "nonimmediate_operand"
3099 "=Yf*f,m ,Yf*f,?Yd*r ,!o ,x,x,x,m,*x,*x,*x,m")
3100 (match_operand:DF 1 "general_operand"
3101 "Yf*fm,Yf*f,G ,Yd*roF,Yd*rF,C,x,m,x,C ,*x,m ,*x"))]
3102 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3103 && (!can_create_pseudo_p ()
3104 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3105 || GET_CODE (operands[1]) != CONST_DOUBLE
3106 || (optimize_function_for_size_p (cfun)
3107 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3108 && standard_80387_constant_p (operands[1]) > 0)
3109 || (TARGET_SSE2 && TARGET_SSE_MATH
3110 && standard_sse_constant_p (operands[1])))
3111 && !memory_operand (operands[0], DFmode))
3112 || (!TARGET_MEMORY_MISMATCH_STALL
3113 && memory_operand (operands[0], DFmode)))"
3115 switch (which_alternative)
3119 return output_387_reg_move (insn, operands);
3122 return standard_80387_constant_opcode (operands[1]);
3130 return standard_sse_constant_opcode (insn, operands[1]);
3138 switch (get_attr_mode (insn))
3141 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3142 return "%vmovapd\t{%1, %0|%0, %1}";
3144 return "%vmovaps\t{%1, %0|%0, %1}";
3147 return "%vmovq\t{%1, %0|%0, %1}";
3149 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3150 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3151 return "%vmovsd\t{%1, %0|%0, %1}";
3153 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3155 return "%vmovlps\t{%1, %d0|%d0, %1}";
3165 (if_then_else (eq_attr "alternative" "5,6,7,8")
3166 (const_string "sse2")
3167 (const_string "*")))
3169 (cond [(eq_attr "alternative" "0,1,2")
3170 (const_string "fmov")
3171 (eq_attr "alternative" "3,4")
3172 (const_string "multi")
3173 (eq_attr "alternative" "5,9")
3174 (const_string "sselog1")
3176 (const_string "ssemov")))
3177 (set (attr "prefix")
3178 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3179 (const_string "orig")
3180 (const_string "maybe_vex")))
3181 (set (attr "prefix_data16")
3182 (if_then_else (eq_attr "mode" "V1DF")
3184 (const_string "*")))
3186 (cond [(eq_attr "alternative" "0,1,2")
3188 (eq_attr "alternative" "3,4")
3191 /* For SSE1, we have many fewer alternatives. */
3192 (not (match_test "TARGET_SSE2"))
3194 (eq_attr "alternative" "5,6,9,10")
3195 (const_string "V4SF")
3196 (const_string "V2SF"))
3198 /* xorps is one byte shorter. */
3199 (eq_attr "alternative" "5,9")
3200 (cond [(match_test "optimize_function_for_size_p (cfun)")
3201 (const_string "V4SF")
3202 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3205 (const_string "V2DF"))
3207 /* For architectures resolving dependencies on
3208 whole SSE registers use APD move to break dependency
3209 chains, otherwise use short move to avoid extra work.
3211 movaps encodes one byte shorter. */
3212 (eq_attr "alternative" "6,10")
3214 [(match_test "optimize_function_for_size_p (cfun)")
3215 (const_string "V4SF")
3216 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3217 (const_string "V2DF")
3219 (const_string "DF"))
3220 /* For architectures resolving dependencies on register
3221 parts we may avoid extra work to zero out upper part
3223 (eq_attr "alternative" "7,11")
3225 (match_test "TARGET_SSE_SPLIT_REGS")
3226 (const_string "V1DF")
3227 (const_string "DF"))
3229 (const_string "DF")))])
3231 (define_insn "*movsf_internal"
3232 [(set (match_operand:SF 0 "nonimmediate_operand"
3233 "=Yf*f,m ,Yf*f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3234 (match_operand:SF 1 "general_operand"
3235 "Yf*fm,Yf*f,G ,rmF,rF,C,x,m,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3236 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3237 && (!can_create_pseudo_p ()
3238 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3239 || GET_CODE (operands[1]) != CONST_DOUBLE
3240 || (optimize_function_for_size_p (cfun)
3241 && ((!TARGET_SSE_MATH
3242 && standard_80387_constant_p (operands[1]) > 0)
3244 && standard_sse_constant_p (operands[1]))))
3245 || memory_operand (operands[0], SFmode))"
3247 switch (which_alternative)
3251 return output_387_reg_move (insn, operands);
3254 return standard_80387_constant_opcode (operands[1]);
3258 return "mov{l}\t{%1, %0|%0, %1}";
3261 return standard_sse_constant_opcode (insn, operands[1]);
3264 if (get_attr_mode (insn) == MODE_V4SF)
3265 return "%vmovaps\t{%1, %0|%0, %1}";
3267 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3271 return "%vmovss\t{%1, %0|%0, %1}";
3277 return "movd\t{%1, %0|%0, %1}";
3280 return "movq\t{%1, %0|%0, %1}";
3284 return "%vmovd\t{%1, %0|%0, %1}";
3291 (cond [(eq_attr "alternative" "0,1,2")
3292 (const_string "fmov")
3293 (eq_attr "alternative" "3,4")
3294 (const_string "imov")
3295 (eq_attr "alternative" "5")
3296 (const_string "sselog1")
3297 (eq_attr "alternative" "9,10,11,14,15")
3298 (const_string "mmxmov")
3300 (const_string "ssemov")))
3301 (set (attr "prefix")
3302 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3303 (const_string "maybe_vex")
3304 (const_string "orig")))
3306 (cond [(eq_attr "alternative" "3,4,9,10")
3308 (eq_attr "alternative" "5")
3310 (and (and (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3311 (match_test "TARGET_SSE2"))
3312 (not (match_test "optimize_function_for_size_p (cfun)")))
3314 (const_string "V4SF"))
3315 /* For architectures resolving dependencies on
3316 whole SSE registers use APS move to break dependency
3317 chains, otherwise use short move to avoid extra work.
3319 Do the same for architectures resolving dependencies on
3320 the parts. While in DF mode it is better to always handle
3321 just register parts, the SF mode is different due to lack
3322 of instructions to load just part of the register. It is
3323 better to maintain the whole registers in single format
3324 to avoid problems on using packed logical operations. */
3325 (eq_attr "alternative" "6")
3327 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3328 (match_test "TARGET_SSE_SPLIT_REGS"))
3329 (const_string "V4SF")
3330 (const_string "SF"))
3331 (eq_attr "alternative" "11")
3332 (const_string "DI")]
3333 (const_string "SF")))])
3336 [(set (match_operand 0 "any_fp_register_operand" "")
3337 (match_operand 1 "memory_operand" ""))]
3339 && (GET_MODE (operands[0]) == TFmode
3340 || GET_MODE (operands[0]) == XFmode
3341 || GET_MODE (operands[0]) == DFmode
3342 || GET_MODE (operands[0]) == SFmode)
3343 && (operands[2] = find_constant_src (insn))"
3344 [(set (match_dup 0) (match_dup 2))]
3346 rtx c = operands[2];
3347 int r = REGNO (operands[0]);
3349 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3350 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3355 [(set (match_operand 0 "any_fp_register_operand" "")
3356 (float_extend (match_operand 1 "memory_operand" "")))]
3358 && (GET_MODE (operands[0]) == TFmode
3359 || GET_MODE (operands[0]) == XFmode
3360 || GET_MODE (operands[0]) == DFmode)
3361 && (operands[2] = find_constant_src (insn))"
3362 [(set (match_dup 0) (match_dup 2))]
3364 rtx c = operands[2];
3365 int r = REGNO (operands[0]);
3367 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3368 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3372 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3374 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
3375 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3377 && (standard_80387_constant_p (operands[1]) == 8
3378 || standard_80387_constant_p (operands[1]) == 9)"
3379 [(set (match_dup 0)(match_dup 1))
3381 (neg:X87MODEF (match_dup 0)))]
3385 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3386 if (real_isnegzero (&r))
3387 operands[1] = CONST0_RTX (<MODE>mode);
3389 operands[1] = CONST1_RTX (<MODE>mode);
3393 [(set (match_operand 0 "nonimmediate_operand" "")
3394 (match_operand 1 "general_operand" ""))]
3396 && (GET_MODE (operands[0]) == TFmode
3397 || GET_MODE (operands[0]) == XFmode
3398 || GET_MODE (operands[0]) == DFmode)
3399 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3401 "ix86_split_long_move (operands); DONE;")
3403 (define_insn "swapxf"
3404 [(set (match_operand:XF 0 "register_operand" "+f")
3405 (match_operand:XF 1 "register_operand" "+f"))
3410 if (STACK_TOP_P (operands[0]))
3415 [(set_attr "type" "fxch")
3416 (set_attr "mode" "XF")])
3418 (define_insn "*swap<mode>"
3419 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3420 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3423 "TARGET_80387 || reload_completed"
3425 if (STACK_TOP_P (operands[0]))
3430 [(set_attr "type" "fxch")
3431 (set_attr "mode" "<MODE>")])
3433 ;; Zero extension instructions
3435 (define_expand "zero_extendsidi2"
3436 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3437 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3442 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3447 (define_insn "*zero_extendsidi2_rex64"
3448 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?!*y,?*Yi,*x")
3450 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3453 mov{l}\t{%1, %k0|%k0, %1}
3455 movd\t{%1, %0|%0, %1}
3456 movd\t{%1, %0|%0, %1}
3457 %vmovd\t{%1, %0|%0, %1}
3458 %vmovd\t{%1, %0|%0, %1}"
3459 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3460 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3461 (set_attr "prefix_0f" "0,*,*,*,*,*")
3462 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3465 [(set (match_operand:DI 0 "memory_operand" "")
3466 (zero_extend:DI (match_dup 0)))]
3468 [(set (match_dup 4) (const_int 0))]
3469 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3471 ;; %%% Kill me once multi-word ops are sane.
3472 (define_insn "zero_extendsidi2_1"
3473 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?!*y,?*Yi,*x")
3475 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3476 (clobber (reg:CC FLAGS_REG))]
3482 movd\t{%1, %0|%0, %1}
3483 movd\t{%1, %0|%0, %1}
3484 %vmovd\t{%1, %0|%0, %1}
3485 %vmovd\t{%1, %0|%0, %1}"
3486 [(set_attr "isa" "*,*,*,*,*,*,sse2")
3487 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3488 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3489 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3492 [(set (match_operand:DI 0 "register_operand" "")
3493 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3494 (clobber (reg:CC FLAGS_REG))]
3495 "!TARGET_64BIT && reload_completed
3496 && true_regnum (operands[0]) == true_regnum (operands[1])"
3497 [(set (match_dup 4) (const_int 0))]
3498 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3501 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3502 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3503 (clobber (reg:CC FLAGS_REG))]
3504 "!TARGET_64BIT && reload_completed
3505 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3506 [(set (match_dup 3) (match_dup 1))
3507 (set (match_dup 4) (const_int 0))]
3508 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3510 (define_insn "zero_extend<mode>di2"
3511 [(set (match_operand:DI 0 "register_operand" "=r")
3513 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3515 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3516 [(set_attr "type" "imovx")
3517 (set_attr "mode" "SI")])
3519 (define_expand "zero_extendhisi2"
3520 [(set (match_operand:SI 0 "register_operand" "")
3521 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3524 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3526 operands[1] = force_reg (HImode, operands[1]);
3527 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3532 (define_insn_and_split "zero_extendhisi2_and"
3533 [(set (match_operand:SI 0 "register_operand" "=r")
3534 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3535 (clobber (reg:CC FLAGS_REG))]
3536 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3538 "&& reload_completed"
3539 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3540 (clobber (reg:CC FLAGS_REG))])]
3542 [(set_attr "type" "alu1")
3543 (set_attr "mode" "SI")])
3545 (define_insn "*zero_extendhisi2_movzwl"
3546 [(set (match_operand:SI 0 "register_operand" "=r")
3547 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3548 "!TARGET_ZERO_EXTEND_WITH_AND
3549 || optimize_function_for_size_p (cfun)"
3550 "movz{wl|x}\t{%1, %0|%0, %1}"
3551 [(set_attr "type" "imovx")
3552 (set_attr "mode" "SI")])
3554 (define_expand "zero_extendqi<mode>2"
3556 [(set (match_operand:SWI24 0 "register_operand" "")
3557 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3558 (clobber (reg:CC FLAGS_REG))])])
3560 (define_insn "*zero_extendqi<mode>2_and"
3561 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3562 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3563 (clobber (reg:CC FLAGS_REG))]
3564 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3566 [(set_attr "type" "alu1")
3567 (set_attr "mode" "<MODE>")])
3569 ;; When source and destination does not overlap, clear destination
3570 ;; first and then do the movb
3572 [(set (match_operand:SWI24 0 "register_operand" "")
3573 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3574 (clobber (reg:CC FLAGS_REG))]
3576 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3577 && ANY_QI_REG_P (operands[0])
3578 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3579 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3580 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3582 operands[2] = gen_lowpart (QImode, operands[0]);
3583 ix86_expand_clear (operands[0]);
3586 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3587 [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3588 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3589 (clobber (reg:CC FLAGS_REG))]
3590 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3592 [(set_attr "type" "imovx,alu1")
3593 (set_attr "mode" "<MODE>")])
3595 ;; For the movzbl case strip only the clobber
3597 [(set (match_operand:SWI24 0 "register_operand" "")
3598 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3599 (clobber (reg:CC FLAGS_REG))]
3601 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3602 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3604 (zero_extend:SWI24 (match_dup 1)))])
3606 ; zero extend to SImode to avoid partial register stalls
3607 (define_insn "*zero_extendqi<mode>2_movzbl"
3608 [(set (match_operand:SWI24 0 "register_operand" "=r")
3609 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3611 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3612 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3613 [(set_attr "type" "imovx")
3614 (set_attr "mode" "SI")])
3616 ;; Rest is handled by single and.
3618 [(set (match_operand:SWI24 0 "register_operand" "")
3619 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3620 (clobber (reg:CC FLAGS_REG))]
3622 && true_regnum (operands[0]) == true_regnum (operands[1])"
3623 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3624 (clobber (reg:CC FLAGS_REG))])])
3626 ;; Sign extension instructions
3628 (define_expand "extendsidi2"
3629 [(set (match_operand:DI 0 "register_operand" "")
3630 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3635 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3640 (define_insn "*extendsidi2_rex64"
3641 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3642 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3646 movs{lq|x}\t{%1, %0|%0, %1}"
3647 [(set_attr "type" "imovx")
3648 (set_attr "mode" "DI")
3649 (set_attr "prefix_0f" "0")
3650 (set_attr "modrm" "0,1")])
3652 (define_insn "extendsidi2_1"
3653 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3654 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3655 (clobber (reg:CC FLAGS_REG))
3656 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3660 ;; Extend to memory case when source register does die.
3662 [(set (match_operand:DI 0 "memory_operand" "")
3663 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3664 (clobber (reg:CC FLAGS_REG))
3665 (clobber (match_operand:SI 2 "register_operand" ""))]
3667 && dead_or_set_p (insn, operands[1])
3668 && !reg_mentioned_p (operands[1], operands[0]))"
3669 [(set (match_dup 3) (match_dup 1))
3670 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3671 (clobber (reg:CC FLAGS_REG))])
3672 (set (match_dup 4) (match_dup 1))]
3673 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3675 ;; Extend to memory case when source register does not die.
3677 [(set (match_operand:DI 0 "memory_operand" "")
3678 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3679 (clobber (reg:CC FLAGS_REG))
3680 (clobber (match_operand:SI 2 "register_operand" ""))]
3684 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3686 emit_move_insn (operands[3], operands[1]);
3688 /* Generate a cltd if possible and doing so it profitable. */
3689 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3690 && true_regnum (operands[1]) == AX_REG
3691 && true_regnum (operands[2]) == DX_REG)
3693 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3697 emit_move_insn (operands[2], operands[1]);
3698 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3700 emit_move_insn (operands[4], operands[2]);
3704 ;; Extend to register case. Optimize case where source and destination
3705 ;; registers match and cases where we can use cltd.
3707 [(set (match_operand:DI 0 "register_operand" "")
3708 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3709 (clobber (reg:CC FLAGS_REG))
3710 (clobber (match_scratch:SI 2 ""))]
3714 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3716 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3717 emit_move_insn (operands[3], operands[1]);
3719 /* Generate a cltd if possible and doing so it profitable. */
3720 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3721 && true_regnum (operands[3]) == AX_REG
3722 && true_regnum (operands[4]) == DX_REG)
3724 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3728 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3729 emit_move_insn (operands[4], operands[1]);
3731 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3735 (define_insn "extend<mode>di2"
3736 [(set (match_operand:DI 0 "register_operand" "=r")
3738 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3740 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3741 [(set_attr "type" "imovx")
3742 (set_attr "mode" "DI")])
3744 (define_insn "extendhisi2"
3745 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3746 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3749 switch (get_attr_prefix_0f (insn))
3752 return "{cwtl|cwde}";
3754 return "movs{wl|x}\t{%1, %0|%0, %1}";
3757 [(set_attr "type" "imovx")
3758 (set_attr "mode" "SI")
3759 (set (attr "prefix_0f")
3760 ;; movsx is short decodable while cwtl is vector decoded.
3761 (if_then_else (and (eq_attr "cpu" "!k6")
3762 (eq_attr "alternative" "0"))
3764 (const_string "1")))
3766 (if_then_else (eq_attr "prefix_0f" "0")
3768 (const_string "1")))])
3770 (define_insn "*extendhisi2_zext"
3771 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3774 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3777 switch (get_attr_prefix_0f (insn))
3780 return "{cwtl|cwde}";
3782 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3785 [(set_attr "type" "imovx")
3786 (set_attr "mode" "SI")
3787 (set (attr "prefix_0f")
3788 ;; movsx is short decodable while cwtl is vector decoded.
3789 (if_then_else (and (eq_attr "cpu" "!k6")
3790 (eq_attr "alternative" "0"))
3792 (const_string "1")))
3794 (if_then_else (eq_attr "prefix_0f" "0")
3796 (const_string "1")))])
3798 (define_insn "extendqisi2"
3799 [(set (match_operand:SI 0 "register_operand" "=r")
3800 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3802 "movs{bl|x}\t{%1, %0|%0, %1}"
3803 [(set_attr "type" "imovx")
3804 (set_attr "mode" "SI")])
3806 (define_insn "*extendqisi2_zext"
3807 [(set (match_operand:DI 0 "register_operand" "=r")
3809 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3811 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3812 [(set_attr "type" "imovx")
3813 (set_attr "mode" "SI")])
3815 (define_insn "extendqihi2"
3816 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3817 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3820 switch (get_attr_prefix_0f (insn))
3823 return "{cbtw|cbw}";
3825 return "movs{bw|x}\t{%1, %0|%0, %1}";
3828 [(set_attr "type" "imovx")
3829 (set_attr "mode" "HI")
3830 (set (attr "prefix_0f")
3831 ;; movsx is short decodable while cwtl is vector decoded.
3832 (if_then_else (and (eq_attr "cpu" "!k6")
3833 (eq_attr "alternative" "0"))
3835 (const_string "1")))
3837 (if_then_else (eq_attr "prefix_0f" "0")
3839 (const_string "1")))])
3841 ;; Conversions between float and double.
3843 ;; These are all no-ops in the model used for the 80387.
3844 ;; So just emit moves.
3846 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3848 [(set (match_operand:DF 0 "push_operand" "")
3849 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3851 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3852 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3855 [(set (match_operand:XF 0 "push_operand" "")
3856 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3858 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3859 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3860 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3862 (define_expand "extendsfdf2"
3863 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3864 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3865 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3867 /* ??? Needed for compress_float_constant since all fp constants
3868 are TARGET_LEGITIMATE_CONSTANT_P. */
3869 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3871 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3872 && standard_80387_constant_p (operands[1]) > 0)
3874 operands[1] = simplify_const_unary_operation
3875 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3876 emit_move_insn_1 (operands[0], operands[1]);
3879 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3883 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3885 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3887 We do the conversion post reload to avoid producing of 128bit spills
3888 that might lead to ICE on 32bit target. The sequence unlikely combine
3891 [(set (match_operand:DF 0 "register_operand" "")
3893 (match_operand:SF 1 "nonimmediate_operand" "")))]
3894 "TARGET_USE_VECTOR_FP_CONVERTS
3895 && optimize_insn_for_speed_p ()
3896 && reload_completed && SSE_REG_P (operands[0])"
3901 (parallel [(const_int 0) (const_int 1)]))))]
3903 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3904 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3905 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3906 Try to avoid move when unpacking can be done in source. */
3907 if (REG_P (operands[1]))
3909 /* If it is unsafe to overwrite upper half of source, we need
3910 to move to destination and unpack there. */
3911 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3912 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3913 && true_regnum (operands[0]) != true_regnum (operands[1]))
3915 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3916 emit_move_insn (tmp, operands[1]);
3919 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3920 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3924 emit_insn (gen_vec_setv4sf_0 (operands[3],
3925 CONST0_RTX (V4SFmode), operands[1]));
3928 (define_insn "*extendsfdf2_mixed"
3929 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3931 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3932 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3934 switch (which_alternative)
3938 return output_387_reg_move (insn, operands);
3941 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3947 [(set_attr "type" "fmov,fmov,ssecvt")
3948 (set_attr "prefix" "orig,orig,maybe_vex")
3949 (set_attr "mode" "SF,XF,DF")])
3951 (define_insn "*extendsfdf2_sse"
3952 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3953 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3954 "TARGET_SSE2 && TARGET_SSE_MATH"
3955 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3956 [(set_attr "type" "ssecvt")
3957 (set_attr "prefix" "maybe_vex")
3958 (set_attr "mode" "DF")])
3960 (define_insn "*extendsfdf2_i387"
3961 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3962 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3964 "* return output_387_reg_move (insn, operands);"
3965 [(set_attr "type" "fmov")
3966 (set_attr "mode" "SF,XF")])
3968 (define_expand "extend<mode>xf2"
3969 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3970 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3973 /* ??? Needed for compress_float_constant since all fp constants
3974 are TARGET_LEGITIMATE_CONSTANT_P. */
3975 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3977 if (standard_80387_constant_p (operands[1]) > 0)
3979 operands[1] = simplify_const_unary_operation
3980 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3981 emit_move_insn_1 (operands[0], operands[1]);
3984 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3988 (define_insn "*extend<mode>xf2_i387"
3989 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3991 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3993 "* return output_387_reg_move (insn, operands);"
3994 [(set_attr "type" "fmov")
3995 (set_attr "mode" "<MODE>,XF")])
3997 ;; %%% This seems bad bad news.
3998 ;; This cannot output into an f-reg because there is no way to be sure
3999 ;; of truncating in that case. Otherwise this is just like a simple move
4000 ;; insn. So we pretend we can output to a reg in order to get better
4001 ;; register preferencing, but we really use a stack slot.
4003 ;; Conversion from DFmode to SFmode.
4005 (define_expand "truncdfsf2"
4006 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4008 (match_operand:DF 1 "nonimmediate_operand" "")))]
4009 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4011 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4013 else if (flag_unsafe_math_optimizations)
4017 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4018 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4023 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4025 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4027 We do the conversion post reload to avoid producing of 128bit spills
4028 that might lead to ICE on 32bit target. The sequence unlikely combine
4031 [(set (match_operand:SF 0 "register_operand" "")
4033 (match_operand:DF 1 "nonimmediate_operand" "")))]
4034 "TARGET_USE_VECTOR_FP_CONVERTS
4035 && optimize_insn_for_speed_p ()
4036 && reload_completed && SSE_REG_P (operands[0])"
4039 (float_truncate:V2SF
4043 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4044 operands[3] = CONST0_RTX (V2SFmode);
4045 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4046 /* Use movsd for loading from memory, unpcklpd for registers.
4047 Try to avoid move when unpacking can be done in source, or SSE3
4048 movddup is available. */
4049 if (REG_P (operands[1]))
4052 && true_regnum (operands[0]) != true_regnum (operands[1])
4053 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4054 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4056 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4057 emit_move_insn (tmp, operands[1]);
4060 else if (!TARGET_SSE3)
4061 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4062 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4065 emit_insn (gen_sse2_loadlpd (operands[4],
4066 CONST0_RTX (V2DFmode), operands[1]));
4069 (define_expand "truncdfsf2_with_temp"
4070 [(parallel [(set (match_operand:SF 0 "" "")
4071 (float_truncate:SF (match_operand:DF 1 "" "")))
4072 (clobber (match_operand:SF 2 "" ""))])])
4074 (define_insn "*truncdfsf_fast_mixed"
4075 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4077 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4078 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4080 switch (which_alternative)
4083 return output_387_reg_move (insn, operands);
4085 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4090 [(set_attr "type" "fmov,ssecvt")
4091 (set_attr "prefix" "orig,maybe_vex")
4092 (set_attr "mode" "SF")])
4094 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4095 ;; because nothing we do here is unsafe.
4096 (define_insn "*truncdfsf_fast_sse"
4097 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4099 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4100 "TARGET_SSE2 && TARGET_SSE_MATH"
4101 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4102 [(set_attr "type" "ssecvt")
4103 (set_attr "prefix" "maybe_vex")
4104 (set_attr "mode" "SF")])
4106 (define_insn "*truncdfsf_fast_i387"
4107 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4109 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4110 "TARGET_80387 && flag_unsafe_math_optimizations"
4111 "* return output_387_reg_move (insn, operands);"
4112 [(set_attr "type" "fmov")
4113 (set_attr "mode" "SF")])
4115 (define_insn "*truncdfsf_mixed"
4116 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4118 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4119 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4120 "TARGET_MIX_SSE_I387"
4122 switch (which_alternative)
4125 return output_387_reg_move (insn, operands);
4127 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4133 [(set_attr "isa" "*,sse2,*,*,*")
4134 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4135 (set_attr "unit" "*,*,i387,i387,i387")
4136 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4137 (set_attr "mode" "SF")])
4139 (define_insn "*truncdfsf_i387"
4140 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4142 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4143 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4146 switch (which_alternative)
4149 return output_387_reg_move (insn, operands);
4155 [(set_attr "type" "fmov,multi,multi,multi")
4156 (set_attr "unit" "*,i387,i387,i387")
4157 (set_attr "mode" "SF")])
4159 (define_insn "*truncdfsf2_i387_1"
4160 [(set (match_operand:SF 0 "memory_operand" "=m")
4162 (match_operand:DF 1 "register_operand" "f")))]
4164 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4165 && !TARGET_MIX_SSE_I387"
4166 "* return output_387_reg_move (insn, operands);"
4167 [(set_attr "type" "fmov")
4168 (set_attr "mode" "SF")])
4171 [(set (match_operand:SF 0 "register_operand" "")
4173 (match_operand:DF 1 "fp_register_operand" "")))
4174 (clobber (match_operand 2 "" ""))]
4176 [(set (match_dup 2) (match_dup 1))
4177 (set (match_dup 0) (match_dup 2))]
4178 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4180 ;; Conversion from XFmode to {SF,DF}mode
4182 (define_expand "truncxf<mode>2"
4183 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4184 (float_truncate:MODEF
4185 (match_operand:XF 1 "register_operand" "")))
4186 (clobber (match_dup 2))])]
4189 if (flag_unsafe_math_optimizations)
4191 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4192 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4193 if (reg != operands[0])
4194 emit_move_insn (operands[0], reg);
4198 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4201 (define_insn "*truncxfsf2_mixed"
4202 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4204 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4205 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4208 gcc_assert (!which_alternative);
4209 return output_387_reg_move (insn, operands);
4211 [(set_attr "type" "fmov,multi,multi,multi")
4212 (set_attr "unit" "*,i387,i387,i387")
4213 (set_attr "mode" "SF")])
4215 (define_insn "*truncxfdf2_mixed"
4216 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4218 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4219 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4222 gcc_assert (!which_alternative);
4223 return output_387_reg_move (insn, operands);
4225 [(set_attr "isa" "*,*,sse2,*")
4226 (set_attr "type" "fmov,multi,multi,multi")
4227 (set_attr "unit" "*,i387,i387,i387")
4228 (set_attr "mode" "DF")])
4230 (define_insn "truncxf<mode>2_i387_noop"
4231 [(set (match_operand:MODEF 0 "register_operand" "=f")
4232 (float_truncate:MODEF
4233 (match_operand:XF 1 "register_operand" "f")))]
4234 "TARGET_80387 && flag_unsafe_math_optimizations"
4235 "* return output_387_reg_move (insn, operands);"
4236 [(set_attr "type" "fmov")
4237 (set_attr "mode" "<MODE>")])
4239 (define_insn "*truncxf<mode>2_i387"
4240 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4241 (float_truncate:MODEF
4242 (match_operand:XF 1 "register_operand" "f")))]
4244 "* return output_387_reg_move (insn, operands);"
4245 [(set_attr "type" "fmov")
4246 (set_attr "mode" "<MODE>")])
4249 [(set (match_operand:MODEF 0 "register_operand" "")
4250 (float_truncate:MODEF
4251 (match_operand:XF 1 "register_operand" "")))
4252 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4253 "TARGET_80387 && reload_completed"
4254 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4255 (set (match_dup 0) (match_dup 2))])
4258 [(set (match_operand:MODEF 0 "memory_operand" "")
4259 (float_truncate:MODEF
4260 (match_operand:XF 1 "register_operand" "")))
4261 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4263 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4265 ;; Signed conversion to DImode.
4267 (define_expand "fix_truncxfdi2"
4268 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4269 (fix:DI (match_operand:XF 1 "register_operand" "")))
4270 (clobber (reg:CC FLAGS_REG))])]
4275 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4280 (define_expand "fix_trunc<mode>di2"
4281 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4282 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4283 (clobber (reg:CC FLAGS_REG))])]
4284 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4287 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4289 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4292 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4294 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4295 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4296 if (out != operands[0])
4297 emit_move_insn (operands[0], out);
4302 ;; Signed conversion to SImode.
4304 (define_expand "fix_truncxfsi2"
4305 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4306 (fix:SI (match_operand:XF 1 "register_operand" "")))
4307 (clobber (reg:CC FLAGS_REG))])]
4312 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4317 (define_expand "fix_trunc<mode>si2"
4318 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4319 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4320 (clobber (reg:CC FLAGS_REG))])]
4321 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4324 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4326 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4329 if (SSE_FLOAT_MODE_P (<MODE>mode))
4331 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4332 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4333 if (out != operands[0])
4334 emit_move_insn (operands[0], out);
4339 ;; Signed conversion to HImode.
4341 (define_expand "fix_trunc<mode>hi2"
4342 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4343 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4344 (clobber (reg:CC FLAGS_REG))])]
4346 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4350 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4355 ;; Unsigned conversion to SImode.
4357 (define_expand "fixuns_trunc<mode>si2"
4359 [(set (match_operand:SI 0 "register_operand" "")
4361 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4363 (clobber (match_scratch:<ssevecmode> 3 ""))
4364 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4365 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4367 enum machine_mode mode = <MODE>mode;
4368 enum machine_mode vecmode = <ssevecmode>mode;
4369 REAL_VALUE_TYPE TWO31r;
4372 if (optimize_insn_for_size_p ())
4375 real_ldexp (&TWO31r, &dconst1, 31);
4376 two31 = const_double_from_real_value (TWO31r, mode);
4377 two31 = ix86_build_const_vector (vecmode, true, two31);
4378 operands[2] = force_reg (vecmode, two31);
4381 (define_insn_and_split "*fixuns_trunc<mode>_1"
4382 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4384 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4385 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4386 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4387 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4388 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4389 && optimize_function_for_speed_p (cfun)"
4391 "&& reload_completed"
4394 ix86_split_convert_uns_si_sse (operands);
4398 ;; Unsigned conversion to HImode.
4399 ;; Without these patterns, we'll try the unsigned SI conversion which
4400 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4402 (define_expand "fixuns_trunc<mode>hi2"
4404 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4405 (set (match_operand:HI 0 "nonimmediate_operand" "")
4406 (subreg:HI (match_dup 2) 0))]
4407 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4408 "operands[2] = gen_reg_rtx (SImode);")
4410 ;; When SSE is available, it is always faster to use it!
4411 (define_insn "fix_trunc<mode>di_sse"
4412 [(set (match_operand:DI 0 "register_operand" "=r,r")
4413 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4414 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4415 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4416 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4417 [(set_attr "type" "sseicvt")
4418 (set_attr "prefix" "maybe_vex")
4419 (set_attr "prefix_rex" "1")
4420 (set_attr "mode" "<MODE>")
4421 (set_attr "athlon_decode" "double,vector")
4422 (set_attr "amdfam10_decode" "double,double")
4423 (set_attr "bdver1_decode" "double,double")])
4425 (define_insn "fix_trunc<mode>si_sse"
4426 [(set (match_operand:SI 0 "register_operand" "=r,r")
4427 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4428 "SSE_FLOAT_MODE_P (<MODE>mode)
4429 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4430 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4431 [(set_attr "type" "sseicvt")
4432 (set_attr "prefix" "maybe_vex")
4433 (set_attr "mode" "<MODE>")
4434 (set_attr "athlon_decode" "double,vector")
4435 (set_attr "amdfam10_decode" "double,double")
4436 (set_attr "bdver1_decode" "double,double")])
4438 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4440 [(set (match_operand:MODEF 0 "register_operand" "")
4441 (match_operand:MODEF 1 "memory_operand" ""))
4442 (set (match_operand:SWI48x 2 "register_operand" "")
4443 (fix:SWI48x (match_dup 0)))]
4444 "TARGET_SHORTEN_X87_SSE
4445 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4446 && peep2_reg_dead_p (2, operands[0])"
4447 [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4449 ;; Avoid vector decoded forms of the instruction.
4451 [(match_scratch:DF 2 "x")
4452 (set (match_operand:SWI48x 0 "register_operand" "")
4453 (fix:SWI48x (match_operand:DF 1 "memory_operand" "")))]
4454 "TARGET_SSE2 && TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4455 [(set (match_dup 2) (match_dup 1))
4456 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4459 [(match_scratch:SF 2 "x")
4460 (set (match_operand:SWI48x 0 "register_operand" "")
4461 (fix:SWI48x (match_operand:SF 1 "memory_operand" "")))]
4462 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4463 [(set (match_dup 2) (match_dup 1))
4464 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4466 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4467 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4468 (fix:SWI248x (match_operand 1 "register_operand" "")))]
4469 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4471 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4472 && (TARGET_64BIT || <MODE>mode != DImode))
4474 && can_create_pseudo_p ()"
4479 if (memory_operand (operands[0], VOIDmode))
4480 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4483 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4484 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4490 [(set_attr "type" "fisttp")
4491 (set_attr "mode" "<MODE>")])
4493 (define_insn "fix_trunc<mode>_i387_fisttp"
4494 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4495 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4496 (clobber (match_scratch:XF 2 "=&1f"))]
4497 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4499 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4500 && (TARGET_64BIT || <MODE>mode != DImode))
4501 && TARGET_SSE_MATH)"
4502 "* return output_fix_trunc (insn, operands, true);"
4503 [(set_attr "type" "fisttp")
4504 (set_attr "mode" "<MODE>")])
4506 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4507 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4508 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4509 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4510 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4511 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4513 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4514 && (TARGET_64BIT || <MODE>mode != DImode))
4515 && TARGET_SSE_MATH)"
4517 [(set_attr "type" "fisttp")
4518 (set_attr "mode" "<MODE>")])
4521 [(set (match_operand:SWI248x 0 "register_operand" "")
4522 (fix:SWI248x (match_operand 1 "register_operand" "")))
4523 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4524 (clobber (match_scratch 3 ""))]
4526 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4527 (clobber (match_dup 3))])
4528 (set (match_dup 0) (match_dup 2))])
4531 [(set (match_operand:SWI248x 0 "memory_operand" "")
4532 (fix:SWI248x (match_operand 1 "register_operand" "")))
4533 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4534 (clobber (match_scratch 3 ""))]
4536 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4537 (clobber (match_dup 3))])])
4539 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4540 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4541 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4542 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4543 ;; function in i386.c.
4544 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4545 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4546 (fix:SWI248x (match_operand 1 "register_operand" "")))
4547 (clobber (reg:CC FLAGS_REG))]
4548 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4550 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4551 && (TARGET_64BIT || <MODE>mode != DImode))
4552 && can_create_pseudo_p ()"
4557 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4559 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4560 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4561 if (memory_operand (operands[0], VOIDmode))
4562 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4563 operands[2], operands[3]));
4566 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4567 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4568 operands[2], operands[3],
4573 [(set_attr "type" "fistp")
4574 (set_attr "i387_cw" "trunc")
4575 (set_attr "mode" "<MODE>")])
4577 (define_insn "fix_truncdi_i387"
4578 [(set (match_operand:DI 0 "memory_operand" "=m")
4579 (fix:DI (match_operand 1 "register_operand" "f")))
4580 (use (match_operand:HI 2 "memory_operand" "m"))
4581 (use (match_operand:HI 3 "memory_operand" "m"))
4582 (clobber (match_scratch:XF 4 "=&1f"))]
4583 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4585 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4586 "* return output_fix_trunc (insn, operands, false);"
4587 [(set_attr "type" "fistp")
4588 (set_attr "i387_cw" "trunc")
4589 (set_attr "mode" "DI")])
4591 (define_insn "fix_truncdi_i387_with_temp"
4592 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4593 (fix:DI (match_operand 1 "register_operand" "f,f")))
4594 (use (match_operand:HI 2 "memory_operand" "m,m"))
4595 (use (match_operand:HI 3 "memory_operand" "m,m"))
4596 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4597 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4598 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4600 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4602 [(set_attr "type" "fistp")
4603 (set_attr "i387_cw" "trunc")
4604 (set_attr "mode" "DI")])
4607 [(set (match_operand:DI 0 "register_operand" "")
4608 (fix:DI (match_operand 1 "register_operand" "")))
4609 (use (match_operand:HI 2 "memory_operand" ""))
4610 (use (match_operand:HI 3 "memory_operand" ""))
4611 (clobber (match_operand:DI 4 "memory_operand" ""))
4612 (clobber (match_scratch 5 ""))]
4614 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4617 (clobber (match_dup 5))])
4618 (set (match_dup 0) (match_dup 4))])
4621 [(set (match_operand:DI 0 "memory_operand" "")
4622 (fix:DI (match_operand 1 "register_operand" "")))
4623 (use (match_operand:HI 2 "memory_operand" ""))
4624 (use (match_operand:HI 3 "memory_operand" ""))
4625 (clobber (match_operand:DI 4 "memory_operand" ""))
4626 (clobber (match_scratch 5 ""))]
4628 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4631 (clobber (match_dup 5))])])
4633 (define_insn "fix_trunc<mode>_i387"
4634 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4635 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4636 (use (match_operand:HI 2 "memory_operand" "m"))
4637 (use (match_operand:HI 3 "memory_operand" "m"))]
4638 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4640 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4641 "* return output_fix_trunc (insn, operands, false);"
4642 [(set_attr "type" "fistp")
4643 (set_attr "i387_cw" "trunc")
4644 (set_attr "mode" "<MODE>")])
4646 (define_insn "fix_trunc<mode>_i387_with_temp"
4647 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4648 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4649 (use (match_operand:HI 2 "memory_operand" "m,m"))
4650 (use (match_operand:HI 3 "memory_operand" "m,m"))
4651 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4652 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4654 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4656 [(set_attr "type" "fistp")
4657 (set_attr "i387_cw" "trunc")
4658 (set_attr "mode" "<MODE>")])
4661 [(set (match_operand:SWI24 0 "register_operand" "")
4662 (fix:SWI24 (match_operand 1 "register_operand" "")))
4663 (use (match_operand:HI 2 "memory_operand" ""))
4664 (use (match_operand:HI 3 "memory_operand" ""))
4665 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4667 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4669 (use (match_dup 3))])
4670 (set (match_dup 0) (match_dup 4))])
4673 [(set (match_operand:SWI24 0 "memory_operand" "")
4674 (fix:SWI24 (match_operand 1 "register_operand" "")))
4675 (use (match_operand:HI 2 "memory_operand" ""))
4676 (use (match_operand:HI 3 "memory_operand" ""))
4677 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4679 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4681 (use (match_dup 3))])])
4683 (define_insn "x86_fnstcw_1"
4684 [(set (match_operand:HI 0 "memory_operand" "=m")
4685 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4688 [(set (attr "length")
4689 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4690 (set_attr "mode" "HI")
4691 (set_attr "unit" "i387")
4692 (set_attr "bdver1_decode" "vector")])
4694 (define_insn "x86_fldcw_1"
4695 [(set (reg:HI FPCR_REG)
4696 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4699 [(set (attr "length")
4700 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4701 (set_attr "mode" "HI")
4702 (set_attr "unit" "i387")
4703 (set_attr "athlon_decode" "vector")
4704 (set_attr "amdfam10_decode" "vector")
4705 (set_attr "bdver1_decode" "vector")])
4707 ;; Conversion between fixed point and floating point.
4709 ;; Even though we only accept memory inputs, the backend _really_
4710 ;; wants to be able to do this between registers.
4712 (define_expand "floathi<mode>2"
4713 [(set (match_operand:X87MODEF 0 "register_operand" "")
4714 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4716 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4717 || TARGET_MIX_SSE_I387)")
4719 ;; Pre-reload splitter to add memory clobber to the pattern.
4720 (define_insn_and_split "*floathi<mode>2_1"
4721 [(set (match_operand:X87MODEF 0 "register_operand" "")
4722 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4724 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4725 || TARGET_MIX_SSE_I387)
4726 && can_create_pseudo_p ()"
4729 [(parallel [(set (match_dup 0)
4730 (float:X87MODEF (match_dup 1)))
4731 (clobber (match_dup 2))])]
4732 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4734 (define_insn "*floathi<mode>2_i387_with_temp"
4735 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4736 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4737 (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4739 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4740 || TARGET_MIX_SSE_I387)"
4742 [(set_attr "type" "fmov,multi")
4743 (set_attr "mode" "<MODE>")
4744 (set_attr "unit" "*,i387")
4745 (set_attr "fp_int_src" "true")])
4747 (define_insn "*floathi<mode>2_i387"
4748 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4749 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4751 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4752 || TARGET_MIX_SSE_I387)"
4754 [(set_attr "type" "fmov")
4755 (set_attr "mode" "<MODE>")
4756 (set_attr "fp_int_src" "true")])
4759 [(set (match_operand:X87MODEF 0 "register_operand" "")
4760 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4761 (clobber (match_operand:HI 2 "memory_operand" ""))]
4763 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4764 || TARGET_MIX_SSE_I387)
4765 && reload_completed"
4766 [(set (match_dup 2) (match_dup 1))
4767 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4770 [(set (match_operand:X87MODEF 0 "register_operand" "")
4771 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4772 (clobber (match_operand:HI 2 "memory_operand" ""))]
4774 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4775 || TARGET_MIX_SSE_I387)
4776 && reload_completed"
4777 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4779 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4780 [(set (match_operand:X87MODEF 0 "register_operand" "")
4782 (match_operand:SWI48x 1 "nonimmediate_operand" "")))]
4784 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4785 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4787 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4788 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4789 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4791 rtx reg = gen_reg_rtx (XFmode);
4792 rtx (*insn)(rtx, rtx);
4794 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4796 if (<X87MODEF:MODE>mode == SFmode)
4797 insn = gen_truncxfsf2;
4798 else if (<X87MODEF:MODE>mode == DFmode)
4799 insn = gen_truncxfdf2;
4803 emit_insn (insn (operands[0], reg));
4808 ;; Pre-reload splitter to add memory clobber to the pattern.
4809 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4810 [(set (match_operand:X87MODEF 0 "register_operand" "")
4811 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))]
4813 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4814 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4815 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4816 || TARGET_MIX_SSE_I387))
4817 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4818 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4819 && ((<SWI48x:MODE>mode == SImode
4820 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4821 && optimize_function_for_speed_p (cfun)
4822 && flag_trapping_math)
4823 || !(TARGET_INTER_UNIT_CONVERSIONS
4824 || optimize_function_for_size_p (cfun)))))
4825 && can_create_pseudo_p ()"
4828 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4829 (clobber (match_dup 2))])]
4831 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4833 /* Avoid store forwarding (partial memory) stall penalty
4834 by passing DImode value through XMM registers. */
4835 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4836 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4837 && optimize_function_for_speed_p (cfun))
4839 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4846 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4847 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4849 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4850 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4851 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4852 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4854 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4855 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4856 (set_attr "unit" "*,i387,*,*,*")
4857 (set_attr "athlon_decode" "*,*,double,direct,double")
4858 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4859 (set_attr "bdver1_decode" "*,*,double,direct,double")
4860 (set_attr "fp_int_src" "true")])
4862 (define_insn "*floatsi<mode>2_vector_mixed"
4863 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4864 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4865 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4866 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4870 [(set_attr "type" "fmov,sseicvt")
4871 (set_attr "mode" "<MODE>,<ssevecmode>")
4872 (set_attr "unit" "i387,*")
4873 (set_attr "athlon_decode" "*,direct")
4874 (set_attr "amdfam10_decode" "*,double")
4875 (set_attr "bdver1_decode" "*,direct")
4876 (set_attr "fp_int_src" "true")])
4878 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4879 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4881 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4882 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4883 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4884 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4886 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4887 (set_attr "mode" "<MODEF:MODE>")
4888 (set_attr "unit" "*,i387,*,*")
4889 (set_attr "athlon_decode" "*,*,double,direct")
4890 (set_attr "amdfam10_decode" "*,*,vector,double")
4891 (set_attr "bdver1_decode" "*,*,double,direct")
4892 (set_attr "fp_int_src" "true")])
4895 [(set (match_operand:MODEF 0 "register_operand" "")
4896 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4897 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4898 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4899 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4900 && TARGET_INTER_UNIT_CONVERSIONS
4902 && (SSE_REG_P (operands[0])
4903 || (GET_CODE (operands[0]) == SUBREG
4904 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4905 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4908 [(set (match_operand:MODEF 0 "register_operand" "")
4909 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4910 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4911 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4912 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4913 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4915 && (SSE_REG_P (operands[0])
4916 || (GET_CODE (operands[0]) == SUBREG
4917 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4918 [(set (match_dup 2) (match_dup 1))
4919 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4921 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4922 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4924 (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4925 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4926 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4927 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4930 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4931 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4932 [(set_attr "type" "fmov,sseicvt,sseicvt")
4933 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4934 (set_attr "mode" "<MODEF:MODE>")
4935 (set (attr "prefix_rex")
4937 (and (eq_attr "prefix" "maybe_vex")
4938 (match_test "<SWI48x:MODE>mode == DImode"))
4940 (const_string "*")))
4941 (set_attr "unit" "i387,*,*")
4942 (set_attr "athlon_decode" "*,double,direct")
4943 (set_attr "amdfam10_decode" "*,vector,double")
4944 (set_attr "bdver1_decode" "*,double,direct")
4945 (set_attr "fp_int_src" "true")])
4947 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4948 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4950 (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4951 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4952 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4953 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4956 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4957 [(set_attr "type" "fmov,sseicvt")
4958 (set_attr "prefix" "orig,maybe_vex")
4959 (set_attr "mode" "<MODEF:MODE>")
4960 (set (attr "prefix_rex")
4962 (and (eq_attr "prefix" "maybe_vex")
4963 (match_test "<SWI48x:MODE>mode == DImode"))
4965 (const_string "*")))
4966 (set_attr "athlon_decode" "*,direct")
4967 (set_attr "amdfam10_decode" "*,double")
4968 (set_attr "bdver1_decode" "*,direct")
4969 (set_attr "fp_int_src" "true")])
4971 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4972 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4974 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4975 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4976 "TARGET_SSE2 && TARGET_SSE_MATH
4977 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4979 [(set_attr "type" "sseicvt")
4980 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4981 (set_attr "athlon_decode" "double,direct,double")
4982 (set_attr "amdfam10_decode" "vector,double,double")
4983 (set_attr "bdver1_decode" "double,direct,double")
4984 (set_attr "fp_int_src" "true")])
4986 (define_insn "*floatsi<mode>2_vector_sse"
4987 [(set (match_operand:MODEF 0 "register_operand" "=x")
4988 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4989 "TARGET_SSE2 && TARGET_SSE_MATH
4990 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4992 [(set_attr "type" "sseicvt")
4993 (set_attr "mode" "<MODE>")
4994 (set_attr "athlon_decode" "direct")
4995 (set_attr "amdfam10_decode" "double")
4996 (set_attr "bdver1_decode" "direct")
4997 (set_attr "fp_int_src" "true")])
5000 [(set (match_operand:MODEF 0 "register_operand" "")
5001 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5002 (clobber (match_operand:SI 2 "memory_operand" ""))]
5003 "TARGET_SSE2 && TARGET_SSE_MATH
5004 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5006 && (SSE_REG_P (operands[0])
5007 || (GET_CODE (operands[0]) == SUBREG
5008 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5011 rtx op1 = operands[1];
5013 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5015 if (GET_CODE (op1) == SUBREG)
5016 op1 = SUBREG_REG (op1);
5018 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5020 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5021 emit_insn (gen_sse2_loadld (operands[4],
5022 CONST0_RTX (V4SImode), operands[1]));
5024 /* We can ignore possible trapping value in the
5025 high part of SSE register for non-trapping math. */
5026 else if (SSE_REG_P (op1) && !flag_trapping_math)
5027 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5030 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5031 emit_move_insn (operands[2], operands[1]);
5032 emit_insn (gen_sse2_loadld (operands[4],
5033 CONST0_RTX (V4SImode), operands[2]));
5035 if (<ssevecmode>mode == V4SFmode)
5036 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5038 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5043 [(set (match_operand:MODEF 0 "register_operand" "")
5044 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5045 (clobber (match_operand:SI 2 "memory_operand" ""))]
5046 "TARGET_SSE2 && TARGET_SSE_MATH
5047 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5049 && (SSE_REG_P (operands[0])
5050 || (GET_CODE (operands[0]) == SUBREG
5051 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5054 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5056 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5058 emit_insn (gen_sse2_loadld (operands[4],
5059 CONST0_RTX (V4SImode), operands[1]));
5060 if (<ssevecmode>mode == V4SFmode)
5061 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5063 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5068 [(set (match_operand:MODEF 0 "register_operand" "")
5069 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5070 "TARGET_SSE2 && TARGET_SSE_MATH
5071 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5073 && (SSE_REG_P (operands[0])
5074 || (GET_CODE (operands[0]) == SUBREG
5075 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5078 rtx op1 = operands[1];
5080 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5082 if (GET_CODE (op1) == SUBREG)
5083 op1 = SUBREG_REG (op1);
5085 if (GENERAL_REG_P (op1))
5087 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5088 if (TARGET_INTER_UNIT_MOVES)
5089 emit_insn (gen_sse2_loadld (operands[4],
5090 CONST0_RTX (V4SImode), operands[1]));
5093 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5095 emit_insn (gen_sse2_loadld (operands[4],
5096 CONST0_RTX (V4SImode), operands[5]));
5097 ix86_free_from_memory (GET_MODE (operands[1]));
5100 /* We can ignore possible trapping value in the
5101 high part of SSE register for non-trapping math. */
5102 else if (SSE_REG_P (op1) && !flag_trapping_math)
5103 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5106 if (<ssevecmode>mode == V4SFmode)
5107 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5109 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5114 [(set (match_operand:MODEF 0 "register_operand" "")
5115 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5116 "TARGET_SSE2 && TARGET_SSE_MATH
5117 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5119 && (SSE_REG_P (operands[0])
5120 || (GET_CODE (operands[0]) == SUBREG
5121 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5124 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5126 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5128 emit_insn (gen_sse2_loadld (operands[4],
5129 CONST0_RTX (V4SImode), operands[1]));
5130 if (<ssevecmode>mode == V4SFmode)
5131 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5133 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5137 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5138 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5140 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5141 (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5142 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5143 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5145 [(set_attr "type" "sseicvt")
5146 (set_attr "mode" "<MODEF:MODE>")
5147 (set_attr "athlon_decode" "double,direct")
5148 (set_attr "amdfam10_decode" "vector,double")
5149 (set_attr "bdver1_decode" "double,direct")
5150 (set_attr "fp_int_src" "true")])
5152 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5153 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5155 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5156 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5157 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5158 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5159 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5160 [(set_attr "type" "sseicvt")
5161 (set_attr "prefix" "maybe_vex")
5162 (set_attr "mode" "<MODEF:MODE>")
5163 (set (attr "prefix_rex")
5165 (and (eq_attr "prefix" "maybe_vex")
5166 (match_test "<SWI48x:MODE>mode == DImode"))
5168 (const_string "*")))
5169 (set_attr "athlon_decode" "double,direct")
5170 (set_attr "amdfam10_decode" "vector,double")
5171 (set_attr "bdver1_decode" "double,direct")
5172 (set_attr "fp_int_src" "true")])
5175 [(set (match_operand:MODEF 0 "register_operand" "")
5176 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "")))
5177 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5178 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5179 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5180 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5182 && (SSE_REG_P (operands[0])
5183 || (GET_CODE (operands[0]) == SUBREG
5184 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5185 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5187 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5188 [(set (match_operand:MODEF 0 "register_operand" "=x")
5190 (match_operand:SWI48x 1 "memory_operand" "m")))]
5191 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5192 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5193 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5194 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5195 [(set_attr "type" "sseicvt")
5196 (set_attr "prefix" "maybe_vex")
5197 (set_attr "mode" "<MODEF:MODE>")
5198 (set (attr "prefix_rex")
5200 (and (eq_attr "prefix" "maybe_vex")
5201 (match_test "<SWI48x:MODE>mode == DImode"))
5203 (const_string "*")))
5204 (set_attr "athlon_decode" "direct")
5205 (set_attr "amdfam10_decode" "double")
5206 (set_attr "bdver1_decode" "direct")
5207 (set_attr "fp_int_src" "true")])
5210 [(set (match_operand:MODEF 0 "register_operand" "")
5211 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
5212 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5213 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5214 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5215 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5217 && (SSE_REG_P (operands[0])
5218 || (GET_CODE (operands[0]) == SUBREG
5219 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5220 [(set (match_dup 2) (match_dup 1))
5221 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5224 [(set (match_operand:MODEF 0 "register_operand" "")
5225 (float:MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5226 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5227 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5228 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5230 && (SSE_REG_P (operands[0])
5231 || (GET_CODE (operands[0]) == SUBREG
5232 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5233 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5235 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5236 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5238 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5239 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5241 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5245 [(set_attr "type" "fmov,multi")
5246 (set_attr "mode" "<X87MODEF:MODE>")
5247 (set_attr "unit" "*,i387")
5248 (set_attr "fp_int_src" "true")])
5250 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5251 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5253 (match_operand:SWI48x 1 "memory_operand" "m")))]
5255 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5257 [(set_attr "type" "fmov")
5258 (set_attr "mode" "<X87MODEF:MODE>")
5259 (set_attr "fp_int_src" "true")])
5262 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5263 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))
5264 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5266 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5267 && reload_completed"
5268 [(set (match_dup 2) (match_dup 1))
5269 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5272 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5273 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5274 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5276 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5277 && reload_completed"
5278 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5280 ;; Avoid store forwarding (partial memory) stall penalty
5281 ;; by passing DImode value through XMM registers. */
5283 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5284 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5286 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5287 (clobber (match_scratch:V4SI 3 "=X,x"))
5288 (clobber (match_scratch:V4SI 4 "=X,x"))
5289 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5290 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5291 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5292 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5294 [(set_attr "type" "multi")
5295 (set_attr "mode" "<X87MODEF:MODE>")
5296 (set_attr "unit" "i387")
5297 (set_attr "fp_int_src" "true")])
5300 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5301 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5302 (clobber (match_scratch:V4SI 3 ""))
5303 (clobber (match_scratch:V4SI 4 ""))
5304 (clobber (match_operand:DI 2 "memory_operand" ""))]
5305 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5306 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5307 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5308 && reload_completed"
5309 [(set (match_dup 2) (match_dup 3))
5310 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5312 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5313 Assemble the 64-bit DImode value in an xmm register. */
5314 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5315 gen_rtx_SUBREG (SImode, operands[1], 0)));
5316 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5317 gen_rtx_SUBREG (SImode, operands[1], 4)));
5318 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5321 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5325 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5326 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5327 (clobber (match_scratch:V4SI 3 ""))
5328 (clobber (match_scratch:V4SI 4 ""))
5329 (clobber (match_operand:DI 2 "memory_operand" ""))]
5330 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5331 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5332 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5333 && reload_completed"
5334 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5336 ;; Avoid store forwarding (partial memory) stall penalty by extending
5337 ;; SImode value to DImode through XMM register instead of pushing two
5338 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5339 ;; targets benefit from this optimization. Also note that fild
5340 ;; loads from memory only.
5342 (define_insn "*floatunssi<mode>2_1"
5343 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5344 (unsigned_float:X87MODEF
5345 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5346 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5347 (clobber (match_scratch:SI 3 "=X,x"))]
5349 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5352 [(set_attr "type" "multi")
5353 (set_attr "mode" "<MODE>")])
5356 [(set (match_operand:X87MODEF 0 "register_operand" "")
5357 (unsigned_float:X87MODEF
5358 (match_operand:SI 1 "register_operand" "")))
5359 (clobber (match_operand:DI 2 "memory_operand" ""))
5360 (clobber (match_scratch:SI 3 ""))]
5362 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5364 && reload_completed"
5365 [(set (match_dup 2) (match_dup 1))
5367 (float:X87MODEF (match_dup 2)))]
5368 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5371 [(set (match_operand:X87MODEF 0 "register_operand" "")
5372 (unsigned_float:X87MODEF
5373 (match_operand:SI 1 "memory_operand" "")))
5374 (clobber (match_operand:DI 2 "memory_operand" ""))
5375 (clobber (match_scratch:SI 3 ""))]
5377 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5379 && reload_completed"
5380 [(set (match_dup 2) (match_dup 3))
5382 (float:X87MODEF (match_dup 2)))]
5384 emit_move_insn (operands[3], operands[1]);
5385 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5388 (define_expand "floatunssi<mode>2"
5390 [(set (match_operand:X87MODEF 0 "register_operand" "")
5391 (unsigned_float:X87MODEF
5392 (match_operand:SI 1 "nonimmediate_operand" "")))
5393 (clobber (match_dup 2))
5394 (clobber (match_scratch:SI 3 ""))])]
5396 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5398 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5400 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5402 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5406 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5409 (define_expand "floatunsdisf2"
5410 [(use (match_operand:SF 0 "register_operand" ""))
5411 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5412 "TARGET_64BIT && TARGET_SSE_MATH"
5413 "x86_emit_floatuns (operands); DONE;")
5415 (define_expand "floatunsdidf2"
5416 [(use (match_operand:DF 0 "register_operand" ""))
5417 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5418 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5419 && TARGET_SSE2 && TARGET_SSE_MATH"
5422 x86_emit_floatuns (operands);
5424 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5428 ;; Load effective address instructions
5430 (define_insn_and_split "*lea<mode>"
5431 [(set (match_operand:SWI48 0 "register_operand" "=r")
5432 (match_operand:SWI48 1 "lea_address_operand" "p"))]
5435 rtx addr = operands[1];
5437 if (SImode_address_operand (addr, VOIDmode))
5439 gcc_assert (TARGET_64BIT);
5440 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5443 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5445 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5448 ix86_split_lea_for_addr (operands, <MODE>mode);
5451 [(set_attr "type" "lea")
5454 (match_operand 1 "SImode_address_operand")
5456 (const_string "<MODE>")))])
5460 (define_expand "add<mode>3"
5461 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5462 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5463 (match_operand:SDWIM 2 "<general_operand>" "")))]
5465 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5467 (define_insn_and_split "*add<dwi>3_doubleword"
5468 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5470 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5471 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5472 (clobber (reg:CC FLAGS_REG))]
5473 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5476 [(parallel [(set (reg:CC FLAGS_REG)
5477 (unspec:CC [(match_dup 1) (match_dup 2)]
5480 (plus:DWIH (match_dup 1) (match_dup 2)))])
5481 (parallel [(set (match_dup 3)
5485 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5487 (clobber (reg:CC FLAGS_REG))])]
5488 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5490 (define_insn "*add<mode>3_cc"
5491 [(set (reg:CC FLAGS_REG)
5493 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5494 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5496 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5497 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5498 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5499 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5500 [(set_attr "type" "alu")
5501 (set_attr "mode" "<MODE>")])
5503 (define_insn "addqi3_cc"
5504 [(set (reg:CC FLAGS_REG)
5506 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5507 (match_operand:QI 2 "general_operand" "qn,qm")]
5509 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5510 (plus:QI (match_dup 1) (match_dup 2)))]
5511 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5512 "add{b}\t{%2, %0|%0, %2}"
5513 [(set_attr "type" "alu")
5514 (set_attr "mode" "QI")])
5516 (define_insn "*add<mode>_1"
5517 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5519 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5520 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5521 (clobber (reg:CC FLAGS_REG))]
5522 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5524 switch (get_attr_type (insn))
5530 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5531 if (operands[2] == const1_rtx)
5532 return "inc{<imodesuffix>}\t%0";
5535 gcc_assert (operands[2] == constm1_rtx);
5536 return "dec{<imodesuffix>}\t%0";
5540 /* For most processors, ADD is faster than LEA. This alternative
5541 was added to use ADD as much as possible. */
5542 if (which_alternative == 2)
5545 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5548 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5549 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5550 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5552 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5556 (cond [(eq_attr "alternative" "3")
5557 (const_string "lea")
5558 (match_operand:SWI48 2 "incdec_operand" "")
5559 (const_string "incdec")
5561 (const_string "alu")))
5562 (set (attr "length_immediate")
5564 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5566 (const_string "*")))
5567 (set_attr "mode" "<MODE>")])
5569 ;; It may seem that nonimmediate operand is proper one for operand 1.
5570 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5571 ;; we take care in ix86_binary_operator_ok to not allow two memory
5572 ;; operands so proper swapping will be done in reload. This allow
5573 ;; patterns constructed from addsi_1 to match.
5575 (define_insn "addsi_1_zext"
5576 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5578 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5579 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5580 (clobber (reg:CC FLAGS_REG))]
5581 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5583 switch (get_attr_type (insn))
5589 if (operands[2] == const1_rtx)
5590 return "inc{l}\t%k0";
5593 gcc_assert (operands[2] == constm1_rtx);
5594 return "dec{l}\t%k0";
5598 /* For most processors, ADD is faster than LEA. This alternative
5599 was added to use ADD as much as possible. */
5600 if (which_alternative == 1)
5603 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5606 if (x86_maybe_negate_const_int (&operands[2], SImode))
5607 return "sub{l}\t{%2, %k0|%k0, %2}";
5609 return "add{l}\t{%2, %k0|%k0, %2}";
5613 (cond [(eq_attr "alternative" "2")
5614 (const_string "lea")
5615 (match_operand:SI 2 "incdec_operand" "")
5616 (const_string "incdec")
5618 (const_string "alu")))
5619 (set (attr "length_immediate")
5621 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5623 (const_string "*")))
5624 (set_attr "mode" "SI")])
5626 (define_insn "*addhi_1"
5627 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5628 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5629 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5630 (clobber (reg:CC FLAGS_REG))]
5631 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5633 switch (get_attr_type (insn))
5639 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5640 if (operands[2] == const1_rtx)
5641 return "inc{w}\t%0";
5644 gcc_assert (operands[2] == constm1_rtx);
5645 return "dec{w}\t%0";
5649 /* For most processors, ADD is faster than LEA. This alternative
5650 was added to use ADD as much as possible. */
5651 if (which_alternative == 2)
5654 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5657 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5658 if (x86_maybe_negate_const_int (&operands[2], HImode))
5659 return "sub{w}\t{%2, %0|%0, %2}";
5661 return "add{w}\t{%2, %0|%0, %2}";
5665 (cond [(eq_attr "alternative" "3")
5666 (const_string "lea")
5667 (match_operand:HI 2 "incdec_operand" "")
5668 (const_string "incdec")
5670 (const_string "alu")))
5671 (set (attr "length_immediate")
5673 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5675 (const_string "*")))
5676 (set_attr "mode" "HI,HI,HI,SI")])
5678 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5679 (define_insn "*addqi_1"
5680 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5681 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5682 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5683 (clobber (reg:CC FLAGS_REG))]
5684 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5686 bool widen = (which_alternative == 3 || which_alternative == 4);
5688 switch (get_attr_type (insn))
5694 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5695 if (operands[2] == const1_rtx)
5696 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5699 gcc_assert (operands[2] == constm1_rtx);
5700 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5704 /* For most processors, ADD is faster than LEA. These alternatives
5705 were added to use ADD as much as possible. */
5706 if (which_alternative == 2 || which_alternative == 4)
5709 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5712 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5713 if (x86_maybe_negate_const_int (&operands[2], QImode))
5716 return "sub{l}\t{%2, %k0|%k0, %2}";
5718 return "sub{b}\t{%2, %0|%0, %2}";
5721 return "add{l}\t{%k2, %k0|%k0, %k2}";
5723 return "add{b}\t{%2, %0|%0, %2}";
5727 (cond [(eq_attr "alternative" "5")
5728 (const_string "lea")
5729 (match_operand:QI 2 "incdec_operand" "")
5730 (const_string "incdec")
5732 (const_string "alu")))
5733 (set (attr "length_immediate")
5735 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5737 (const_string "*")))
5738 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5740 (define_insn "*addqi_1_slp"
5741 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5742 (plus:QI (match_dup 0)
5743 (match_operand:QI 1 "general_operand" "qn,qm")))
5744 (clobber (reg:CC FLAGS_REG))]
5745 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5746 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5748 switch (get_attr_type (insn))
5751 if (operands[1] == const1_rtx)
5752 return "inc{b}\t%0";
5755 gcc_assert (operands[1] == constm1_rtx);
5756 return "dec{b}\t%0";
5760 if (x86_maybe_negate_const_int (&operands[1], QImode))
5761 return "sub{b}\t{%1, %0|%0, %1}";
5763 return "add{b}\t{%1, %0|%0, %1}";
5767 (if_then_else (match_operand:QI 1 "incdec_operand" "")
5768 (const_string "incdec")
5769 (const_string "alu1")))
5770 (set (attr "memory")
5771 (if_then_else (match_operand 1 "memory_operand" "")
5772 (const_string "load")
5773 (const_string "none")))
5774 (set_attr "mode" "QI")])
5776 ;; Split non destructive adds if we cannot use lea.
5778 [(set (match_operand:SWI48 0 "register_operand" "")
5779 (plus:SWI48 (match_operand:SWI48 1 "register_operand" "")
5780 (match_operand:SWI48 2 "nonmemory_operand" "")))
5781 (clobber (reg:CC FLAGS_REG))]
5782 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5783 [(set (match_dup 0) (match_dup 1))
5784 (parallel [(set (match_dup 0) (plus:<MODE> (match_dup 0) (match_dup 2)))
5785 (clobber (reg:CC FLAGS_REG))])])
5787 ;; Convert add to the lea pattern to avoid flags dependency.
5789 [(set (match_operand:SWI 0 "register_operand" "")
5790 (plus:SWI (match_operand:SWI 1 "register_operand" "")
5791 (match_operand:SWI 2 "<nonmemory_operand>" "")))
5792 (clobber (reg:CC FLAGS_REG))]
5793 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5796 enum machine_mode mode = <MODE>mode;
5799 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5802 operands[0] = gen_lowpart (mode, operands[0]);
5803 operands[1] = gen_lowpart (mode, operands[1]);
5804 operands[2] = gen_lowpart (mode, operands[2]);
5807 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5809 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5813 ;; Convert add to the lea pattern to avoid flags dependency.
5815 [(set (match_operand:DI 0 "register_operand" "")
5817 (plus:SI (match_operand:SI 1 "register_operand" "")
5818 (match_operand:SI 2 "x86_64_nonmemory_operand" ""))))
5819 (clobber (reg:CC FLAGS_REG))]
5820 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5822 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5824 (define_insn "*add<mode>_2"
5825 [(set (reg FLAGS_REG)
5828 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5829 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5831 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5832 (plus:SWI (match_dup 1) (match_dup 2)))]
5833 "ix86_match_ccmode (insn, CCGOCmode)
5834 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5836 switch (get_attr_type (insn))
5839 if (operands[2] == const1_rtx)
5840 return "inc{<imodesuffix>}\t%0";
5843 gcc_assert (operands[2] == constm1_rtx);
5844 return "dec{<imodesuffix>}\t%0";
5848 if (which_alternative == 2)
5851 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5854 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5855 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5856 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5858 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5862 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5863 (const_string "incdec")
5864 (const_string "alu")))
5865 (set (attr "length_immediate")
5867 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5869 (const_string "*")))
5870 (set_attr "mode" "<MODE>")])
5872 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5873 (define_insn "*addsi_2_zext"
5874 [(set (reg FLAGS_REG)
5876 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5877 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5879 (set (match_operand:DI 0 "register_operand" "=r,r")
5880 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5881 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5882 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5884 switch (get_attr_type (insn))
5887 if (operands[2] == const1_rtx)
5888 return "inc{l}\t%k0";
5891 gcc_assert (operands[2] == constm1_rtx);
5892 return "dec{l}\t%k0";
5896 if (which_alternative == 1)
5899 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5902 if (x86_maybe_negate_const_int (&operands[2], SImode))
5903 return "sub{l}\t{%2, %k0|%k0, %2}";
5905 return "add{l}\t{%2, %k0|%k0, %2}";
5909 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5910 (const_string "incdec")
5911 (const_string "alu")))
5912 (set (attr "length_immediate")
5914 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5916 (const_string "*")))
5917 (set_attr "mode" "SI")])
5919 (define_insn "*add<mode>_3"
5920 [(set (reg FLAGS_REG)
5922 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5923 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5924 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5925 "ix86_match_ccmode (insn, CCZmode)
5926 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5928 switch (get_attr_type (insn))
5931 if (operands[2] == const1_rtx)
5932 return "inc{<imodesuffix>}\t%0";
5935 gcc_assert (operands[2] == constm1_rtx);
5936 return "dec{<imodesuffix>}\t%0";
5940 if (which_alternative == 1)
5943 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5946 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5947 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5948 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5950 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5954 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5955 (const_string "incdec")
5956 (const_string "alu")))
5957 (set (attr "length_immediate")
5959 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5961 (const_string "*")))
5962 (set_attr "mode" "<MODE>")])
5964 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5965 (define_insn "*addsi_3_zext"
5966 [(set (reg FLAGS_REG)
5968 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5969 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5970 (set (match_operand:DI 0 "register_operand" "=r,r")
5971 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5972 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5973 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5975 switch (get_attr_type (insn))
5978 if (operands[2] == const1_rtx)
5979 return "inc{l}\t%k0";
5982 gcc_assert (operands[2] == constm1_rtx);
5983 return "dec{l}\t%k0";
5987 if (which_alternative == 1)
5990 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5993 if (x86_maybe_negate_const_int (&operands[2], SImode))
5994 return "sub{l}\t{%2, %k0|%k0, %2}";
5996 return "add{l}\t{%2, %k0|%k0, %2}";
6000 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6001 (const_string "incdec")
6002 (const_string "alu")))
6003 (set (attr "length_immediate")
6005 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6007 (const_string "*")))
6008 (set_attr "mode" "SI")])
6010 ; For comparisons against 1, -1 and 128, we may generate better code
6011 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6012 ; is matched then. We can't accept general immediate, because for
6013 ; case of overflows, the result is messed up.
6014 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6015 ; only for comparisons not depending on it.
6017 (define_insn "*adddi_4"
6018 [(set (reg FLAGS_REG)
6020 (match_operand:DI 1 "nonimmediate_operand" "0")
6021 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6022 (clobber (match_scratch:DI 0 "=rm"))]
6024 && ix86_match_ccmode (insn, CCGCmode)"
6026 switch (get_attr_type (insn))
6029 if (operands[2] == constm1_rtx)
6030 return "inc{q}\t%0";
6033 gcc_assert (operands[2] == const1_rtx);
6034 return "dec{q}\t%0";
6038 if (x86_maybe_negate_const_int (&operands[2], DImode))
6039 return "add{q}\t{%2, %0|%0, %2}";
6041 return "sub{q}\t{%2, %0|%0, %2}";
6045 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6046 (const_string "incdec")
6047 (const_string "alu")))
6048 (set (attr "length_immediate")
6050 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6052 (const_string "*")))
6053 (set_attr "mode" "DI")])
6055 ; For comparisons against 1, -1 and 128, we may generate better code
6056 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6057 ; is matched then. We can't accept general immediate, because for
6058 ; case of overflows, the result is messed up.
6059 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6060 ; only for comparisons not depending on it.
6062 (define_insn "*add<mode>_4"
6063 [(set (reg FLAGS_REG)
6065 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6066 (match_operand:SWI124 2 "const_int_operand" "n")))
6067 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6068 "ix86_match_ccmode (insn, CCGCmode)"
6070 switch (get_attr_type (insn))
6073 if (operands[2] == constm1_rtx)
6074 return "inc{<imodesuffix>}\t%0";
6077 gcc_assert (operands[2] == const1_rtx);
6078 return "dec{<imodesuffix>}\t%0";
6082 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6083 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6085 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6089 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6090 (const_string "incdec")
6091 (const_string "alu")))
6092 (set (attr "length_immediate")
6094 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6096 (const_string "*")))
6097 (set_attr "mode" "<MODE>")])
6099 (define_insn "*add<mode>_5"
6100 [(set (reg FLAGS_REG)
6103 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6104 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6106 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6107 "ix86_match_ccmode (insn, CCGOCmode)
6108 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6110 switch (get_attr_type (insn))
6113 if (operands[2] == const1_rtx)
6114 return "inc{<imodesuffix>}\t%0";
6117 gcc_assert (operands[2] == constm1_rtx);
6118 return "dec{<imodesuffix>}\t%0";
6122 if (which_alternative == 1)
6125 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6128 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6129 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6130 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6132 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6136 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6137 (const_string "incdec")
6138 (const_string "alu")))
6139 (set (attr "length_immediate")
6141 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6143 (const_string "*")))
6144 (set_attr "mode" "<MODE>")])
6146 (define_insn "*addqi_ext_1_rex64"
6147 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6152 (match_operand 1 "ext_register_operand" "0")
6155 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6156 (clobber (reg:CC FLAGS_REG))]
6159 switch (get_attr_type (insn))
6162 if (operands[2] == const1_rtx)
6163 return "inc{b}\t%h0";
6166 gcc_assert (operands[2] == constm1_rtx);
6167 return "dec{b}\t%h0";
6171 return "add{b}\t{%2, %h0|%h0, %2}";
6175 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6176 (const_string "incdec")
6177 (const_string "alu")))
6178 (set_attr "modrm" "1")
6179 (set_attr "mode" "QI")])
6181 (define_insn "addqi_ext_1"
6182 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6187 (match_operand 1 "ext_register_operand" "0")
6190 (match_operand:QI 2 "general_operand" "Qmn")))
6191 (clobber (reg:CC FLAGS_REG))]
6194 switch (get_attr_type (insn))
6197 if (operands[2] == const1_rtx)
6198 return "inc{b}\t%h0";
6201 gcc_assert (operands[2] == constm1_rtx);
6202 return "dec{b}\t%h0";
6206 return "add{b}\t{%2, %h0|%h0, %2}";
6210 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6211 (const_string "incdec")
6212 (const_string "alu")))
6213 (set_attr "modrm" "1")
6214 (set_attr "mode" "QI")])
6216 (define_insn "*addqi_ext_2"
6217 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6222 (match_operand 1 "ext_register_operand" "%0")
6226 (match_operand 2 "ext_register_operand" "Q")
6229 (clobber (reg:CC FLAGS_REG))]
6231 "add{b}\t{%h2, %h0|%h0, %h2}"
6232 [(set_attr "type" "alu")
6233 (set_attr "mode" "QI")])
6235 ;; The lea patterns for modes less than 32 bits need to be matched by
6236 ;; several insns converted to real lea by splitters.
6238 (define_insn_and_split "*lea_general_1"
6239 [(set (match_operand 0 "register_operand" "=r")
6240 (plus (plus (match_operand 1 "index_register_operand" "l")
6241 (match_operand 2 "register_operand" "r"))
6242 (match_operand 3 "immediate_operand" "i")))]
6243 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6244 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6245 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6246 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6247 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6248 || GET_MODE (operands[3]) == VOIDmode)"
6250 "&& reload_completed"
6253 enum machine_mode mode = SImode;
6256 operands[0] = gen_lowpart (mode, operands[0]);
6257 operands[1] = gen_lowpart (mode, operands[1]);
6258 operands[2] = gen_lowpart (mode, operands[2]);
6259 operands[3] = gen_lowpart (mode, operands[3]);
6261 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6264 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6267 [(set_attr "type" "lea")
6268 (set_attr "mode" "SI")])
6270 (define_insn_and_split "*lea_general_2"
6271 [(set (match_operand 0 "register_operand" "=r")
6272 (plus (mult (match_operand 1 "index_register_operand" "l")
6273 (match_operand 2 "const248_operand" "n"))
6274 (match_operand 3 "nonmemory_operand" "ri")))]
6275 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6276 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6277 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6278 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6279 || GET_MODE (operands[3]) == VOIDmode)"
6281 "&& reload_completed"
6284 enum machine_mode mode = SImode;
6287 operands[0] = gen_lowpart (mode, operands[0]);
6288 operands[1] = gen_lowpart (mode, operands[1]);
6289 operands[3] = gen_lowpart (mode, operands[3]);
6291 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6294 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6297 [(set_attr "type" "lea")
6298 (set_attr "mode" "SI")])
6300 (define_insn_and_split "*lea_general_3"
6301 [(set (match_operand 0 "register_operand" "=r")
6302 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6303 (match_operand 2 "const248_operand" "n"))
6304 (match_operand 3 "register_operand" "r"))
6305 (match_operand 4 "immediate_operand" "i")))]
6306 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6307 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6308 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6309 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6311 "&& reload_completed"
6314 enum machine_mode mode = SImode;
6317 operands[0] = gen_lowpart (mode, operands[0]);
6318 operands[1] = gen_lowpart (mode, operands[1]);
6319 operands[3] = gen_lowpart (mode, operands[3]);
6320 operands[4] = gen_lowpart (mode, operands[4]);
6322 pat = gen_rtx_PLUS (mode,
6324 gen_rtx_MULT (mode, operands[1],
6329 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6332 [(set_attr "type" "lea")
6333 (set_attr "mode" "SI")])
6335 (define_insn_and_split "*lea_general_4"
6336 [(set (match_operand 0 "register_operand" "=r")
6338 (match_operand 1 "index_register_operand" "l")
6339 (match_operand 2 "const_int_operand" "n"))
6340 (match_operand 3 "const_int_operand" "n")))]
6341 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6342 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6343 || GET_MODE (operands[0]) == SImode
6344 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6345 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6346 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6347 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6348 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6350 "&& reload_completed"
6353 enum machine_mode mode = GET_MODE (operands[0]);
6356 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6359 operands[0] = gen_lowpart (mode, operands[0]);
6360 operands[1] = gen_lowpart (mode, operands[1]);
6363 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6365 pat = plus_constant (gen_rtx_MULT (mode, operands[1], operands[2]),
6366 INTVAL (operands[3]));
6368 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6371 [(set_attr "type" "lea")
6373 (if_then_else (match_operand:DI 0 "" "")
6375 (const_string "SI")))])
6377 ;; Subtract instructions
6379 (define_expand "sub<mode>3"
6380 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6381 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6382 (match_operand:SDWIM 2 "<general_operand>" "")))]
6384 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6386 (define_insn_and_split "*sub<dwi>3_doubleword"
6387 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6389 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6390 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6391 (clobber (reg:CC FLAGS_REG))]
6392 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6395 [(parallel [(set (reg:CC FLAGS_REG)
6396 (compare:CC (match_dup 1) (match_dup 2)))
6398 (minus:DWIH (match_dup 1) (match_dup 2)))])
6399 (parallel [(set (match_dup 3)
6403 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6405 (clobber (reg:CC FLAGS_REG))])]
6406 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6408 (define_insn "*sub<mode>_1"
6409 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6411 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6412 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6413 (clobber (reg:CC FLAGS_REG))]
6414 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6415 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6416 [(set_attr "type" "alu")
6417 (set_attr "mode" "<MODE>")])
6419 (define_insn "*subsi_1_zext"
6420 [(set (match_operand:DI 0 "register_operand" "=r")
6422 (minus:SI (match_operand:SI 1 "register_operand" "0")
6423 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6424 (clobber (reg:CC FLAGS_REG))]
6425 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6426 "sub{l}\t{%2, %k0|%k0, %2}"
6427 [(set_attr "type" "alu")
6428 (set_attr "mode" "SI")])
6430 (define_insn "*subqi_1_slp"
6431 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6432 (minus:QI (match_dup 0)
6433 (match_operand:QI 1 "general_operand" "qn,qm")))
6434 (clobber (reg:CC FLAGS_REG))]
6435 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6436 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6437 "sub{b}\t{%1, %0|%0, %1}"
6438 [(set_attr "type" "alu1")
6439 (set_attr "mode" "QI")])
6441 (define_insn "*sub<mode>_2"
6442 [(set (reg FLAGS_REG)
6445 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6446 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6448 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6449 (minus:SWI (match_dup 1) (match_dup 2)))]
6450 "ix86_match_ccmode (insn, CCGOCmode)
6451 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6452 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6453 [(set_attr "type" "alu")
6454 (set_attr "mode" "<MODE>")])
6456 (define_insn "*subsi_2_zext"
6457 [(set (reg FLAGS_REG)
6459 (minus:SI (match_operand:SI 1 "register_operand" "0")
6460 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6462 (set (match_operand:DI 0 "register_operand" "=r")
6464 (minus:SI (match_dup 1)
6466 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6467 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6468 "sub{l}\t{%2, %k0|%k0, %2}"
6469 [(set_attr "type" "alu")
6470 (set_attr "mode" "SI")])
6472 (define_insn "*sub<mode>_3"
6473 [(set (reg FLAGS_REG)
6474 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6475 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6476 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6477 (minus:SWI (match_dup 1) (match_dup 2)))]
6478 "ix86_match_ccmode (insn, CCmode)
6479 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6480 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6481 [(set_attr "type" "alu")
6482 (set_attr "mode" "<MODE>")])
6484 (define_insn "*subsi_3_zext"
6485 [(set (reg FLAGS_REG)
6486 (compare (match_operand:SI 1 "register_operand" "0")
6487 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6488 (set (match_operand:DI 0 "register_operand" "=r")
6490 (minus:SI (match_dup 1)
6492 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6493 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6494 "sub{l}\t{%2, %1|%1, %2}"
6495 [(set_attr "type" "alu")
6496 (set_attr "mode" "SI")])
6498 ;; Add with carry and subtract with borrow
6500 (define_expand "<plusminus_insn><mode>3_carry"
6502 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6504 (match_operand:SWI 1 "nonimmediate_operand" "")
6505 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6506 [(match_operand 3 "flags_reg_operand" "")
6508 (match_operand:SWI 2 "<general_operand>" ""))))
6509 (clobber (reg:CC FLAGS_REG))])]
6510 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6512 (define_insn "*<plusminus_insn><mode>3_carry"
6513 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6515 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6517 (match_operator 3 "ix86_carry_flag_operator"
6518 [(reg FLAGS_REG) (const_int 0)])
6519 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6520 (clobber (reg:CC FLAGS_REG))]
6521 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6522 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6523 [(set_attr "type" "alu")
6524 (set_attr "use_carry" "1")
6525 (set_attr "pent_pair" "pu")
6526 (set_attr "mode" "<MODE>")])
6528 (define_insn "*addsi3_carry_zext"
6529 [(set (match_operand:DI 0 "register_operand" "=r")
6531 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6532 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6533 [(reg FLAGS_REG) (const_int 0)])
6534 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6535 (clobber (reg:CC FLAGS_REG))]
6536 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6537 "adc{l}\t{%2, %k0|%k0, %2}"
6538 [(set_attr "type" "alu")
6539 (set_attr "use_carry" "1")
6540 (set_attr "pent_pair" "pu")
6541 (set_attr "mode" "SI")])
6543 (define_insn "*subsi3_carry_zext"
6544 [(set (match_operand:DI 0 "register_operand" "=r")
6546 (minus:SI (match_operand:SI 1 "register_operand" "0")
6547 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6548 [(reg FLAGS_REG) (const_int 0)])
6549 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6550 (clobber (reg:CC FLAGS_REG))]
6551 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6552 "sbb{l}\t{%2, %k0|%k0, %2}"
6553 [(set_attr "type" "alu")
6554 (set_attr "pent_pair" "pu")
6555 (set_attr "mode" "SI")])
6557 ;; Overflow setting add and subtract instructions
6559 (define_insn "*add<mode>3_cconly_overflow"
6560 [(set (reg:CCC FLAGS_REG)
6563 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6564 (match_operand:SWI 2 "<general_operand>" "<g>"))
6566 (clobber (match_scratch:SWI 0 "=<r>"))]
6567 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6568 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6569 [(set_attr "type" "alu")
6570 (set_attr "mode" "<MODE>")])
6572 (define_insn "*sub<mode>3_cconly_overflow"
6573 [(set (reg:CCC FLAGS_REG)
6576 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6577 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6580 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6581 [(set_attr "type" "icmp")
6582 (set_attr "mode" "<MODE>")])
6584 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6585 [(set (reg:CCC FLAGS_REG)
6588 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6589 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6591 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6592 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6593 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6594 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6595 [(set_attr "type" "alu")
6596 (set_attr "mode" "<MODE>")])
6598 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6599 [(set (reg:CCC FLAGS_REG)
6602 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6603 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6605 (set (match_operand:DI 0 "register_operand" "=r")
6606 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6607 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6608 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6609 [(set_attr "type" "alu")
6610 (set_attr "mode" "SI")])
6612 ;; The patterns that match these are at the end of this file.
6614 (define_expand "<plusminus_insn>xf3"
6615 [(set (match_operand:XF 0 "register_operand" "")
6617 (match_operand:XF 1 "register_operand" "")
6618 (match_operand:XF 2 "register_operand" "")))]
6621 (define_expand "<plusminus_insn><mode>3"
6622 [(set (match_operand:MODEF 0 "register_operand" "")
6624 (match_operand:MODEF 1 "register_operand" "")
6625 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6626 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6627 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6629 ;; Multiply instructions
6631 (define_expand "mul<mode>3"
6632 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6634 (match_operand:SWIM248 1 "register_operand" "")
6635 (match_operand:SWIM248 2 "<general_operand>" "")))
6636 (clobber (reg:CC FLAGS_REG))])])
6638 (define_expand "mulqi3"
6639 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6641 (match_operand:QI 1 "register_operand" "")
6642 (match_operand:QI 2 "nonimmediate_operand" "")))
6643 (clobber (reg:CC FLAGS_REG))])]
6644 "TARGET_QIMODE_MATH")
6647 ;; IMUL reg32/64, reg32/64, imm8 Direct
6648 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6649 ;; IMUL reg32/64, reg32/64, imm32 Direct
6650 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6651 ;; IMUL reg32/64, reg32/64 Direct
6652 ;; IMUL reg32/64, mem32/64 Direct
6654 ;; On BDVER1, all above IMULs use DirectPath
6656 (define_insn "*mul<mode>3_1"
6657 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6659 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6660 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6661 (clobber (reg:CC FLAGS_REG))]
6662 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6664 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6665 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6666 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6667 [(set_attr "type" "imul")
6668 (set_attr "prefix_0f" "0,0,1")
6669 (set (attr "athlon_decode")
6670 (cond [(eq_attr "cpu" "athlon")
6671 (const_string "vector")
6672 (eq_attr "alternative" "1")
6673 (const_string "vector")
6674 (and (eq_attr "alternative" "2")
6675 (match_operand 1 "memory_operand" ""))
6676 (const_string "vector")]
6677 (const_string "direct")))
6678 (set (attr "amdfam10_decode")
6679 (cond [(and (eq_attr "alternative" "0,1")
6680 (match_operand 1 "memory_operand" ""))
6681 (const_string "vector")]
6682 (const_string "direct")))
6683 (set_attr "bdver1_decode" "direct")
6684 (set_attr "mode" "<MODE>")])
6686 (define_insn "*mulsi3_1_zext"
6687 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6689 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6690 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6691 (clobber (reg:CC FLAGS_REG))]
6693 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6695 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6696 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6697 imul{l}\t{%2, %k0|%k0, %2}"
6698 [(set_attr "type" "imul")
6699 (set_attr "prefix_0f" "0,0,1")
6700 (set (attr "athlon_decode")
6701 (cond [(eq_attr "cpu" "athlon")
6702 (const_string "vector")
6703 (eq_attr "alternative" "1")
6704 (const_string "vector")
6705 (and (eq_attr "alternative" "2")
6706 (match_operand 1 "memory_operand" ""))
6707 (const_string "vector")]
6708 (const_string "direct")))
6709 (set (attr "amdfam10_decode")
6710 (cond [(and (eq_attr "alternative" "0,1")
6711 (match_operand 1 "memory_operand" ""))
6712 (const_string "vector")]
6713 (const_string "direct")))
6714 (set_attr "bdver1_decode" "direct")
6715 (set_attr "mode" "SI")])
6718 ;; IMUL reg16, reg16, imm8 VectorPath
6719 ;; IMUL reg16, mem16, imm8 VectorPath
6720 ;; IMUL reg16, reg16, imm16 VectorPath
6721 ;; IMUL reg16, mem16, imm16 VectorPath
6722 ;; IMUL reg16, reg16 Direct
6723 ;; IMUL reg16, mem16 Direct
6725 ;; On BDVER1, all HI MULs use DoublePath
6727 (define_insn "*mulhi3_1"
6728 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6729 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6730 (match_operand:HI 2 "general_operand" "K,n,mr")))
6731 (clobber (reg:CC FLAGS_REG))]
6733 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6735 imul{w}\t{%2, %1, %0|%0, %1, %2}
6736 imul{w}\t{%2, %1, %0|%0, %1, %2}
6737 imul{w}\t{%2, %0|%0, %2}"
6738 [(set_attr "type" "imul")
6739 (set_attr "prefix_0f" "0,0,1")
6740 (set (attr "athlon_decode")
6741 (cond [(eq_attr "cpu" "athlon")
6742 (const_string "vector")
6743 (eq_attr "alternative" "1,2")
6744 (const_string "vector")]
6745 (const_string "direct")))
6746 (set (attr "amdfam10_decode")
6747 (cond [(eq_attr "alternative" "0,1")
6748 (const_string "vector")]
6749 (const_string "direct")))
6750 (set_attr "bdver1_decode" "double")
6751 (set_attr "mode" "HI")])
6753 ;;On AMDFAM10 and BDVER1
6757 (define_insn "*mulqi3_1"
6758 [(set (match_operand:QI 0 "register_operand" "=a")
6759 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6760 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6761 (clobber (reg:CC FLAGS_REG))]
6763 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6765 [(set_attr "type" "imul")
6766 (set_attr "length_immediate" "0")
6767 (set (attr "athlon_decode")
6768 (if_then_else (eq_attr "cpu" "athlon")
6769 (const_string "vector")
6770 (const_string "direct")))
6771 (set_attr "amdfam10_decode" "direct")
6772 (set_attr "bdver1_decode" "direct")
6773 (set_attr "mode" "QI")])
6775 (define_expand "<u>mul<mode><dwi>3"
6776 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6779 (match_operand:DWIH 1 "nonimmediate_operand" ""))
6781 (match_operand:DWIH 2 "register_operand" ""))))
6782 (clobber (reg:CC FLAGS_REG))])])
6784 (define_expand "<u>mulqihi3"
6785 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6788 (match_operand:QI 1 "nonimmediate_operand" ""))
6790 (match_operand:QI 2 "register_operand" ""))))
6791 (clobber (reg:CC FLAGS_REG))])]
6792 "TARGET_QIMODE_MATH")
6794 (define_insn "*bmi2_umulditi3_1"
6795 [(set (match_operand:DI 0 "register_operand" "=r")
6797 (match_operand:DI 2 "nonimmediate_operand" "%d")
6798 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6799 (set (match_operand:DI 1 "register_operand" "=r")
6802 (mult:TI (zero_extend:TI (match_dup 2))
6803 (zero_extend:TI (match_dup 3)))
6805 "TARGET_64BIT && TARGET_BMI2
6806 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6807 "mulx\t{%3, %0, %1|%1, %0, %3}"
6808 [(set_attr "type" "imulx")
6809 (set_attr "prefix" "vex")
6810 (set_attr "mode" "DI")])
6812 (define_insn "*bmi2_umulsidi3_1"
6813 [(set (match_operand:SI 0 "register_operand" "=r")
6815 (match_operand:SI 2 "nonimmediate_operand" "%d")
6816 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6817 (set (match_operand:SI 1 "register_operand" "=r")
6820 (mult:DI (zero_extend:DI (match_dup 2))
6821 (zero_extend:DI (match_dup 3)))
6823 "!TARGET_64BIT && TARGET_BMI2
6824 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6825 "mulx\t{%3, %0, %1|%1, %0, %3}"
6826 [(set_attr "type" "imulx")
6827 (set_attr "prefix" "vex")
6828 (set_attr "mode" "SI")])
6830 (define_insn "*umul<mode><dwi>3_1"
6831 [(set (match_operand:<DWI> 0 "register_operand" "=A,r")
6834 (match_operand:DWIH 1 "nonimmediate_operand" "%0,d"))
6836 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6837 (clobber (reg:CC FLAGS_REG))]
6838 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6840 mul{<imodesuffix>}\t%2
6842 [(set_attr "isa" "*,bmi2")
6843 (set_attr "type" "imul,imulx")
6844 (set_attr "length_immediate" "0,*")
6845 (set (attr "athlon_decode")
6846 (cond [(eq_attr "alternative" "0")
6847 (if_then_else (eq_attr "cpu" "athlon")
6848 (const_string "vector")
6849 (const_string "double"))]
6850 (const_string "*")))
6851 (set_attr "amdfam10_decode" "double,*")
6852 (set_attr "bdver1_decode" "direct,*")
6853 (set_attr "prefix" "orig,vex")
6854 (set_attr "mode" "<MODE>")])
6856 ;; Convert mul to the mulx pattern to avoid flags dependency.
6858 [(set (match_operand:<DWI> 0 "register_operand" "")
6861 (match_operand:DWIH 1 "register_operand" ""))
6863 (match_operand:DWIH 2 "nonimmediate_operand" ""))))
6864 (clobber (reg:CC FLAGS_REG))]
6865 "TARGET_BMI2 && reload_completed
6866 && true_regnum (operands[1]) == DX_REG"
6867 [(parallel [(set (match_dup 3)
6868 (mult:DWIH (match_dup 1) (match_dup 2)))
6872 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6873 (zero_extend:<DWI> (match_dup 2)))
6876 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6878 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6881 (define_insn "*mul<mode><dwi>3_1"
6882 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6885 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6887 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6888 (clobber (reg:CC FLAGS_REG))]
6889 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6890 "imul{<imodesuffix>}\t%2"
6891 [(set_attr "type" "imul")
6892 (set_attr "length_immediate" "0")
6893 (set (attr "athlon_decode")
6894 (if_then_else (eq_attr "cpu" "athlon")
6895 (const_string "vector")
6896 (const_string "double")))
6897 (set_attr "amdfam10_decode" "double")
6898 (set_attr "bdver1_decode" "direct")
6899 (set_attr "mode" "<MODE>")])
6901 (define_insn "*<u>mulqihi3_1"
6902 [(set (match_operand:HI 0 "register_operand" "=a")
6905 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6907 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6908 (clobber (reg:CC FLAGS_REG))]
6910 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6911 "<sgnprefix>mul{b}\t%2"
6912 [(set_attr "type" "imul")
6913 (set_attr "length_immediate" "0")
6914 (set (attr "athlon_decode")
6915 (if_then_else (eq_attr "cpu" "athlon")
6916 (const_string "vector")
6917 (const_string "direct")))
6918 (set_attr "amdfam10_decode" "direct")
6919 (set_attr "bdver1_decode" "direct")
6920 (set_attr "mode" "QI")])
6922 (define_expand "<s>mul<mode>3_highpart"
6923 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6928 (match_operand:SWI48 1 "nonimmediate_operand" ""))
6930 (match_operand:SWI48 2 "register_operand" "")))
6932 (clobber (match_scratch:SWI48 3 ""))
6933 (clobber (reg:CC FLAGS_REG))])]
6935 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6937 (define_insn "*<s>muldi3_highpart_1"
6938 [(set (match_operand:DI 0 "register_operand" "=d")
6943 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6945 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6947 (clobber (match_scratch:DI 3 "=1"))
6948 (clobber (reg:CC FLAGS_REG))]
6950 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6951 "<sgnprefix>mul{q}\t%2"
6952 [(set_attr "type" "imul")
6953 (set_attr "length_immediate" "0")
6954 (set (attr "athlon_decode")
6955 (if_then_else (eq_attr "cpu" "athlon")
6956 (const_string "vector")
6957 (const_string "double")))
6958 (set_attr "amdfam10_decode" "double")
6959 (set_attr "bdver1_decode" "direct")
6960 (set_attr "mode" "DI")])
6962 (define_insn "*<s>mulsi3_highpart_1"
6963 [(set (match_operand:SI 0 "register_operand" "=d")
6968 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6970 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6972 (clobber (match_scratch:SI 3 "=1"))
6973 (clobber (reg:CC FLAGS_REG))]
6974 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6975 "<sgnprefix>mul{l}\t%2"
6976 [(set_attr "type" "imul")
6977 (set_attr "length_immediate" "0")
6978 (set (attr "athlon_decode")
6979 (if_then_else (eq_attr "cpu" "athlon")
6980 (const_string "vector")
6981 (const_string "double")))
6982 (set_attr "amdfam10_decode" "double")
6983 (set_attr "bdver1_decode" "direct")
6984 (set_attr "mode" "SI")])
6986 (define_insn "*<s>mulsi3_highpart_zext"
6987 [(set (match_operand:DI 0 "register_operand" "=d")
6988 (zero_extend:DI (truncate:SI
6990 (mult:DI (any_extend:DI
6991 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6993 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6995 (clobber (match_scratch:SI 3 "=1"))
6996 (clobber (reg:CC FLAGS_REG))]
6998 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6999 "<sgnprefix>mul{l}\t%2"
7000 [(set_attr "type" "imul")
7001 (set_attr "length_immediate" "0")
7002 (set (attr "athlon_decode")
7003 (if_then_else (eq_attr "cpu" "athlon")
7004 (const_string "vector")
7005 (const_string "double")))
7006 (set_attr "amdfam10_decode" "double")
7007 (set_attr "bdver1_decode" "direct")
7008 (set_attr "mode" "SI")])
7010 ;; The patterns that match these are at the end of this file.
7012 (define_expand "mulxf3"
7013 [(set (match_operand:XF 0 "register_operand" "")
7014 (mult:XF (match_operand:XF 1 "register_operand" "")
7015 (match_operand:XF 2 "register_operand" "")))]
7018 (define_expand "mul<mode>3"
7019 [(set (match_operand:MODEF 0 "register_operand" "")
7020 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7021 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7022 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7023 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7025 ;; Divide instructions
7027 ;; The patterns that match these are at the end of this file.
7029 (define_expand "divxf3"
7030 [(set (match_operand:XF 0 "register_operand" "")
7031 (div:XF (match_operand:XF 1 "register_operand" "")
7032 (match_operand:XF 2 "register_operand" "")))]
7035 (define_expand "divdf3"
7036 [(set (match_operand:DF 0 "register_operand" "")
7037 (div:DF (match_operand:DF 1 "register_operand" "")
7038 (match_operand:DF 2 "nonimmediate_operand" "")))]
7039 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7040 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7042 (define_expand "divsf3"
7043 [(set (match_operand:SF 0 "register_operand" "")
7044 (div:SF (match_operand:SF 1 "register_operand" "")
7045 (match_operand:SF 2 "nonimmediate_operand" "")))]
7046 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7051 && optimize_insn_for_speed_p ()
7052 && flag_finite_math_only && !flag_trapping_math
7053 && flag_unsafe_math_optimizations)
7055 ix86_emit_swdivsf (operands[0], operands[1],
7056 operands[2], SFmode);
7061 ;; Divmod instructions.
7063 (define_expand "divmod<mode>4"
7064 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7066 (match_operand:SWIM248 1 "register_operand" "")
7067 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7068 (set (match_operand:SWIM248 3 "register_operand" "")
7069 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7070 (clobber (reg:CC FLAGS_REG))])])
7072 ;; Split with 8bit unsigned divide:
7073 ;; if (dividend an divisor are in [0-255])
7074 ;; use 8bit unsigned integer divide
7076 ;; use original integer divide
7078 [(set (match_operand:SWI48 0 "register_operand" "")
7079 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7080 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7081 (set (match_operand:SWI48 1 "register_operand" "")
7082 (mod:SWI48 (match_dup 2) (match_dup 3)))
7083 (clobber (reg:CC FLAGS_REG))]
7084 "TARGET_USE_8BIT_IDIV
7085 && TARGET_QIMODE_MATH
7086 && can_create_pseudo_p ()
7087 && !optimize_insn_for_size_p ()"
7089 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7091 (define_insn_and_split "divmod<mode>4_1"
7092 [(set (match_operand:SWI48 0 "register_operand" "=a")
7093 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7094 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7095 (set (match_operand:SWI48 1 "register_operand" "=&d")
7096 (mod:SWI48 (match_dup 2) (match_dup 3)))
7097 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7098 (clobber (reg:CC FLAGS_REG))]
7102 [(parallel [(set (match_dup 1)
7103 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7104 (clobber (reg:CC FLAGS_REG))])
7105 (parallel [(set (match_dup 0)
7106 (div:SWI48 (match_dup 2) (match_dup 3)))
7108 (mod:SWI48 (match_dup 2) (match_dup 3)))
7110 (clobber (reg:CC FLAGS_REG))])]
7112 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7114 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7115 operands[4] = operands[2];
7118 /* Avoid use of cltd in favor of a mov+shift. */
7119 emit_move_insn (operands[1], operands[2]);
7120 operands[4] = operands[1];
7123 [(set_attr "type" "multi")
7124 (set_attr "mode" "<MODE>")])
7126 (define_insn_and_split "*divmod<mode>4"
7127 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7128 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7129 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7130 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7131 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7132 (clobber (reg:CC FLAGS_REG))]
7136 [(parallel [(set (match_dup 1)
7137 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7138 (clobber (reg:CC FLAGS_REG))])
7139 (parallel [(set (match_dup 0)
7140 (div:SWIM248 (match_dup 2) (match_dup 3)))
7142 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7144 (clobber (reg:CC FLAGS_REG))])]
7146 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7148 if (<MODE>mode != HImode
7149 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7150 operands[4] = operands[2];
7153 /* Avoid use of cltd in favor of a mov+shift. */
7154 emit_move_insn (operands[1], operands[2]);
7155 operands[4] = operands[1];
7158 [(set_attr "type" "multi")
7159 (set_attr "mode" "<MODE>")])
7161 (define_insn "*divmod<mode>4_noext"
7162 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7163 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7164 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7165 (set (match_operand:SWIM248 1 "register_operand" "=d")
7166 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7167 (use (match_operand:SWIM248 4 "register_operand" "1"))
7168 (clobber (reg:CC FLAGS_REG))]
7170 "idiv{<imodesuffix>}\t%3"
7171 [(set_attr "type" "idiv")
7172 (set_attr "mode" "<MODE>")])
7174 (define_expand "divmodqi4"
7175 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7177 (match_operand:QI 1 "register_operand" "")
7178 (match_operand:QI 2 "nonimmediate_operand" "")))
7179 (set (match_operand:QI 3 "register_operand" "")
7180 (mod:QI (match_dup 1) (match_dup 2)))
7181 (clobber (reg:CC FLAGS_REG))])]
7182 "TARGET_QIMODE_MATH"
7187 tmp0 = gen_reg_rtx (HImode);
7188 tmp1 = gen_reg_rtx (HImode);
7190 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7192 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7193 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7195 /* Extract remainder from AH. */
7196 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7197 insn = emit_move_insn (operands[3], tmp1);
7199 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7200 set_unique_reg_note (insn, REG_EQUAL, mod);
7202 /* Extract quotient from AL. */
7203 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7205 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7206 set_unique_reg_note (insn, REG_EQUAL, div);
7211 ;; Divide AX by r/m8, with result stored in
7214 ;; Change div/mod to HImode and extend the second argument to HImode
7215 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7216 ;; combine may fail.
7217 (define_insn "divmodhiqi3"
7218 [(set (match_operand:HI 0 "register_operand" "=a")
7223 (mod:HI (match_operand:HI 1 "register_operand" "0")
7225 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7229 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7230 (clobber (reg:CC FLAGS_REG))]
7231 "TARGET_QIMODE_MATH"
7233 [(set_attr "type" "idiv")
7234 (set_attr "mode" "QI")])
7236 (define_expand "udivmod<mode>4"
7237 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7239 (match_operand:SWIM248 1 "register_operand" "")
7240 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7241 (set (match_operand:SWIM248 3 "register_operand" "")
7242 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7243 (clobber (reg:CC FLAGS_REG))])])
7245 ;; Split with 8bit unsigned divide:
7246 ;; if (dividend an divisor are in [0-255])
7247 ;; use 8bit unsigned integer divide
7249 ;; use original integer divide
7251 [(set (match_operand:SWI48 0 "register_operand" "")
7252 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7253 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7254 (set (match_operand:SWI48 1 "register_operand" "")
7255 (umod:SWI48 (match_dup 2) (match_dup 3)))
7256 (clobber (reg:CC FLAGS_REG))]
7257 "TARGET_USE_8BIT_IDIV
7258 && TARGET_QIMODE_MATH
7259 && can_create_pseudo_p ()
7260 && !optimize_insn_for_size_p ()"
7262 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7264 (define_insn_and_split "udivmod<mode>4_1"
7265 [(set (match_operand:SWI48 0 "register_operand" "=a")
7266 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7267 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7268 (set (match_operand:SWI48 1 "register_operand" "=&d")
7269 (umod:SWI48 (match_dup 2) (match_dup 3)))
7270 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7271 (clobber (reg:CC FLAGS_REG))]
7275 [(set (match_dup 1) (const_int 0))
7276 (parallel [(set (match_dup 0)
7277 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7279 (umod:SWI48 (match_dup 2) (match_dup 3)))
7281 (clobber (reg:CC FLAGS_REG))])]
7283 [(set_attr "type" "multi")
7284 (set_attr "mode" "<MODE>")])
7286 (define_insn_and_split "*udivmod<mode>4"
7287 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7288 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7289 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7290 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7291 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7292 (clobber (reg:CC FLAGS_REG))]
7296 [(set (match_dup 1) (const_int 0))
7297 (parallel [(set (match_dup 0)
7298 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7300 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7302 (clobber (reg:CC FLAGS_REG))])]
7304 [(set_attr "type" "multi")
7305 (set_attr "mode" "<MODE>")])
7307 (define_insn "*udivmod<mode>4_noext"
7308 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7309 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7310 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7311 (set (match_operand:SWIM248 1 "register_operand" "=d")
7312 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7313 (use (match_operand:SWIM248 4 "register_operand" "1"))
7314 (clobber (reg:CC FLAGS_REG))]
7316 "div{<imodesuffix>}\t%3"
7317 [(set_attr "type" "idiv")
7318 (set_attr "mode" "<MODE>")])
7320 (define_expand "udivmodqi4"
7321 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7323 (match_operand:QI 1 "register_operand" "")
7324 (match_operand:QI 2 "nonimmediate_operand" "")))
7325 (set (match_operand:QI 3 "register_operand" "")
7326 (umod:QI (match_dup 1) (match_dup 2)))
7327 (clobber (reg:CC FLAGS_REG))])]
7328 "TARGET_QIMODE_MATH"
7333 tmp0 = gen_reg_rtx (HImode);
7334 tmp1 = gen_reg_rtx (HImode);
7336 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7338 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7339 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7341 /* Extract remainder from AH. */
7342 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7343 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7344 insn = emit_move_insn (operands[3], tmp1);
7346 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7347 set_unique_reg_note (insn, REG_EQUAL, mod);
7349 /* Extract quotient from AL. */
7350 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7352 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7353 set_unique_reg_note (insn, REG_EQUAL, div);
7358 (define_insn "udivmodhiqi3"
7359 [(set (match_operand:HI 0 "register_operand" "=a")
7364 (mod:HI (match_operand:HI 1 "register_operand" "0")
7366 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7370 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7371 (clobber (reg:CC FLAGS_REG))]
7372 "TARGET_QIMODE_MATH"
7374 [(set_attr "type" "idiv")
7375 (set_attr "mode" "QI")])
7377 ;; We cannot use div/idiv for double division, because it causes
7378 ;; "division by zero" on the overflow and that's not what we expect
7379 ;; from truncate. Because true (non truncating) double division is
7380 ;; never generated, we can't create this insn anyway.
7383 ; [(set (match_operand:SI 0 "register_operand" "=a")
7385 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7387 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7388 ; (set (match_operand:SI 3 "register_operand" "=d")
7390 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7391 ; (clobber (reg:CC FLAGS_REG))]
7393 ; "div{l}\t{%2, %0|%0, %2}"
7394 ; [(set_attr "type" "idiv")])
7396 ;;- Logical AND instructions
7398 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7399 ;; Note that this excludes ah.
7401 (define_expand "testsi_ccno_1"
7402 [(set (reg:CCNO FLAGS_REG)
7404 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7405 (match_operand:SI 1 "x86_64_nonmemory_operand" ""))
7408 (define_expand "testqi_ccz_1"
7409 [(set (reg:CCZ FLAGS_REG)
7410 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7411 (match_operand:QI 1 "nonmemory_operand" ""))
7414 (define_expand "testdi_ccno_1"
7415 [(set (reg:CCNO FLAGS_REG)
7417 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7418 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7420 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7422 (define_insn "*testdi_1"
7423 [(set (reg FLAGS_REG)
7426 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7427 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7429 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7430 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7432 test{l}\t{%k1, %k0|%k0, %k1}
7433 test{l}\t{%k1, %k0|%k0, %k1}
7434 test{q}\t{%1, %0|%0, %1}
7435 test{q}\t{%1, %0|%0, %1}
7436 test{q}\t{%1, %0|%0, %1}"
7437 [(set_attr "type" "test")
7438 (set_attr "modrm" "0,1,0,1,1")
7439 (set_attr "mode" "SI,SI,DI,DI,DI")])
7441 (define_insn "*testqi_1_maybe_si"
7442 [(set (reg FLAGS_REG)
7445 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7446 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7448 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7449 && ix86_match_ccmode (insn,
7450 CONST_INT_P (operands[1])
7451 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7453 if (which_alternative == 3)
7455 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7456 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7457 return "test{l}\t{%1, %k0|%k0, %1}";
7459 return "test{b}\t{%1, %0|%0, %1}";
7461 [(set_attr "type" "test")
7462 (set_attr "modrm" "0,1,1,1")
7463 (set_attr "mode" "QI,QI,QI,SI")
7464 (set_attr "pent_pair" "uv,np,uv,np")])
7466 (define_insn "*test<mode>_1"
7467 [(set (reg FLAGS_REG)
7470 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7471 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7473 "ix86_match_ccmode (insn, CCNOmode)
7474 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7475 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7476 [(set_attr "type" "test")
7477 (set_attr "modrm" "0,1,1")
7478 (set_attr "mode" "<MODE>")
7479 (set_attr "pent_pair" "uv,np,uv")])
7481 (define_expand "testqi_ext_ccno_0"
7482 [(set (reg:CCNO FLAGS_REG)
7486 (match_operand 0 "ext_register_operand" "")
7489 (match_operand 1 "const_int_operand" ""))
7492 (define_insn "*testqi_ext_0"
7493 [(set (reg FLAGS_REG)
7497 (match_operand 0 "ext_register_operand" "Q")
7500 (match_operand 1 "const_int_operand" "n"))
7502 "ix86_match_ccmode (insn, CCNOmode)"
7503 "test{b}\t{%1, %h0|%h0, %1}"
7504 [(set_attr "type" "test")
7505 (set_attr "mode" "QI")
7506 (set_attr "length_immediate" "1")
7507 (set_attr "modrm" "1")
7508 (set_attr "pent_pair" "np")])
7510 (define_insn "*testqi_ext_1_rex64"
7511 [(set (reg FLAGS_REG)
7515 (match_operand 0 "ext_register_operand" "Q")
7519 (match_operand:QI 1 "register_operand" "Q")))
7521 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7522 "test{b}\t{%1, %h0|%h0, %1}"
7523 [(set_attr "type" "test")
7524 (set_attr "mode" "QI")])
7526 (define_insn "*testqi_ext_1"
7527 [(set (reg FLAGS_REG)
7531 (match_operand 0 "ext_register_operand" "Q")
7535 (match_operand:QI 1 "general_operand" "Qm")))
7537 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7538 "test{b}\t{%1, %h0|%h0, %1}"
7539 [(set_attr "type" "test")
7540 (set_attr "mode" "QI")])
7542 (define_insn "*testqi_ext_2"
7543 [(set (reg FLAGS_REG)
7547 (match_operand 0 "ext_register_operand" "Q")
7551 (match_operand 1 "ext_register_operand" "Q")
7555 "ix86_match_ccmode (insn, CCNOmode)"
7556 "test{b}\t{%h1, %h0|%h0, %h1}"
7557 [(set_attr "type" "test")
7558 (set_attr "mode" "QI")])
7560 (define_insn "*testqi_ext_3_rex64"
7561 [(set (reg FLAGS_REG)
7562 (compare (zero_extract:DI
7563 (match_operand 0 "nonimmediate_operand" "rm")
7564 (match_operand:DI 1 "const_int_operand" "")
7565 (match_operand:DI 2 "const_int_operand" ""))
7568 && ix86_match_ccmode (insn, CCNOmode)
7569 && INTVAL (operands[1]) > 0
7570 && INTVAL (operands[2]) >= 0
7571 /* Ensure that resulting mask is zero or sign extended operand. */
7572 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7573 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7574 && INTVAL (operands[1]) > 32))
7575 && (GET_MODE (operands[0]) == SImode
7576 || GET_MODE (operands[0]) == DImode
7577 || GET_MODE (operands[0]) == HImode
7578 || GET_MODE (operands[0]) == QImode)"
7581 ;; Combine likes to form bit extractions for some tests. Humor it.
7582 (define_insn "*testqi_ext_3"
7583 [(set (reg FLAGS_REG)
7584 (compare (zero_extract:SI
7585 (match_operand 0 "nonimmediate_operand" "rm")
7586 (match_operand:SI 1 "const_int_operand" "")
7587 (match_operand:SI 2 "const_int_operand" ""))
7589 "ix86_match_ccmode (insn, CCNOmode)
7590 && INTVAL (operands[1]) > 0
7591 && INTVAL (operands[2]) >= 0
7592 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7593 && (GET_MODE (operands[0]) == SImode
7594 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7595 || GET_MODE (operands[0]) == HImode
7596 || GET_MODE (operands[0]) == QImode)"
7600 [(set (match_operand 0 "flags_reg_operand" "")
7601 (match_operator 1 "compare_operator"
7603 (match_operand 2 "nonimmediate_operand" "")
7604 (match_operand 3 "const_int_operand" "")
7605 (match_operand 4 "const_int_operand" ""))
7607 "ix86_match_ccmode (insn, CCNOmode)"
7608 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7610 rtx val = operands[2];
7611 HOST_WIDE_INT len = INTVAL (operands[3]);
7612 HOST_WIDE_INT pos = INTVAL (operands[4]);
7614 enum machine_mode mode, submode;
7616 mode = GET_MODE (val);
7619 /* ??? Combine likes to put non-volatile mem extractions in QImode
7620 no matter the size of the test. So find a mode that works. */
7621 if (! MEM_VOLATILE_P (val))
7623 mode = smallest_mode_for_size (pos + len, MODE_INT);
7624 val = adjust_address (val, mode, 0);
7627 else if (GET_CODE (val) == SUBREG
7628 && (submode = GET_MODE (SUBREG_REG (val)),
7629 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7630 && pos + len <= GET_MODE_BITSIZE (submode)
7631 && GET_MODE_CLASS (submode) == MODE_INT)
7633 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7635 val = SUBREG_REG (val);
7637 else if (mode == HImode && pos + len <= 8)
7639 /* Small HImode tests can be converted to QImode. */
7641 val = gen_lowpart (QImode, val);
7644 if (len == HOST_BITS_PER_WIDE_INT)
7647 mask = ((HOST_WIDE_INT)1 << len) - 1;
7650 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7653 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7654 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7655 ;; this is relatively important trick.
7656 ;; Do the conversion only post-reload to avoid limiting of the register class
7659 [(set (match_operand 0 "flags_reg_operand" "")
7660 (match_operator 1 "compare_operator"
7661 [(and (match_operand 2 "register_operand" "")
7662 (match_operand 3 "const_int_operand" ""))
7665 && QI_REG_P (operands[2])
7666 && GET_MODE (operands[2]) != QImode
7667 && ((ix86_match_ccmode (insn, CCZmode)
7668 && !(INTVAL (operands[3]) & ~(255 << 8)))
7669 || (ix86_match_ccmode (insn, CCNOmode)
7670 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7673 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7677 operands[2] = gen_lowpart (SImode, operands[2]);
7678 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7682 [(set (match_operand 0 "flags_reg_operand" "")
7683 (match_operator 1 "compare_operator"
7684 [(and (match_operand 2 "nonimmediate_operand" "")
7685 (match_operand 3 "const_int_operand" ""))
7688 && GET_MODE (operands[2]) != QImode
7689 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7690 && ((ix86_match_ccmode (insn, CCZmode)
7691 && !(INTVAL (operands[3]) & ~255))
7692 || (ix86_match_ccmode (insn, CCNOmode)
7693 && !(INTVAL (operands[3]) & ~127)))"
7695 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7698 operands[2] = gen_lowpart (QImode, operands[2]);
7699 operands[3] = gen_lowpart (QImode, operands[3]);
7702 ;; %%% This used to optimize known byte-wide and operations to memory,
7703 ;; and sometimes to QImode registers. If this is considered useful,
7704 ;; it should be done with splitters.
7706 (define_expand "and<mode>3"
7707 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7708 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7709 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7712 if (<MODE>mode == DImode
7713 && GET_CODE (operands[2]) == CONST_INT
7714 && INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffffffff
7715 && REG_P (operands[1]))
7716 emit_insn (gen_zero_extendsidi2 (operands[0],
7717 gen_lowpart (SImode, operands[1])));
7719 ix86_expand_binary_operator (AND, <MODE>mode, operands);
7723 (define_insn "*anddi_1"
7724 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7726 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7727 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7728 (clobber (reg:CC FLAGS_REG))]
7729 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7731 switch (get_attr_type (insn))
7735 enum machine_mode mode;
7737 gcc_assert (CONST_INT_P (operands[2]));
7738 if (INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffffffff)
7740 else if (INTVAL (operands[2]) == 0xffff)
7744 gcc_assert (INTVAL (operands[2]) == 0xff);
7748 operands[1] = gen_lowpart (mode, operands[1]);
7750 return "mov{l}\t{%1, %k0|%k0, %1}";
7751 else if (mode == HImode)
7752 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7754 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7758 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7759 if (get_attr_mode (insn) == MODE_SI)
7760 return "and{l}\t{%k2, %k0|%k0, %k2}";
7762 return "and{q}\t{%2, %0|%0, %2}";
7765 [(set_attr "type" "alu,alu,alu,imovx")
7766 (set_attr "length_immediate" "*,*,*,0")
7767 (set (attr "prefix_rex")
7769 (and (eq_attr "type" "imovx")
7770 (and (match_test "INTVAL (operands[2]) == 0xff")
7771 (match_operand 1 "ext_QIreg_operand" "")))
7773 (const_string "*")))
7774 (set_attr "mode" "SI,DI,DI,SI")])
7776 (define_insn "*andsi_1"
7777 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7778 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7779 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7780 (clobber (reg:CC FLAGS_REG))]
7781 "ix86_binary_operator_ok (AND, SImode, operands)"
7783 switch (get_attr_type (insn))
7787 enum machine_mode mode;
7789 gcc_assert (CONST_INT_P (operands[2]));
7790 if (INTVAL (operands[2]) == 0xffff)
7794 gcc_assert (INTVAL (operands[2]) == 0xff);
7798 operands[1] = gen_lowpart (mode, operands[1]);
7800 return "movz{wl|x}\t{%1, %0|%0, %1}";
7802 return "movz{bl|x}\t{%1, %0|%0, %1}";
7806 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7807 return "and{l}\t{%2, %0|%0, %2}";
7810 [(set_attr "type" "alu,alu,imovx")
7811 (set (attr "prefix_rex")
7813 (and (eq_attr "type" "imovx")
7814 (and (match_test "INTVAL (operands[2]) == 0xff")
7815 (match_operand 1 "ext_QIreg_operand" "")))
7817 (const_string "*")))
7818 (set_attr "length_immediate" "*,*,0")
7819 (set_attr "mode" "SI")])
7821 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7822 (define_insn "*andsi_1_zext"
7823 [(set (match_operand:DI 0 "register_operand" "=r")
7825 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7826 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7827 (clobber (reg:CC FLAGS_REG))]
7828 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7829 "and{l}\t{%2, %k0|%k0, %2}"
7830 [(set_attr "type" "alu")
7831 (set_attr "mode" "SI")])
7833 (define_insn "*andhi_1"
7834 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7835 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7836 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7837 (clobber (reg:CC FLAGS_REG))]
7838 "ix86_binary_operator_ok (AND, HImode, operands)"
7840 switch (get_attr_type (insn))
7843 gcc_assert (CONST_INT_P (operands[2]));
7844 gcc_assert (INTVAL (operands[2]) == 0xff);
7845 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7848 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7850 return "and{w}\t{%2, %0|%0, %2}";
7853 [(set_attr "type" "alu,alu,imovx")
7854 (set_attr "length_immediate" "*,*,0")
7855 (set (attr "prefix_rex")
7857 (and (eq_attr "type" "imovx")
7858 (match_operand 1 "ext_QIreg_operand" ""))
7860 (const_string "*")))
7861 (set_attr "mode" "HI,HI,SI")])
7863 ;; %%% Potential partial reg stall on alternative 2. What to do?
7864 (define_insn "*andqi_1"
7865 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7866 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7867 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7868 (clobber (reg:CC FLAGS_REG))]
7869 "ix86_binary_operator_ok (AND, QImode, operands)"
7871 and{b}\t{%2, %0|%0, %2}
7872 and{b}\t{%2, %0|%0, %2}
7873 and{l}\t{%k2, %k0|%k0, %k2}"
7874 [(set_attr "type" "alu")
7875 (set_attr "mode" "QI,QI,SI")])
7877 (define_insn "*andqi_1_slp"
7878 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7879 (and:QI (match_dup 0)
7880 (match_operand:QI 1 "general_operand" "qn,qmn")))
7881 (clobber (reg:CC FLAGS_REG))]
7882 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7883 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7884 "and{b}\t{%1, %0|%0, %1}"
7885 [(set_attr "type" "alu1")
7886 (set_attr "mode" "QI")])
7889 [(set (match_operand 0 "register_operand" "")
7891 (const_int -65536)))
7892 (clobber (reg:CC FLAGS_REG))]
7893 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7894 || optimize_function_for_size_p (cfun)"
7895 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7896 "operands[1] = gen_lowpart (HImode, operands[0]);")
7899 [(set (match_operand 0 "ext_register_operand" "")
7902 (clobber (reg:CC FLAGS_REG))]
7903 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7904 && reload_completed"
7905 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7906 "operands[1] = gen_lowpart (QImode, operands[0]);")
7909 [(set (match_operand 0 "ext_register_operand" "")
7911 (const_int -65281)))
7912 (clobber (reg:CC FLAGS_REG))]
7913 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7914 && reload_completed"
7915 [(parallel [(set (zero_extract:SI (match_dup 0)
7919 (zero_extract:SI (match_dup 0)
7922 (zero_extract:SI (match_dup 0)
7925 (clobber (reg:CC FLAGS_REG))])]
7926 "operands[0] = gen_lowpart (SImode, operands[0]);")
7928 (define_insn "*anddi_2"
7929 [(set (reg FLAGS_REG)
7932 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7933 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7935 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7936 (and:DI (match_dup 1) (match_dup 2)))]
7937 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7938 && ix86_binary_operator_ok (AND, DImode, operands)"
7940 and{l}\t{%k2, %k0|%k0, %k2}
7941 and{q}\t{%2, %0|%0, %2}
7942 and{q}\t{%2, %0|%0, %2}"
7943 [(set_attr "type" "alu")
7944 (set_attr "mode" "SI,DI,DI")])
7946 (define_insn "*andqi_2_maybe_si"
7947 [(set (reg FLAGS_REG)
7949 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7950 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7952 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7953 (and:QI (match_dup 1) (match_dup 2)))]
7954 "ix86_binary_operator_ok (AND, QImode, operands)
7955 && ix86_match_ccmode (insn,
7956 CONST_INT_P (operands[2])
7957 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7959 if (which_alternative == 2)
7961 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7962 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7963 return "and{l}\t{%2, %k0|%k0, %2}";
7965 return "and{b}\t{%2, %0|%0, %2}";
7967 [(set_attr "type" "alu")
7968 (set_attr "mode" "QI,QI,SI")])
7970 (define_insn "*and<mode>_2"
7971 [(set (reg FLAGS_REG)
7972 (compare (and:SWI124
7973 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7974 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7976 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7977 (and:SWI124 (match_dup 1) (match_dup 2)))]
7978 "ix86_match_ccmode (insn, CCNOmode)
7979 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7980 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7981 [(set_attr "type" "alu")
7982 (set_attr "mode" "<MODE>")])
7984 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7985 (define_insn "*andsi_2_zext"
7986 [(set (reg FLAGS_REG)
7988 (match_operand:SI 1 "nonimmediate_operand" "%0")
7989 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7991 (set (match_operand:DI 0 "register_operand" "=r")
7992 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7993 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7994 && ix86_binary_operator_ok (AND, SImode, operands)"
7995 "and{l}\t{%2, %k0|%k0, %2}"
7996 [(set_attr "type" "alu")
7997 (set_attr "mode" "SI")])
7999 (define_insn "*andqi_2_slp"
8000 [(set (reg FLAGS_REG)
8002 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8003 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8005 (set (strict_low_part (match_dup 0))
8006 (and:QI (match_dup 0) (match_dup 1)))]
8007 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8008 && ix86_match_ccmode (insn, CCNOmode)
8009 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8010 "and{b}\t{%1, %0|%0, %1}"
8011 [(set_attr "type" "alu1")
8012 (set_attr "mode" "QI")])
8014 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8015 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8016 ;; for a QImode operand, which of course failed.
8017 (define_insn "andqi_ext_0"
8018 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8023 (match_operand 1 "ext_register_operand" "0")
8026 (match_operand 2 "const_int_operand" "n")))
8027 (clobber (reg:CC FLAGS_REG))]
8029 "and{b}\t{%2, %h0|%h0, %2}"
8030 [(set_attr "type" "alu")
8031 (set_attr "length_immediate" "1")
8032 (set_attr "modrm" "1")
8033 (set_attr "mode" "QI")])
8035 ;; Generated by peephole translating test to and. This shows up
8036 ;; often in fp comparisons.
8037 (define_insn "*andqi_ext_0_cc"
8038 [(set (reg FLAGS_REG)
8042 (match_operand 1 "ext_register_operand" "0")
8045 (match_operand 2 "const_int_operand" "n"))
8047 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8056 "ix86_match_ccmode (insn, CCNOmode)"
8057 "and{b}\t{%2, %h0|%h0, %2}"
8058 [(set_attr "type" "alu")
8059 (set_attr "length_immediate" "1")
8060 (set_attr "modrm" "1")
8061 (set_attr "mode" "QI")])
8063 (define_insn "*andqi_ext_1_rex64"
8064 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8069 (match_operand 1 "ext_register_operand" "0")
8073 (match_operand 2 "ext_register_operand" "Q"))))
8074 (clobber (reg:CC FLAGS_REG))]
8076 "and{b}\t{%2, %h0|%h0, %2}"
8077 [(set_attr "type" "alu")
8078 (set_attr "length_immediate" "0")
8079 (set_attr "mode" "QI")])
8081 (define_insn "*andqi_ext_1"
8082 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8087 (match_operand 1 "ext_register_operand" "0")
8091 (match_operand:QI 2 "general_operand" "Qm"))))
8092 (clobber (reg:CC FLAGS_REG))]
8094 "and{b}\t{%2, %h0|%h0, %2}"
8095 [(set_attr "type" "alu")
8096 (set_attr "length_immediate" "0")
8097 (set_attr "mode" "QI")])
8099 (define_insn "*andqi_ext_2"
8100 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8105 (match_operand 1 "ext_register_operand" "%0")
8109 (match_operand 2 "ext_register_operand" "Q")
8112 (clobber (reg:CC FLAGS_REG))]
8114 "and{b}\t{%h2, %h0|%h0, %h2}"
8115 [(set_attr "type" "alu")
8116 (set_attr "length_immediate" "0")
8117 (set_attr "mode" "QI")])
8119 ;; Convert wide AND instructions with immediate operand to shorter QImode
8120 ;; equivalents when possible.
8121 ;; Don't do the splitting with memory operands, since it introduces risk
8122 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8123 ;; for size, but that can (should?) be handled by generic code instead.
8125 [(set (match_operand 0 "register_operand" "")
8126 (and (match_operand 1 "register_operand" "")
8127 (match_operand 2 "const_int_operand" "")))
8128 (clobber (reg:CC FLAGS_REG))]
8130 && QI_REG_P (operands[0])
8131 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8132 && !(~INTVAL (operands[2]) & ~(255 << 8))
8133 && GET_MODE (operands[0]) != QImode"
8134 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8135 (and:SI (zero_extract:SI (match_dup 1)
8136 (const_int 8) (const_int 8))
8138 (clobber (reg:CC FLAGS_REG))])]
8140 operands[0] = gen_lowpart (SImode, operands[0]);
8141 operands[1] = gen_lowpart (SImode, operands[1]);
8142 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8145 ;; Since AND can be encoded with sign extended immediate, this is only
8146 ;; profitable when 7th bit is not set.
8148 [(set (match_operand 0 "register_operand" "")
8149 (and (match_operand 1 "general_operand" "")
8150 (match_operand 2 "const_int_operand" "")))
8151 (clobber (reg:CC FLAGS_REG))]
8153 && ANY_QI_REG_P (operands[0])
8154 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8155 && !(~INTVAL (operands[2]) & ~255)
8156 && !(INTVAL (operands[2]) & 128)
8157 && GET_MODE (operands[0]) != QImode"
8158 [(parallel [(set (strict_low_part (match_dup 0))
8159 (and:QI (match_dup 1)
8161 (clobber (reg:CC FLAGS_REG))])]
8163 operands[0] = gen_lowpart (QImode, operands[0]);
8164 operands[1] = gen_lowpart (QImode, operands[1]);
8165 operands[2] = gen_lowpart (QImode, operands[2]);
8168 ;; Logical inclusive and exclusive OR instructions
8170 ;; %%% This used to optimize known byte-wide and operations to memory.
8171 ;; If this is considered useful, it should be done with splitters.
8173 (define_expand "<code><mode>3"
8174 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8175 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8176 (match_operand:SWIM 2 "<general_operand>" "")))]
8178 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8180 (define_insn "*<code><mode>_1"
8181 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8183 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8184 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8185 (clobber (reg:CC FLAGS_REG))]
8186 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8187 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8188 [(set_attr "type" "alu")
8189 (set_attr "mode" "<MODE>")])
8191 ;; %%% Potential partial reg stall on alternative 2. What to do?
8192 (define_insn "*<code>qi_1"
8193 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8194 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8195 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8196 (clobber (reg:CC FLAGS_REG))]
8197 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8199 <logic>{b}\t{%2, %0|%0, %2}
8200 <logic>{b}\t{%2, %0|%0, %2}
8201 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8202 [(set_attr "type" "alu")
8203 (set_attr "mode" "QI,QI,SI")])
8205 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8206 (define_insn "*<code>si_1_zext"
8207 [(set (match_operand:DI 0 "register_operand" "=r")
8209 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8210 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8211 (clobber (reg:CC FLAGS_REG))]
8212 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8213 "<logic>{l}\t{%2, %k0|%k0, %2}"
8214 [(set_attr "type" "alu")
8215 (set_attr "mode" "SI")])
8217 (define_insn "*<code>si_1_zext_imm"
8218 [(set (match_operand:DI 0 "register_operand" "=r")
8220 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8221 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8222 (clobber (reg:CC FLAGS_REG))]
8223 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8224 "<logic>{l}\t{%2, %k0|%k0, %2}"
8225 [(set_attr "type" "alu")
8226 (set_attr "mode" "SI")])
8228 (define_insn "*<code>qi_1_slp"
8229 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8230 (any_or:QI (match_dup 0)
8231 (match_operand:QI 1 "general_operand" "qmn,qn")))
8232 (clobber (reg:CC FLAGS_REG))]
8233 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8234 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8235 "<logic>{b}\t{%1, %0|%0, %1}"
8236 [(set_attr "type" "alu1")
8237 (set_attr "mode" "QI")])
8239 (define_insn "*<code><mode>_2"
8240 [(set (reg FLAGS_REG)
8241 (compare (any_or:SWI
8242 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8243 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8245 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8246 (any_or:SWI (match_dup 1) (match_dup 2)))]
8247 "ix86_match_ccmode (insn, CCNOmode)
8248 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8249 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8250 [(set_attr "type" "alu")
8251 (set_attr "mode" "<MODE>")])
8253 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8254 ;; ??? Special case for immediate operand is missing - it is tricky.
8255 (define_insn "*<code>si_2_zext"
8256 [(set (reg FLAGS_REG)
8257 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8258 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8260 (set (match_operand:DI 0 "register_operand" "=r")
8261 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8262 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8263 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8264 "<logic>{l}\t{%2, %k0|%k0, %2}"
8265 [(set_attr "type" "alu")
8266 (set_attr "mode" "SI")])
8268 (define_insn "*<code>si_2_zext_imm"
8269 [(set (reg FLAGS_REG)
8271 (match_operand:SI 1 "nonimmediate_operand" "%0")
8272 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8274 (set (match_operand:DI 0 "register_operand" "=r")
8275 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8276 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8277 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8278 "<logic>{l}\t{%2, %k0|%k0, %2}"
8279 [(set_attr "type" "alu")
8280 (set_attr "mode" "SI")])
8282 (define_insn "*<code>qi_2_slp"
8283 [(set (reg FLAGS_REG)
8284 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8285 (match_operand:QI 1 "general_operand" "qmn,qn"))
8287 (set (strict_low_part (match_dup 0))
8288 (any_or:QI (match_dup 0) (match_dup 1)))]
8289 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8290 && ix86_match_ccmode (insn, CCNOmode)
8291 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8292 "<logic>{b}\t{%1, %0|%0, %1}"
8293 [(set_attr "type" "alu1")
8294 (set_attr "mode" "QI")])
8296 (define_insn "*<code><mode>_3"
8297 [(set (reg FLAGS_REG)
8298 (compare (any_or:SWI
8299 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8300 (match_operand:SWI 2 "<general_operand>" "<g>"))
8302 (clobber (match_scratch:SWI 0 "=<r>"))]
8303 "ix86_match_ccmode (insn, CCNOmode)
8304 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8305 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8306 [(set_attr "type" "alu")
8307 (set_attr "mode" "<MODE>")])
8309 (define_insn "*<code>qi_ext_0"
8310 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8315 (match_operand 1 "ext_register_operand" "0")
8318 (match_operand 2 "const_int_operand" "n")))
8319 (clobber (reg:CC FLAGS_REG))]
8320 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8321 "<logic>{b}\t{%2, %h0|%h0, %2}"
8322 [(set_attr "type" "alu")
8323 (set_attr "length_immediate" "1")
8324 (set_attr "modrm" "1")
8325 (set_attr "mode" "QI")])
8327 (define_insn "*<code>qi_ext_1_rex64"
8328 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8333 (match_operand 1 "ext_register_operand" "0")
8337 (match_operand 2 "ext_register_operand" "Q"))))
8338 (clobber (reg:CC FLAGS_REG))]
8340 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8341 "<logic>{b}\t{%2, %h0|%h0, %2}"
8342 [(set_attr "type" "alu")
8343 (set_attr "length_immediate" "0")
8344 (set_attr "mode" "QI")])
8346 (define_insn "*<code>qi_ext_1"
8347 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8352 (match_operand 1 "ext_register_operand" "0")
8356 (match_operand:QI 2 "general_operand" "Qm"))))
8357 (clobber (reg:CC FLAGS_REG))]
8359 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8360 "<logic>{b}\t{%2, %h0|%h0, %2}"
8361 [(set_attr "type" "alu")
8362 (set_attr "length_immediate" "0")
8363 (set_attr "mode" "QI")])
8365 (define_insn "*<code>qi_ext_2"
8366 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8370 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8373 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8376 (clobber (reg:CC FLAGS_REG))]
8377 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8378 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8379 [(set_attr "type" "alu")
8380 (set_attr "length_immediate" "0")
8381 (set_attr "mode" "QI")])
8384 [(set (match_operand 0 "register_operand" "")
8385 (any_or (match_operand 1 "register_operand" "")
8386 (match_operand 2 "const_int_operand" "")))
8387 (clobber (reg:CC FLAGS_REG))]
8389 && QI_REG_P (operands[0])
8390 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8391 && !(INTVAL (operands[2]) & ~(255 << 8))
8392 && GET_MODE (operands[0]) != QImode"
8393 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8394 (any_or:SI (zero_extract:SI (match_dup 1)
8395 (const_int 8) (const_int 8))
8397 (clobber (reg:CC FLAGS_REG))])]
8399 operands[0] = gen_lowpart (SImode, operands[0]);
8400 operands[1] = gen_lowpart (SImode, operands[1]);
8401 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8404 ;; Since OR can be encoded with sign extended immediate, this is only
8405 ;; profitable when 7th bit is set.
8407 [(set (match_operand 0 "register_operand" "")
8408 (any_or (match_operand 1 "general_operand" "")
8409 (match_operand 2 "const_int_operand" "")))
8410 (clobber (reg:CC FLAGS_REG))]
8412 && ANY_QI_REG_P (operands[0])
8413 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8414 && !(INTVAL (operands[2]) & ~255)
8415 && (INTVAL (operands[2]) & 128)
8416 && GET_MODE (operands[0]) != QImode"
8417 [(parallel [(set (strict_low_part (match_dup 0))
8418 (any_or:QI (match_dup 1)
8420 (clobber (reg:CC FLAGS_REG))])]
8422 operands[0] = gen_lowpart (QImode, operands[0]);
8423 operands[1] = gen_lowpart (QImode, operands[1]);
8424 operands[2] = gen_lowpart (QImode, operands[2]);
8427 (define_expand "xorqi_cc_ext_1"
8429 (set (reg:CCNO FLAGS_REG)
8433 (match_operand 1 "ext_register_operand" "")
8436 (match_operand:QI 2 "general_operand" ""))
8438 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8448 (define_insn "*xorqi_cc_ext_1_rex64"
8449 [(set (reg FLAGS_REG)
8453 (match_operand 1 "ext_register_operand" "0")
8456 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8458 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8467 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8468 "xor{b}\t{%2, %h0|%h0, %2}"
8469 [(set_attr "type" "alu")
8470 (set_attr "modrm" "1")
8471 (set_attr "mode" "QI")])
8473 (define_insn "*xorqi_cc_ext_1"
8474 [(set (reg FLAGS_REG)
8478 (match_operand 1 "ext_register_operand" "0")
8481 (match_operand:QI 2 "general_operand" "qmn"))
8483 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8492 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8493 "xor{b}\t{%2, %h0|%h0, %2}"
8494 [(set_attr "type" "alu")
8495 (set_attr "modrm" "1")
8496 (set_attr "mode" "QI")])
8498 ;; Negation instructions
8500 (define_expand "neg<mode>2"
8501 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8502 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8504 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8506 (define_insn_and_split "*neg<dwi>2_doubleword"
8507 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8508 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8509 (clobber (reg:CC FLAGS_REG))]
8510 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8514 [(set (reg:CCZ FLAGS_REG)
8515 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8516 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8519 (plus:DWIH (match_dup 3)
8520 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8522 (clobber (reg:CC FLAGS_REG))])
8525 (neg:DWIH (match_dup 2)))
8526 (clobber (reg:CC FLAGS_REG))])]
8527 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8529 (define_insn "*neg<mode>2_1"
8530 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8531 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8532 (clobber (reg:CC FLAGS_REG))]
8533 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8534 "neg{<imodesuffix>}\t%0"
8535 [(set_attr "type" "negnot")
8536 (set_attr "mode" "<MODE>")])
8538 ;; Combine is quite creative about this pattern.
8539 (define_insn "*negsi2_1_zext"
8540 [(set (match_operand:DI 0 "register_operand" "=r")
8542 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8545 (clobber (reg:CC FLAGS_REG))]
8546 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8548 [(set_attr "type" "negnot")
8549 (set_attr "mode" "SI")])
8551 ;; The problem with neg is that it does not perform (compare x 0),
8552 ;; it really performs (compare 0 x), which leaves us with the zero
8553 ;; flag being the only useful item.
8555 (define_insn "*neg<mode>2_cmpz"
8556 [(set (reg:CCZ FLAGS_REG)
8558 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8560 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8561 (neg:SWI (match_dup 1)))]
8562 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8563 "neg{<imodesuffix>}\t%0"
8564 [(set_attr "type" "negnot")
8565 (set_attr "mode" "<MODE>")])
8567 (define_insn "*negsi2_cmpz_zext"
8568 [(set (reg:CCZ FLAGS_REG)
8572 (match_operand:DI 1 "register_operand" "0")
8576 (set (match_operand:DI 0 "register_operand" "=r")
8577 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8580 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8582 [(set_attr "type" "negnot")
8583 (set_attr "mode" "SI")])
8585 ;; Changing of sign for FP values is doable using integer unit too.
8587 (define_expand "<code><mode>2"
8588 [(set (match_operand:X87MODEF 0 "register_operand" "")
8589 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8590 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8591 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8593 (define_insn "*absneg<mode>2_mixed"
8594 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8595 (match_operator:MODEF 3 "absneg_operator"
8596 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8597 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8598 (clobber (reg:CC FLAGS_REG))]
8599 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8602 (define_insn "*absneg<mode>2_sse"
8603 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8604 (match_operator:MODEF 3 "absneg_operator"
8605 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8606 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8607 (clobber (reg:CC FLAGS_REG))]
8608 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8611 (define_insn "*absneg<mode>2_i387"
8612 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8613 (match_operator:X87MODEF 3 "absneg_operator"
8614 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8615 (use (match_operand 2 "" ""))
8616 (clobber (reg:CC FLAGS_REG))]
8617 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8620 (define_expand "<code>tf2"
8621 [(set (match_operand:TF 0 "register_operand" "")
8622 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8624 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8626 (define_insn "*absnegtf2_sse"
8627 [(set (match_operand:TF 0 "register_operand" "=x,x")
8628 (match_operator:TF 3 "absneg_operator"
8629 [(match_operand:TF 1 "register_operand" "0,x")]))
8630 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8631 (clobber (reg:CC FLAGS_REG))]
8635 ;; Splitters for fp abs and neg.
8638 [(set (match_operand 0 "fp_register_operand" "")
8639 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8640 (use (match_operand 2 "" ""))
8641 (clobber (reg:CC FLAGS_REG))]
8643 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8646 [(set (match_operand 0 "register_operand" "")
8647 (match_operator 3 "absneg_operator"
8648 [(match_operand 1 "register_operand" "")]))
8649 (use (match_operand 2 "nonimmediate_operand" ""))
8650 (clobber (reg:CC FLAGS_REG))]
8651 "reload_completed && SSE_REG_P (operands[0])"
8652 [(set (match_dup 0) (match_dup 3))]
8654 enum machine_mode mode = GET_MODE (operands[0]);
8655 enum machine_mode vmode = GET_MODE (operands[2]);
8658 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8659 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8660 if (operands_match_p (operands[0], operands[2]))
8663 operands[1] = operands[2];
8666 if (GET_CODE (operands[3]) == ABS)
8667 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8669 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8674 [(set (match_operand:SF 0 "register_operand" "")
8675 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8676 (use (match_operand:V4SF 2 "" ""))
8677 (clobber (reg:CC FLAGS_REG))]
8679 [(parallel [(set (match_dup 0) (match_dup 1))
8680 (clobber (reg:CC FLAGS_REG))])]
8683 operands[0] = gen_lowpart (SImode, operands[0]);
8684 if (GET_CODE (operands[1]) == ABS)
8686 tmp = gen_int_mode (0x7fffffff, SImode);
8687 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8691 tmp = gen_int_mode (0x80000000, SImode);
8692 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8698 [(set (match_operand:DF 0 "register_operand" "")
8699 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8700 (use (match_operand 2 "" ""))
8701 (clobber (reg:CC FLAGS_REG))]
8703 [(parallel [(set (match_dup 0) (match_dup 1))
8704 (clobber (reg:CC FLAGS_REG))])]
8709 tmp = gen_lowpart (DImode, operands[0]);
8710 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8713 if (GET_CODE (operands[1]) == ABS)
8716 tmp = gen_rtx_NOT (DImode, tmp);
8720 operands[0] = gen_highpart (SImode, operands[0]);
8721 if (GET_CODE (operands[1]) == ABS)
8723 tmp = gen_int_mode (0x7fffffff, SImode);
8724 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8728 tmp = gen_int_mode (0x80000000, SImode);
8729 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8736 [(set (match_operand:XF 0 "register_operand" "")
8737 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8738 (use (match_operand 2 "" ""))
8739 (clobber (reg:CC FLAGS_REG))]
8741 [(parallel [(set (match_dup 0) (match_dup 1))
8742 (clobber (reg:CC FLAGS_REG))])]
8745 operands[0] = gen_rtx_REG (SImode,
8746 true_regnum (operands[0])
8747 + (TARGET_64BIT ? 1 : 2));
8748 if (GET_CODE (operands[1]) == ABS)
8750 tmp = GEN_INT (0x7fff);
8751 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8755 tmp = GEN_INT (0x8000);
8756 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8761 ;; Conditionalize these after reload. If they match before reload, we
8762 ;; lose the clobber and ability to use integer instructions.
8764 (define_insn "*<code><mode>2_1"
8765 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8766 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8768 && (reload_completed
8769 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8770 "f<absneg_mnemonic>"
8771 [(set_attr "type" "fsgn")
8772 (set_attr "mode" "<MODE>")])
8774 (define_insn "*<code>extendsfdf2"
8775 [(set (match_operand:DF 0 "register_operand" "=f")
8776 (absneg:DF (float_extend:DF
8777 (match_operand:SF 1 "register_operand" "0"))))]
8778 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8779 "f<absneg_mnemonic>"
8780 [(set_attr "type" "fsgn")
8781 (set_attr "mode" "DF")])
8783 (define_insn "*<code>extendsfxf2"
8784 [(set (match_operand:XF 0 "register_operand" "=f")
8785 (absneg:XF (float_extend:XF
8786 (match_operand:SF 1 "register_operand" "0"))))]
8788 "f<absneg_mnemonic>"
8789 [(set_attr "type" "fsgn")
8790 (set_attr "mode" "XF")])
8792 (define_insn "*<code>extenddfxf2"
8793 [(set (match_operand:XF 0 "register_operand" "=f")
8794 (absneg:XF (float_extend:XF
8795 (match_operand:DF 1 "register_operand" "0"))))]
8797 "f<absneg_mnemonic>"
8798 [(set_attr "type" "fsgn")
8799 (set_attr "mode" "XF")])
8801 ;; Copysign instructions
8803 (define_mode_iterator CSGNMODE [SF DF TF])
8804 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8806 (define_expand "copysign<mode>3"
8807 [(match_operand:CSGNMODE 0 "register_operand" "")
8808 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8809 (match_operand:CSGNMODE 2 "register_operand" "")]
8810 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8811 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8812 "ix86_expand_copysign (operands); DONE;")
8814 (define_insn_and_split "copysign<mode>3_const"
8815 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8817 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8818 (match_operand:CSGNMODE 2 "register_operand" "0")
8819 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8821 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8822 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8824 "&& reload_completed"
8826 "ix86_split_copysign_const (operands); DONE;")
8828 (define_insn "copysign<mode>3_var"
8829 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8831 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8832 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8833 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8834 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8836 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8837 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8838 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8842 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8844 [(match_operand:CSGNMODE 2 "register_operand" "")
8845 (match_operand:CSGNMODE 3 "register_operand" "")
8846 (match_operand:<CSGNVMODE> 4 "" "")
8847 (match_operand:<CSGNVMODE> 5 "" "")]
8849 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8850 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8851 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8852 && reload_completed"
8854 "ix86_split_copysign_var (operands); DONE;")
8856 ;; One complement instructions
8858 (define_expand "one_cmpl<mode>2"
8859 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8860 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8862 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8864 (define_insn "*one_cmpl<mode>2_1"
8865 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8866 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8867 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8868 "not{<imodesuffix>}\t%0"
8869 [(set_attr "type" "negnot")
8870 (set_attr "mode" "<MODE>")])
8872 ;; %%% Potential partial reg stall on alternative 1. What to do?
8873 (define_insn "*one_cmplqi2_1"
8874 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8875 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8876 "ix86_unary_operator_ok (NOT, QImode, operands)"
8880 [(set_attr "type" "negnot")
8881 (set_attr "mode" "QI,SI")])
8883 ;; ??? Currently never generated - xor is used instead.
8884 (define_insn "*one_cmplsi2_1_zext"
8885 [(set (match_operand:DI 0 "register_operand" "=r")
8887 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8888 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8890 [(set_attr "type" "negnot")
8891 (set_attr "mode" "SI")])
8893 (define_insn "*one_cmpl<mode>2_2"
8894 [(set (reg FLAGS_REG)
8895 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8897 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8898 (not:SWI (match_dup 1)))]
8899 "ix86_match_ccmode (insn, CCNOmode)
8900 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8902 [(set_attr "type" "alu1")
8903 (set_attr "mode" "<MODE>")])
8906 [(set (match_operand 0 "flags_reg_operand" "")
8907 (match_operator 2 "compare_operator"
8908 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8910 (set (match_operand:SWI 1 "nonimmediate_operand" "")
8911 (not:SWI (match_dup 3)))]
8912 "ix86_match_ccmode (insn, CCNOmode)"
8913 [(parallel [(set (match_dup 0)
8914 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8917 (xor:SWI (match_dup 3) (const_int -1)))])])
8919 ;; ??? Currently never generated - xor is used instead.
8920 (define_insn "*one_cmplsi2_2_zext"
8921 [(set (reg FLAGS_REG)
8922 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8924 (set (match_operand:DI 0 "register_operand" "=r")
8925 (zero_extend:DI (not:SI (match_dup 1))))]
8926 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8927 && ix86_unary_operator_ok (NOT, SImode, operands)"
8929 [(set_attr "type" "alu1")
8930 (set_attr "mode" "SI")])
8933 [(set (match_operand 0 "flags_reg_operand" "")
8934 (match_operator 2 "compare_operator"
8935 [(not:SI (match_operand:SI 3 "register_operand" ""))
8937 (set (match_operand:DI 1 "register_operand" "")
8938 (zero_extend:DI (not:SI (match_dup 3))))]
8939 "ix86_match_ccmode (insn, CCNOmode)"
8940 [(parallel [(set (match_dup 0)
8941 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8944 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8946 ;; Shift instructions
8948 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8949 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8950 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8951 ;; from the assembler input.
8953 ;; This instruction shifts the target reg/mem as usual, but instead of
8954 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8955 ;; is a left shift double, bits are taken from the high order bits of
8956 ;; reg, else if the insn is a shift right double, bits are taken from the
8957 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8958 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8960 ;; Since sh[lr]d does not change the `reg' operand, that is done
8961 ;; separately, making all shifts emit pairs of shift double and normal
8962 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8963 ;; support a 63 bit shift, each shift where the count is in a reg expands
8964 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8966 ;; If the shift count is a constant, we need never emit more than one
8967 ;; shift pair, instead using moves and sign extension for counts greater
8970 (define_expand "ashl<mode>3"
8971 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8972 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8973 (match_operand:QI 2 "nonmemory_operand" "")))]
8975 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8977 (define_insn "*ashl<mode>3_doubleword"
8978 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8979 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8980 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8981 (clobber (reg:CC FLAGS_REG))]
8984 [(set_attr "type" "multi")])
8987 [(set (match_operand:DWI 0 "register_operand" "")
8988 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8989 (match_operand:QI 2 "nonmemory_operand" "")))
8990 (clobber (reg:CC FLAGS_REG))]
8991 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8993 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8995 ;; By default we don't ask for a scratch register, because when DWImode
8996 ;; values are manipulated, registers are already at a premium. But if
8997 ;; we have one handy, we won't turn it away.
9000 [(match_scratch:DWIH 3 "r")
9001 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9003 (match_operand:<DWI> 1 "nonmemory_operand" "")
9004 (match_operand:QI 2 "nonmemory_operand" "")))
9005 (clobber (reg:CC FLAGS_REG))])
9009 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9011 (define_insn "x86_64_shld"
9012 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9013 (ior:DI (ashift:DI (match_dup 0)
9014 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9015 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9016 (minus:QI (const_int 64) (match_dup 2)))))
9017 (clobber (reg:CC FLAGS_REG))]
9019 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9020 [(set_attr "type" "ishift")
9021 (set_attr "prefix_0f" "1")
9022 (set_attr "mode" "DI")
9023 (set_attr "athlon_decode" "vector")
9024 (set_attr "amdfam10_decode" "vector")
9025 (set_attr "bdver1_decode" "vector")])
9027 (define_insn "x86_shld"
9028 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9029 (ior:SI (ashift:SI (match_dup 0)
9030 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9031 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9032 (minus:QI (const_int 32) (match_dup 2)))))
9033 (clobber (reg:CC FLAGS_REG))]
9035 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9036 [(set_attr "type" "ishift")
9037 (set_attr "prefix_0f" "1")
9038 (set_attr "mode" "SI")
9039 (set_attr "pent_pair" "np")
9040 (set_attr "athlon_decode" "vector")
9041 (set_attr "amdfam10_decode" "vector")
9042 (set_attr "bdver1_decode" "vector")])
9044 (define_expand "x86_shift<mode>_adj_1"
9045 [(set (reg:CCZ FLAGS_REG)
9046 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9049 (set (match_operand:SWI48 0 "register_operand" "")
9050 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9051 (match_operand:SWI48 1 "register_operand" "")
9054 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9055 (match_operand:SWI48 3 "register_operand" "")
9058 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9060 (define_expand "x86_shift<mode>_adj_2"
9061 [(use (match_operand:SWI48 0 "register_operand" ""))
9062 (use (match_operand:SWI48 1 "register_operand" ""))
9063 (use (match_operand:QI 2 "register_operand" ""))]
9066 rtx label = gen_label_rtx ();
9069 emit_insn (gen_testqi_ccz_1 (operands[2],
9070 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9072 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9073 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9074 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9075 gen_rtx_LABEL_REF (VOIDmode, label),
9077 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9078 JUMP_LABEL (tmp) = label;
9080 emit_move_insn (operands[0], operands[1]);
9081 ix86_expand_clear (operands[1]);
9084 LABEL_NUSES (label) = 1;
9089 ;; Avoid useless masking of count operand.
9090 (define_insn "*ashl<mode>3_mask"
9091 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9093 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9096 (match_operand:SI 2 "register_operand" "c")
9097 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9098 (clobber (reg:CC FLAGS_REG))]
9099 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9100 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9101 == GET_MODE_BITSIZE (<MODE>mode)-1"
9103 return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9105 [(set_attr "type" "ishift")
9106 (set_attr "mode" "<MODE>")])
9108 (define_insn "*bmi2_ashl<mode>3_1"
9109 [(set (match_operand:SWI48 0 "register_operand" "=r")
9110 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9111 (match_operand:SWI48 2 "register_operand" "r")))]
9113 "shlx\t{%2, %1, %0|%0, %1, %2}"
9114 [(set_attr "type" "ishiftx")
9115 (set_attr "mode" "<MODE>")])
9117 (define_insn "*ashl<mode>3_1"
9118 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9119 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9120 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9121 (clobber (reg:CC FLAGS_REG))]
9122 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9124 switch (get_attr_type (insn))
9131 gcc_assert (operands[2] == const1_rtx);
9132 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9133 return "add{<imodesuffix>}\t%0, %0";
9136 if (operands[2] == const1_rtx
9137 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9138 return "sal{<imodesuffix>}\t%0";
9140 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9143 [(set_attr "isa" "*,*,bmi2")
9145 (cond [(eq_attr "alternative" "1")
9146 (const_string "lea")
9147 (eq_attr "alternative" "2")
9148 (const_string "ishiftx")
9149 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9150 (match_operand 0 "register_operand" ""))
9151 (match_operand 2 "const1_operand" ""))
9152 (const_string "alu")
9154 (const_string "ishift")))
9155 (set (attr "length_immediate")
9157 (ior (eq_attr "type" "alu")
9158 (and (eq_attr "type" "ishift")
9159 (and (match_operand 2 "const1_operand" "")
9160 (ior (match_test "TARGET_SHIFT1")
9161 (match_test "optimize_function_for_size_p (cfun)")))))
9163 (const_string "*")))
9164 (set_attr "mode" "<MODE>")])
9166 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9168 [(set (match_operand:SWI48 0 "register_operand" "")
9169 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9170 (match_operand:QI 2 "register_operand" "")))
9171 (clobber (reg:CC FLAGS_REG))]
9172 "TARGET_BMI2 && reload_completed"
9174 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9175 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9177 (define_insn "*bmi2_ashlsi3_1_zext"
9178 [(set (match_operand:DI 0 "register_operand" "=r")
9180 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9181 (match_operand:SI 2 "register_operand" "r"))))]
9182 "TARGET_64BIT && TARGET_BMI2"
9183 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9184 [(set_attr "type" "ishiftx")
9185 (set_attr "mode" "SI")])
9187 (define_insn "*ashlsi3_1_zext"
9188 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9190 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9191 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9192 (clobber (reg:CC FLAGS_REG))]
9193 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9195 switch (get_attr_type (insn))
9202 gcc_assert (operands[2] == const1_rtx);
9203 return "add{l}\t%k0, %k0";
9206 if (operands[2] == const1_rtx
9207 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9208 return "sal{l}\t%k0";
9210 return "sal{l}\t{%2, %k0|%k0, %2}";
9213 [(set_attr "isa" "*,*,bmi2")
9215 (cond [(eq_attr "alternative" "1")
9216 (const_string "lea")
9217 (eq_attr "alternative" "2")
9218 (const_string "ishiftx")
9219 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9220 (match_operand 2 "const1_operand" ""))
9221 (const_string "alu")
9223 (const_string "ishift")))
9224 (set (attr "length_immediate")
9226 (ior (eq_attr "type" "alu")
9227 (and (eq_attr "type" "ishift")
9228 (and (match_operand 2 "const1_operand" "")
9229 (ior (match_test "TARGET_SHIFT1")
9230 (match_test "optimize_function_for_size_p (cfun)")))))
9232 (const_string "*")))
9233 (set_attr "mode" "SI")])
9235 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9237 [(set (match_operand:DI 0 "register_operand" "")
9239 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
9240 (match_operand:QI 2 "register_operand" ""))))
9241 (clobber (reg:CC FLAGS_REG))]
9242 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9244 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9245 "operands[2] = gen_lowpart (SImode, operands[2]);")
9247 (define_insn "*ashlhi3_1"
9248 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9249 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9250 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9251 (clobber (reg:CC FLAGS_REG))]
9252 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9254 switch (get_attr_type (insn))
9260 gcc_assert (operands[2] == const1_rtx);
9261 return "add{w}\t%0, %0";
9264 if (operands[2] == const1_rtx
9265 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9266 return "sal{w}\t%0";
9268 return "sal{w}\t{%2, %0|%0, %2}";
9272 (cond [(eq_attr "alternative" "1")
9273 (const_string "lea")
9274 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9275 (match_operand 0 "register_operand" ""))
9276 (match_operand 2 "const1_operand" ""))
9277 (const_string "alu")
9279 (const_string "ishift")))
9280 (set (attr "length_immediate")
9282 (ior (eq_attr "type" "alu")
9283 (and (eq_attr "type" "ishift")
9284 (and (match_operand 2 "const1_operand" "")
9285 (ior (match_test "TARGET_SHIFT1")
9286 (match_test "optimize_function_for_size_p (cfun)")))))
9288 (const_string "*")))
9289 (set_attr "mode" "HI,SI")])
9291 ;; %%% Potential partial reg stall on alternative 1. What to do?
9292 (define_insn "*ashlqi3_1"
9293 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9294 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9295 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9296 (clobber (reg:CC FLAGS_REG))]
9297 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9299 switch (get_attr_type (insn))
9305 gcc_assert (operands[2] == const1_rtx);
9306 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9307 return "add{l}\t%k0, %k0";
9309 return "add{b}\t%0, %0";
9312 if (operands[2] == const1_rtx
9313 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9315 if (get_attr_mode (insn) == MODE_SI)
9316 return "sal{l}\t%k0";
9318 return "sal{b}\t%0";
9322 if (get_attr_mode (insn) == MODE_SI)
9323 return "sal{l}\t{%2, %k0|%k0, %2}";
9325 return "sal{b}\t{%2, %0|%0, %2}";
9330 (cond [(eq_attr "alternative" "2")
9331 (const_string "lea")
9332 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9333 (match_operand 0 "register_operand" ""))
9334 (match_operand 2 "const1_operand" ""))
9335 (const_string "alu")
9337 (const_string "ishift")))
9338 (set (attr "length_immediate")
9340 (ior (eq_attr "type" "alu")
9341 (and (eq_attr "type" "ishift")
9342 (and (match_operand 2 "const1_operand" "")
9343 (ior (match_test "TARGET_SHIFT1")
9344 (match_test "optimize_function_for_size_p (cfun)")))))
9346 (const_string "*")))
9347 (set_attr "mode" "QI,SI,SI")])
9349 (define_insn "*ashlqi3_1_slp"
9350 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9351 (ashift:QI (match_dup 0)
9352 (match_operand:QI 1 "nonmemory_operand" "cI")))
9353 (clobber (reg:CC FLAGS_REG))]
9354 "(optimize_function_for_size_p (cfun)
9355 || !TARGET_PARTIAL_FLAG_REG_STALL
9356 || (operands[1] == const1_rtx
9358 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9360 switch (get_attr_type (insn))
9363 gcc_assert (operands[1] == const1_rtx);
9364 return "add{b}\t%0, %0";
9367 if (operands[1] == const1_rtx
9368 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9369 return "sal{b}\t%0";
9371 return "sal{b}\t{%1, %0|%0, %1}";
9375 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9376 (match_operand 0 "register_operand" ""))
9377 (match_operand 1 "const1_operand" ""))
9378 (const_string "alu")
9380 (const_string "ishift1")))
9381 (set (attr "length_immediate")
9383 (ior (eq_attr "type" "alu")
9384 (and (eq_attr "type" "ishift1")
9385 (and (match_operand 1 "const1_operand" "")
9386 (ior (match_test "TARGET_SHIFT1")
9387 (match_test "optimize_function_for_size_p (cfun)")))))
9389 (const_string "*")))
9390 (set_attr "mode" "QI")])
9392 ;; Convert ashift to the lea pattern to avoid flags dependency.
9394 [(set (match_operand 0 "register_operand" "")
9395 (ashift (match_operand 1 "index_register_operand" "")
9396 (match_operand:QI 2 "const_int_operand" "")))
9397 (clobber (reg:CC FLAGS_REG))]
9398 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9400 && true_regnum (operands[0]) != true_regnum (operands[1])"
9403 enum machine_mode mode = GET_MODE (operands[0]);
9406 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9409 operands[0] = gen_lowpart (mode, operands[0]);
9410 operands[1] = gen_lowpart (mode, operands[1]);
9413 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9415 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9417 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9421 ;; Convert ashift to the lea pattern to avoid flags dependency.
9423 [(set (match_operand:DI 0 "register_operand" "")
9425 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9426 (match_operand:QI 2 "const_int_operand" ""))))
9427 (clobber (reg:CC FLAGS_REG))]
9428 "TARGET_64BIT && reload_completed
9429 && true_regnum (operands[0]) != true_regnum (operands[1])"
9431 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9433 operands[1] = gen_lowpart (DImode, operands[1]);
9434 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9437 ;; This pattern can't accept a variable shift count, since shifts by
9438 ;; zero don't affect the flags. We assume that shifts by constant
9439 ;; zero are optimized away.
9440 (define_insn "*ashl<mode>3_cmp"
9441 [(set (reg FLAGS_REG)
9443 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9444 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9446 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9447 (ashift:SWI (match_dup 1) (match_dup 2)))]
9448 "(optimize_function_for_size_p (cfun)
9449 || !TARGET_PARTIAL_FLAG_REG_STALL
9450 || (operands[2] == const1_rtx
9452 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9453 && ix86_match_ccmode (insn, CCGOCmode)
9454 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9456 switch (get_attr_type (insn))
9459 gcc_assert (operands[2] == const1_rtx);
9460 return "add{<imodesuffix>}\t%0, %0";
9463 if (operands[2] == const1_rtx
9464 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9465 return "sal{<imodesuffix>}\t%0";
9467 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9471 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9472 (match_operand 0 "register_operand" ""))
9473 (match_operand 2 "const1_operand" ""))
9474 (const_string "alu")
9476 (const_string "ishift")))
9477 (set (attr "length_immediate")
9479 (ior (eq_attr "type" "alu")
9480 (and (eq_attr "type" "ishift")
9481 (and (match_operand 2 "const1_operand" "")
9482 (ior (match_test "TARGET_SHIFT1")
9483 (match_test "optimize_function_for_size_p (cfun)")))))
9485 (const_string "*")))
9486 (set_attr "mode" "<MODE>")])
9488 (define_insn "*ashlsi3_cmp_zext"
9489 [(set (reg FLAGS_REG)
9491 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9492 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9494 (set (match_operand:DI 0 "register_operand" "=r")
9495 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9497 && (optimize_function_for_size_p (cfun)
9498 || !TARGET_PARTIAL_FLAG_REG_STALL
9499 || (operands[2] == const1_rtx
9501 || TARGET_DOUBLE_WITH_ADD)))
9502 && ix86_match_ccmode (insn, CCGOCmode)
9503 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9505 switch (get_attr_type (insn))
9508 gcc_assert (operands[2] == const1_rtx);
9509 return "add{l}\t%k0, %k0";
9512 if (operands[2] == const1_rtx
9513 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9514 return "sal{l}\t%k0";
9516 return "sal{l}\t{%2, %k0|%k0, %2}";
9520 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9521 (match_operand 2 "const1_operand" ""))
9522 (const_string "alu")
9524 (const_string "ishift")))
9525 (set (attr "length_immediate")
9527 (ior (eq_attr "type" "alu")
9528 (and (eq_attr "type" "ishift")
9529 (and (match_operand 2 "const1_operand" "")
9530 (ior (match_test "TARGET_SHIFT1")
9531 (match_test "optimize_function_for_size_p (cfun)")))))
9533 (const_string "*")))
9534 (set_attr "mode" "SI")])
9536 (define_insn "*ashl<mode>3_cconly"
9537 [(set (reg FLAGS_REG)
9539 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9540 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9542 (clobber (match_scratch:SWI 0 "=<r>"))]
9543 "(optimize_function_for_size_p (cfun)
9544 || !TARGET_PARTIAL_FLAG_REG_STALL
9545 || (operands[2] == const1_rtx
9547 || TARGET_DOUBLE_WITH_ADD)))
9548 && ix86_match_ccmode (insn, CCGOCmode)"
9550 switch (get_attr_type (insn))
9553 gcc_assert (operands[2] == const1_rtx);
9554 return "add{<imodesuffix>}\t%0, %0";
9557 if (operands[2] == const1_rtx
9558 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9559 return "sal{<imodesuffix>}\t%0";
9561 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9565 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9566 (match_operand 0 "register_operand" ""))
9567 (match_operand 2 "const1_operand" ""))
9568 (const_string "alu")
9570 (const_string "ishift")))
9571 (set (attr "length_immediate")
9573 (ior (eq_attr "type" "alu")
9574 (and (eq_attr "type" "ishift")
9575 (and (match_operand 2 "const1_operand" "")
9576 (ior (match_test "TARGET_SHIFT1")
9577 (match_test "optimize_function_for_size_p (cfun)")))))
9579 (const_string "*")))
9580 (set_attr "mode" "<MODE>")])
9582 ;; See comment above `ashl<mode>3' about how this works.
9584 (define_expand "<shift_insn><mode>3"
9585 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9586 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9587 (match_operand:QI 2 "nonmemory_operand" "")))]
9589 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9591 ;; Avoid useless masking of count operand.
9592 (define_insn "*<shift_insn><mode>3_mask"
9593 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9595 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9598 (match_operand:SI 2 "register_operand" "c")
9599 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9600 (clobber (reg:CC FLAGS_REG))]
9601 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9602 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9603 == GET_MODE_BITSIZE (<MODE>mode)-1"
9605 return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9607 [(set_attr "type" "ishift")
9608 (set_attr "mode" "<MODE>")])
9610 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9611 [(set (match_operand:DWI 0 "register_operand" "=r")
9612 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9613 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9614 (clobber (reg:CC FLAGS_REG))]
9617 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9619 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9620 [(set_attr "type" "multi")])
9622 ;; By default we don't ask for a scratch register, because when DWImode
9623 ;; values are manipulated, registers are already at a premium. But if
9624 ;; we have one handy, we won't turn it away.
9627 [(match_scratch:DWIH 3 "r")
9628 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9630 (match_operand:<DWI> 1 "register_operand" "")
9631 (match_operand:QI 2 "nonmemory_operand" "")))
9632 (clobber (reg:CC FLAGS_REG))])
9636 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9638 (define_insn "x86_64_shrd"
9639 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9640 (ior:DI (ashiftrt:DI (match_dup 0)
9641 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9642 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9643 (minus:QI (const_int 64) (match_dup 2)))))
9644 (clobber (reg:CC FLAGS_REG))]
9646 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9647 [(set_attr "type" "ishift")
9648 (set_attr "prefix_0f" "1")
9649 (set_attr "mode" "DI")
9650 (set_attr "athlon_decode" "vector")
9651 (set_attr "amdfam10_decode" "vector")
9652 (set_attr "bdver1_decode" "vector")])
9654 (define_insn "x86_shrd"
9655 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9656 (ior:SI (ashiftrt:SI (match_dup 0)
9657 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9658 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9659 (minus:QI (const_int 32) (match_dup 2)))))
9660 (clobber (reg:CC FLAGS_REG))]
9662 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9663 [(set_attr "type" "ishift")
9664 (set_attr "prefix_0f" "1")
9665 (set_attr "mode" "SI")
9666 (set_attr "pent_pair" "np")
9667 (set_attr "athlon_decode" "vector")
9668 (set_attr "amdfam10_decode" "vector")
9669 (set_attr "bdver1_decode" "vector")])
9671 (define_insn "ashrdi3_cvt"
9672 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9673 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9674 (match_operand:QI 2 "const_int_operand" "")))
9675 (clobber (reg:CC FLAGS_REG))]
9676 "TARGET_64BIT && INTVAL (operands[2]) == 63
9677 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9678 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9681 sar{q}\t{%2, %0|%0, %2}"
9682 [(set_attr "type" "imovx,ishift")
9683 (set_attr "prefix_0f" "0,*")
9684 (set_attr "length_immediate" "0,*")
9685 (set_attr "modrm" "0,1")
9686 (set_attr "mode" "DI")])
9688 (define_insn "ashrsi3_cvt"
9689 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9690 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9691 (match_operand:QI 2 "const_int_operand" "")))
9692 (clobber (reg:CC FLAGS_REG))]
9693 "INTVAL (operands[2]) == 31
9694 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9695 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9698 sar{l}\t{%2, %0|%0, %2}"
9699 [(set_attr "type" "imovx,ishift")
9700 (set_attr "prefix_0f" "0,*")
9701 (set_attr "length_immediate" "0,*")
9702 (set_attr "modrm" "0,1")
9703 (set_attr "mode" "SI")])
9705 (define_insn "*ashrsi3_cvt_zext"
9706 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9708 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9709 (match_operand:QI 2 "const_int_operand" ""))))
9710 (clobber (reg:CC FLAGS_REG))]
9711 "TARGET_64BIT && INTVAL (operands[2]) == 31
9712 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9713 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9716 sar{l}\t{%2, %k0|%k0, %2}"
9717 [(set_attr "type" "imovx,ishift")
9718 (set_attr "prefix_0f" "0,*")
9719 (set_attr "length_immediate" "0,*")
9720 (set_attr "modrm" "0,1")
9721 (set_attr "mode" "SI")])
9723 (define_expand "x86_shift<mode>_adj_3"
9724 [(use (match_operand:SWI48 0 "register_operand" ""))
9725 (use (match_operand:SWI48 1 "register_operand" ""))
9726 (use (match_operand:QI 2 "register_operand" ""))]
9729 rtx label = gen_label_rtx ();
9732 emit_insn (gen_testqi_ccz_1 (operands[2],
9733 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9735 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9736 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9737 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9738 gen_rtx_LABEL_REF (VOIDmode, label),
9740 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9741 JUMP_LABEL (tmp) = label;
9743 emit_move_insn (operands[0], operands[1]);
9744 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9745 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9747 LABEL_NUSES (label) = 1;
9752 (define_insn "*bmi2_<shift_insn><mode>3_1"
9753 [(set (match_operand:SWI48 0 "register_operand" "=r")
9754 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9755 (match_operand:SWI48 2 "register_operand" "r")))]
9757 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9758 [(set_attr "type" "ishiftx")
9759 (set_attr "mode" "<MODE>")])
9761 (define_insn "*<shift_insn><mode>3_1"
9762 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9764 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9765 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9766 (clobber (reg:CC FLAGS_REG))]
9767 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9769 switch (get_attr_type (insn))
9775 if (operands[2] == const1_rtx
9776 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9777 return "<shift>{<imodesuffix>}\t%0";
9779 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9782 [(set_attr "isa" "*,bmi2")
9783 (set_attr "type" "ishift,ishiftx")
9784 (set (attr "length_immediate")
9786 (and (match_operand 2 "const1_operand" "")
9787 (ior (match_test "TARGET_SHIFT1")
9788 (match_test "optimize_function_for_size_p (cfun)")))
9790 (const_string "*")))
9791 (set_attr "mode" "<MODE>")])
9793 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9795 [(set (match_operand:SWI48 0 "register_operand" "")
9796 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9797 (match_operand:QI 2 "register_operand" "")))
9798 (clobber (reg:CC FLAGS_REG))]
9799 "TARGET_BMI2 && reload_completed"
9801 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9802 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9804 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9805 [(set (match_operand:DI 0 "register_operand" "=r")
9807 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9808 (match_operand:SI 2 "register_operand" "r"))))]
9809 "TARGET_64BIT && TARGET_BMI2"
9810 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9811 [(set_attr "type" "ishiftx")
9812 (set_attr "mode" "SI")])
9814 (define_insn "*<shift_insn>si3_1_zext"
9815 [(set (match_operand:DI 0 "register_operand" "=r,r")
9817 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9818 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9819 (clobber (reg:CC FLAGS_REG))]
9820 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9822 switch (get_attr_type (insn))
9828 if (operands[2] == const1_rtx
9829 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9830 return "<shift>{l}\t%k0";
9832 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9835 [(set_attr "isa" "*,bmi2")
9836 (set_attr "type" "ishift,ishiftx")
9837 (set (attr "length_immediate")
9839 (and (match_operand 2 "const1_operand" "")
9840 (ior (match_test "TARGET_SHIFT1")
9841 (match_test "optimize_function_for_size_p (cfun)")))
9843 (const_string "*")))
9844 (set_attr "mode" "SI")])
9846 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9848 [(set (match_operand:DI 0 "register_operand" "")
9850 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
9851 (match_operand:QI 2 "register_operand" ""))))
9852 (clobber (reg:CC FLAGS_REG))]
9853 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9855 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9856 "operands[2] = gen_lowpart (SImode, operands[2]);")
9858 (define_insn "*<shift_insn><mode>3_1"
9859 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9861 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9862 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9863 (clobber (reg:CC FLAGS_REG))]
9864 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9866 if (operands[2] == const1_rtx
9867 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9868 return "<shift>{<imodesuffix>}\t%0";
9870 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9872 [(set_attr "type" "ishift")
9873 (set (attr "length_immediate")
9875 (and (match_operand 2 "const1_operand" "")
9876 (ior (match_test "TARGET_SHIFT1")
9877 (match_test "optimize_function_for_size_p (cfun)")))
9879 (const_string "*")))
9880 (set_attr "mode" "<MODE>")])
9882 (define_insn "*<shift_insn>qi3_1_slp"
9883 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9884 (any_shiftrt:QI (match_dup 0)
9885 (match_operand:QI 1 "nonmemory_operand" "cI")))
9886 (clobber (reg:CC FLAGS_REG))]
9887 "(optimize_function_for_size_p (cfun)
9888 || !TARGET_PARTIAL_REG_STALL
9889 || (operands[1] == const1_rtx
9892 if (operands[1] == const1_rtx
9893 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9894 return "<shift>{b}\t%0";
9896 return "<shift>{b}\t{%1, %0|%0, %1}";
9898 [(set_attr "type" "ishift1")
9899 (set (attr "length_immediate")
9901 (and (match_operand 1 "const1_operand" "")
9902 (ior (match_test "TARGET_SHIFT1")
9903 (match_test "optimize_function_for_size_p (cfun)")))
9905 (const_string "*")))
9906 (set_attr "mode" "QI")])
9908 ;; This pattern can't accept a variable shift count, since shifts by
9909 ;; zero don't affect the flags. We assume that shifts by constant
9910 ;; zero are optimized away.
9911 (define_insn "*<shift_insn><mode>3_cmp"
9912 [(set (reg FLAGS_REG)
9915 (match_operand:SWI 1 "nonimmediate_operand" "0")
9916 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9918 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9919 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9920 "(optimize_function_for_size_p (cfun)
9921 || !TARGET_PARTIAL_FLAG_REG_STALL
9922 || (operands[2] == const1_rtx
9924 && ix86_match_ccmode (insn, CCGOCmode)
9925 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9927 if (operands[2] == const1_rtx
9928 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9929 return "<shift>{<imodesuffix>}\t%0";
9931 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9933 [(set_attr "type" "ishift")
9934 (set (attr "length_immediate")
9936 (and (match_operand 2 "const1_operand" "")
9937 (ior (match_test "TARGET_SHIFT1")
9938 (match_test "optimize_function_for_size_p (cfun)")))
9940 (const_string "*")))
9941 (set_attr "mode" "<MODE>")])
9943 (define_insn "*<shift_insn>si3_cmp_zext"
9944 [(set (reg FLAGS_REG)
9946 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9947 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9949 (set (match_operand:DI 0 "register_operand" "=r")
9950 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9952 && (optimize_function_for_size_p (cfun)
9953 || !TARGET_PARTIAL_FLAG_REG_STALL
9954 || (operands[2] == const1_rtx
9956 && ix86_match_ccmode (insn, CCGOCmode)
9957 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9959 if (operands[2] == const1_rtx
9960 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9961 return "<shift>{l}\t%k0";
9963 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9965 [(set_attr "type" "ishift")
9966 (set (attr "length_immediate")
9968 (and (match_operand 2 "const1_operand" "")
9969 (ior (match_test "TARGET_SHIFT1")
9970 (match_test "optimize_function_for_size_p (cfun)")))
9972 (const_string "*")))
9973 (set_attr "mode" "SI")])
9975 (define_insn "*<shift_insn><mode>3_cconly"
9976 [(set (reg FLAGS_REG)
9979 (match_operand:SWI 1 "register_operand" "0")
9980 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9982 (clobber (match_scratch:SWI 0 "=<r>"))]
9983 "(optimize_function_for_size_p (cfun)
9984 || !TARGET_PARTIAL_FLAG_REG_STALL
9985 || (operands[2] == const1_rtx
9987 && ix86_match_ccmode (insn, CCGOCmode)"
9989 if (operands[2] == const1_rtx
9990 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9991 return "<shift>{<imodesuffix>}\t%0";
9993 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9995 [(set_attr "type" "ishift")
9996 (set (attr "length_immediate")
9998 (and (match_operand 2 "const1_operand" "")
9999 (ior (match_test "TARGET_SHIFT1")
10000 (match_test "optimize_function_for_size_p (cfun)")))
10002 (const_string "*")))
10003 (set_attr "mode" "<MODE>")])
10005 ;; Rotate instructions
10007 (define_expand "<rotate_insn>ti3"
10008 [(set (match_operand:TI 0 "register_operand" "")
10009 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10010 (match_operand:QI 2 "nonmemory_operand" "")))]
10013 if (const_1_to_63_operand (operands[2], VOIDmode))
10014 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10015 (operands[0], operands[1], operands[2]));
10022 (define_expand "<rotate_insn>di3"
10023 [(set (match_operand:DI 0 "shiftdi_operand" "")
10024 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10025 (match_operand:QI 2 "nonmemory_operand" "")))]
10029 ix86_expand_binary_operator (<CODE>, DImode, operands);
10030 else if (const_1_to_31_operand (operands[2], VOIDmode))
10031 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10032 (operands[0], operands[1], operands[2]));
10039 (define_expand "<rotate_insn><mode>3"
10040 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10041 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10042 (match_operand:QI 2 "nonmemory_operand" "")))]
10044 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10046 ;; Avoid useless masking of count operand.
10047 (define_insn "*<rotate_insn><mode>3_mask"
10048 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10050 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10053 (match_operand:SI 2 "register_operand" "c")
10054 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10055 (clobber (reg:CC FLAGS_REG))]
10056 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10057 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10058 == GET_MODE_BITSIZE (<MODE>mode)-1"
10060 return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10062 [(set_attr "type" "rotate")
10063 (set_attr "mode" "<MODE>")])
10065 ;; Implement rotation using two double-precision
10066 ;; shift instructions and a scratch register.
10068 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10069 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10070 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10071 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10072 (clobber (reg:CC FLAGS_REG))
10073 (clobber (match_scratch:DWIH 3 "=&r"))]
10077 [(set (match_dup 3) (match_dup 4))
10079 [(set (match_dup 4)
10080 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10081 (lshiftrt:DWIH (match_dup 5)
10082 (minus:QI (match_dup 6) (match_dup 2)))))
10083 (clobber (reg:CC FLAGS_REG))])
10085 [(set (match_dup 5)
10086 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10087 (lshiftrt:DWIH (match_dup 3)
10088 (minus:QI (match_dup 6) (match_dup 2)))))
10089 (clobber (reg:CC FLAGS_REG))])]
10091 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10093 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10096 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10097 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10098 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10099 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10100 (clobber (reg:CC FLAGS_REG))
10101 (clobber (match_scratch:DWIH 3 "=&r"))]
10105 [(set (match_dup 3) (match_dup 4))
10107 [(set (match_dup 4)
10108 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10109 (ashift:DWIH (match_dup 5)
10110 (minus:QI (match_dup 6) (match_dup 2)))))
10111 (clobber (reg:CC FLAGS_REG))])
10113 [(set (match_dup 5)
10114 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10115 (ashift:DWIH (match_dup 3)
10116 (minus:QI (match_dup 6) (match_dup 2)))))
10117 (clobber (reg:CC FLAGS_REG))])]
10119 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10121 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10124 (define_insn "*bmi2_rorx<mode>3_1"
10125 [(set (match_operand:SWI48 0 "register_operand" "=r")
10126 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10127 (match_operand:QI 2 "immediate_operand" "<S>")))]
10129 "rorx\t{%2, %1, %0|%0, %1, %2}"
10130 [(set_attr "type" "rotatex")
10131 (set_attr "mode" "<MODE>")])
10133 (define_insn "*<rotate_insn><mode>3_1"
10134 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10136 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10137 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10138 (clobber (reg:CC FLAGS_REG))]
10139 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10141 switch (get_attr_type (insn))
10147 if (operands[2] == const1_rtx
10148 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10149 return "<rotate>{<imodesuffix>}\t%0";
10151 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10154 [(set_attr "isa" "*,bmi2")
10155 (set_attr "type" "rotate,rotatex")
10156 (set (attr "length_immediate")
10158 (and (eq_attr "type" "rotate")
10159 (and (match_operand 2 "const1_operand" "")
10160 (ior (match_test "TARGET_SHIFT1")
10161 (match_test "optimize_function_for_size_p (cfun)"))))
10163 (const_string "*")))
10164 (set_attr "mode" "<MODE>")])
10166 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10168 [(set (match_operand:SWI48 0 "register_operand" "")
10169 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10170 (match_operand:QI 2 "immediate_operand" "")))
10171 (clobber (reg:CC FLAGS_REG))]
10172 "TARGET_BMI2 && reload_completed"
10173 [(set (match_dup 0)
10174 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10177 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10181 [(set (match_operand:SWI48 0 "register_operand" "")
10182 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10183 (match_operand:QI 2 "immediate_operand" "")))
10184 (clobber (reg:CC FLAGS_REG))]
10185 "TARGET_BMI2 && reload_completed"
10186 [(set (match_dup 0)
10187 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10189 (define_insn "*bmi2_rorxsi3_1_zext"
10190 [(set (match_operand:DI 0 "register_operand" "=r")
10192 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10193 (match_operand:QI 2 "immediate_operand" "I"))))]
10194 "TARGET_64BIT && TARGET_BMI2"
10195 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10196 [(set_attr "type" "rotatex")
10197 (set_attr "mode" "SI")])
10199 (define_insn "*<rotate_insn>si3_1_zext"
10200 [(set (match_operand:DI 0 "register_operand" "=r,r")
10202 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10203 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10204 (clobber (reg:CC FLAGS_REG))]
10205 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10207 switch (get_attr_type (insn))
10213 if (operands[2] == const1_rtx
10214 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10215 return "<rotate>{l}\t%k0";
10217 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10220 [(set_attr "isa" "*,bmi2")
10221 (set_attr "type" "rotate,rotatex")
10222 (set (attr "length_immediate")
10224 (and (eq_attr "type" "rotate")
10225 (and (match_operand 2 "const1_operand" "")
10226 (ior (match_test "TARGET_SHIFT1")
10227 (match_test "optimize_function_for_size_p (cfun)"))))
10229 (const_string "*")))
10230 (set_attr "mode" "SI")])
10232 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10234 [(set (match_operand:DI 0 "register_operand" "")
10236 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
10237 (match_operand:QI 2 "immediate_operand" ""))))
10238 (clobber (reg:CC FLAGS_REG))]
10239 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10240 [(set (match_dup 0)
10241 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10244 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10248 [(set (match_operand:DI 0 "register_operand" "")
10250 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
10251 (match_operand:QI 2 "immediate_operand" ""))))
10252 (clobber (reg:CC FLAGS_REG))]
10253 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10254 [(set (match_dup 0)
10255 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10257 (define_insn "*<rotate_insn><mode>3_1"
10258 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10259 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10260 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10261 (clobber (reg:CC FLAGS_REG))]
10262 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10264 if (operands[2] == const1_rtx
10265 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10266 return "<rotate>{<imodesuffix>}\t%0";
10268 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10270 [(set_attr "type" "rotate")
10271 (set (attr "length_immediate")
10273 (and (match_operand 2 "const1_operand" "")
10274 (ior (match_test "TARGET_SHIFT1")
10275 (match_test "optimize_function_for_size_p (cfun)")))
10277 (const_string "*")))
10278 (set_attr "mode" "<MODE>")])
10280 (define_insn "*<rotate_insn>qi3_1_slp"
10281 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10282 (any_rotate:QI (match_dup 0)
10283 (match_operand:QI 1 "nonmemory_operand" "cI")))
10284 (clobber (reg:CC FLAGS_REG))]
10285 "(optimize_function_for_size_p (cfun)
10286 || !TARGET_PARTIAL_REG_STALL
10287 || (operands[1] == const1_rtx
10288 && TARGET_SHIFT1))"
10290 if (operands[1] == const1_rtx
10291 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10292 return "<rotate>{b}\t%0";
10294 return "<rotate>{b}\t{%1, %0|%0, %1}";
10296 [(set_attr "type" "rotate1")
10297 (set (attr "length_immediate")
10299 (and (match_operand 1 "const1_operand" "")
10300 (ior (match_test "TARGET_SHIFT1")
10301 (match_test "optimize_function_for_size_p (cfun)")))
10303 (const_string "*")))
10304 (set_attr "mode" "QI")])
10307 [(set (match_operand:HI 0 "register_operand" "")
10308 (any_rotate:HI (match_dup 0) (const_int 8)))
10309 (clobber (reg:CC FLAGS_REG))]
10311 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10312 [(parallel [(set (strict_low_part (match_dup 0))
10313 (bswap:HI (match_dup 0)))
10314 (clobber (reg:CC FLAGS_REG))])])
10316 ;; Bit set / bit test instructions
10318 (define_expand "extv"
10319 [(set (match_operand:SI 0 "register_operand" "")
10320 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10321 (match_operand:SI 2 "const8_operand" "")
10322 (match_operand:SI 3 "const8_operand" "")))]
10325 /* Handle extractions from %ah et al. */
10326 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10329 /* From mips.md: extract_bit_field doesn't verify that our source
10330 matches the predicate, so check it again here. */
10331 if (! ext_register_operand (operands[1], VOIDmode))
10335 (define_expand "extzv"
10336 [(set (match_operand:SI 0 "register_operand" "")
10337 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10338 (match_operand:SI 2 "const8_operand" "")
10339 (match_operand:SI 3 "const8_operand" "")))]
10342 /* Handle extractions from %ah et al. */
10343 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10346 /* From mips.md: extract_bit_field doesn't verify that our source
10347 matches the predicate, so check it again here. */
10348 if (! ext_register_operand (operands[1], VOIDmode))
10352 (define_expand "insv"
10353 [(set (zero_extract (match_operand 0 "register_operand" "")
10354 (match_operand 1 "const_int_operand" "")
10355 (match_operand 2 "const_int_operand" ""))
10356 (match_operand 3 "register_operand" ""))]
10359 rtx (*gen_mov_insv_1) (rtx, rtx);
10361 if (ix86_expand_pinsr (operands))
10364 /* Handle insertions to %ah et al. */
10365 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10368 /* From mips.md: insert_bit_field doesn't verify that our source
10369 matches the predicate, so check it again here. */
10370 if (! ext_register_operand (operands[0], VOIDmode))
10373 gen_mov_insv_1 = (TARGET_64BIT
10374 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10376 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10380 ;; %%% bts, btr, btc, bt.
10381 ;; In general these instructions are *slow* when applied to memory,
10382 ;; since they enforce atomic operation. When applied to registers,
10383 ;; it depends on the cpu implementation. They're never faster than
10384 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10385 ;; no point. But in 64-bit, we can't hold the relevant immediates
10386 ;; within the instruction itself, so operating on bits in the high
10387 ;; 32-bits of a register becomes easier.
10389 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10390 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10391 ;; negdf respectively, so they can never be disabled entirely.
10393 (define_insn "*btsq"
10394 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10396 (match_operand:DI 1 "const_0_to_63_operand" ""))
10398 (clobber (reg:CC FLAGS_REG))]
10399 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10400 "bts{q}\t{%1, %0|%0, %1}"
10401 [(set_attr "type" "alu1")
10402 (set_attr "prefix_0f" "1")
10403 (set_attr "mode" "DI")])
10405 (define_insn "*btrq"
10406 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10408 (match_operand:DI 1 "const_0_to_63_operand" ""))
10410 (clobber (reg:CC FLAGS_REG))]
10411 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10412 "btr{q}\t{%1, %0|%0, %1}"
10413 [(set_attr "type" "alu1")
10414 (set_attr "prefix_0f" "1")
10415 (set_attr "mode" "DI")])
10417 (define_insn "*btcq"
10418 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10420 (match_operand:DI 1 "const_0_to_63_operand" ""))
10421 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10422 (clobber (reg:CC FLAGS_REG))]
10423 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10424 "btc{q}\t{%1, %0|%0, %1}"
10425 [(set_attr "type" "alu1")
10426 (set_attr "prefix_0f" "1")
10427 (set_attr "mode" "DI")])
10429 ;; Allow Nocona to avoid these instructions if a register is available.
10432 [(match_scratch:DI 2 "r")
10433 (parallel [(set (zero_extract:DI
10434 (match_operand:DI 0 "register_operand" "")
10436 (match_operand:DI 1 "const_0_to_63_operand" ""))
10438 (clobber (reg:CC FLAGS_REG))])]
10439 "TARGET_64BIT && !TARGET_USE_BT"
10442 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10445 if (HOST_BITS_PER_WIDE_INT >= 64)
10446 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10447 else if (i < HOST_BITS_PER_WIDE_INT)
10448 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10450 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10452 op1 = immed_double_const (lo, hi, DImode);
10455 emit_move_insn (operands[2], op1);
10459 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10464 [(match_scratch:DI 2 "r")
10465 (parallel [(set (zero_extract:DI
10466 (match_operand:DI 0 "register_operand" "")
10468 (match_operand:DI 1 "const_0_to_63_operand" ""))
10470 (clobber (reg:CC FLAGS_REG))])]
10471 "TARGET_64BIT && !TARGET_USE_BT"
10474 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10477 if (HOST_BITS_PER_WIDE_INT >= 64)
10478 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10479 else if (i < HOST_BITS_PER_WIDE_INT)
10480 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10482 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10484 op1 = immed_double_const (~lo, ~hi, DImode);
10487 emit_move_insn (operands[2], op1);
10491 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10496 [(match_scratch:DI 2 "r")
10497 (parallel [(set (zero_extract:DI
10498 (match_operand:DI 0 "register_operand" "")
10500 (match_operand:DI 1 "const_0_to_63_operand" ""))
10501 (not:DI (zero_extract:DI
10502 (match_dup 0) (const_int 1) (match_dup 1))))
10503 (clobber (reg:CC FLAGS_REG))])]
10504 "TARGET_64BIT && !TARGET_USE_BT"
10507 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10510 if (HOST_BITS_PER_WIDE_INT >= 64)
10511 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10512 else if (i < HOST_BITS_PER_WIDE_INT)
10513 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10515 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10517 op1 = immed_double_const (lo, hi, DImode);
10520 emit_move_insn (operands[2], op1);
10524 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10528 (define_insn "*bt<mode>"
10529 [(set (reg:CCC FLAGS_REG)
10531 (zero_extract:SWI48
10532 (match_operand:SWI48 0 "register_operand" "r")
10534 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10536 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10537 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10538 [(set_attr "type" "alu1")
10539 (set_attr "prefix_0f" "1")
10540 (set_attr "mode" "<MODE>")])
10542 ;; Store-flag instructions.
10544 ;; For all sCOND expanders, also expand the compare or test insn that
10545 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10547 (define_insn_and_split "*setcc_di_1"
10548 [(set (match_operand:DI 0 "register_operand" "=q")
10549 (match_operator:DI 1 "ix86_comparison_operator"
10550 [(reg FLAGS_REG) (const_int 0)]))]
10551 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10553 "&& reload_completed"
10554 [(set (match_dup 2) (match_dup 1))
10555 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10557 PUT_MODE (operands[1], QImode);
10558 operands[2] = gen_lowpart (QImode, operands[0]);
10561 (define_insn_and_split "*setcc_si_1_and"
10562 [(set (match_operand:SI 0 "register_operand" "=q")
10563 (match_operator:SI 1 "ix86_comparison_operator"
10564 [(reg FLAGS_REG) (const_int 0)]))
10565 (clobber (reg:CC FLAGS_REG))]
10566 "!TARGET_PARTIAL_REG_STALL
10567 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10569 "&& reload_completed"
10570 [(set (match_dup 2) (match_dup 1))
10571 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10572 (clobber (reg:CC FLAGS_REG))])]
10574 PUT_MODE (operands[1], QImode);
10575 operands[2] = gen_lowpart (QImode, operands[0]);
10578 (define_insn_and_split "*setcc_si_1_movzbl"
10579 [(set (match_operand:SI 0 "register_operand" "=q")
10580 (match_operator:SI 1 "ix86_comparison_operator"
10581 [(reg FLAGS_REG) (const_int 0)]))]
10582 "!TARGET_PARTIAL_REG_STALL
10583 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10585 "&& reload_completed"
10586 [(set (match_dup 2) (match_dup 1))
10587 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10589 PUT_MODE (operands[1], QImode);
10590 operands[2] = gen_lowpart (QImode, operands[0]);
10593 (define_insn "*setcc_qi"
10594 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10595 (match_operator:QI 1 "ix86_comparison_operator"
10596 [(reg FLAGS_REG) (const_int 0)]))]
10599 [(set_attr "type" "setcc")
10600 (set_attr "mode" "QI")])
10602 (define_insn "*setcc_qi_slp"
10603 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10604 (match_operator:QI 1 "ix86_comparison_operator"
10605 [(reg FLAGS_REG) (const_int 0)]))]
10608 [(set_attr "type" "setcc")
10609 (set_attr "mode" "QI")])
10611 ;; In general it is not safe to assume too much about CCmode registers,
10612 ;; so simplify-rtx stops when it sees a second one. Under certain
10613 ;; conditions this is safe on x86, so help combine not create
10620 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10621 (ne:QI (match_operator 1 "ix86_comparison_operator"
10622 [(reg FLAGS_REG) (const_int 0)])
10625 [(set (match_dup 0) (match_dup 1))]
10626 "PUT_MODE (operands[1], QImode);")
10629 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10630 (ne:QI (match_operator 1 "ix86_comparison_operator"
10631 [(reg FLAGS_REG) (const_int 0)])
10634 [(set (match_dup 0) (match_dup 1))]
10635 "PUT_MODE (operands[1], QImode);")
10638 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10639 (eq:QI (match_operator 1 "ix86_comparison_operator"
10640 [(reg FLAGS_REG) (const_int 0)])
10643 [(set (match_dup 0) (match_dup 1))]
10645 rtx new_op1 = copy_rtx (operands[1]);
10646 operands[1] = new_op1;
10647 PUT_MODE (new_op1, QImode);
10648 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10649 GET_MODE (XEXP (new_op1, 0))));
10651 /* Make sure that (a) the CCmode we have for the flags is strong
10652 enough for the reversed compare or (b) we have a valid FP compare. */
10653 if (! ix86_comparison_operator (new_op1, VOIDmode))
10658 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10659 (eq:QI (match_operator 1 "ix86_comparison_operator"
10660 [(reg FLAGS_REG) (const_int 0)])
10663 [(set (match_dup 0) (match_dup 1))]
10665 rtx new_op1 = copy_rtx (operands[1]);
10666 operands[1] = new_op1;
10667 PUT_MODE (new_op1, QImode);
10668 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10669 GET_MODE (XEXP (new_op1, 0))));
10671 /* Make sure that (a) the CCmode we have for the flags is strong
10672 enough for the reversed compare or (b) we have a valid FP compare. */
10673 if (! ix86_comparison_operator (new_op1, VOIDmode))
10677 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10678 ;; subsequent logical operations are used to imitate conditional moves.
10679 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10682 (define_insn "setcc_<mode>_sse"
10683 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10684 (match_operator:MODEF 3 "sse_comparison_operator"
10685 [(match_operand:MODEF 1 "register_operand" "0,x")
10686 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10687 "SSE_FLOAT_MODE_P (<MODE>mode)"
10689 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10690 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10691 [(set_attr "isa" "noavx,avx")
10692 (set_attr "type" "ssecmp")
10693 (set_attr "length_immediate" "1")
10694 (set_attr "prefix" "orig,vex")
10695 (set_attr "mode" "<MODE>")])
10697 ;; Basic conditional jump instructions.
10698 ;; We ignore the overflow flag for signed branch instructions.
10700 (define_insn "*jcc_1"
10702 (if_then_else (match_operator 1 "ix86_comparison_operator"
10703 [(reg FLAGS_REG) (const_int 0)])
10704 (label_ref (match_operand 0 "" ""))
10708 [(set_attr "type" "ibr")
10709 (set_attr "modrm" "0")
10710 (set (attr "length")
10711 (if_then_else (and (ge (minus (match_dup 0) (pc))
10713 (lt (minus (match_dup 0) (pc))
10718 (define_insn "*jcc_2"
10720 (if_then_else (match_operator 1 "ix86_comparison_operator"
10721 [(reg FLAGS_REG) (const_int 0)])
10723 (label_ref (match_operand 0 "" ""))))]
10726 [(set_attr "type" "ibr")
10727 (set_attr "modrm" "0")
10728 (set (attr "length")
10729 (if_then_else (and (ge (minus (match_dup 0) (pc))
10731 (lt (minus (match_dup 0) (pc))
10736 ;; In general it is not safe to assume too much about CCmode registers,
10737 ;; so simplify-rtx stops when it sees a second one. Under certain
10738 ;; conditions this is safe on x86, so help combine not create
10746 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10747 [(reg FLAGS_REG) (const_int 0)])
10749 (label_ref (match_operand 1 "" ""))
10753 (if_then_else (match_dup 0)
10754 (label_ref (match_dup 1))
10756 "PUT_MODE (operands[0], VOIDmode);")
10760 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10761 [(reg FLAGS_REG) (const_int 0)])
10763 (label_ref (match_operand 1 "" ""))
10767 (if_then_else (match_dup 0)
10768 (label_ref (match_dup 1))
10771 rtx new_op0 = copy_rtx (operands[0]);
10772 operands[0] = new_op0;
10773 PUT_MODE (new_op0, VOIDmode);
10774 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10775 GET_MODE (XEXP (new_op0, 0))));
10777 /* Make sure that (a) the CCmode we have for the flags is strong
10778 enough for the reversed compare or (b) we have a valid FP compare. */
10779 if (! ix86_comparison_operator (new_op0, VOIDmode))
10783 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10784 ;; pass generates from shift insn with QImode operand. Actually, the mode
10785 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10786 ;; appropriate modulo of the bit offset value.
10788 (define_insn_and_split "*jcc_bt<mode>"
10790 (if_then_else (match_operator 0 "bt_comparison_operator"
10791 [(zero_extract:SWI48
10792 (match_operand:SWI48 1 "register_operand" "r")
10795 (match_operand:QI 2 "register_operand" "r")))
10797 (label_ref (match_operand 3 "" ""))
10799 (clobber (reg:CC FLAGS_REG))]
10800 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10803 [(set (reg:CCC FLAGS_REG)
10805 (zero_extract:SWI48
10811 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10812 (label_ref (match_dup 3))
10815 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10817 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10820 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10821 ;; also for DImode, this is what combine produces.
10822 (define_insn_and_split "*jcc_bt<mode>_mask"
10824 (if_then_else (match_operator 0 "bt_comparison_operator"
10825 [(zero_extract:SWI48
10826 (match_operand:SWI48 1 "register_operand" "r")
10829 (match_operand:SI 2 "register_operand" "r")
10830 (match_operand:SI 3 "const_int_operand" "n")))])
10831 (label_ref (match_operand 4 "" ""))
10833 (clobber (reg:CC FLAGS_REG))]
10834 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10835 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10836 == GET_MODE_BITSIZE (<MODE>mode)-1"
10839 [(set (reg:CCC FLAGS_REG)
10841 (zero_extract:SWI48
10847 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10848 (label_ref (match_dup 4))
10851 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10853 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10856 (define_insn_and_split "*jcc_btsi_1"
10858 (if_then_else (match_operator 0 "bt_comparison_operator"
10861 (match_operand:SI 1 "register_operand" "r")
10862 (match_operand:QI 2 "register_operand" "r"))
10865 (label_ref (match_operand 3 "" ""))
10867 (clobber (reg:CC FLAGS_REG))]
10868 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10871 [(set (reg:CCC FLAGS_REG)
10879 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10880 (label_ref (match_dup 3))
10883 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10885 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10888 ;; avoid useless masking of bit offset operand
10889 (define_insn_and_split "*jcc_btsi_mask_1"
10892 (match_operator 0 "bt_comparison_operator"
10895 (match_operand:SI 1 "register_operand" "r")
10898 (match_operand:SI 2 "register_operand" "r")
10899 (match_operand:SI 3 "const_int_operand" "n")) 0))
10902 (label_ref (match_operand 4 "" ""))
10904 (clobber (reg:CC FLAGS_REG))]
10905 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10906 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10909 [(set (reg:CCC FLAGS_REG)
10917 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10918 (label_ref (match_dup 4))
10920 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10922 ;; Define combination compare-and-branch fp compare instructions to help
10925 (define_insn "*fp_jcc_1_387"
10927 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10928 [(match_operand 1 "register_operand" "f")
10929 (match_operand 2 "nonimmediate_operand" "fm")])
10930 (label_ref (match_operand 3 "" ""))
10932 (clobber (reg:CCFP FPSR_REG))
10933 (clobber (reg:CCFP FLAGS_REG))
10934 (clobber (match_scratch:HI 4 "=a"))]
10936 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10937 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10938 && SELECT_CC_MODE (GET_CODE (operands[0]),
10939 operands[1], operands[2]) == CCFPmode
10943 (define_insn "*fp_jcc_1r_387"
10945 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10946 [(match_operand 1 "register_operand" "f")
10947 (match_operand 2 "nonimmediate_operand" "fm")])
10949 (label_ref (match_operand 3 "" ""))))
10950 (clobber (reg:CCFP FPSR_REG))
10951 (clobber (reg:CCFP FLAGS_REG))
10952 (clobber (match_scratch:HI 4 "=a"))]
10954 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10955 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10956 && SELECT_CC_MODE (GET_CODE (operands[0]),
10957 operands[1], operands[2]) == CCFPmode
10961 (define_insn "*fp_jcc_2_387"
10963 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10964 [(match_operand 1 "register_operand" "f")
10965 (match_operand 2 "register_operand" "f")])
10966 (label_ref (match_operand 3 "" ""))
10968 (clobber (reg:CCFP FPSR_REG))
10969 (clobber (reg:CCFP FLAGS_REG))
10970 (clobber (match_scratch:HI 4 "=a"))]
10971 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10972 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10976 (define_insn "*fp_jcc_2r_387"
10978 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10979 [(match_operand 1 "register_operand" "f")
10980 (match_operand 2 "register_operand" "f")])
10982 (label_ref (match_operand 3 "" ""))))
10983 (clobber (reg:CCFP FPSR_REG))
10984 (clobber (reg:CCFP FLAGS_REG))
10985 (clobber (match_scratch:HI 4 "=a"))]
10986 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10987 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10991 (define_insn "*fp_jcc_3_387"
10993 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10994 [(match_operand 1 "register_operand" "f")
10995 (match_operand 2 "const0_operand" "")])
10996 (label_ref (match_operand 3 "" ""))
10998 (clobber (reg:CCFP FPSR_REG))
10999 (clobber (reg:CCFP FLAGS_REG))
11000 (clobber (match_scratch:HI 4 "=a"))]
11001 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11002 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11003 && SELECT_CC_MODE (GET_CODE (operands[0]),
11004 operands[1], operands[2]) == CCFPmode
11010 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11011 [(match_operand 1 "register_operand" "")
11012 (match_operand 2 "nonimmediate_operand" "")])
11013 (match_operand 3 "" "")
11014 (match_operand 4 "" "")))
11015 (clobber (reg:CCFP FPSR_REG))
11016 (clobber (reg:CCFP FLAGS_REG))]
11020 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11021 operands[3], operands[4], NULL_RTX, NULL_RTX);
11027 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11028 [(match_operand 1 "register_operand" "")
11029 (match_operand 2 "general_operand" "")])
11030 (match_operand 3 "" "")
11031 (match_operand 4 "" "")))
11032 (clobber (reg:CCFP FPSR_REG))
11033 (clobber (reg:CCFP FLAGS_REG))
11034 (clobber (match_scratch:HI 5 "=a"))]
11038 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11039 operands[3], operands[4], operands[5], NULL_RTX);
11043 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11044 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11045 ;; with a precedence over other operators and is always put in the first
11046 ;; place. Swap condition and operands to match ficom instruction.
11048 (define_insn "*fp_jcc_4_<mode>_387"
11051 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11052 [(match_operator 1 "float_operator"
11053 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11054 (match_operand 3 "register_operand" "f,f")])
11055 (label_ref (match_operand 4 "" ""))
11057 (clobber (reg:CCFP FPSR_REG))
11058 (clobber (reg:CCFP FLAGS_REG))
11059 (clobber (match_scratch:HI 5 "=a,a"))]
11060 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11061 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11062 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11063 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11070 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11071 [(match_operator 1 "float_operator"
11072 [(match_operand:SWI24 2 "memory_operand" "")])
11073 (match_operand 3 "register_operand" "")])
11074 (match_operand 4 "" "")
11075 (match_operand 5 "" "")))
11076 (clobber (reg:CCFP FPSR_REG))
11077 (clobber (reg:CCFP FLAGS_REG))
11078 (clobber (match_scratch:HI 6 "=a"))]
11082 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11084 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11085 operands[3], operands[7],
11086 operands[4], operands[5], operands[6], NULL_RTX);
11090 ;; %%% Kill this when reload knows how to do it.
11094 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11095 [(match_operator 1 "float_operator"
11096 [(match_operand:SWI24 2 "register_operand" "")])
11097 (match_operand 3 "register_operand" "")])
11098 (match_operand 4 "" "")
11099 (match_operand 5 "" "")))
11100 (clobber (reg:CCFP FPSR_REG))
11101 (clobber (reg:CCFP FLAGS_REG))
11102 (clobber (match_scratch:HI 6 "=a"))]
11106 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11107 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11109 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11110 operands[3], operands[7],
11111 operands[4], operands[5], operands[6], operands[2]);
11115 ;; Unconditional and other jump instructions
11117 (define_insn "jump"
11119 (label_ref (match_operand 0 "" "")))]
11122 [(set_attr "type" "ibr")
11123 (set (attr "length")
11124 (if_then_else (and (ge (minus (match_dup 0) (pc))
11126 (lt (minus (match_dup 0) (pc))
11130 (set_attr "modrm" "0")])
11132 (define_expand "indirect_jump"
11133 [(set (pc) (match_operand 0 "indirect_branch_operand" ""))])
11135 (define_insn "*indirect_jump"
11136 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))]
11139 [(set_attr "type" "ibr")
11140 (set_attr "length_immediate" "0")])
11142 (define_expand "tablejump"
11143 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand" ""))
11144 (use (label_ref (match_operand 1 "" "")))])]
11147 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11148 relative. Convert the relative address to an absolute address. */
11152 enum rtx_code code;
11154 /* We can't use @GOTOFF for text labels on VxWorks;
11155 see gotoff_operand. */
11156 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11160 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11162 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11166 op1 = pic_offset_table_rtx;
11171 op0 = pic_offset_table_rtx;
11175 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11178 else if (TARGET_X32)
11179 operands[0] = convert_memory_address (Pmode, operands[0]);
11182 (define_insn "*tablejump_1"
11183 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))
11184 (use (label_ref (match_operand 1 "" "")))]
11187 [(set_attr "type" "ibr")
11188 (set_attr "length_immediate" "0")])
11190 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11193 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11194 (set (match_operand:QI 1 "register_operand" "")
11195 (match_operator:QI 2 "ix86_comparison_operator"
11196 [(reg FLAGS_REG) (const_int 0)]))
11197 (set (match_operand 3 "q_regs_operand" "")
11198 (zero_extend (match_dup 1)))]
11199 "(peep2_reg_dead_p (3, operands[1])
11200 || operands_match_p (operands[1], operands[3]))
11201 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11202 [(set (match_dup 4) (match_dup 0))
11203 (set (strict_low_part (match_dup 5))
11206 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11207 operands[5] = gen_lowpart (QImode, operands[3]);
11208 ix86_expand_clear (operands[3]);
11211 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11214 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11215 (set (match_operand:QI 1 "register_operand" "")
11216 (match_operator:QI 2 "ix86_comparison_operator"
11217 [(reg FLAGS_REG) (const_int 0)]))
11218 (parallel [(set (match_operand 3 "q_regs_operand" "")
11219 (zero_extend (match_dup 1)))
11220 (clobber (reg:CC FLAGS_REG))])]
11221 "(peep2_reg_dead_p (3, operands[1])
11222 || operands_match_p (operands[1], operands[3]))
11223 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11224 [(set (match_dup 4) (match_dup 0))
11225 (set (strict_low_part (match_dup 5))
11228 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11229 operands[5] = gen_lowpart (QImode, operands[3]);
11230 ix86_expand_clear (operands[3]);
11233 ;; Call instructions.
11235 ;; The predicates normally associated with named expanders are not properly
11236 ;; checked for calls. This is a bug in the generic code, but it isn't that
11237 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11239 ;; P6 processors will jump to the address after the decrement when %esp
11240 ;; is used as a call operand, so they will execute return address as a code.
11241 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11243 ;; Register constraint for call instruction.
11244 (define_mode_attr c [(SI "l") (DI "r")])
11246 ;; Call subroutine returning no value.
11248 (define_expand "call"
11249 [(call (match_operand:QI 0 "" "")
11250 (match_operand 1 "" ""))
11251 (use (match_operand 2 "" ""))]
11254 ix86_expand_call (NULL, operands[0], operands[1],
11255 operands[2], NULL, false);
11259 (define_expand "sibcall"
11260 [(call (match_operand:QI 0 "" "")
11261 (match_operand 1 "" ""))
11262 (use (match_operand 2 "" ""))]
11265 ix86_expand_call (NULL, operands[0], operands[1],
11266 operands[2], NULL, true);
11270 (define_insn_and_split "*call_vzeroupper"
11271 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11272 (match_operand 1 "" ""))
11273 (unspec [(match_operand 2 "const_int_operand" "")]
11274 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11275 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11277 "&& reload_completed"
11279 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11280 [(set_attr "type" "call")])
11282 (define_insn "*call"
11283 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11284 (match_operand 1 "" ""))]
11285 "!SIBLING_CALL_P (insn)"
11286 "* return ix86_output_call_insn (insn, operands[0]);"
11287 [(set_attr "type" "call")])
11289 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11290 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11291 (match_operand 1 "" ""))
11292 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11293 (clobber (reg:TI XMM6_REG))
11294 (clobber (reg:TI XMM7_REG))
11295 (clobber (reg:TI XMM8_REG))
11296 (clobber (reg:TI XMM9_REG))
11297 (clobber (reg:TI XMM10_REG))
11298 (clobber (reg:TI XMM11_REG))
11299 (clobber (reg:TI XMM12_REG))
11300 (clobber (reg:TI XMM13_REG))
11301 (clobber (reg:TI XMM14_REG))
11302 (clobber (reg:TI XMM15_REG))
11303 (clobber (reg:DI SI_REG))
11304 (clobber (reg:DI DI_REG))
11305 (unspec [(match_operand 2 "const_int_operand" "")]
11306 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11307 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11309 "&& reload_completed"
11311 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11312 [(set_attr "type" "call")])
11314 (define_insn "*call_rex64_ms_sysv"
11315 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11316 (match_operand 1 "" ""))
11317 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11318 (clobber (reg:TI XMM6_REG))
11319 (clobber (reg:TI XMM7_REG))
11320 (clobber (reg:TI XMM8_REG))
11321 (clobber (reg:TI XMM9_REG))
11322 (clobber (reg:TI XMM10_REG))
11323 (clobber (reg:TI XMM11_REG))
11324 (clobber (reg:TI XMM12_REG))
11325 (clobber (reg:TI XMM13_REG))
11326 (clobber (reg:TI XMM14_REG))
11327 (clobber (reg:TI XMM15_REG))
11328 (clobber (reg:DI SI_REG))
11329 (clobber (reg:DI DI_REG))]
11330 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11331 "* return ix86_output_call_insn (insn, operands[0]);"
11332 [(set_attr "type" "call")])
11334 (define_insn_and_split "*sibcall_vzeroupper"
11335 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11336 (match_operand 1 "" ""))
11337 (unspec [(match_operand 2 "const_int_operand" "")]
11338 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11339 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11341 "&& reload_completed"
11343 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11344 [(set_attr "type" "call")])
11346 (define_insn "*sibcall"
11347 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11348 (match_operand 1 "" ""))]
11349 "SIBLING_CALL_P (insn)"
11350 "* return ix86_output_call_insn (insn, operands[0]);"
11351 [(set_attr "type" "call")])
11353 (define_expand "call_pop"
11354 [(parallel [(call (match_operand:QI 0 "" "")
11355 (match_operand:SI 1 "" ""))
11356 (set (reg:SI SP_REG)
11357 (plus:SI (reg:SI SP_REG)
11358 (match_operand:SI 3 "" "")))])]
11361 ix86_expand_call (NULL, operands[0], operands[1],
11362 operands[2], operands[3], false);
11366 (define_insn_and_split "*call_pop_vzeroupper"
11367 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11368 (match_operand:SI 1 "" ""))
11369 (set (reg:SI SP_REG)
11370 (plus:SI (reg:SI SP_REG)
11371 (match_operand:SI 2 "immediate_operand" "i")))
11372 (unspec [(match_operand 3 "const_int_operand" "")]
11373 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11374 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11376 "&& reload_completed"
11378 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11379 [(set_attr "type" "call")])
11381 (define_insn "*call_pop"
11382 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11383 (match_operand 1 "" ""))
11384 (set (reg:SI SP_REG)
11385 (plus:SI (reg:SI SP_REG)
11386 (match_operand:SI 2 "immediate_operand" "i")))]
11387 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11388 "* return ix86_output_call_insn (insn, operands[0]);"
11389 [(set_attr "type" "call")])
11391 (define_insn_and_split "*sibcall_pop_vzeroupper"
11392 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11393 (match_operand 1 "" ""))
11394 (set (reg:SI SP_REG)
11395 (plus:SI (reg:SI SP_REG)
11396 (match_operand:SI 2 "immediate_operand" "i")))
11397 (unspec [(match_operand 3 "const_int_operand" "")]
11398 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11399 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11401 "&& reload_completed"
11403 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11404 [(set_attr "type" "call")])
11406 (define_insn "*sibcall_pop"
11407 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11408 (match_operand 1 "" ""))
11409 (set (reg:SI SP_REG)
11410 (plus:SI (reg:SI SP_REG)
11411 (match_operand:SI 2 "immediate_operand" "i")))]
11412 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11413 "* return ix86_output_call_insn (insn, operands[0]);"
11414 [(set_attr "type" "call")])
11416 ;; Call subroutine, returning value in operand 0
11418 (define_expand "call_value"
11419 [(set (match_operand 0 "" "")
11420 (call (match_operand:QI 1 "" "")
11421 (match_operand 2 "" "")))
11422 (use (match_operand 3 "" ""))]
11425 ix86_expand_call (operands[0], operands[1], operands[2],
11426 operands[3], NULL, false);
11430 (define_expand "sibcall_value"
11431 [(set (match_operand 0 "" "")
11432 (call (match_operand:QI 1 "" "")
11433 (match_operand 2 "" "")))
11434 (use (match_operand 3 "" ""))]
11437 ix86_expand_call (operands[0], operands[1], operands[2],
11438 operands[3], NULL, true);
11442 (define_insn_and_split "*call_value_vzeroupper"
11443 [(set (match_operand 0 "" "")
11444 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11445 (match_operand 2 "" "")))
11446 (unspec [(match_operand 3 "const_int_operand" "")]
11447 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11448 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11450 "&& reload_completed"
11452 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11453 [(set_attr "type" "callv")])
11455 (define_insn "*call_value"
11456 [(set (match_operand 0 "" "")
11457 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11458 (match_operand 2 "" "")))]
11459 "!SIBLING_CALL_P (insn)"
11460 "* return ix86_output_call_insn (insn, operands[1]);"
11461 [(set_attr "type" "callv")])
11463 (define_insn_and_split "*sibcall_value_vzeroupper"
11464 [(set (match_operand 0 "" "")
11465 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11466 (match_operand 2 "" "")))
11467 (unspec [(match_operand 3 "const_int_operand" "")]
11468 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11469 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11471 "&& reload_completed"
11473 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11474 [(set_attr "type" "callv")])
11476 (define_insn "*sibcall_value"
11477 [(set (match_operand 0 "" "")
11478 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11479 (match_operand 2 "" "")))]
11480 "SIBLING_CALL_P (insn)"
11481 "* return ix86_output_call_insn (insn, operands[1]);"
11482 [(set_attr "type" "callv")])
11484 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11485 [(set (match_operand 0 "" "")
11486 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11487 (match_operand 2 "" "")))
11488 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11489 (clobber (reg:TI XMM6_REG))
11490 (clobber (reg:TI XMM7_REG))
11491 (clobber (reg:TI XMM8_REG))
11492 (clobber (reg:TI XMM9_REG))
11493 (clobber (reg:TI XMM10_REG))
11494 (clobber (reg:TI XMM11_REG))
11495 (clobber (reg:TI XMM12_REG))
11496 (clobber (reg:TI XMM13_REG))
11497 (clobber (reg:TI XMM14_REG))
11498 (clobber (reg:TI XMM15_REG))
11499 (clobber (reg:DI SI_REG))
11500 (clobber (reg:DI DI_REG))
11501 (unspec [(match_operand 3 "const_int_operand" "")]
11502 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11503 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11505 "&& reload_completed"
11507 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11508 [(set_attr "type" "callv")])
11510 (define_insn "*call_value_rex64_ms_sysv"
11511 [(set (match_operand 0 "" "")
11512 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11513 (match_operand 2 "" "")))
11514 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11515 (clobber (reg:TI XMM6_REG))
11516 (clobber (reg:TI XMM7_REG))
11517 (clobber (reg:TI XMM8_REG))
11518 (clobber (reg:TI XMM9_REG))
11519 (clobber (reg:TI XMM10_REG))
11520 (clobber (reg:TI XMM11_REG))
11521 (clobber (reg:TI XMM12_REG))
11522 (clobber (reg:TI XMM13_REG))
11523 (clobber (reg:TI XMM14_REG))
11524 (clobber (reg:TI XMM15_REG))
11525 (clobber (reg:DI SI_REG))
11526 (clobber (reg:DI DI_REG))]
11527 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11528 "* return ix86_output_call_insn (insn, operands[1]);"
11529 [(set_attr "type" "callv")])
11531 (define_expand "call_value_pop"
11532 [(parallel [(set (match_operand 0 "" "")
11533 (call (match_operand:QI 1 "" "")
11534 (match_operand:SI 2 "" "")))
11535 (set (reg:SI SP_REG)
11536 (plus:SI (reg:SI SP_REG)
11537 (match_operand:SI 4 "" "")))])]
11540 ix86_expand_call (operands[0], operands[1], operands[2],
11541 operands[3], operands[4], false);
11545 (define_insn_and_split "*call_value_pop_vzeroupper"
11546 [(set (match_operand 0 "" "")
11547 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11548 (match_operand 2 "" "")))
11549 (set (reg:SI SP_REG)
11550 (plus:SI (reg:SI SP_REG)
11551 (match_operand:SI 3 "immediate_operand" "i")))
11552 (unspec [(match_operand 4 "const_int_operand" "")]
11553 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11554 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11556 "&& reload_completed"
11558 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11559 [(set_attr "type" "callv")])
11561 (define_insn "*call_value_pop"
11562 [(set (match_operand 0 "" "")
11563 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11564 (match_operand 2 "" "")))
11565 (set (reg:SI SP_REG)
11566 (plus:SI (reg:SI SP_REG)
11567 (match_operand:SI 3 "immediate_operand" "i")))]
11568 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11569 "* return ix86_output_call_insn (insn, operands[1]);"
11570 [(set_attr "type" "callv")])
11572 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11573 [(set (match_operand 0 "" "")
11574 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11575 (match_operand 2 "" "")))
11576 (set (reg:SI SP_REG)
11577 (plus:SI (reg:SI SP_REG)
11578 (match_operand:SI 3 "immediate_operand" "i")))
11579 (unspec [(match_operand 4 "const_int_operand" "")]
11580 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11581 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11583 "&& reload_completed"
11585 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11586 [(set_attr "type" "callv")])
11588 (define_insn "*sibcall_value_pop"
11589 [(set (match_operand 0 "" "")
11590 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11591 (match_operand 2 "" "")))
11592 (set (reg:SI SP_REG)
11593 (plus:SI (reg:SI SP_REG)
11594 (match_operand:SI 3 "immediate_operand" "i")))]
11595 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11596 "* return ix86_output_call_insn (insn, operands[1]);"
11597 [(set_attr "type" "callv")])
11599 ;; Call subroutine returning any type.
11601 (define_expand "untyped_call"
11602 [(parallel [(call (match_operand 0 "" "")
11604 (match_operand 1 "" "")
11605 (match_operand 2 "" "")])]
11610 /* In order to give reg-stack an easier job in validating two
11611 coprocessor registers as containing a possible return value,
11612 simply pretend the untyped call returns a complex long double
11615 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11616 and should have the default ABI. */
11618 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11619 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11620 operands[0], const0_rtx,
11621 GEN_INT ((TARGET_64BIT
11622 ? (ix86_abi == SYSV_ABI
11623 ? X86_64_SSE_REGPARM_MAX
11624 : X86_64_MS_SSE_REGPARM_MAX)
11625 : X86_32_SSE_REGPARM_MAX)
11629 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11631 rtx set = XVECEXP (operands[2], 0, i);
11632 emit_move_insn (SET_DEST (set), SET_SRC (set));
11635 /* The optimizer does not know that the call sets the function value
11636 registers we stored in the result block. We avoid problems by
11637 claiming that all hard registers are used and clobbered at this
11639 emit_insn (gen_blockage ());
11644 ;; Prologue and epilogue instructions
11646 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11647 ;; all of memory. This blocks insns from being moved across this point.
11649 (define_insn "blockage"
11650 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11653 [(set_attr "length" "0")])
11655 ;; Do not schedule instructions accessing memory across this point.
11657 (define_expand "memory_blockage"
11658 [(set (match_dup 0)
11659 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11662 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11663 MEM_VOLATILE_P (operands[0]) = 1;
11666 (define_insn "*memory_blockage"
11667 [(set (match_operand:BLK 0 "" "")
11668 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11671 [(set_attr "length" "0")])
11673 ;; As USE insns aren't meaningful after reload, this is used instead
11674 ;; to prevent deleting instructions setting registers for PIC code
11675 (define_insn "prologue_use"
11676 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11679 [(set_attr "length" "0")])
11681 ;; Insn emitted into the body of a function to return from a function.
11682 ;; This is only done if the function's epilogue is known to be simple.
11683 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11685 (define_expand "return"
11687 "ix86_can_use_return_insn_p ()"
11689 ix86_maybe_emit_epilogue_vzeroupper ();
11690 if (crtl->args.pops_args)
11692 rtx popc = GEN_INT (crtl->args.pops_args);
11693 emit_jump_insn (gen_simple_return_pop_internal (popc));
11698 ;; We need to disable this for TARGET_SEH, as otherwise
11699 ;; shrink-wrapped prologue gets enabled too. This might exceed
11700 ;; the maximum size of prologue in unwind information.
11702 (define_expand "simple_return"
11706 ix86_maybe_emit_epilogue_vzeroupper ();
11707 if (crtl->args.pops_args)
11709 rtx popc = GEN_INT (crtl->args.pops_args);
11710 emit_jump_insn (gen_simple_return_pop_internal (popc));
11715 (define_insn "simple_return_internal"
11719 [(set_attr "length" "1")
11720 (set_attr "atom_unit" "jeu")
11721 (set_attr "length_immediate" "0")
11722 (set_attr "modrm" "0")])
11724 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11725 ;; instruction Athlon and K8 have.
11727 (define_insn "simple_return_internal_long"
11729 (unspec [(const_int 0)] UNSPEC_REP)]
11732 [(set_attr "length" "2")
11733 (set_attr "atom_unit" "jeu")
11734 (set_attr "length_immediate" "0")
11735 (set_attr "prefix_rep" "1")
11736 (set_attr "modrm" "0")])
11738 (define_insn "simple_return_pop_internal"
11740 (use (match_operand:SI 0 "const_int_operand" ""))]
11743 [(set_attr "length" "3")
11744 (set_attr "atom_unit" "jeu")
11745 (set_attr "length_immediate" "2")
11746 (set_attr "modrm" "0")])
11748 (define_insn "simple_return_indirect_internal"
11750 (use (match_operand:SI 0 "register_operand" "r"))]
11753 [(set_attr "type" "ibr")
11754 (set_attr "length_immediate" "0")])
11760 [(set_attr "length" "1")
11761 (set_attr "length_immediate" "0")
11762 (set_attr "modrm" "0")])
11764 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11765 (define_insn "nops"
11766 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11770 int num = INTVAL (operands[0]);
11772 gcc_assert (num >= 1 && num <= 8);
11775 fputs ("\tnop\n", asm_out_file);
11779 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11780 (set_attr "length_immediate" "0")
11781 (set_attr "modrm" "0")])
11783 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11784 ;; branch prediction penalty for the third jump in a 16-byte
11788 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11791 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11792 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11794 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11795 The align insn is used to avoid 3 jump instructions in the row to improve
11796 branch prediction and the benefits hardly outweigh the cost of extra 8
11797 nops on the average inserted by full alignment pseudo operation. */
11801 [(set_attr "length" "16")])
11803 (define_expand "prologue"
11806 "ix86_expand_prologue (); DONE;")
11808 (define_insn "set_got"
11809 [(set (match_operand:SI 0 "register_operand" "=r")
11810 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11811 (clobber (reg:CC FLAGS_REG))]
11813 "* return output_set_got (operands[0], NULL_RTX);"
11814 [(set_attr "type" "multi")
11815 (set_attr "length" "12")])
11817 (define_insn "set_got_labelled"
11818 [(set (match_operand:SI 0 "register_operand" "=r")
11819 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11821 (clobber (reg:CC FLAGS_REG))]
11823 "* return output_set_got (operands[0], operands[1]);"
11824 [(set_attr "type" "multi")
11825 (set_attr "length" "12")])
11827 (define_insn "set_got_rex64"
11828 [(set (match_operand:DI 0 "register_operand" "=r")
11829 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11831 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11832 [(set_attr "type" "lea")
11833 (set_attr "length_address" "4")
11834 (set_attr "mode" "DI")])
11836 (define_insn "set_rip_rex64"
11837 [(set (match_operand:DI 0 "register_operand" "=r")
11838 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11840 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11841 [(set_attr "type" "lea")
11842 (set_attr "length_address" "4")
11843 (set_attr "mode" "DI")])
11845 (define_insn "set_got_offset_rex64"
11846 [(set (match_operand:DI 0 "register_operand" "=r")
11848 [(label_ref (match_operand 1 "" ""))]
11849 UNSPEC_SET_GOT_OFFSET))]
11851 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11852 [(set_attr "type" "imov")
11853 (set_attr "length_immediate" "0")
11854 (set_attr "length_address" "8")
11855 (set_attr "mode" "DI")])
11857 (define_expand "epilogue"
11860 "ix86_expand_epilogue (1); DONE;")
11862 (define_expand "sibcall_epilogue"
11865 "ix86_expand_epilogue (0); DONE;")
11867 (define_expand "eh_return"
11868 [(use (match_operand 0 "register_operand" ""))]
11871 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11873 /* Tricky bit: we write the address of the handler to which we will
11874 be returning into someone else's stack frame, one word below the
11875 stack address we wish to restore. */
11876 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11877 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11878 tmp = gen_rtx_MEM (Pmode, tmp);
11879 emit_move_insn (tmp, ra);
11881 emit_jump_insn (gen_eh_return_internal ());
11886 (define_insn_and_split "eh_return_internal"
11890 "epilogue_completed"
11892 "ix86_expand_epilogue (2); DONE;")
11894 (define_insn "leave"
11895 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11896 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11897 (clobber (mem:BLK (scratch)))]
11900 [(set_attr "type" "leave")])
11902 (define_insn "leave_rex64"
11903 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11904 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11905 (clobber (mem:BLK (scratch)))]
11908 [(set_attr "type" "leave")])
11910 ;; Handle -fsplit-stack.
11912 (define_expand "split_stack_prologue"
11916 ix86_expand_split_stack_prologue ();
11920 ;; In order to support the call/return predictor, we use a return
11921 ;; instruction which the middle-end doesn't see.
11922 (define_insn "split_stack_return"
11923 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11924 UNSPECV_SPLIT_STACK_RETURN)]
11927 if (operands[0] == const0_rtx)
11932 [(set_attr "atom_unit" "jeu")
11933 (set_attr "modrm" "0")
11934 (set (attr "length")
11935 (if_then_else (match_operand:SI 0 "const0_operand" "")
11938 (set (attr "length_immediate")
11939 (if_then_else (match_operand:SI 0 "const0_operand" "")
11943 ;; If there are operand 0 bytes available on the stack, jump to
11946 (define_expand "split_stack_space_check"
11947 [(set (pc) (if_then_else
11948 (ltu (minus (reg SP_REG)
11949 (match_operand 0 "register_operand" ""))
11950 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11951 (label_ref (match_operand 1 "" ""))
11955 rtx reg, size, limit;
11957 reg = gen_reg_rtx (Pmode);
11958 size = force_reg (Pmode, operands[0]);
11959 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11960 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11961 UNSPEC_STACK_CHECK);
11962 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11963 ix86_expand_branch (GEU, reg, limit, operands[1]);
11968 ;; Bit manipulation instructions.
11970 (define_expand "ffs<mode>2"
11971 [(set (match_dup 2) (const_int -1))
11972 (parallel [(set (reg:CCZ FLAGS_REG)
11974 (match_operand:SWI48 1 "nonimmediate_operand" "")
11976 (set (match_operand:SWI48 0 "register_operand" "")
11977 (ctz:SWI48 (match_dup 1)))])
11978 (set (match_dup 0) (if_then_else:SWI48
11979 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11982 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11983 (clobber (reg:CC FLAGS_REG))])]
11986 if (<MODE>mode == SImode && !TARGET_CMOVE)
11988 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11991 operands[2] = gen_reg_rtx (<MODE>mode);
11994 (define_insn_and_split "ffssi2_no_cmove"
11995 [(set (match_operand:SI 0 "register_operand" "=r")
11996 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11997 (clobber (match_scratch:SI 2 "=&q"))
11998 (clobber (reg:CC FLAGS_REG))]
12001 "&& reload_completed"
12002 [(parallel [(set (reg:CCZ FLAGS_REG)
12003 (compare:CCZ (match_dup 1) (const_int 0)))
12004 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12005 (set (strict_low_part (match_dup 3))
12006 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
12007 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12008 (clobber (reg:CC FLAGS_REG))])
12009 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12010 (clobber (reg:CC FLAGS_REG))])
12011 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12012 (clobber (reg:CC FLAGS_REG))])]
12014 operands[3] = gen_lowpart (QImode, operands[2]);
12015 ix86_expand_clear (operands[2]);
12018 (define_insn "*ffs<mode>_1"
12019 [(set (reg:CCZ FLAGS_REG)
12020 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12022 (set (match_operand:SWI48 0 "register_operand" "=r")
12023 (ctz:SWI48 (match_dup 1)))]
12025 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12026 [(set_attr "type" "alu1")
12027 (set_attr "prefix_0f" "1")
12028 (set_attr "mode" "<MODE>")])
12030 (define_insn "ctz<mode>2"
12031 [(set (match_operand:SWI248 0 "register_operand" "=r")
12032 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12033 (clobber (reg:CC FLAGS_REG))]
12037 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12039 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12041 [(set_attr "type" "alu1")
12042 (set_attr "prefix_0f" "1")
12043 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
12044 (set_attr "mode" "<MODE>")])
12046 (define_expand "clz<mode>2"
12048 [(set (match_operand:SWI248 0 "register_operand" "")
12051 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12052 (clobber (reg:CC FLAGS_REG))])
12054 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12055 (clobber (reg:CC FLAGS_REG))])]
12060 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12063 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12066 (define_insn "clz<mode>2_lzcnt"
12067 [(set (match_operand:SWI248 0 "register_operand" "=r")
12068 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12069 (clobber (reg:CC FLAGS_REG))]
12071 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12072 [(set_attr "prefix_rep" "1")
12073 (set_attr "type" "bitmanip")
12074 (set_attr "mode" "<MODE>")])
12076 ;; BMI instructions.
12077 (define_insn "*bmi_andn_<mode>"
12078 [(set (match_operand:SWI48 0 "register_operand" "=r")
12081 (match_operand:SWI48 1 "register_operand" "r"))
12082 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12083 (clobber (reg:CC FLAGS_REG))]
12085 "andn\t{%2, %1, %0|%0, %1, %2}"
12086 [(set_attr "type" "bitmanip")
12087 (set_attr "mode" "<MODE>")])
12089 (define_insn "bmi_bextr_<mode>"
12090 [(set (match_operand:SWI48 0 "register_operand" "=r")
12091 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12092 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12094 (clobber (reg:CC FLAGS_REG))]
12096 "bextr\t{%2, %1, %0|%0, %1, %2}"
12097 [(set_attr "type" "bitmanip")
12098 (set_attr "mode" "<MODE>")])
12100 (define_insn "*bmi_blsi_<mode>"
12101 [(set (match_operand:SWI48 0 "register_operand" "=r")
12104 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12106 (clobber (reg:CC FLAGS_REG))]
12108 "blsi\t{%1, %0|%0, %1}"
12109 [(set_attr "type" "bitmanip")
12110 (set_attr "mode" "<MODE>")])
12112 (define_insn "*bmi_blsmsk_<mode>"
12113 [(set (match_operand:SWI48 0 "register_operand" "=r")
12116 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12119 (clobber (reg:CC FLAGS_REG))]
12121 "blsmsk\t{%1, %0|%0, %1}"
12122 [(set_attr "type" "bitmanip")
12123 (set_attr "mode" "<MODE>")])
12125 (define_insn "*bmi_blsr_<mode>"
12126 [(set (match_operand:SWI48 0 "register_operand" "=r")
12129 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12132 (clobber (reg:CC FLAGS_REG))]
12134 "blsr\t{%1, %0|%0, %1}"
12135 [(set_attr "type" "bitmanip")
12136 (set_attr "mode" "<MODE>")])
12138 ;; BMI2 instructions.
12139 (define_insn "bmi2_bzhi_<mode>3"
12140 [(set (match_operand:SWI48 0 "register_operand" "=r")
12141 (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
12142 (lshiftrt:SWI48 (const_int -1)
12143 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
12144 (clobber (reg:CC FLAGS_REG))]
12146 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12147 [(set_attr "type" "bitmanip")
12148 (set_attr "prefix" "vex")
12149 (set_attr "mode" "<MODE>")])
12151 (define_insn "bmi2_pdep_<mode>3"
12152 [(set (match_operand:SWI48 0 "register_operand" "=r")
12153 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12154 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12157 "pdep\t{%2, %1, %0|%0, %1, %2}"
12158 [(set_attr "type" "bitmanip")
12159 (set_attr "prefix" "vex")
12160 (set_attr "mode" "<MODE>")])
12162 (define_insn "bmi2_pext_<mode>3"
12163 [(set (match_operand:SWI48 0 "register_operand" "=r")
12164 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12165 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12168 "pext\t{%2, %1, %0|%0, %1, %2}"
12169 [(set_attr "type" "bitmanip")
12170 (set_attr "prefix" "vex")
12171 (set_attr "mode" "<MODE>")])
12173 ;; TBM instructions.
12174 (define_insn "tbm_bextri_<mode>"
12175 [(set (match_operand:SWI48 0 "register_operand" "=r")
12176 (zero_extract:SWI48
12177 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12178 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12179 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12180 (clobber (reg:CC FLAGS_REG))]
12183 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12184 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12186 [(set_attr "type" "bitmanip")
12187 (set_attr "mode" "<MODE>")])
12189 (define_insn "*tbm_blcfill_<mode>"
12190 [(set (match_operand:SWI48 0 "register_operand" "=r")
12193 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12196 (clobber (reg:CC FLAGS_REG))]
12198 "blcfill\t{%1, %0|%0, %1}"
12199 [(set_attr "type" "bitmanip")
12200 (set_attr "mode" "<MODE>")])
12202 (define_insn "*tbm_blci_<mode>"
12203 [(set (match_operand:SWI48 0 "register_operand" "=r")
12207 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12210 (clobber (reg:CC FLAGS_REG))]
12212 "blci\t{%1, %0|%0, %1}"
12213 [(set_attr "type" "bitmanip")
12214 (set_attr "mode" "<MODE>")])
12216 (define_insn "*tbm_blcic_<mode>"
12217 [(set (match_operand:SWI48 0 "register_operand" "=r")
12220 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12224 (clobber (reg:CC FLAGS_REG))]
12226 "blcic\t{%1, %0|%0, %1}"
12227 [(set_attr "type" "bitmanip")
12228 (set_attr "mode" "<MODE>")])
12230 (define_insn "*tbm_blcmsk_<mode>"
12231 [(set (match_operand:SWI48 0 "register_operand" "=r")
12234 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12237 (clobber (reg:CC FLAGS_REG))]
12239 "blcmsk\t{%1, %0|%0, %1}"
12240 [(set_attr "type" "bitmanip")
12241 (set_attr "mode" "<MODE>")])
12243 (define_insn "*tbm_blcs_<mode>"
12244 [(set (match_operand:SWI48 0 "register_operand" "=r")
12247 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12250 (clobber (reg:CC FLAGS_REG))]
12252 "blcs\t{%1, %0|%0, %1}"
12253 [(set_attr "type" "bitmanip")
12254 (set_attr "mode" "<MODE>")])
12256 (define_insn "*tbm_blsfill_<mode>"
12257 [(set (match_operand:SWI48 0 "register_operand" "=r")
12260 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12263 (clobber (reg:CC FLAGS_REG))]
12265 "blsfill\t{%1, %0|%0, %1}"
12266 [(set_attr "type" "bitmanip")
12267 (set_attr "mode" "<MODE>")])
12269 (define_insn "*tbm_blsic_<mode>"
12270 [(set (match_operand:SWI48 0 "register_operand" "=r")
12273 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12277 (clobber (reg:CC FLAGS_REG))]
12279 "blsic\t{%1, %0|%0, %1}"
12280 [(set_attr "type" "bitmanip")
12281 (set_attr "mode" "<MODE>")])
12283 (define_insn "*tbm_t1mskc_<mode>"
12284 [(set (match_operand:SWI48 0 "register_operand" "=r")
12287 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12291 (clobber (reg:CC FLAGS_REG))]
12293 "t1mskc\t{%1, %0|%0, %1}"
12294 [(set_attr "type" "bitmanip")
12295 (set_attr "mode" "<MODE>")])
12297 (define_insn "*tbm_tzmsk_<mode>"
12298 [(set (match_operand:SWI48 0 "register_operand" "=r")
12301 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12305 (clobber (reg:CC FLAGS_REG))]
12307 "tzmsk\t{%1, %0|%0, %1}"
12308 [(set_attr "type" "bitmanip")
12309 (set_attr "mode" "<MODE>")])
12311 (define_insn "bsr_rex64"
12312 [(set (match_operand:DI 0 "register_operand" "=r")
12313 (minus:DI (const_int 63)
12314 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12315 (clobber (reg:CC FLAGS_REG))]
12317 "bsr{q}\t{%1, %0|%0, %1}"
12318 [(set_attr "type" "alu1")
12319 (set_attr "prefix_0f" "1")
12320 (set_attr "mode" "DI")])
12323 [(set (match_operand:SI 0 "register_operand" "=r")
12324 (minus:SI (const_int 31)
12325 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12326 (clobber (reg:CC FLAGS_REG))]
12328 "bsr{l}\t{%1, %0|%0, %1}"
12329 [(set_attr "type" "alu1")
12330 (set_attr "prefix_0f" "1")
12331 (set_attr "mode" "SI")])
12333 (define_insn "*bsrhi"
12334 [(set (match_operand:HI 0 "register_operand" "=r")
12335 (minus:HI (const_int 15)
12336 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12337 (clobber (reg:CC FLAGS_REG))]
12339 "bsr{w}\t{%1, %0|%0, %1}"
12340 [(set_attr "type" "alu1")
12341 (set_attr "prefix_0f" "1")
12342 (set_attr "mode" "HI")])
12344 (define_insn "popcount<mode>2"
12345 [(set (match_operand:SWI248 0 "register_operand" "=r")
12347 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12348 (clobber (reg:CC FLAGS_REG))]
12352 return "popcnt\t{%1, %0|%0, %1}";
12354 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12357 [(set_attr "prefix_rep" "1")
12358 (set_attr "type" "bitmanip")
12359 (set_attr "mode" "<MODE>")])
12361 (define_insn "*popcount<mode>2_cmp"
12362 [(set (reg FLAGS_REG)
12365 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12367 (set (match_operand:SWI248 0 "register_operand" "=r")
12368 (popcount:SWI248 (match_dup 1)))]
12369 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12372 return "popcnt\t{%1, %0|%0, %1}";
12374 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12377 [(set_attr "prefix_rep" "1")
12378 (set_attr "type" "bitmanip")
12379 (set_attr "mode" "<MODE>")])
12381 (define_insn "*popcountsi2_cmp_zext"
12382 [(set (reg FLAGS_REG)
12384 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12386 (set (match_operand:DI 0 "register_operand" "=r")
12387 (zero_extend:DI(popcount:SI (match_dup 1))))]
12388 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12391 return "popcnt\t{%1, %0|%0, %1}";
12393 return "popcnt{l}\t{%1, %0|%0, %1}";
12396 [(set_attr "prefix_rep" "1")
12397 (set_attr "type" "bitmanip")
12398 (set_attr "mode" "SI")])
12400 (define_expand "bswap<mode>2"
12401 [(set (match_operand:SWI48 0 "register_operand" "")
12402 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12405 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12407 rtx x = operands[0];
12409 emit_move_insn (x, operands[1]);
12410 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12411 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12412 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12417 (define_insn "*bswap<mode>2_movbe"
12418 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12419 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12421 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12424 movbe\t{%1, %0|%0, %1}
12425 movbe\t{%1, %0|%0, %1}"
12426 [(set_attr "type" "bitmanip,imov,imov")
12427 (set_attr "modrm" "0,1,1")
12428 (set_attr "prefix_0f" "*,1,1")
12429 (set_attr "prefix_extra" "*,1,1")
12430 (set_attr "mode" "<MODE>")])
12432 (define_insn "*bswap<mode>2_1"
12433 [(set (match_operand:SWI48 0 "register_operand" "=r")
12434 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12437 [(set_attr "type" "bitmanip")
12438 (set_attr "modrm" "0")
12439 (set_attr "mode" "<MODE>")])
12441 (define_insn "*bswaphi_lowpart_1"
12442 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12443 (bswap:HI (match_dup 0)))
12444 (clobber (reg:CC FLAGS_REG))]
12445 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12447 xchg{b}\t{%h0, %b0|%b0, %h0}
12448 rol{w}\t{$8, %0|%0, 8}"
12449 [(set_attr "length" "2,4")
12450 (set_attr "mode" "QI,HI")])
12452 (define_insn "bswaphi_lowpart"
12453 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12454 (bswap:HI (match_dup 0)))
12455 (clobber (reg:CC FLAGS_REG))]
12457 "rol{w}\t{$8, %0|%0, 8}"
12458 [(set_attr "length" "4")
12459 (set_attr "mode" "HI")])
12461 (define_expand "paritydi2"
12462 [(set (match_operand:DI 0 "register_operand" "")
12463 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12466 rtx scratch = gen_reg_rtx (QImode);
12469 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12470 NULL_RTX, operands[1]));
12472 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12473 gen_rtx_REG (CCmode, FLAGS_REG),
12475 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12478 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12481 rtx tmp = gen_reg_rtx (SImode);
12483 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12484 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12489 (define_expand "paritysi2"
12490 [(set (match_operand:SI 0 "register_operand" "")
12491 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12494 rtx scratch = gen_reg_rtx (QImode);
12497 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12499 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12500 gen_rtx_REG (CCmode, FLAGS_REG),
12502 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12504 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12508 (define_insn_and_split "paritydi2_cmp"
12509 [(set (reg:CC FLAGS_REG)
12510 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12512 (clobber (match_scratch:DI 0 "=r"))
12513 (clobber (match_scratch:SI 1 "=&r"))
12514 (clobber (match_scratch:HI 2 "=Q"))]
12517 "&& reload_completed"
12519 [(set (match_dup 1)
12520 (xor:SI (match_dup 1) (match_dup 4)))
12521 (clobber (reg:CC FLAGS_REG))])
12523 [(set (reg:CC FLAGS_REG)
12524 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12525 (clobber (match_dup 1))
12526 (clobber (match_dup 2))])]
12528 operands[4] = gen_lowpart (SImode, operands[3]);
12532 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12533 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12536 operands[1] = gen_highpart (SImode, operands[3]);
12539 (define_insn_and_split "paritysi2_cmp"
12540 [(set (reg:CC FLAGS_REG)
12541 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12543 (clobber (match_scratch:SI 0 "=r"))
12544 (clobber (match_scratch:HI 1 "=&Q"))]
12547 "&& reload_completed"
12549 [(set (match_dup 1)
12550 (xor:HI (match_dup 1) (match_dup 3)))
12551 (clobber (reg:CC FLAGS_REG))])
12553 [(set (reg:CC FLAGS_REG)
12554 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12555 (clobber (match_dup 1))])]
12557 operands[3] = gen_lowpart (HImode, operands[2]);
12559 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12560 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12563 (define_insn "*parityhi2_cmp"
12564 [(set (reg:CC FLAGS_REG)
12565 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12567 (clobber (match_scratch:HI 0 "=Q"))]
12569 "xor{b}\t{%h0, %b0|%b0, %h0}"
12570 [(set_attr "length" "2")
12571 (set_attr "mode" "HI")])
12574 ;; Thread-local storage patterns for ELF.
12576 ;; Note that these code sequences must appear exactly as shown
12577 ;; in order to allow linker relaxation.
12579 (define_insn "*tls_global_dynamic_32_gnu"
12580 [(set (match_operand:SI 0 "register_operand" "=a")
12582 [(match_operand:SI 1 "register_operand" "b")
12583 (match_operand:SI 2 "tls_symbolic_operand" "")
12584 (match_operand:SI 3 "constant_call_address_operand" "z")]
12586 (clobber (match_scratch:SI 4 "=d"))
12587 (clobber (match_scratch:SI 5 "=c"))
12588 (clobber (reg:CC FLAGS_REG))]
12589 "!TARGET_64BIT && TARGET_GNU_TLS"
12592 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12593 if (TARGET_SUN_TLS)
12594 #ifdef HAVE_AS_IX86_TLSGDPLT
12595 return "call\t%a2@tlsgdplt";
12597 return "call\t%p3@plt";
12599 return "call\t%P3";
12601 [(set_attr "type" "multi")
12602 (set_attr "length" "12")])
12604 (define_expand "tls_global_dynamic_32"
12606 [(set (match_operand:SI 0 "register_operand" "")
12607 (unspec:SI [(match_operand:SI 2 "register_operand" "")
12608 (match_operand:SI 1 "tls_symbolic_operand" "")
12609 (match_operand:SI 3 "constant_call_address_operand" "")]
12611 (clobber (match_scratch:SI 4 ""))
12612 (clobber (match_scratch:SI 5 ""))
12613 (clobber (reg:CC FLAGS_REG))])])
12615 (define_insn "*tls_global_dynamic_64"
12616 [(set (match_operand:DI 0 "register_operand" "=a")
12618 (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12619 (match_operand:DI 3 "" "")))
12620 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12625 fputs (ASM_BYTE "0x66\n", asm_out_file);
12627 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12628 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12629 fputs ("\trex64\n", asm_out_file);
12630 if (TARGET_SUN_TLS)
12631 return "call\t%p2@plt";
12632 return "call\t%P2";
12634 [(set_attr "type" "multi")
12635 (set (attr "length")
12636 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12638 (define_expand "tls_global_dynamic_64"
12640 [(set (match_operand:DI 0 "register_operand" "")
12642 (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12644 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12647 (define_insn "*tls_local_dynamic_base_32_gnu"
12648 [(set (match_operand:SI 0 "register_operand" "=a")
12650 [(match_operand:SI 1 "register_operand" "b")
12651 (match_operand:SI 2 "constant_call_address_operand" "z")]
12652 UNSPEC_TLS_LD_BASE))
12653 (clobber (match_scratch:SI 3 "=d"))
12654 (clobber (match_scratch:SI 4 "=c"))
12655 (clobber (reg:CC FLAGS_REG))]
12656 "!TARGET_64BIT && TARGET_GNU_TLS"
12659 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12660 if (TARGET_SUN_TLS)
12661 #ifdef HAVE_AS_IX86_TLSLDMPLT
12662 return "call\t%&@tlsldmplt";
12664 return "call\t%p2@plt";
12666 return "call\t%P2";
12668 [(set_attr "type" "multi")
12669 (set_attr "length" "11")])
12671 (define_expand "tls_local_dynamic_base_32"
12673 [(set (match_operand:SI 0 "register_operand" "")
12675 [(match_operand:SI 1 "register_operand" "")
12676 (match_operand:SI 2 "constant_call_address_operand" "")]
12677 UNSPEC_TLS_LD_BASE))
12678 (clobber (match_scratch:SI 3 ""))
12679 (clobber (match_scratch:SI 4 ""))
12680 (clobber (reg:CC FLAGS_REG))])])
12682 (define_insn "*tls_local_dynamic_base_64"
12683 [(set (match_operand:DI 0 "register_operand" "=a")
12685 (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12686 (match_operand:DI 2 "" "")))
12687 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12691 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12692 if (TARGET_SUN_TLS)
12693 return "call\t%p1@plt";
12694 return "call\t%P1";
12696 [(set_attr "type" "multi")
12697 (set_attr "length" "12")])
12699 (define_expand "tls_local_dynamic_base_64"
12701 [(set (match_operand:DI 0 "register_operand" "")
12703 (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12705 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12707 ;; Local dynamic of a single variable is a lose. Show combine how
12708 ;; to convert that back to global dynamic.
12710 (define_insn_and_split "*tls_local_dynamic_32_once"
12711 [(set (match_operand:SI 0 "register_operand" "=a")
12713 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12714 (match_operand:SI 2 "constant_call_address_operand" "z")]
12715 UNSPEC_TLS_LD_BASE)
12716 (const:SI (unspec:SI
12717 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12719 (clobber (match_scratch:SI 4 "=d"))
12720 (clobber (match_scratch:SI 5 "=c"))
12721 (clobber (reg:CC FLAGS_REG))]
12726 [(set (match_dup 0)
12727 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12729 (clobber (match_dup 4))
12730 (clobber (match_dup 5))
12731 (clobber (reg:CC FLAGS_REG))])])
12733 ;; Segment register for the thread base ptr load
12734 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12736 ;; Load and add the thread base pointer from %<tp_seg>:0.
12737 (define_insn "*load_tp_x32"
12738 [(set (match_operand:SI 0 "register_operand" "=r")
12739 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12741 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12742 [(set_attr "type" "imov")
12743 (set_attr "modrm" "0")
12744 (set_attr "length" "7")
12745 (set_attr "memory" "load")
12746 (set_attr "imm_disp" "false")])
12748 (define_insn "*load_tp_x32_zext"
12749 [(set (match_operand:DI 0 "register_operand" "=r")
12750 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12752 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12753 [(set_attr "type" "imov")
12754 (set_attr "modrm" "0")
12755 (set_attr "length" "7")
12756 (set_attr "memory" "load")
12757 (set_attr "imm_disp" "false")])
12759 (define_insn "*load_tp_<mode>"
12760 [(set (match_operand:P 0 "register_operand" "=r")
12761 (unspec:P [(const_int 0)] UNSPEC_TP))]
12763 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12764 [(set_attr "type" "imov")
12765 (set_attr "modrm" "0")
12766 (set_attr "length" "7")
12767 (set_attr "memory" "load")
12768 (set_attr "imm_disp" "false")])
12770 (define_insn "*add_tp_x32"
12771 [(set (match_operand:SI 0 "register_operand" "=r")
12772 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12773 (match_operand:SI 1 "register_operand" "0")))
12774 (clobber (reg:CC FLAGS_REG))]
12776 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12777 [(set_attr "type" "alu")
12778 (set_attr "modrm" "0")
12779 (set_attr "length" "7")
12780 (set_attr "memory" "load")
12781 (set_attr "imm_disp" "false")])
12783 (define_insn "*add_tp_x32_zext"
12784 [(set (match_operand:DI 0 "register_operand" "=r")
12786 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12787 (match_operand:SI 1 "register_operand" "0"))))
12788 (clobber (reg:CC FLAGS_REG))]
12790 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12791 [(set_attr "type" "alu")
12792 (set_attr "modrm" "0")
12793 (set_attr "length" "7")
12794 (set_attr "memory" "load")
12795 (set_attr "imm_disp" "false")])
12797 (define_insn "*add_tp_<mode>"
12798 [(set (match_operand:P 0 "register_operand" "=r")
12799 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12800 (match_operand:P 1 "register_operand" "0")))
12801 (clobber (reg:CC FLAGS_REG))]
12803 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12804 [(set_attr "type" "alu")
12805 (set_attr "modrm" "0")
12806 (set_attr "length" "7")
12807 (set_attr "memory" "load")
12808 (set_attr "imm_disp" "false")])
12810 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12811 ;; %rax as destination of the initial executable code sequence.
12812 (define_insn "tls_initial_exec_64_sun"
12813 [(set (match_operand:DI 0 "register_operand" "=a")
12815 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12816 UNSPEC_TLS_IE_SUN))
12817 (clobber (reg:CC FLAGS_REG))]
12818 "TARGET_64BIT && TARGET_SUN_TLS"
12821 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12822 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12824 [(set_attr "type" "multi")])
12826 ;; GNU2 TLS patterns can be split.
12828 (define_expand "tls_dynamic_gnu2_32"
12829 [(set (match_dup 3)
12830 (plus:SI (match_operand:SI 2 "register_operand" "")
12832 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12835 [(set (match_operand:SI 0 "register_operand" "")
12836 (unspec:SI [(match_dup 1) (match_dup 3)
12837 (match_dup 2) (reg:SI SP_REG)]
12839 (clobber (reg:CC FLAGS_REG))])]
12840 "!TARGET_64BIT && TARGET_GNU2_TLS"
12842 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12843 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12846 (define_insn "*tls_dynamic_gnu2_lea_32"
12847 [(set (match_operand:SI 0 "register_operand" "=r")
12848 (plus:SI (match_operand:SI 1 "register_operand" "b")
12850 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12851 UNSPEC_TLSDESC))))]
12852 "!TARGET_64BIT && TARGET_GNU2_TLS"
12853 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
12854 [(set_attr "type" "lea")
12855 (set_attr "mode" "SI")
12856 (set_attr "length" "6")
12857 (set_attr "length_address" "4")])
12859 (define_insn "*tls_dynamic_gnu2_call_32"
12860 [(set (match_operand:SI 0 "register_operand" "=a")
12861 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12862 (match_operand:SI 2 "register_operand" "0")
12863 ;; we have to make sure %ebx still points to the GOT
12864 (match_operand:SI 3 "register_operand" "b")
12867 (clobber (reg:CC FLAGS_REG))]
12868 "!TARGET_64BIT && TARGET_GNU2_TLS"
12869 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12870 [(set_attr "type" "call")
12871 (set_attr "length" "2")
12872 (set_attr "length_address" "0")])
12874 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12875 [(set (match_operand:SI 0 "register_operand" "=&a")
12877 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12878 (match_operand:SI 4 "" "")
12879 (match_operand:SI 2 "register_operand" "b")
12882 (const:SI (unspec:SI
12883 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12885 (clobber (reg:CC FLAGS_REG))]
12886 "!TARGET_64BIT && TARGET_GNU2_TLS"
12889 [(set (match_dup 0) (match_dup 5))]
12891 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12892 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12895 (define_expand "tls_dynamic_gnu2_64"
12896 [(set (match_dup 2)
12897 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12900 [(set (match_operand:DI 0 "register_operand" "")
12901 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12903 (clobber (reg:CC FLAGS_REG))])]
12904 "TARGET_64BIT && TARGET_GNU2_TLS"
12906 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12907 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12910 (define_insn "*tls_dynamic_gnu2_lea_64"
12911 [(set (match_operand:DI 0 "register_operand" "=r")
12912 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12914 "TARGET_64BIT && TARGET_GNU2_TLS"
12915 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
12916 [(set_attr "type" "lea")
12917 (set_attr "mode" "DI")
12918 (set_attr "length" "7")
12919 (set_attr "length_address" "4")])
12921 (define_insn "*tls_dynamic_gnu2_call_64"
12922 [(set (match_operand:DI 0 "register_operand" "=a")
12923 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")
12924 (match_operand:DI 2 "register_operand" "0")
12927 (clobber (reg:CC FLAGS_REG))]
12928 "TARGET_64BIT && TARGET_GNU2_TLS"
12929 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12930 [(set_attr "type" "call")
12931 (set_attr "length" "2")
12932 (set_attr "length_address" "0")])
12934 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12935 [(set (match_operand:DI 0 "register_operand" "=&a")
12937 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12938 (match_operand:DI 3 "" "")
12941 (const:DI (unspec:DI
12942 [(match_operand 1 "tls_symbolic_operand" "")]
12944 (clobber (reg:CC FLAGS_REG))]
12945 "TARGET_64BIT && TARGET_GNU2_TLS"
12948 [(set (match_dup 0) (match_dup 4))]
12950 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12951 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12954 ;; These patterns match the binary 387 instructions for addM3, subM3,
12955 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12956 ;; SFmode. The first is the normal insn, the second the same insn but
12957 ;; with one operand a conversion, and the third the same insn but with
12958 ;; the other operand a conversion. The conversion may be SFmode or
12959 ;; SImode if the target mode DFmode, but only SImode if the target mode
12962 ;; Gcc is slightly more smart about handling normal two address instructions
12963 ;; so use special patterns for add and mull.
12965 (define_insn "*fop_<mode>_comm_mixed"
12966 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12967 (match_operator:MODEF 3 "binary_fp_operator"
12968 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12969 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12970 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12971 && COMMUTATIVE_ARITH_P (operands[3])
12972 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12973 "* return output_387_binary_op (insn, operands);"
12974 [(set (attr "type")
12975 (if_then_else (eq_attr "alternative" "1,2")
12976 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12977 (const_string "ssemul")
12978 (const_string "sseadd"))
12979 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12980 (const_string "fmul")
12981 (const_string "fop"))))
12982 (set_attr "isa" "*,noavx,avx")
12983 (set_attr "prefix" "orig,orig,vex")
12984 (set_attr "mode" "<MODE>")])
12986 (define_insn "*fop_<mode>_comm_sse"
12987 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12988 (match_operator:MODEF 3 "binary_fp_operator"
12989 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12990 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12991 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12992 && COMMUTATIVE_ARITH_P (operands[3])
12993 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12994 "* return output_387_binary_op (insn, operands);"
12995 [(set (attr "type")
12996 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12997 (const_string "ssemul")
12998 (const_string "sseadd")))
12999 (set_attr "isa" "noavx,avx")
13000 (set_attr "prefix" "orig,vex")
13001 (set_attr "mode" "<MODE>")])
13003 (define_insn "*fop_<mode>_comm_i387"
13004 [(set (match_operand:MODEF 0 "register_operand" "=f")
13005 (match_operator:MODEF 3 "binary_fp_operator"
13006 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13007 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13008 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13009 && COMMUTATIVE_ARITH_P (operands[3])
13010 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13011 "* return output_387_binary_op (insn, operands);"
13012 [(set (attr "type")
13013 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13014 (const_string "fmul")
13015 (const_string "fop")))
13016 (set_attr "mode" "<MODE>")])
13018 (define_insn "*fop_<mode>_1_mixed"
13019 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13020 (match_operator:MODEF 3 "binary_fp_operator"
13021 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13022 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13023 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13024 && !COMMUTATIVE_ARITH_P (operands[3])
13025 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13026 "* return output_387_binary_op (insn, operands);"
13027 [(set (attr "type")
13028 (cond [(and (eq_attr "alternative" "2,3")
13029 (match_operand:MODEF 3 "mult_operator" ""))
13030 (const_string "ssemul")
13031 (and (eq_attr "alternative" "2,3")
13032 (match_operand:MODEF 3 "div_operator" ""))
13033 (const_string "ssediv")
13034 (eq_attr "alternative" "2,3")
13035 (const_string "sseadd")
13036 (match_operand:MODEF 3 "mult_operator" "")
13037 (const_string "fmul")
13038 (match_operand:MODEF 3 "div_operator" "")
13039 (const_string "fdiv")
13041 (const_string "fop")))
13042 (set_attr "isa" "*,*,noavx,avx")
13043 (set_attr "prefix" "orig,orig,orig,vex")
13044 (set_attr "mode" "<MODE>")])
13046 (define_insn "*rcpsf2_sse"
13047 [(set (match_operand:SF 0 "register_operand" "=x")
13048 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13051 "%vrcpss\t{%1, %d0|%d0, %1}"
13052 [(set_attr "type" "sse")
13053 (set_attr "atom_sse_attr" "rcp")
13054 (set_attr "prefix" "maybe_vex")
13055 (set_attr "mode" "SF")])
13057 (define_insn "*fop_<mode>_1_sse"
13058 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13059 (match_operator:MODEF 3 "binary_fp_operator"
13060 [(match_operand:MODEF 1 "register_operand" "0,x")
13061 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13062 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13063 && !COMMUTATIVE_ARITH_P (operands[3])"
13064 "* return output_387_binary_op (insn, operands);"
13065 [(set (attr "type")
13066 (cond [(match_operand:MODEF 3 "mult_operator" "")
13067 (const_string "ssemul")
13068 (match_operand:MODEF 3 "div_operator" "")
13069 (const_string "ssediv")
13071 (const_string "sseadd")))
13072 (set_attr "isa" "noavx,avx")
13073 (set_attr "prefix" "orig,vex")
13074 (set_attr "mode" "<MODE>")])
13076 ;; This pattern is not fully shadowed by the pattern above.
13077 (define_insn "*fop_<mode>_1_i387"
13078 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13079 (match_operator:MODEF 3 "binary_fp_operator"
13080 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13081 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13082 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13083 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13084 && !COMMUTATIVE_ARITH_P (operands[3])
13085 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13086 "* return output_387_binary_op (insn, operands);"
13087 [(set (attr "type")
13088 (cond [(match_operand:MODEF 3 "mult_operator" "")
13089 (const_string "fmul")
13090 (match_operand:MODEF 3 "div_operator" "")
13091 (const_string "fdiv")
13093 (const_string "fop")))
13094 (set_attr "mode" "<MODE>")])
13096 ;; ??? Add SSE splitters for these!
13097 (define_insn "*fop_<MODEF:mode>_2_i387"
13098 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13099 (match_operator:MODEF 3 "binary_fp_operator"
13101 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13102 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13103 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13104 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13105 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13106 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13107 [(set (attr "type")
13108 (cond [(match_operand:MODEF 3 "mult_operator" "")
13109 (const_string "fmul")
13110 (match_operand:MODEF 3 "div_operator" "")
13111 (const_string "fdiv")
13113 (const_string "fop")))
13114 (set_attr "fp_int_src" "true")
13115 (set_attr "mode" "<SWI24:MODE>")])
13117 (define_insn "*fop_<MODEF:mode>_3_i387"
13118 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13119 (match_operator:MODEF 3 "binary_fp_operator"
13120 [(match_operand:MODEF 1 "register_operand" "0,0")
13122 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13123 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13124 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13125 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13126 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13127 [(set (attr "type")
13128 (cond [(match_operand:MODEF 3 "mult_operator" "")
13129 (const_string "fmul")
13130 (match_operand:MODEF 3 "div_operator" "")
13131 (const_string "fdiv")
13133 (const_string "fop")))
13134 (set_attr "fp_int_src" "true")
13135 (set_attr "mode" "<MODE>")])
13137 (define_insn "*fop_df_4_i387"
13138 [(set (match_operand:DF 0 "register_operand" "=f,f")
13139 (match_operator:DF 3 "binary_fp_operator"
13141 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13142 (match_operand:DF 2 "register_operand" "0,f")]))]
13143 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13144 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13145 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13146 "* return output_387_binary_op (insn, operands);"
13147 [(set (attr "type")
13148 (cond [(match_operand:DF 3 "mult_operator" "")
13149 (const_string "fmul")
13150 (match_operand:DF 3 "div_operator" "")
13151 (const_string "fdiv")
13153 (const_string "fop")))
13154 (set_attr "mode" "SF")])
13156 (define_insn "*fop_df_5_i387"
13157 [(set (match_operand:DF 0 "register_operand" "=f,f")
13158 (match_operator:DF 3 "binary_fp_operator"
13159 [(match_operand:DF 1 "register_operand" "0,f")
13161 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13162 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13163 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13164 "* return output_387_binary_op (insn, operands);"
13165 [(set (attr "type")
13166 (cond [(match_operand:DF 3 "mult_operator" "")
13167 (const_string "fmul")
13168 (match_operand:DF 3 "div_operator" "")
13169 (const_string "fdiv")
13171 (const_string "fop")))
13172 (set_attr "mode" "SF")])
13174 (define_insn "*fop_df_6_i387"
13175 [(set (match_operand:DF 0 "register_operand" "=f,f")
13176 (match_operator:DF 3 "binary_fp_operator"
13178 (match_operand:SF 1 "register_operand" "0,f"))
13180 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13181 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13182 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13183 "* return output_387_binary_op (insn, operands);"
13184 [(set (attr "type")
13185 (cond [(match_operand:DF 3 "mult_operator" "")
13186 (const_string "fmul")
13187 (match_operand:DF 3 "div_operator" "")
13188 (const_string "fdiv")
13190 (const_string "fop")))
13191 (set_attr "mode" "SF")])
13193 (define_insn "*fop_xf_comm_i387"
13194 [(set (match_operand:XF 0 "register_operand" "=f")
13195 (match_operator:XF 3 "binary_fp_operator"
13196 [(match_operand:XF 1 "register_operand" "%0")
13197 (match_operand:XF 2 "register_operand" "f")]))]
13199 && COMMUTATIVE_ARITH_P (operands[3])"
13200 "* return output_387_binary_op (insn, operands);"
13201 [(set (attr "type")
13202 (if_then_else (match_operand:XF 3 "mult_operator" "")
13203 (const_string "fmul")
13204 (const_string "fop")))
13205 (set_attr "mode" "XF")])
13207 (define_insn "*fop_xf_1_i387"
13208 [(set (match_operand:XF 0 "register_operand" "=f,f")
13209 (match_operator:XF 3 "binary_fp_operator"
13210 [(match_operand:XF 1 "register_operand" "0,f")
13211 (match_operand:XF 2 "register_operand" "f,0")]))]
13213 && !COMMUTATIVE_ARITH_P (operands[3])"
13214 "* return output_387_binary_op (insn, operands);"
13215 [(set (attr "type")
13216 (cond [(match_operand:XF 3 "mult_operator" "")
13217 (const_string "fmul")
13218 (match_operand:XF 3 "div_operator" "")
13219 (const_string "fdiv")
13221 (const_string "fop")))
13222 (set_attr "mode" "XF")])
13224 (define_insn "*fop_xf_2_i387"
13225 [(set (match_operand:XF 0 "register_operand" "=f,f")
13226 (match_operator:XF 3 "binary_fp_operator"
13228 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13229 (match_operand:XF 2 "register_operand" "0,0")]))]
13230 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13231 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13232 [(set (attr "type")
13233 (cond [(match_operand:XF 3 "mult_operator" "")
13234 (const_string "fmul")
13235 (match_operand:XF 3 "div_operator" "")
13236 (const_string "fdiv")
13238 (const_string "fop")))
13239 (set_attr "fp_int_src" "true")
13240 (set_attr "mode" "<MODE>")])
13242 (define_insn "*fop_xf_3_i387"
13243 [(set (match_operand:XF 0 "register_operand" "=f,f")
13244 (match_operator:XF 3 "binary_fp_operator"
13245 [(match_operand:XF 1 "register_operand" "0,0")
13247 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13248 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13249 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13250 [(set (attr "type")
13251 (cond [(match_operand:XF 3 "mult_operator" "")
13252 (const_string "fmul")
13253 (match_operand:XF 3 "div_operator" "")
13254 (const_string "fdiv")
13256 (const_string "fop")))
13257 (set_attr "fp_int_src" "true")
13258 (set_attr "mode" "<MODE>")])
13260 (define_insn "*fop_xf_4_i387"
13261 [(set (match_operand:XF 0 "register_operand" "=f,f")
13262 (match_operator:XF 3 "binary_fp_operator"
13264 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13265 (match_operand:XF 2 "register_operand" "0,f")]))]
13267 "* return output_387_binary_op (insn, operands);"
13268 [(set (attr "type")
13269 (cond [(match_operand:XF 3 "mult_operator" "")
13270 (const_string "fmul")
13271 (match_operand:XF 3 "div_operator" "")
13272 (const_string "fdiv")
13274 (const_string "fop")))
13275 (set_attr "mode" "<MODE>")])
13277 (define_insn "*fop_xf_5_i387"
13278 [(set (match_operand:XF 0 "register_operand" "=f,f")
13279 (match_operator:XF 3 "binary_fp_operator"
13280 [(match_operand:XF 1 "register_operand" "0,f")
13282 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13284 "* return output_387_binary_op (insn, operands);"
13285 [(set (attr "type")
13286 (cond [(match_operand:XF 3 "mult_operator" "")
13287 (const_string "fmul")
13288 (match_operand:XF 3 "div_operator" "")
13289 (const_string "fdiv")
13291 (const_string "fop")))
13292 (set_attr "mode" "<MODE>")])
13294 (define_insn "*fop_xf_6_i387"
13295 [(set (match_operand:XF 0 "register_operand" "=f,f")
13296 (match_operator:XF 3 "binary_fp_operator"
13298 (match_operand:MODEF 1 "register_operand" "0,f"))
13300 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13302 "* return output_387_binary_op (insn, operands);"
13303 [(set (attr "type")
13304 (cond [(match_operand:XF 3 "mult_operator" "")
13305 (const_string "fmul")
13306 (match_operand:XF 3 "div_operator" "")
13307 (const_string "fdiv")
13309 (const_string "fop")))
13310 (set_attr "mode" "<MODE>")])
13313 [(set (match_operand 0 "register_operand" "")
13314 (match_operator 3 "binary_fp_operator"
13315 [(float (match_operand:SWI24 1 "register_operand" ""))
13316 (match_operand 2 "register_operand" "")]))]
13318 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13319 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13322 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13323 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13324 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13325 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13326 GET_MODE (operands[3]),
13329 ix86_free_from_memory (GET_MODE (operands[1]));
13334 [(set (match_operand 0 "register_operand" "")
13335 (match_operator 3 "binary_fp_operator"
13336 [(match_operand 1 "register_operand" "")
13337 (float (match_operand:SWI24 2 "register_operand" ""))]))]
13339 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13340 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13343 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13344 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13345 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13346 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13347 GET_MODE (operands[3]),
13350 ix86_free_from_memory (GET_MODE (operands[2]));
13354 ;; FPU special functions.
13356 ;; This pattern implements a no-op XFmode truncation for
13357 ;; all fancy i386 XFmode math functions.
13359 (define_insn "truncxf<mode>2_i387_noop_unspec"
13360 [(set (match_operand:MODEF 0 "register_operand" "=f")
13361 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13362 UNSPEC_TRUNC_NOOP))]
13363 "TARGET_USE_FANCY_MATH_387"
13364 "* return output_387_reg_move (insn, operands);"
13365 [(set_attr "type" "fmov")
13366 (set_attr "mode" "<MODE>")])
13368 (define_insn "sqrtxf2"
13369 [(set (match_operand:XF 0 "register_operand" "=f")
13370 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13371 "TARGET_USE_FANCY_MATH_387"
13373 [(set_attr "type" "fpspc")
13374 (set_attr "mode" "XF")
13375 (set_attr "athlon_decode" "direct")
13376 (set_attr "amdfam10_decode" "direct")
13377 (set_attr "bdver1_decode" "direct")])
13379 (define_insn "sqrt_extend<mode>xf2_i387"
13380 [(set (match_operand:XF 0 "register_operand" "=f")
13383 (match_operand:MODEF 1 "register_operand" "0"))))]
13384 "TARGET_USE_FANCY_MATH_387"
13386 [(set_attr "type" "fpspc")
13387 (set_attr "mode" "XF")
13388 (set_attr "athlon_decode" "direct")
13389 (set_attr "amdfam10_decode" "direct")
13390 (set_attr "bdver1_decode" "direct")])
13392 (define_insn "*rsqrtsf2_sse"
13393 [(set (match_operand:SF 0 "register_operand" "=x")
13394 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13397 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13398 [(set_attr "type" "sse")
13399 (set_attr "atom_sse_attr" "rcp")
13400 (set_attr "prefix" "maybe_vex")
13401 (set_attr "mode" "SF")])
13403 (define_expand "rsqrtsf2"
13404 [(set (match_operand:SF 0 "register_operand" "")
13405 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13409 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13413 (define_insn "*sqrt<mode>2_sse"
13414 [(set (match_operand:MODEF 0 "register_operand" "=x")
13416 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13417 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13418 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13419 [(set_attr "type" "sse")
13420 (set_attr "atom_sse_attr" "sqrt")
13421 (set_attr "prefix" "maybe_vex")
13422 (set_attr "mode" "<MODE>")
13423 (set_attr "athlon_decode" "*")
13424 (set_attr "amdfam10_decode" "*")
13425 (set_attr "bdver1_decode" "*")])
13427 (define_expand "sqrt<mode>2"
13428 [(set (match_operand:MODEF 0 "register_operand" "")
13430 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13431 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13432 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13434 if (<MODE>mode == SFmode
13436 && TARGET_RECIP_SQRT
13437 && !optimize_function_for_size_p (cfun)
13438 && flag_finite_math_only && !flag_trapping_math
13439 && flag_unsafe_math_optimizations)
13441 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13445 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13447 rtx op0 = gen_reg_rtx (XFmode);
13448 rtx op1 = force_reg (<MODE>mode, operands[1]);
13450 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13451 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13456 (define_insn "fpremxf4_i387"
13457 [(set (match_operand:XF 0 "register_operand" "=f")
13458 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13459 (match_operand:XF 3 "register_operand" "1")]
13461 (set (match_operand:XF 1 "register_operand" "=u")
13462 (unspec:XF [(match_dup 2) (match_dup 3)]
13464 (set (reg:CCFP FPSR_REG)
13465 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13467 "TARGET_USE_FANCY_MATH_387"
13469 [(set_attr "type" "fpspc")
13470 (set_attr "mode" "XF")])
13472 (define_expand "fmodxf3"
13473 [(use (match_operand:XF 0 "register_operand" ""))
13474 (use (match_operand:XF 1 "general_operand" ""))
13475 (use (match_operand:XF 2 "general_operand" ""))]
13476 "TARGET_USE_FANCY_MATH_387"
13478 rtx label = gen_label_rtx ();
13480 rtx op1 = gen_reg_rtx (XFmode);
13481 rtx op2 = gen_reg_rtx (XFmode);
13483 emit_move_insn (op2, operands[2]);
13484 emit_move_insn (op1, operands[1]);
13486 emit_label (label);
13487 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13488 ix86_emit_fp_unordered_jump (label);
13489 LABEL_NUSES (label) = 1;
13491 emit_move_insn (operands[0], op1);
13495 (define_expand "fmod<mode>3"
13496 [(use (match_operand:MODEF 0 "register_operand" ""))
13497 (use (match_operand:MODEF 1 "general_operand" ""))
13498 (use (match_operand:MODEF 2 "general_operand" ""))]
13499 "TARGET_USE_FANCY_MATH_387"
13501 rtx (*gen_truncxf) (rtx, rtx);
13503 rtx label = gen_label_rtx ();
13505 rtx op1 = gen_reg_rtx (XFmode);
13506 rtx op2 = gen_reg_rtx (XFmode);
13508 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13509 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13511 emit_label (label);
13512 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13513 ix86_emit_fp_unordered_jump (label);
13514 LABEL_NUSES (label) = 1;
13516 /* Truncate the result properly for strict SSE math. */
13517 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13518 && !TARGET_MIX_SSE_I387)
13519 gen_truncxf = gen_truncxf<mode>2;
13521 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13523 emit_insn (gen_truncxf (operands[0], op1));
13527 (define_insn "fprem1xf4_i387"
13528 [(set (match_operand:XF 0 "register_operand" "=f")
13529 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13530 (match_operand:XF 3 "register_operand" "1")]
13532 (set (match_operand:XF 1 "register_operand" "=u")
13533 (unspec:XF [(match_dup 2) (match_dup 3)]
13535 (set (reg:CCFP FPSR_REG)
13536 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13538 "TARGET_USE_FANCY_MATH_387"
13540 [(set_attr "type" "fpspc")
13541 (set_attr "mode" "XF")])
13543 (define_expand "remainderxf3"
13544 [(use (match_operand:XF 0 "register_operand" ""))
13545 (use (match_operand:XF 1 "general_operand" ""))
13546 (use (match_operand:XF 2 "general_operand" ""))]
13547 "TARGET_USE_FANCY_MATH_387"
13549 rtx label = gen_label_rtx ();
13551 rtx op1 = gen_reg_rtx (XFmode);
13552 rtx op2 = gen_reg_rtx (XFmode);
13554 emit_move_insn (op2, operands[2]);
13555 emit_move_insn (op1, operands[1]);
13557 emit_label (label);
13558 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13559 ix86_emit_fp_unordered_jump (label);
13560 LABEL_NUSES (label) = 1;
13562 emit_move_insn (operands[0], op1);
13566 (define_expand "remainder<mode>3"
13567 [(use (match_operand:MODEF 0 "register_operand" ""))
13568 (use (match_operand:MODEF 1 "general_operand" ""))
13569 (use (match_operand:MODEF 2 "general_operand" ""))]
13570 "TARGET_USE_FANCY_MATH_387"
13572 rtx (*gen_truncxf) (rtx, rtx);
13574 rtx label = gen_label_rtx ();
13576 rtx op1 = gen_reg_rtx (XFmode);
13577 rtx op2 = gen_reg_rtx (XFmode);
13579 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13580 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13582 emit_label (label);
13584 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13585 ix86_emit_fp_unordered_jump (label);
13586 LABEL_NUSES (label) = 1;
13588 /* Truncate the result properly for strict SSE math. */
13589 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13590 && !TARGET_MIX_SSE_I387)
13591 gen_truncxf = gen_truncxf<mode>2;
13593 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13595 emit_insn (gen_truncxf (operands[0], op1));
13599 (define_insn "*sinxf2_i387"
13600 [(set (match_operand:XF 0 "register_operand" "=f")
13601 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13602 "TARGET_USE_FANCY_MATH_387
13603 && flag_unsafe_math_optimizations"
13605 [(set_attr "type" "fpspc")
13606 (set_attr "mode" "XF")])
13608 (define_insn "*sin_extend<mode>xf2_i387"
13609 [(set (match_operand:XF 0 "register_operand" "=f")
13610 (unspec:XF [(float_extend:XF
13611 (match_operand:MODEF 1 "register_operand" "0"))]
13613 "TARGET_USE_FANCY_MATH_387
13614 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13615 || TARGET_MIX_SSE_I387)
13616 && flag_unsafe_math_optimizations"
13618 [(set_attr "type" "fpspc")
13619 (set_attr "mode" "XF")])
13621 (define_insn "*cosxf2_i387"
13622 [(set (match_operand:XF 0 "register_operand" "=f")
13623 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13624 "TARGET_USE_FANCY_MATH_387
13625 && flag_unsafe_math_optimizations"
13627 [(set_attr "type" "fpspc")
13628 (set_attr "mode" "XF")])
13630 (define_insn "*cos_extend<mode>xf2_i387"
13631 [(set (match_operand:XF 0 "register_operand" "=f")
13632 (unspec:XF [(float_extend:XF
13633 (match_operand:MODEF 1 "register_operand" "0"))]
13635 "TARGET_USE_FANCY_MATH_387
13636 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13637 || TARGET_MIX_SSE_I387)
13638 && flag_unsafe_math_optimizations"
13640 [(set_attr "type" "fpspc")
13641 (set_attr "mode" "XF")])
13643 ;; When sincos pattern is defined, sin and cos builtin functions will be
13644 ;; expanded to sincos pattern with one of its outputs left unused.
13645 ;; CSE pass will figure out if two sincos patterns can be combined,
13646 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13647 ;; depending on the unused output.
13649 (define_insn "sincosxf3"
13650 [(set (match_operand:XF 0 "register_operand" "=f")
13651 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13652 UNSPEC_SINCOS_COS))
13653 (set (match_operand:XF 1 "register_operand" "=u")
13654 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13655 "TARGET_USE_FANCY_MATH_387
13656 && flag_unsafe_math_optimizations"
13658 [(set_attr "type" "fpspc")
13659 (set_attr "mode" "XF")])
13662 [(set (match_operand:XF 0 "register_operand" "")
13663 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13664 UNSPEC_SINCOS_COS))
13665 (set (match_operand:XF 1 "register_operand" "")
13666 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13667 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13668 && can_create_pseudo_p ()"
13669 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13672 [(set (match_operand:XF 0 "register_operand" "")
13673 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13674 UNSPEC_SINCOS_COS))
13675 (set (match_operand:XF 1 "register_operand" "")
13676 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13677 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13678 && can_create_pseudo_p ()"
13679 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13681 (define_insn "sincos_extend<mode>xf3_i387"
13682 [(set (match_operand:XF 0 "register_operand" "=f")
13683 (unspec:XF [(float_extend:XF
13684 (match_operand:MODEF 2 "register_operand" "0"))]
13685 UNSPEC_SINCOS_COS))
13686 (set (match_operand:XF 1 "register_operand" "=u")
13687 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13688 "TARGET_USE_FANCY_MATH_387
13689 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13690 || TARGET_MIX_SSE_I387)
13691 && flag_unsafe_math_optimizations"
13693 [(set_attr "type" "fpspc")
13694 (set_attr "mode" "XF")])
13697 [(set (match_operand:XF 0 "register_operand" "")
13698 (unspec:XF [(float_extend:XF
13699 (match_operand:MODEF 2 "register_operand" ""))]
13700 UNSPEC_SINCOS_COS))
13701 (set (match_operand:XF 1 "register_operand" "")
13702 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13703 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13704 && can_create_pseudo_p ()"
13705 [(set (match_dup 1)
13706 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13709 [(set (match_operand:XF 0 "register_operand" "")
13710 (unspec:XF [(float_extend:XF
13711 (match_operand:MODEF 2 "register_operand" ""))]
13712 UNSPEC_SINCOS_COS))
13713 (set (match_operand:XF 1 "register_operand" "")
13714 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13715 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13716 && can_create_pseudo_p ()"
13717 [(set (match_dup 0)
13718 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13720 (define_expand "sincos<mode>3"
13721 [(use (match_operand:MODEF 0 "register_operand" ""))
13722 (use (match_operand:MODEF 1 "register_operand" ""))
13723 (use (match_operand:MODEF 2 "register_operand" ""))]
13724 "TARGET_USE_FANCY_MATH_387
13725 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13726 || TARGET_MIX_SSE_I387)
13727 && flag_unsafe_math_optimizations"
13729 rtx op0 = gen_reg_rtx (XFmode);
13730 rtx op1 = gen_reg_rtx (XFmode);
13732 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13733 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13734 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13738 (define_insn "fptanxf4_i387"
13739 [(set (match_operand:XF 0 "register_operand" "=f")
13740 (match_operand:XF 3 "const_double_operand" "F"))
13741 (set (match_operand:XF 1 "register_operand" "=u")
13742 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13744 "TARGET_USE_FANCY_MATH_387
13745 && flag_unsafe_math_optimizations
13746 && standard_80387_constant_p (operands[3]) == 2"
13748 [(set_attr "type" "fpspc")
13749 (set_attr "mode" "XF")])
13751 (define_insn "fptan_extend<mode>xf4_i387"
13752 [(set (match_operand:MODEF 0 "register_operand" "=f")
13753 (match_operand:MODEF 3 "const_double_operand" "F"))
13754 (set (match_operand:XF 1 "register_operand" "=u")
13755 (unspec:XF [(float_extend:XF
13756 (match_operand:MODEF 2 "register_operand" "0"))]
13758 "TARGET_USE_FANCY_MATH_387
13759 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13760 || TARGET_MIX_SSE_I387)
13761 && flag_unsafe_math_optimizations
13762 && standard_80387_constant_p (operands[3]) == 2"
13764 [(set_attr "type" "fpspc")
13765 (set_attr "mode" "XF")])
13767 (define_expand "tanxf2"
13768 [(use (match_operand:XF 0 "register_operand" ""))
13769 (use (match_operand:XF 1 "register_operand" ""))]
13770 "TARGET_USE_FANCY_MATH_387
13771 && flag_unsafe_math_optimizations"
13773 rtx one = gen_reg_rtx (XFmode);
13774 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13776 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13780 (define_expand "tan<mode>2"
13781 [(use (match_operand:MODEF 0 "register_operand" ""))
13782 (use (match_operand:MODEF 1 "register_operand" ""))]
13783 "TARGET_USE_FANCY_MATH_387
13784 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13785 || TARGET_MIX_SSE_I387)
13786 && flag_unsafe_math_optimizations"
13788 rtx op0 = gen_reg_rtx (XFmode);
13790 rtx one = gen_reg_rtx (<MODE>mode);
13791 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13793 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13794 operands[1], op2));
13795 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13799 (define_insn "*fpatanxf3_i387"
13800 [(set (match_operand:XF 0 "register_operand" "=f")
13801 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13802 (match_operand:XF 2 "register_operand" "u")]
13804 (clobber (match_scratch:XF 3 "=2"))]
13805 "TARGET_USE_FANCY_MATH_387
13806 && flag_unsafe_math_optimizations"
13808 [(set_attr "type" "fpspc")
13809 (set_attr "mode" "XF")])
13811 (define_insn "fpatan_extend<mode>xf3_i387"
13812 [(set (match_operand:XF 0 "register_operand" "=f")
13813 (unspec:XF [(float_extend:XF
13814 (match_operand:MODEF 1 "register_operand" "0"))
13816 (match_operand:MODEF 2 "register_operand" "u"))]
13818 (clobber (match_scratch:XF 3 "=2"))]
13819 "TARGET_USE_FANCY_MATH_387
13820 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13821 || TARGET_MIX_SSE_I387)
13822 && flag_unsafe_math_optimizations"
13824 [(set_attr "type" "fpspc")
13825 (set_attr "mode" "XF")])
13827 (define_expand "atan2xf3"
13828 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13829 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13830 (match_operand:XF 1 "register_operand" "")]
13832 (clobber (match_scratch:XF 3 ""))])]
13833 "TARGET_USE_FANCY_MATH_387
13834 && flag_unsafe_math_optimizations")
13836 (define_expand "atan2<mode>3"
13837 [(use (match_operand:MODEF 0 "register_operand" ""))
13838 (use (match_operand:MODEF 1 "register_operand" ""))
13839 (use (match_operand:MODEF 2 "register_operand" ""))]
13840 "TARGET_USE_FANCY_MATH_387
13841 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13842 || TARGET_MIX_SSE_I387)
13843 && flag_unsafe_math_optimizations"
13845 rtx op0 = gen_reg_rtx (XFmode);
13847 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13848 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13852 (define_expand "atanxf2"
13853 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13854 (unspec:XF [(match_dup 2)
13855 (match_operand:XF 1 "register_operand" "")]
13857 (clobber (match_scratch:XF 3 ""))])]
13858 "TARGET_USE_FANCY_MATH_387
13859 && flag_unsafe_math_optimizations"
13861 operands[2] = gen_reg_rtx (XFmode);
13862 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13865 (define_expand "atan<mode>2"
13866 [(use (match_operand:MODEF 0 "register_operand" ""))
13867 (use (match_operand:MODEF 1 "register_operand" ""))]
13868 "TARGET_USE_FANCY_MATH_387
13869 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13870 || TARGET_MIX_SSE_I387)
13871 && flag_unsafe_math_optimizations"
13873 rtx op0 = gen_reg_rtx (XFmode);
13875 rtx op2 = gen_reg_rtx (<MODE>mode);
13876 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13878 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13879 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13883 (define_expand "asinxf2"
13884 [(set (match_dup 2)
13885 (mult:XF (match_operand:XF 1 "register_operand" "")
13887 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13888 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13889 (parallel [(set (match_operand:XF 0 "register_operand" "")
13890 (unspec:XF [(match_dup 5) (match_dup 1)]
13892 (clobber (match_scratch:XF 6 ""))])]
13893 "TARGET_USE_FANCY_MATH_387
13894 && flag_unsafe_math_optimizations"
13898 if (optimize_insn_for_size_p ())
13901 for (i = 2; i < 6; i++)
13902 operands[i] = gen_reg_rtx (XFmode);
13904 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13907 (define_expand "asin<mode>2"
13908 [(use (match_operand:MODEF 0 "register_operand" ""))
13909 (use (match_operand:MODEF 1 "general_operand" ""))]
13910 "TARGET_USE_FANCY_MATH_387
13911 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13912 || TARGET_MIX_SSE_I387)
13913 && flag_unsafe_math_optimizations"
13915 rtx op0 = gen_reg_rtx (XFmode);
13916 rtx op1 = gen_reg_rtx (XFmode);
13918 if (optimize_insn_for_size_p ())
13921 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13922 emit_insn (gen_asinxf2 (op0, op1));
13923 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13927 (define_expand "acosxf2"
13928 [(set (match_dup 2)
13929 (mult:XF (match_operand:XF 1 "register_operand" "")
13931 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13932 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13933 (parallel [(set (match_operand:XF 0 "register_operand" "")
13934 (unspec:XF [(match_dup 1) (match_dup 5)]
13936 (clobber (match_scratch:XF 6 ""))])]
13937 "TARGET_USE_FANCY_MATH_387
13938 && flag_unsafe_math_optimizations"
13942 if (optimize_insn_for_size_p ())
13945 for (i = 2; i < 6; i++)
13946 operands[i] = gen_reg_rtx (XFmode);
13948 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13951 (define_expand "acos<mode>2"
13952 [(use (match_operand:MODEF 0 "register_operand" ""))
13953 (use (match_operand:MODEF 1 "general_operand" ""))]
13954 "TARGET_USE_FANCY_MATH_387
13955 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13956 || TARGET_MIX_SSE_I387)
13957 && flag_unsafe_math_optimizations"
13959 rtx op0 = gen_reg_rtx (XFmode);
13960 rtx op1 = gen_reg_rtx (XFmode);
13962 if (optimize_insn_for_size_p ())
13965 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13966 emit_insn (gen_acosxf2 (op0, op1));
13967 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13971 (define_insn "fyl2xxf3_i387"
13972 [(set (match_operand:XF 0 "register_operand" "=f")
13973 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13974 (match_operand:XF 2 "register_operand" "u")]
13976 (clobber (match_scratch:XF 3 "=2"))]
13977 "TARGET_USE_FANCY_MATH_387
13978 && flag_unsafe_math_optimizations"
13980 [(set_attr "type" "fpspc")
13981 (set_attr "mode" "XF")])
13983 (define_insn "fyl2x_extend<mode>xf3_i387"
13984 [(set (match_operand:XF 0 "register_operand" "=f")
13985 (unspec:XF [(float_extend:XF
13986 (match_operand:MODEF 1 "register_operand" "0"))
13987 (match_operand:XF 2 "register_operand" "u")]
13989 (clobber (match_scratch:XF 3 "=2"))]
13990 "TARGET_USE_FANCY_MATH_387
13991 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13992 || TARGET_MIX_SSE_I387)
13993 && flag_unsafe_math_optimizations"
13995 [(set_attr "type" "fpspc")
13996 (set_attr "mode" "XF")])
13998 (define_expand "logxf2"
13999 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14000 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14001 (match_dup 2)] UNSPEC_FYL2X))
14002 (clobber (match_scratch:XF 3 ""))])]
14003 "TARGET_USE_FANCY_MATH_387
14004 && flag_unsafe_math_optimizations"
14006 operands[2] = gen_reg_rtx (XFmode);
14007 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14010 (define_expand "log<mode>2"
14011 [(use (match_operand:MODEF 0 "register_operand" ""))
14012 (use (match_operand:MODEF 1 "register_operand" ""))]
14013 "TARGET_USE_FANCY_MATH_387
14014 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14015 || TARGET_MIX_SSE_I387)
14016 && flag_unsafe_math_optimizations"
14018 rtx op0 = gen_reg_rtx (XFmode);
14020 rtx op2 = gen_reg_rtx (XFmode);
14021 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14023 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14024 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14028 (define_expand "log10xf2"
14029 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14030 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14031 (match_dup 2)] UNSPEC_FYL2X))
14032 (clobber (match_scratch:XF 3 ""))])]
14033 "TARGET_USE_FANCY_MATH_387
14034 && flag_unsafe_math_optimizations"
14036 operands[2] = gen_reg_rtx (XFmode);
14037 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14040 (define_expand "log10<mode>2"
14041 [(use (match_operand:MODEF 0 "register_operand" ""))
14042 (use (match_operand:MODEF 1 "register_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"
14048 rtx op0 = gen_reg_rtx (XFmode);
14050 rtx op2 = gen_reg_rtx (XFmode);
14051 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14053 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14054 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14058 (define_expand "log2xf2"
14059 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14060 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14061 (match_dup 2)] UNSPEC_FYL2X))
14062 (clobber (match_scratch:XF 3 ""))])]
14063 "TARGET_USE_FANCY_MATH_387
14064 && flag_unsafe_math_optimizations"
14066 operands[2] = gen_reg_rtx (XFmode);
14067 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14070 (define_expand "log2<mode>2"
14071 [(use (match_operand:MODEF 0 "register_operand" ""))
14072 (use (match_operand:MODEF 1 "register_operand" ""))]
14073 "TARGET_USE_FANCY_MATH_387
14074 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14075 || TARGET_MIX_SSE_I387)
14076 && flag_unsafe_math_optimizations"
14078 rtx op0 = gen_reg_rtx (XFmode);
14080 rtx op2 = gen_reg_rtx (XFmode);
14081 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14083 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14084 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14088 (define_insn "fyl2xp1xf3_i387"
14089 [(set (match_operand:XF 0 "register_operand" "=f")
14090 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14091 (match_operand:XF 2 "register_operand" "u")]
14093 (clobber (match_scratch:XF 3 "=2"))]
14094 "TARGET_USE_FANCY_MATH_387
14095 && flag_unsafe_math_optimizations"
14097 [(set_attr "type" "fpspc")
14098 (set_attr "mode" "XF")])
14100 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14101 [(set (match_operand:XF 0 "register_operand" "=f")
14102 (unspec:XF [(float_extend:XF
14103 (match_operand:MODEF 1 "register_operand" "0"))
14104 (match_operand:XF 2 "register_operand" "u")]
14106 (clobber (match_scratch:XF 3 "=2"))]
14107 "TARGET_USE_FANCY_MATH_387
14108 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14109 || TARGET_MIX_SSE_I387)
14110 && flag_unsafe_math_optimizations"
14112 [(set_attr "type" "fpspc")
14113 (set_attr "mode" "XF")])
14115 (define_expand "log1pxf2"
14116 [(use (match_operand:XF 0 "register_operand" ""))
14117 (use (match_operand:XF 1 "register_operand" ""))]
14118 "TARGET_USE_FANCY_MATH_387
14119 && flag_unsafe_math_optimizations"
14121 if (optimize_insn_for_size_p ())
14124 ix86_emit_i387_log1p (operands[0], operands[1]);
14128 (define_expand "log1p<mode>2"
14129 [(use (match_operand:MODEF 0 "register_operand" ""))
14130 (use (match_operand:MODEF 1 "register_operand" ""))]
14131 "TARGET_USE_FANCY_MATH_387
14132 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14133 || TARGET_MIX_SSE_I387)
14134 && flag_unsafe_math_optimizations"
14138 if (optimize_insn_for_size_p ())
14141 op0 = gen_reg_rtx (XFmode);
14143 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14145 ix86_emit_i387_log1p (op0, operands[1]);
14146 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14150 (define_insn "fxtractxf3_i387"
14151 [(set (match_operand:XF 0 "register_operand" "=f")
14152 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14153 UNSPEC_XTRACT_FRACT))
14154 (set (match_operand:XF 1 "register_operand" "=u")
14155 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14156 "TARGET_USE_FANCY_MATH_387
14157 && flag_unsafe_math_optimizations"
14159 [(set_attr "type" "fpspc")
14160 (set_attr "mode" "XF")])
14162 (define_insn "fxtract_extend<mode>xf3_i387"
14163 [(set (match_operand:XF 0 "register_operand" "=f")
14164 (unspec:XF [(float_extend:XF
14165 (match_operand:MODEF 2 "register_operand" "0"))]
14166 UNSPEC_XTRACT_FRACT))
14167 (set (match_operand:XF 1 "register_operand" "=u")
14168 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14169 "TARGET_USE_FANCY_MATH_387
14170 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14171 || TARGET_MIX_SSE_I387)
14172 && flag_unsafe_math_optimizations"
14174 [(set_attr "type" "fpspc")
14175 (set_attr "mode" "XF")])
14177 (define_expand "logbxf2"
14178 [(parallel [(set (match_dup 2)
14179 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14180 UNSPEC_XTRACT_FRACT))
14181 (set (match_operand:XF 0 "register_operand" "")
14182 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14183 "TARGET_USE_FANCY_MATH_387
14184 && flag_unsafe_math_optimizations"
14185 "operands[2] = gen_reg_rtx (XFmode);")
14187 (define_expand "logb<mode>2"
14188 [(use (match_operand:MODEF 0 "register_operand" ""))
14189 (use (match_operand:MODEF 1 "register_operand" ""))]
14190 "TARGET_USE_FANCY_MATH_387
14191 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14192 || TARGET_MIX_SSE_I387)
14193 && flag_unsafe_math_optimizations"
14195 rtx op0 = gen_reg_rtx (XFmode);
14196 rtx op1 = gen_reg_rtx (XFmode);
14198 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14199 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14203 (define_expand "ilogbxf2"
14204 [(use (match_operand:SI 0 "register_operand" ""))
14205 (use (match_operand:XF 1 "register_operand" ""))]
14206 "TARGET_USE_FANCY_MATH_387
14207 && flag_unsafe_math_optimizations"
14211 if (optimize_insn_for_size_p ())
14214 op0 = gen_reg_rtx (XFmode);
14215 op1 = gen_reg_rtx (XFmode);
14217 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14218 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14222 (define_expand "ilogb<mode>2"
14223 [(use (match_operand:SI 0 "register_operand" ""))
14224 (use (match_operand:MODEF 1 "register_operand" ""))]
14225 "TARGET_USE_FANCY_MATH_387
14226 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14227 || TARGET_MIX_SSE_I387)
14228 && flag_unsafe_math_optimizations"
14232 if (optimize_insn_for_size_p ())
14235 op0 = gen_reg_rtx (XFmode);
14236 op1 = gen_reg_rtx (XFmode);
14238 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14239 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14243 (define_insn "*f2xm1xf2_i387"
14244 [(set (match_operand:XF 0 "register_operand" "=f")
14245 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14247 "TARGET_USE_FANCY_MATH_387
14248 && flag_unsafe_math_optimizations"
14250 [(set_attr "type" "fpspc")
14251 (set_attr "mode" "XF")])
14253 (define_insn "*fscalexf4_i387"
14254 [(set (match_operand:XF 0 "register_operand" "=f")
14255 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14256 (match_operand:XF 3 "register_operand" "1")]
14257 UNSPEC_FSCALE_FRACT))
14258 (set (match_operand:XF 1 "register_operand" "=u")
14259 (unspec:XF [(match_dup 2) (match_dup 3)]
14260 UNSPEC_FSCALE_EXP))]
14261 "TARGET_USE_FANCY_MATH_387
14262 && flag_unsafe_math_optimizations"
14264 [(set_attr "type" "fpspc")
14265 (set_attr "mode" "XF")])
14267 (define_expand "expNcorexf3"
14268 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14269 (match_operand:XF 2 "register_operand" "")))
14270 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14271 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14272 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14273 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14274 (parallel [(set (match_operand:XF 0 "register_operand" "")
14275 (unspec:XF [(match_dup 8) (match_dup 4)]
14276 UNSPEC_FSCALE_FRACT))
14278 (unspec:XF [(match_dup 8) (match_dup 4)]
14279 UNSPEC_FSCALE_EXP))])]
14280 "TARGET_USE_FANCY_MATH_387
14281 && flag_unsafe_math_optimizations"
14285 if (optimize_insn_for_size_p ())
14288 for (i = 3; i < 10; i++)
14289 operands[i] = gen_reg_rtx (XFmode);
14291 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14294 (define_expand "expxf2"
14295 [(use (match_operand:XF 0 "register_operand" ""))
14296 (use (match_operand:XF 1 "register_operand" ""))]
14297 "TARGET_USE_FANCY_MATH_387
14298 && flag_unsafe_math_optimizations"
14302 if (optimize_insn_for_size_p ())
14305 op2 = gen_reg_rtx (XFmode);
14306 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14308 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14312 (define_expand "exp<mode>2"
14313 [(use (match_operand:MODEF 0 "register_operand" ""))
14314 (use (match_operand:MODEF 1 "general_operand" ""))]
14315 "TARGET_USE_FANCY_MATH_387
14316 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14317 || TARGET_MIX_SSE_I387)
14318 && flag_unsafe_math_optimizations"
14322 if (optimize_insn_for_size_p ())
14325 op0 = gen_reg_rtx (XFmode);
14326 op1 = gen_reg_rtx (XFmode);
14328 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14329 emit_insn (gen_expxf2 (op0, op1));
14330 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14334 (define_expand "exp10xf2"
14335 [(use (match_operand:XF 0 "register_operand" ""))
14336 (use (match_operand:XF 1 "register_operand" ""))]
14337 "TARGET_USE_FANCY_MATH_387
14338 && flag_unsafe_math_optimizations"
14342 if (optimize_insn_for_size_p ())
14345 op2 = gen_reg_rtx (XFmode);
14346 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14348 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14352 (define_expand "exp10<mode>2"
14353 [(use (match_operand:MODEF 0 "register_operand" ""))
14354 (use (match_operand:MODEF 1 "general_operand" ""))]
14355 "TARGET_USE_FANCY_MATH_387
14356 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14357 || TARGET_MIX_SSE_I387)
14358 && flag_unsafe_math_optimizations"
14362 if (optimize_insn_for_size_p ())
14365 op0 = gen_reg_rtx (XFmode);
14366 op1 = gen_reg_rtx (XFmode);
14368 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14369 emit_insn (gen_exp10xf2 (op0, op1));
14370 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14374 (define_expand "exp2xf2"
14375 [(use (match_operand:XF 0 "register_operand" ""))
14376 (use (match_operand:XF 1 "register_operand" ""))]
14377 "TARGET_USE_FANCY_MATH_387
14378 && flag_unsafe_math_optimizations"
14382 if (optimize_insn_for_size_p ())
14385 op2 = gen_reg_rtx (XFmode);
14386 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14388 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14392 (define_expand "exp2<mode>2"
14393 [(use (match_operand:MODEF 0 "register_operand" ""))
14394 (use (match_operand:MODEF 1 "general_operand" ""))]
14395 "TARGET_USE_FANCY_MATH_387
14396 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14397 || TARGET_MIX_SSE_I387)
14398 && flag_unsafe_math_optimizations"
14402 if (optimize_insn_for_size_p ())
14405 op0 = gen_reg_rtx (XFmode);
14406 op1 = gen_reg_rtx (XFmode);
14408 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14409 emit_insn (gen_exp2xf2 (op0, op1));
14410 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14414 (define_expand "expm1xf2"
14415 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14417 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14418 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14419 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14420 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14421 (parallel [(set (match_dup 7)
14422 (unspec:XF [(match_dup 6) (match_dup 4)]
14423 UNSPEC_FSCALE_FRACT))
14425 (unspec:XF [(match_dup 6) (match_dup 4)]
14426 UNSPEC_FSCALE_EXP))])
14427 (parallel [(set (match_dup 10)
14428 (unspec:XF [(match_dup 9) (match_dup 8)]
14429 UNSPEC_FSCALE_FRACT))
14430 (set (match_dup 11)
14431 (unspec:XF [(match_dup 9) (match_dup 8)]
14432 UNSPEC_FSCALE_EXP))])
14433 (set (match_dup 12) (minus:XF (match_dup 10)
14434 (float_extend:XF (match_dup 13))))
14435 (set (match_operand:XF 0 "register_operand" "")
14436 (plus:XF (match_dup 12) (match_dup 7)))]
14437 "TARGET_USE_FANCY_MATH_387
14438 && flag_unsafe_math_optimizations"
14442 if (optimize_insn_for_size_p ())
14445 for (i = 2; i < 13; i++)
14446 operands[i] = gen_reg_rtx (XFmode);
14449 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14451 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14454 (define_expand "expm1<mode>2"
14455 [(use (match_operand:MODEF 0 "register_operand" ""))
14456 (use (match_operand:MODEF 1 "general_operand" ""))]
14457 "TARGET_USE_FANCY_MATH_387
14458 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14459 || TARGET_MIX_SSE_I387)
14460 && flag_unsafe_math_optimizations"
14464 if (optimize_insn_for_size_p ())
14467 op0 = gen_reg_rtx (XFmode);
14468 op1 = gen_reg_rtx (XFmode);
14470 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14471 emit_insn (gen_expm1xf2 (op0, op1));
14472 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14476 (define_expand "ldexpxf3"
14477 [(set (match_dup 3)
14478 (float:XF (match_operand:SI 2 "register_operand" "")))
14479 (parallel [(set (match_operand:XF 0 " register_operand" "")
14480 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14482 UNSPEC_FSCALE_FRACT))
14484 (unspec:XF [(match_dup 1) (match_dup 3)]
14485 UNSPEC_FSCALE_EXP))])]
14486 "TARGET_USE_FANCY_MATH_387
14487 && flag_unsafe_math_optimizations"
14489 if (optimize_insn_for_size_p ())
14492 operands[3] = gen_reg_rtx (XFmode);
14493 operands[4] = gen_reg_rtx (XFmode);
14496 (define_expand "ldexp<mode>3"
14497 [(use (match_operand:MODEF 0 "register_operand" ""))
14498 (use (match_operand:MODEF 1 "general_operand" ""))
14499 (use (match_operand:SI 2 "register_operand" ""))]
14500 "TARGET_USE_FANCY_MATH_387
14501 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14502 || TARGET_MIX_SSE_I387)
14503 && flag_unsafe_math_optimizations"
14507 if (optimize_insn_for_size_p ())
14510 op0 = gen_reg_rtx (XFmode);
14511 op1 = gen_reg_rtx (XFmode);
14513 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14514 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14515 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14519 (define_expand "scalbxf3"
14520 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14521 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14522 (match_operand:XF 2 "register_operand" "")]
14523 UNSPEC_FSCALE_FRACT))
14525 (unspec:XF [(match_dup 1) (match_dup 2)]
14526 UNSPEC_FSCALE_EXP))])]
14527 "TARGET_USE_FANCY_MATH_387
14528 && flag_unsafe_math_optimizations"
14530 if (optimize_insn_for_size_p ())
14533 operands[3] = gen_reg_rtx (XFmode);
14536 (define_expand "scalb<mode>3"
14537 [(use (match_operand:MODEF 0 "register_operand" ""))
14538 (use (match_operand:MODEF 1 "general_operand" ""))
14539 (use (match_operand:MODEF 2 "general_operand" ""))]
14540 "TARGET_USE_FANCY_MATH_387
14541 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14542 || TARGET_MIX_SSE_I387)
14543 && flag_unsafe_math_optimizations"
14547 if (optimize_insn_for_size_p ())
14550 op0 = gen_reg_rtx (XFmode);
14551 op1 = gen_reg_rtx (XFmode);
14552 op2 = gen_reg_rtx (XFmode);
14554 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14555 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14556 emit_insn (gen_scalbxf3 (op0, op1, op2));
14557 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14561 (define_expand "significandxf2"
14562 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14563 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14564 UNSPEC_XTRACT_FRACT))
14566 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14567 "TARGET_USE_FANCY_MATH_387
14568 && flag_unsafe_math_optimizations"
14569 "operands[2] = gen_reg_rtx (XFmode);")
14571 (define_expand "significand<mode>2"
14572 [(use (match_operand:MODEF 0 "register_operand" ""))
14573 (use (match_operand:MODEF 1 "register_operand" ""))]
14574 "TARGET_USE_FANCY_MATH_387
14575 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14576 || TARGET_MIX_SSE_I387)
14577 && flag_unsafe_math_optimizations"
14579 rtx op0 = gen_reg_rtx (XFmode);
14580 rtx op1 = gen_reg_rtx (XFmode);
14582 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14583 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14588 (define_insn "sse4_1_round<mode>2"
14589 [(set (match_operand:MODEF 0 "register_operand" "=x")
14590 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14591 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14594 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14595 [(set_attr "type" "ssecvt")
14596 (set_attr "prefix_extra" "1")
14597 (set_attr "prefix" "maybe_vex")
14598 (set_attr "mode" "<MODE>")])
14600 (define_insn "rintxf2"
14601 [(set (match_operand:XF 0 "register_operand" "=f")
14602 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14604 "TARGET_USE_FANCY_MATH_387
14605 && flag_unsafe_math_optimizations"
14607 [(set_attr "type" "fpspc")
14608 (set_attr "mode" "XF")])
14610 (define_expand "rint<mode>2"
14611 [(use (match_operand:MODEF 0 "register_operand" ""))
14612 (use (match_operand:MODEF 1 "register_operand" ""))]
14613 "(TARGET_USE_FANCY_MATH_387
14614 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14615 || TARGET_MIX_SSE_I387)
14616 && flag_unsafe_math_optimizations)
14617 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14618 && !flag_trapping_math)"
14620 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14621 && !flag_trapping_math)
14624 emit_insn (gen_sse4_1_round<mode>2
14625 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14626 else if (optimize_insn_for_size_p ())
14629 ix86_expand_rint (operands[0], operands[1]);
14633 rtx op0 = gen_reg_rtx (XFmode);
14634 rtx op1 = gen_reg_rtx (XFmode);
14636 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14637 emit_insn (gen_rintxf2 (op0, op1));
14639 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14644 (define_expand "round<mode>2"
14645 [(match_operand:X87MODEF 0 "register_operand" "")
14646 (match_operand:X87MODEF 1 "nonimmediate_operand" "")]
14647 "(TARGET_USE_FANCY_MATH_387
14648 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14649 || TARGET_MIX_SSE_I387)
14650 && flag_unsafe_math_optimizations)
14651 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14652 && !flag_trapping_math && !flag_rounding_math)"
14654 if (optimize_insn_for_size_p ())
14657 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14658 && !flag_trapping_math && !flag_rounding_math)
14662 operands[1] = force_reg (<MODE>mode, operands[1]);
14663 ix86_expand_round_sse4 (operands[0], operands[1]);
14665 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14666 ix86_expand_round (operands[0], operands[1]);
14668 ix86_expand_rounddf_32 (operands[0], operands[1]);
14672 operands[1] = force_reg (<MODE>mode, operands[1]);
14673 ix86_emit_i387_round (operands[0], operands[1]);
14678 (define_insn_and_split "*fistdi2_1"
14679 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14680 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14682 "TARGET_USE_FANCY_MATH_387
14683 && can_create_pseudo_p ()"
14688 if (memory_operand (operands[0], VOIDmode))
14689 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14692 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14693 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14698 [(set_attr "type" "fpspc")
14699 (set_attr "mode" "DI")])
14701 (define_insn "fistdi2"
14702 [(set (match_operand:DI 0 "memory_operand" "=m")
14703 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14705 (clobber (match_scratch:XF 2 "=&1f"))]
14706 "TARGET_USE_FANCY_MATH_387"
14707 "* return output_fix_trunc (insn, operands, false);"
14708 [(set_attr "type" "fpspc")
14709 (set_attr "mode" "DI")])
14711 (define_insn "fistdi2_with_temp"
14712 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14713 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14715 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14716 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14717 "TARGET_USE_FANCY_MATH_387"
14719 [(set_attr "type" "fpspc")
14720 (set_attr "mode" "DI")])
14723 [(set (match_operand:DI 0 "register_operand" "")
14724 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14726 (clobber (match_operand:DI 2 "memory_operand" ""))
14727 (clobber (match_scratch 3 ""))]
14729 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14730 (clobber (match_dup 3))])
14731 (set (match_dup 0) (match_dup 2))])
14734 [(set (match_operand:DI 0 "memory_operand" "")
14735 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14737 (clobber (match_operand:DI 2 "memory_operand" ""))
14738 (clobber (match_scratch 3 ""))]
14740 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14741 (clobber (match_dup 3))])])
14743 (define_insn_and_split "*fist<mode>2_1"
14744 [(set (match_operand:SWI24 0 "register_operand" "")
14745 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14747 "TARGET_USE_FANCY_MATH_387
14748 && can_create_pseudo_p ()"
14753 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14754 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14758 [(set_attr "type" "fpspc")
14759 (set_attr "mode" "<MODE>")])
14761 (define_insn "fist<mode>2"
14762 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14763 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14765 "TARGET_USE_FANCY_MATH_387"
14766 "* return output_fix_trunc (insn, operands, false);"
14767 [(set_attr "type" "fpspc")
14768 (set_attr "mode" "<MODE>")])
14770 (define_insn "fist<mode>2_with_temp"
14771 [(set (match_operand:SWI24 0 "register_operand" "=r")
14772 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14774 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14775 "TARGET_USE_FANCY_MATH_387"
14777 [(set_attr "type" "fpspc")
14778 (set_attr "mode" "<MODE>")])
14781 [(set (match_operand:SWI24 0 "register_operand" "")
14782 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14784 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14786 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14787 (set (match_dup 0) (match_dup 2))])
14790 [(set (match_operand:SWI24 0 "memory_operand" "")
14791 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14793 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14795 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14797 (define_expand "lrintxf<mode>2"
14798 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14799 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14801 "TARGET_USE_FANCY_MATH_387")
14803 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14804 [(set (match_operand:SWI48x 0 "nonimmediate_operand" "")
14805 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")]
14806 UNSPEC_FIX_NOTRUNC))]
14807 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14808 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14810 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14811 [(match_operand:SWI248x 0 "nonimmediate_operand" "")
14812 (match_operand:X87MODEF 1 "register_operand" "")]
14813 "(TARGET_USE_FANCY_MATH_387
14814 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14815 || TARGET_MIX_SSE_I387)
14816 && flag_unsafe_math_optimizations)
14817 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14818 && <SWI248x:MODE>mode != HImode
14819 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14820 && !flag_trapping_math && !flag_rounding_math)"
14822 if (optimize_insn_for_size_p ())
14825 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14826 && <SWI248x:MODE>mode != HImode
14827 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14828 && !flag_trapping_math && !flag_rounding_math)
14829 ix86_expand_lround (operands[0], operands[1]);
14831 ix86_emit_i387_round (operands[0], operands[1]);
14835 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14836 (define_insn_and_split "frndintxf2_floor"
14837 [(set (match_operand:XF 0 "register_operand" "")
14838 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14839 UNSPEC_FRNDINT_FLOOR))
14840 (clobber (reg:CC FLAGS_REG))]
14841 "TARGET_USE_FANCY_MATH_387
14842 && flag_unsafe_math_optimizations
14843 && can_create_pseudo_p ()"
14848 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14850 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14851 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14853 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14854 operands[2], operands[3]));
14857 [(set_attr "type" "frndint")
14858 (set_attr "i387_cw" "floor")
14859 (set_attr "mode" "XF")])
14861 (define_insn "frndintxf2_floor_i387"
14862 [(set (match_operand:XF 0 "register_operand" "=f")
14863 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14864 UNSPEC_FRNDINT_FLOOR))
14865 (use (match_operand:HI 2 "memory_operand" "m"))
14866 (use (match_operand:HI 3 "memory_operand" "m"))]
14867 "TARGET_USE_FANCY_MATH_387
14868 && flag_unsafe_math_optimizations"
14869 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14870 [(set_attr "type" "frndint")
14871 (set_attr "i387_cw" "floor")
14872 (set_attr "mode" "XF")])
14874 (define_expand "floorxf2"
14875 [(use (match_operand:XF 0 "register_operand" ""))
14876 (use (match_operand:XF 1 "register_operand" ""))]
14877 "TARGET_USE_FANCY_MATH_387
14878 && flag_unsafe_math_optimizations"
14880 if (optimize_insn_for_size_p ())
14882 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14886 (define_expand "floor<mode>2"
14887 [(use (match_operand:MODEF 0 "register_operand" ""))
14888 (use (match_operand:MODEF 1 "register_operand" ""))]
14889 "(TARGET_USE_FANCY_MATH_387
14890 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14891 || TARGET_MIX_SSE_I387)
14892 && flag_unsafe_math_optimizations)
14893 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14894 && !flag_trapping_math)"
14896 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14897 && !flag_trapping_math)
14900 emit_insn (gen_sse4_1_round<mode>2
14901 (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14902 else if (optimize_insn_for_size_p ())
14904 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14905 ix86_expand_floorceil (operands[0], operands[1], true);
14907 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
14913 if (optimize_insn_for_size_p ())
14916 op0 = gen_reg_rtx (XFmode);
14917 op1 = gen_reg_rtx (XFmode);
14918 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14919 emit_insn (gen_frndintxf2_floor (op0, op1));
14921 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14926 (define_insn_and_split "*fist<mode>2_floor_1"
14927 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14928 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14929 UNSPEC_FIST_FLOOR))
14930 (clobber (reg:CC FLAGS_REG))]
14931 "TARGET_USE_FANCY_MATH_387
14932 && flag_unsafe_math_optimizations
14933 && can_create_pseudo_p ()"
14938 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14940 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14941 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14942 if (memory_operand (operands[0], VOIDmode))
14943 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14944 operands[2], operands[3]));
14947 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14948 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14949 operands[2], operands[3],
14954 [(set_attr "type" "fistp")
14955 (set_attr "i387_cw" "floor")
14956 (set_attr "mode" "<MODE>")])
14958 (define_insn "fistdi2_floor"
14959 [(set (match_operand:DI 0 "memory_operand" "=m")
14960 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14961 UNSPEC_FIST_FLOOR))
14962 (use (match_operand:HI 2 "memory_operand" "m"))
14963 (use (match_operand:HI 3 "memory_operand" "m"))
14964 (clobber (match_scratch:XF 4 "=&1f"))]
14965 "TARGET_USE_FANCY_MATH_387
14966 && flag_unsafe_math_optimizations"
14967 "* return output_fix_trunc (insn, operands, false);"
14968 [(set_attr "type" "fistp")
14969 (set_attr "i387_cw" "floor")
14970 (set_attr "mode" "DI")])
14972 (define_insn "fistdi2_floor_with_temp"
14973 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14974 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14975 UNSPEC_FIST_FLOOR))
14976 (use (match_operand:HI 2 "memory_operand" "m,m"))
14977 (use (match_operand:HI 3 "memory_operand" "m,m"))
14978 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14979 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14980 "TARGET_USE_FANCY_MATH_387
14981 && flag_unsafe_math_optimizations"
14983 [(set_attr "type" "fistp")
14984 (set_attr "i387_cw" "floor")
14985 (set_attr "mode" "DI")])
14988 [(set (match_operand:DI 0 "register_operand" "")
14989 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14990 UNSPEC_FIST_FLOOR))
14991 (use (match_operand:HI 2 "memory_operand" ""))
14992 (use (match_operand:HI 3 "memory_operand" ""))
14993 (clobber (match_operand:DI 4 "memory_operand" ""))
14994 (clobber (match_scratch 5 ""))]
14996 [(parallel [(set (match_dup 4)
14997 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14998 (use (match_dup 2))
14999 (use (match_dup 3))
15000 (clobber (match_dup 5))])
15001 (set (match_dup 0) (match_dup 4))])
15004 [(set (match_operand:DI 0 "memory_operand" "")
15005 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15006 UNSPEC_FIST_FLOOR))
15007 (use (match_operand:HI 2 "memory_operand" ""))
15008 (use (match_operand:HI 3 "memory_operand" ""))
15009 (clobber (match_operand:DI 4 "memory_operand" ""))
15010 (clobber (match_scratch 5 ""))]
15012 [(parallel [(set (match_dup 0)
15013 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15014 (use (match_dup 2))
15015 (use (match_dup 3))
15016 (clobber (match_dup 5))])])
15018 (define_insn "fist<mode>2_floor"
15019 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15020 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15021 UNSPEC_FIST_FLOOR))
15022 (use (match_operand:HI 2 "memory_operand" "m"))
15023 (use (match_operand:HI 3 "memory_operand" "m"))]
15024 "TARGET_USE_FANCY_MATH_387
15025 && flag_unsafe_math_optimizations"
15026 "* return output_fix_trunc (insn, operands, false);"
15027 [(set_attr "type" "fistp")
15028 (set_attr "i387_cw" "floor")
15029 (set_attr "mode" "<MODE>")])
15031 (define_insn "fist<mode>2_floor_with_temp"
15032 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15033 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15034 UNSPEC_FIST_FLOOR))
15035 (use (match_operand:HI 2 "memory_operand" "m,m"))
15036 (use (match_operand:HI 3 "memory_operand" "m,m"))
15037 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15038 "TARGET_USE_FANCY_MATH_387
15039 && flag_unsafe_math_optimizations"
15041 [(set_attr "type" "fistp")
15042 (set_attr "i387_cw" "floor")
15043 (set_attr "mode" "<MODE>")])
15046 [(set (match_operand:SWI24 0 "register_operand" "")
15047 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15048 UNSPEC_FIST_FLOOR))
15049 (use (match_operand:HI 2 "memory_operand" ""))
15050 (use (match_operand:HI 3 "memory_operand" ""))
15051 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15053 [(parallel [(set (match_dup 4)
15054 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15055 (use (match_dup 2))
15056 (use (match_dup 3))])
15057 (set (match_dup 0) (match_dup 4))])
15060 [(set (match_operand:SWI24 0 "memory_operand" "")
15061 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15062 UNSPEC_FIST_FLOOR))
15063 (use (match_operand:HI 2 "memory_operand" ""))
15064 (use (match_operand:HI 3 "memory_operand" ""))
15065 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15067 [(parallel [(set (match_dup 0)
15068 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15069 (use (match_dup 2))
15070 (use (match_dup 3))])])
15072 (define_expand "lfloorxf<mode>2"
15073 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15074 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15075 UNSPEC_FIST_FLOOR))
15076 (clobber (reg:CC FLAGS_REG))])]
15077 "TARGET_USE_FANCY_MATH_387
15078 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15079 && flag_unsafe_math_optimizations")
15081 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15082 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15083 (match_operand:MODEF 1 "register_operand" "")]
15084 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15085 && !flag_trapping_math"
15087 if (TARGET_64BIT && optimize_insn_for_size_p ())
15089 ix86_expand_lfloorceil (operands[0], operands[1], true);
15093 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15094 (define_insn_and_split "frndintxf2_ceil"
15095 [(set (match_operand:XF 0 "register_operand" "")
15096 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15097 UNSPEC_FRNDINT_CEIL))
15098 (clobber (reg:CC FLAGS_REG))]
15099 "TARGET_USE_FANCY_MATH_387
15100 && flag_unsafe_math_optimizations
15101 && can_create_pseudo_p ()"
15106 ix86_optimize_mode_switching[I387_CEIL] = 1;
15108 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15109 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15111 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15112 operands[2], operands[3]));
15115 [(set_attr "type" "frndint")
15116 (set_attr "i387_cw" "ceil")
15117 (set_attr "mode" "XF")])
15119 (define_insn "frndintxf2_ceil_i387"
15120 [(set (match_operand:XF 0 "register_operand" "=f")
15121 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15122 UNSPEC_FRNDINT_CEIL))
15123 (use (match_operand:HI 2 "memory_operand" "m"))
15124 (use (match_operand:HI 3 "memory_operand" "m"))]
15125 "TARGET_USE_FANCY_MATH_387
15126 && flag_unsafe_math_optimizations"
15127 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15128 [(set_attr "type" "frndint")
15129 (set_attr "i387_cw" "ceil")
15130 (set_attr "mode" "XF")])
15132 (define_expand "ceilxf2"
15133 [(use (match_operand:XF 0 "register_operand" ""))
15134 (use (match_operand:XF 1 "register_operand" ""))]
15135 "TARGET_USE_FANCY_MATH_387
15136 && flag_unsafe_math_optimizations"
15138 if (optimize_insn_for_size_p ())
15140 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15144 (define_expand "ceil<mode>2"
15145 [(use (match_operand:MODEF 0 "register_operand" ""))
15146 (use (match_operand:MODEF 1 "register_operand" ""))]
15147 "(TARGET_USE_FANCY_MATH_387
15148 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15149 || TARGET_MIX_SSE_I387)
15150 && flag_unsafe_math_optimizations)
15151 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15152 && !flag_trapping_math)"
15154 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15155 && !flag_trapping_math)
15158 emit_insn (gen_sse4_1_round<mode>2
15159 (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
15160 else if (optimize_insn_for_size_p ())
15162 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15163 ix86_expand_floorceil (operands[0], operands[1], false);
15165 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15171 if (optimize_insn_for_size_p ())
15174 op0 = gen_reg_rtx (XFmode);
15175 op1 = gen_reg_rtx (XFmode);
15176 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15177 emit_insn (gen_frndintxf2_ceil (op0, op1));
15179 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15184 (define_insn_and_split "*fist<mode>2_ceil_1"
15185 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15186 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15188 (clobber (reg:CC FLAGS_REG))]
15189 "TARGET_USE_FANCY_MATH_387
15190 && flag_unsafe_math_optimizations
15191 && can_create_pseudo_p ()"
15196 ix86_optimize_mode_switching[I387_CEIL] = 1;
15198 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15199 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15200 if (memory_operand (operands[0], VOIDmode))
15201 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15202 operands[2], operands[3]));
15205 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15206 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15207 operands[2], operands[3],
15212 [(set_attr "type" "fistp")
15213 (set_attr "i387_cw" "ceil")
15214 (set_attr "mode" "<MODE>")])
15216 (define_insn "fistdi2_ceil"
15217 [(set (match_operand:DI 0 "memory_operand" "=m")
15218 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15220 (use (match_operand:HI 2 "memory_operand" "m"))
15221 (use (match_operand:HI 3 "memory_operand" "m"))
15222 (clobber (match_scratch:XF 4 "=&1f"))]
15223 "TARGET_USE_FANCY_MATH_387
15224 && flag_unsafe_math_optimizations"
15225 "* return output_fix_trunc (insn, operands, false);"
15226 [(set_attr "type" "fistp")
15227 (set_attr "i387_cw" "ceil")
15228 (set_attr "mode" "DI")])
15230 (define_insn "fistdi2_ceil_with_temp"
15231 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15232 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15234 (use (match_operand:HI 2 "memory_operand" "m,m"))
15235 (use (match_operand:HI 3 "memory_operand" "m,m"))
15236 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15237 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15238 "TARGET_USE_FANCY_MATH_387
15239 && flag_unsafe_math_optimizations"
15241 [(set_attr "type" "fistp")
15242 (set_attr "i387_cw" "ceil")
15243 (set_attr "mode" "DI")])
15246 [(set (match_operand:DI 0 "register_operand" "")
15247 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15249 (use (match_operand:HI 2 "memory_operand" ""))
15250 (use (match_operand:HI 3 "memory_operand" ""))
15251 (clobber (match_operand:DI 4 "memory_operand" ""))
15252 (clobber (match_scratch 5 ""))]
15254 [(parallel [(set (match_dup 4)
15255 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15256 (use (match_dup 2))
15257 (use (match_dup 3))
15258 (clobber (match_dup 5))])
15259 (set (match_dup 0) (match_dup 4))])
15262 [(set (match_operand:DI 0 "memory_operand" "")
15263 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15265 (use (match_operand:HI 2 "memory_operand" ""))
15266 (use (match_operand:HI 3 "memory_operand" ""))
15267 (clobber (match_operand:DI 4 "memory_operand" ""))
15268 (clobber (match_scratch 5 ""))]
15270 [(parallel [(set (match_dup 0)
15271 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15272 (use (match_dup 2))
15273 (use (match_dup 3))
15274 (clobber (match_dup 5))])])
15276 (define_insn "fist<mode>2_ceil"
15277 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15278 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15280 (use (match_operand:HI 2 "memory_operand" "m"))
15281 (use (match_operand:HI 3 "memory_operand" "m"))]
15282 "TARGET_USE_FANCY_MATH_387
15283 && flag_unsafe_math_optimizations"
15284 "* return output_fix_trunc (insn, operands, false);"
15285 [(set_attr "type" "fistp")
15286 (set_attr "i387_cw" "ceil")
15287 (set_attr "mode" "<MODE>")])
15289 (define_insn "fist<mode>2_ceil_with_temp"
15290 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15291 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15293 (use (match_operand:HI 2 "memory_operand" "m,m"))
15294 (use (match_operand:HI 3 "memory_operand" "m,m"))
15295 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15296 "TARGET_USE_FANCY_MATH_387
15297 && flag_unsafe_math_optimizations"
15299 [(set_attr "type" "fistp")
15300 (set_attr "i387_cw" "ceil")
15301 (set_attr "mode" "<MODE>")])
15304 [(set (match_operand:SWI24 0 "register_operand" "")
15305 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15307 (use (match_operand:HI 2 "memory_operand" ""))
15308 (use (match_operand:HI 3 "memory_operand" ""))
15309 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15311 [(parallel [(set (match_dup 4)
15312 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15313 (use (match_dup 2))
15314 (use (match_dup 3))])
15315 (set (match_dup 0) (match_dup 4))])
15318 [(set (match_operand:SWI24 0 "memory_operand" "")
15319 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15321 (use (match_operand:HI 2 "memory_operand" ""))
15322 (use (match_operand:HI 3 "memory_operand" ""))
15323 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15325 [(parallel [(set (match_dup 0)
15326 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15327 (use (match_dup 2))
15328 (use (match_dup 3))])])
15330 (define_expand "lceilxf<mode>2"
15331 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15332 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15334 (clobber (reg:CC FLAGS_REG))])]
15335 "TARGET_USE_FANCY_MATH_387
15336 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15337 && flag_unsafe_math_optimizations")
15339 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15340 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15341 (match_operand:MODEF 1 "register_operand" "")]
15342 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15343 && !flag_trapping_math"
15345 ix86_expand_lfloorceil (operands[0], operands[1], false);
15349 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15350 (define_insn_and_split "frndintxf2_trunc"
15351 [(set (match_operand:XF 0 "register_operand" "")
15352 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15353 UNSPEC_FRNDINT_TRUNC))
15354 (clobber (reg:CC FLAGS_REG))]
15355 "TARGET_USE_FANCY_MATH_387
15356 && flag_unsafe_math_optimizations
15357 && can_create_pseudo_p ()"
15362 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15364 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15365 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15367 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15368 operands[2], operands[3]));
15371 [(set_attr "type" "frndint")
15372 (set_attr "i387_cw" "trunc")
15373 (set_attr "mode" "XF")])
15375 (define_insn "frndintxf2_trunc_i387"
15376 [(set (match_operand:XF 0 "register_operand" "=f")
15377 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15378 UNSPEC_FRNDINT_TRUNC))
15379 (use (match_operand:HI 2 "memory_operand" "m"))
15380 (use (match_operand:HI 3 "memory_operand" "m"))]
15381 "TARGET_USE_FANCY_MATH_387
15382 && flag_unsafe_math_optimizations"
15383 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15384 [(set_attr "type" "frndint")
15385 (set_attr "i387_cw" "trunc")
15386 (set_attr "mode" "XF")])
15388 (define_expand "btruncxf2"
15389 [(use (match_operand:XF 0 "register_operand" ""))
15390 (use (match_operand:XF 1 "register_operand" ""))]
15391 "TARGET_USE_FANCY_MATH_387
15392 && flag_unsafe_math_optimizations"
15394 if (optimize_insn_for_size_p ())
15396 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15400 (define_expand "btrunc<mode>2"
15401 [(use (match_operand:MODEF 0 "register_operand" ""))
15402 (use (match_operand:MODEF 1 "register_operand" ""))]
15403 "(TARGET_USE_FANCY_MATH_387
15404 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15405 || TARGET_MIX_SSE_I387)
15406 && flag_unsafe_math_optimizations)
15407 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15408 && !flag_trapping_math)"
15410 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15411 && !flag_trapping_math)
15414 emit_insn (gen_sse4_1_round<mode>2
15415 (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15416 else if (optimize_insn_for_size_p ())
15418 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15419 ix86_expand_trunc (operands[0], operands[1]);
15421 ix86_expand_truncdf_32 (operands[0], operands[1]);
15427 if (optimize_insn_for_size_p ())
15430 op0 = gen_reg_rtx (XFmode);
15431 op1 = gen_reg_rtx (XFmode);
15432 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15433 emit_insn (gen_frndintxf2_trunc (op0, op1));
15435 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15440 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15441 (define_insn_and_split "frndintxf2_mask_pm"
15442 [(set (match_operand:XF 0 "register_operand" "")
15443 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15444 UNSPEC_FRNDINT_MASK_PM))
15445 (clobber (reg:CC FLAGS_REG))]
15446 "TARGET_USE_FANCY_MATH_387
15447 && flag_unsafe_math_optimizations
15448 && can_create_pseudo_p ()"
15453 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15455 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15456 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15458 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15459 operands[2], operands[3]));
15462 [(set_attr "type" "frndint")
15463 (set_attr "i387_cw" "mask_pm")
15464 (set_attr "mode" "XF")])
15466 (define_insn "frndintxf2_mask_pm_i387"
15467 [(set (match_operand:XF 0 "register_operand" "=f")
15468 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15469 UNSPEC_FRNDINT_MASK_PM))
15470 (use (match_operand:HI 2 "memory_operand" "m"))
15471 (use (match_operand:HI 3 "memory_operand" "m"))]
15472 "TARGET_USE_FANCY_MATH_387
15473 && flag_unsafe_math_optimizations"
15474 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15475 [(set_attr "type" "frndint")
15476 (set_attr "i387_cw" "mask_pm")
15477 (set_attr "mode" "XF")])
15479 (define_expand "nearbyintxf2"
15480 [(use (match_operand:XF 0 "register_operand" ""))
15481 (use (match_operand:XF 1 "register_operand" ""))]
15482 "TARGET_USE_FANCY_MATH_387
15483 && flag_unsafe_math_optimizations"
15485 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15489 (define_expand "nearbyint<mode>2"
15490 [(use (match_operand:MODEF 0 "register_operand" ""))
15491 (use (match_operand:MODEF 1 "register_operand" ""))]
15492 "TARGET_USE_FANCY_MATH_387
15493 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15494 || TARGET_MIX_SSE_I387)
15495 && flag_unsafe_math_optimizations"
15497 rtx op0 = gen_reg_rtx (XFmode);
15498 rtx op1 = gen_reg_rtx (XFmode);
15500 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15501 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15503 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15507 (define_insn "fxam<mode>2_i387"
15508 [(set (match_operand:HI 0 "register_operand" "=a")
15510 [(match_operand:X87MODEF 1 "register_operand" "f")]
15512 "TARGET_USE_FANCY_MATH_387"
15513 "fxam\n\tfnstsw\t%0"
15514 [(set_attr "type" "multi")
15515 (set_attr "length" "4")
15516 (set_attr "unit" "i387")
15517 (set_attr "mode" "<MODE>")])
15519 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15520 [(set (match_operand:HI 0 "register_operand" "")
15522 [(match_operand:MODEF 1 "memory_operand" "")]
15524 "TARGET_USE_FANCY_MATH_387
15525 && can_create_pseudo_p ()"
15528 [(set (match_dup 2)(match_dup 1))
15530 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15532 operands[2] = gen_reg_rtx (<MODE>mode);
15534 MEM_VOLATILE_P (operands[1]) = 1;
15536 [(set_attr "type" "multi")
15537 (set_attr "unit" "i387")
15538 (set_attr "mode" "<MODE>")])
15540 (define_expand "isinfxf2"
15541 [(use (match_operand:SI 0 "register_operand" ""))
15542 (use (match_operand:XF 1 "register_operand" ""))]
15543 "TARGET_USE_FANCY_MATH_387
15544 && TARGET_C99_FUNCTIONS"
15546 rtx mask = GEN_INT (0x45);
15547 rtx val = GEN_INT (0x05);
15551 rtx scratch = gen_reg_rtx (HImode);
15552 rtx res = gen_reg_rtx (QImode);
15554 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15556 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15557 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15558 cond = gen_rtx_fmt_ee (EQ, QImode,
15559 gen_rtx_REG (CCmode, FLAGS_REG),
15561 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15562 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15566 (define_expand "isinf<mode>2"
15567 [(use (match_operand:SI 0 "register_operand" ""))
15568 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15569 "TARGET_USE_FANCY_MATH_387
15570 && TARGET_C99_FUNCTIONS
15571 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15573 rtx mask = GEN_INT (0x45);
15574 rtx val = GEN_INT (0x05);
15578 rtx scratch = gen_reg_rtx (HImode);
15579 rtx res = gen_reg_rtx (QImode);
15581 /* Remove excess precision by forcing value through memory. */
15582 if (memory_operand (operands[1], VOIDmode))
15583 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15586 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15588 emit_move_insn (temp, operands[1]);
15589 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15592 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15593 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15594 cond = gen_rtx_fmt_ee (EQ, QImode,
15595 gen_rtx_REG (CCmode, FLAGS_REG),
15597 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15598 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15602 (define_expand "signbitxf2"
15603 [(use (match_operand:SI 0 "register_operand" ""))
15604 (use (match_operand:XF 1 "register_operand" ""))]
15605 "TARGET_USE_FANCY_MATH_387"
15607 rtx scratch = gen_reg_rtx (HImode);
15609 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15610 emit_insn (gen_andsi3 (operands[0],
15611 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15615 (define_insn "movmsk_df"
15616 [(set (match_operand:SI 0 "register_operand" "=r")
15618 [(match_operand:DF 1 "register_operand" "x")]
15620 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15621 "%vmovmskpd\t{%1, %0|%0, %1}"
15622 [(set_attr "type" "ssemov")
15623 (set_attr "prefix" "maybe_vex")
15624 (set_attr "mode" "DF")])
15626 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15627 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15628 (define_expand "signbitdf2"
15629 [(use (match_operand:SI 0 "register_operand" ""))
15630 (use (match_operand:DF 1 "register_operand" ""))]
15631 "TARGET_USE_FANCY_MATH_387
15632 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15634 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15636 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15637 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15641 rtx scratch = gen_reg_rtx (HImode);
15643 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15644 emit_insn (gen_andsi3 (operands[0],
15645 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15650 (define_expand "signbitsf2"
15651 [(use (match_operand:SI 0 "register_operand" ""))
15652 (use (match_operand:SF 1 "register_operand" ""))]
15653 "TARGET_USE_FANCY_MATH_387
15654 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15656 rtx scratch = gen_reg_rtx (HImode);
15658 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15659 emit_insn (gen_andsi3 (operands[0],
15660 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15664 ;; Block operation instructions
15667 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15670 [(set_attr "length" "1")
15671 (set_attr "length_immediate" "0")
15672 (set_attr "modrm" "0")])
15674 (define_expand "movmem<mode>"
15675 [(use (match_operand:BLK 0 "memory_operand" ""))
15676 (use (match_operand:BLK 1 "memory_operand" ""))
15677 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15678 (use (match_operand:SWI48 3 "const_int_operand" ""))
15679 (use (match_operand:SI 4 "const_int_operand" ""))
15680 (use (match_operand:SI 5 "const_int_operand" ""))]
15683 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15684 operands[4], operands[5]))
15690 ;; Most CPUs don't like single string operations
15691 ;; Handle this case here to simplify previous expander.
15693 (define_expand "strmov"
15694 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15695 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15696 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15697 (clobber (reg:CC FLAGS_REG))])
15698 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15699 (clobber (reg:CC FLAGS_REG))])]
15702 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15704 /* If .md ever supports :P for Pmode, these can be directly
15705 in the pattern above. */
15706 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15707 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15709 /* Can't use this if the user has appropriated esi or edi. */
15710 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15711 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15713 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15714 operands[2], operands[3],
15715 operands[5], operands[6]));
15719 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15722 (define_expand "strmov_singleop"
15723 [(parallel [(set (match_operand 1 "memory_operand" "")
15724 (match_operand 3 "memory_operand" ""))
15725 (set (match_operand 0 "register_operand" "")
15726 (match_operand 4 "" ""))
15727 (set (match_operand 2 "register_operand" "")
15728 (match_operand 5 "" ""))])]
15730 "ix86_current_function_needs_cld = 1;")
15732 (define_insn "*strmovdi_rex_1"
15733 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15734 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15735 (set (match_operand:DI 0 "register_operand" "=D")
15736 (plus:DI (match_dup 2)
15738 (set (match_operand:DI 1 "register_operand" "=S")
15739 (plus:DI (match_dup 3)
15742 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15744 [(set_attr "type" "str")
15745 (set_attr "memory" "both")
15746 (set_attr "mode" "DI")])
15748 (define_insn "*strmovsi_1"
15749 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15750 (mem:SI (match_operand:P 3 "register_operand" "1")))
15751 (set (match_operand:P 0 "register_operand" "=D")
15752 (plus:P (match_dup 2)
15754 (set (match_operand:P 1 "register_operand" "=S")
15755 (plus:P (match_dup 3)
15757 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15759 [(set_attr "type" "str")
15760 (set_attr "memory" "both")
15761 (set_attr "mode" "SI")])
15763 (define_insn "*strmovhi_1"
15764 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15765 (mem:HI (match_operand:P 3 "register_operand" "1")))
15766 (set (match_operand:P 0 "register_operand" "=D")
15767 (plus:P (match_dup 2)
15769 (set (match_operand:P 1 "register_operand" "=S")
15770 (plus:P (match_dup 3)
15772 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15774 [(set_attr "type" "str")
15775 (set_attr "memory" "both")
15776 (set_attr "mode" "HI")])
15778 (define_insn "*strmovqi_1"
15779 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15780 (mem:QI (match_operand:P 3 "register_operand" "1")))
15781 (set (match_operand:P 0 "register_operand" "=D")
15782 (plus:P (match_dup 2)
15784 (set (match_operand:P 1 "register_operand" "=S")
15785 (plus:P (match_dup 3)
15787 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15789 [(set_attr "type" "str")
15790 (set_attr "memory" "both")
15791 (set (attr "prefix_rex")
15793 (match_test "<P:MODE>mode == DImode")
15795 (const_string "*")))
15796 (set_attr "mode" "QI")])
15798 (define_expand "rep_mov"
15799 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15800 (set (match_operand 0 "register_operand" "")
15801 (match_operand 5 "" ""))
15802 (set (match_operand 2 "register_operand" "")
15803 (match_operand 6 "" ""))
15804 (set (match_operand 1 "memory_operand" "")
15805 (match_operand 3 "memory_operand" ""))
15806 (use (match_dup 4))])]
15808 "ix86_current_function_needs_cld = 1;")
15810 (define_insn "*rep_movdi_rex64"
15811 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15812 (set (match_operand:DI 0 "register_operand" "=D")
15813 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15815 (match_operand:DI 3 "register_operand" "0")))
15816 (set (match_operand:DI 1 "register_operand" "=S")
15817 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15818 (match_operand:DI 4 "register_operand" "1")))
15819 (set (mem:BLK (match_dup 3))
15820 (mem:BLK (match_dup 4)))
15821 (use (match_dup 5))]
15823 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15825 [(set_attr "type" "str")
15826 (set_attr "prefix_rep" "1")
15827 (set_attr "memory" "both")
15828 (set_attr "mode" "DI")])
15830 (define_insn "*rep_movsi"
15831 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15832 (set (match_operand:P 0 "register_operand" "=D")
15833 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15835 (match_operand:P 3 "register_operand" "0")))
15836 (set (match_operand:P 1 "register_operand" "=S")
15837 (plus:P (ashift:P (match_dup 5) (const_int 2))
15838 (match_operand:P 4 "register_operand" "1")))
15839 (set (mem:BLK (match_dup 3))
15840 (mem:BLK (match_dup 4)))
15841 (use (match_dup 5))]
15842 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15843 "rep{%;} movs{l|d}"
15844 [(set_attr "type" "str")
15845 (set_attr "prefix_rep" "1")
15846 (set_attr "memory" "both")
15847 (set_attr "mode" "SI")])
15849 (define_insn "*rep_movqi"
15850 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15851 (set (match_operand:P 0 "register_operand" "=D")
15852 (plus:P (match_operand:P 3 "register_operand" "0")
15853 (match_operand:P 5 "register_operand" "2")))
15854 (set (match_operand:P 1 "register_operand" "=S")
15855 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15856 (set (mem:BLK (match_dup 3))
15857 (mem:BLK (match_dup 4)))
15858 (use (match_dup 5))]
15859 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15861 [(set_attr "type" "str")
15862 (set_attr "prefix_rep" "1")
15863 (set_attr "memory" "both")
15864 (set_attr "mode" "QI")])
15866 (define_expand "setmem<mode>"
15867 [(use (match_operand:BLK 0 "memory_operand" ""))
15868 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15869 (use (match_operand:QI 2 "nonmemory_operand" ""))
15870 (use (match_operand 3 "const_int_operand" ""))
15871 (use (match_operand:SI 4 "const_int_operand" ""))
15872 (use (match_operand:SI 5 "const_int_operand" ""))]
15875 if (ix86_expand_setmem (operands[0], operands[1],
15876 operands[2], operands[3],
15877 operands[4], operands[5]))
15883 ;; Most CPUs don't like single string operations
15884 ;; Handle this case here to simplify previous expander.
15886 (define_expand "strset"
15887 [(set (match_operand 1 "memory_operand" "")
15888 (match_operand 2 "register_operand" ""))
15889 (parallel [(set (match_operand 0 "register_operand" "")
15891 (clobber (reg:CC FLAGS_REG))])]
15894 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15895 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15897 /* If .md ever supports :P for Pmode, this can be directly
15898 in the pattern above. */
15899 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15900 GEN_INT (GET_MODE_SIZE (GET_MODE
15902 /* Can't use this if the user has appropriated eax or edi. */
15903 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15904 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15906 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15912 (define_expand "strset_singleop"
15913 [(parallel [(set (match_operand 1 "memory_operand" "")
15914 (match_operand 2 "register_operand" ""))
15915 (set (match_operand 0 "register_operand" "")
15916 (match_operand 3 "" ""))
15917 (unspec [(const_int 0)] UNSPEC_STOS)])]
15919 "ix86_current_function_needs_cld = 1;")
15921 (define_insn "*strsetdi_rex_1"
15922 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15923 (match_operand:DI 2 "register_operand" "a"))
15924 (set (match_operand:DI 0 "register_operand" "=D")
15925 (plus:DI (match_dup 1)
15927 (unspec [(const_int 0)] UNSPEC_STOS)]
15929 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15931 [(set_attr "type" "str")
15932 (set_attr "memory" "store")
15933 (set_attr "mode" "DI")])
15935 (define_insn "*strsetsi_1"
15936 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15937 (match_operand:SI 2 "register_operand" "a"))
15938 (set (match_operand:P 0 "register_operand" "=D")
15939 (plus:P (match_dup 1)
15941 (unspec [(const_int 0)] UNSPEC_STOS)]
15942 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15944 [(set_attr "type" "str")
15945 (set_attr "memory" "store")
15946 (set_attr "mode" "SI")])
15948 (define_insn "*strsethi_1"
15949 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15950 (match_operand:HI 2 "register_operand" "a"))
15951 (set (match_operand:P 0 "register_operand" "=D")
15952 (plus:P (match_dup 1)
15954 (unspec [(const_int 0)] UNSPEC_STOS)]
15955 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15957 [(set_attr "type" "str")
15958 (set_attr "memory" "store")
15959 (set_attr "mode" "HI")])
15961 (define_insn "*strsetqi_1"
15962 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15963 (match_operand:QI 2 "register_operand" "a"))
15964 (set (match_operand:P 0 "register_operand" "=D")
15965 (plus:P (match_dup 1)
15967 (unspec [(const_int 0)] UNSPEC_STOS)]
15968 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15970 [(set_attr "type" "str")
15971 (set_attr "memory" "store")
15972 (set (attr "prefix_rex")
15974 (match_test "<P:MODE>mode == DImode")
15976 (const_string "*")))
15977 (set_attr "mode" "QI")])
15979 (define_expand "rep_stos"
15980 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15981 (set (match_operand 0 "register_operand" "")
15982 (match_operand 4 "" ""))
15983 (set (match_operand 2 "memory_operand" "") (const_int 0))
15984 (use (match_operand 3 "register_operand" ""))
15985 (use (match_dup 1))])]
15987 "ix86_current_function_needs_cld = 1;")
15989 (define_insn "*rep_stosdi_rex64"
15990 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15991 (set (match_operand:DI 0 "register_operand" "=D")
15992 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15994 (match_operand:DI 3 "register_operand" "0")))
15995 (set (mem:BLK (match_dup 3))
15997 (use (match_operand:DI 2 "register_operand" "a"))
15998 (use (match_dup 4))]
16000 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16002 [(set_attr "type" "str")
16003 (set_attr "prefix_rep" "1")
16004 (set_attr "memory" "store")
16005 (set_attr "mode" "DI")])
16007 (define_insn "*rep_stossi"
16008 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16009 (set (match_operand:P 0 "register_operand" "=D")
16010 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16012 (match_operand:P 3 "register_operand" "0")))
16013 (set (mem:BLK (match_dup 3))
16015 (use (match_operand:SI 2 "register_operand" "a"))
16016 (use (match_dup 4))]
16017 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16018 "rep{%;} stos{l|d}"
16019 [(set_attr "type" "str")
16020 (set_attr "prefix_rep" "1")
16021 (set_attr "memory" "store")
16022 (set_attr "mode" "SI")])
16024 (define_insn "*rep_stosqi"
16025 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16026 (set (match_operand:P 0 "register_operand" "=D")
16027 (plus:P (match_operand:P 3 "register_operand" "0")
16028 (match_operand:P 4 "register_operand" "1")))
16029 (set (mem:BLK (match_dup 3))
16031 (use (match_operand:QI 2 "register_operand" "a"))
16032 (use (match_dup 4))]
16033 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16035 [(set_attr "type" "str")
16036 (set_attr "prefix_rep" "1")
16037 (set_attr "memory" "store")
16038 (set (attr "prefix_rex")
16040 (match_test "<P:MODE>mode == DImode")
16042 (const_string "*")))
16043 (set_attr "mode" "QI")])
16045 (define_expand "cmpstrnsi"
16046 [(set (match_operand:SI 0 "register_operand" "")
16047 (compare:SI (match_operand:BLK 1 "general_operand" "")
16048 (match_operand:BLK 2 "general_operand" "")))
16049 (use (match_operand 3 "general_operand" ""))
16050 (use (match_operand 4 "immediate_operand" ""))]
16053 rtx addr1, addr2, out, outlow, count, countreg, align;
16055 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16058 /* Can't use this if the user has appropriated ecx, esi or edi. */
16059 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16064 out = gen_reg_rtx (SImode);
16066 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16067 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16068 if (addr1 != XEXP (operands[1], 0))
16069 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16070 if (addr2 != XEXP (operands[2], 0))
16071 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16073 count = operands[3];
16074 countreg = ix86_zero_extend_to_Pmode (count);
16076 /* %%% Iff we are testing strict equality, we can use known alignment
16077 to good advantage. This may be possible with combine, particularly
16078 once cc0 is dead. */
16079 align = operands[4];
16081 if (CONST_INT_P (count))
16083 if (INTVAL (count) == 0)
16085 emit_move_insn (operands[0], const0_rtx);
16088 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16089 operands[1], operands[2]));
16093 rtx (*gen_cmp) (rtx, rtx);
16095 gen_cmp = (TARGET_64BIT
16096 ? gen_cmpdi_1 : gen_cmpsi_1);
16098 emit_insn (gen_cmp (countreg, countreg));
16099 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16100 operands[1], operands[2]));
16103 outlow = gen_lowpart (QImode, out);
16104 emit_insn (gen_cmpintqi (outlow));
16105 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16107 if (operands[0] != out)
16108 emit_move_insn (operands[0], out);
16113 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16115 (define_expand "cmpintqi"
16116 [(set (match_dup 1)
16117 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16119 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16120 (parallel [(set (match_operand:QI 0 "register_operand" "")
16121 (minus:QI (match_dup 1)
16123 (clobber (reg:CC FLAGS_REG))])]
16126 operands[1] = gen_reg_rtx (QImode);
16127 operands[2] = gen_reg_rtx (QImode);
16130 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16131 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16133 (define_expand "cmpstrnqi_nz_1"
16134 [(parallel [(set (reg:CC FLAGS_REG)
16135 (compare:CC (match_operand 4 "memory_operand" "")
16136 (match_operand 5 "memory_operand" "")))
16137 (use (match_operand 2 "register_operand" ""))
16138 (use (match_operand:SI 3 "immediate_operand" ""))
16139 (clobber (match_operand 0 "register_operand" ""))
16140 (clobber (match_operand 1 "register_operand" ""))
16141 (clobber (match_dup 2))])]
16143 "ix86_current_function_needs_cld = 1;")
16145 (define_insn "*cmpstrnqi_nz_1"
16146 [(set (reg:CC FLAGS_REG)
16147 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16148 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16149 (use (match_operand:P 6 "register_operand" "2"))
16150 (use (match_operand:SI 3 "immediate_operand" "i"))
16151 (clobber (match_operand:P 0 "register_operand" "=S"))
16152 (clobber (match_operand:P 1 "register_operand" "=D"))
16153 (clobber (match_operand:P 2 "register_operand" "=c"))]
16154 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16156 [(set_attr "type" "str")
16157 (set_attr "mode" "QI")
16158 (set (attr "prefix_rex")
16160 (match_test "<P:MODE>mode == DImode")
16162 (const_string "*")))
16163 (set_attr "prefix_rep" "1")])
16165 ;; The same, but the count is not known to not be zero.
16167 (define_expand "cmpstrnqi_1"
16168 [(parallel [(set (reg:CC FLAGS_REG)
16169 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16171 (compare:CC (match_operand 4 "memory_operand" "")
16172 (match_operand 5 "memory_operand" ""))
16174 (use (match_operand:SI 3 "immediate_operand" ""))
16175 (use (reg:CC FLAGS_REG))
16176 (clobber (match_operand 0 "register_operand" ""))
16177 (clobber (match_operand 1 "register_operand" ""))
16178 (clobber (match_dup 2))])]
16180 "ix86_current_function_needs_cld = 1;")
16182 (define_insn "*cmpstrnqi_1"
16183 [(set (reg:CC FLAGS_REG)
16184 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16186 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16187 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16189 (use (match_operand:SI 3 "immediate_operand" "i"))
16190 (use (reg:CC FLAGS_REG))
16191 (clobber (match_operand:P 0 "register_operand" "=S"))
16192 (clobber (match_operand:P 1 "register_operand" "=D"))
16193 (clobber (match_operand:P 2 "register_operand" "=c"))]
16194 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16196 [(set_attr "type" "str")
16197 (set_attr "mode" "QI")
16198 (set (attr "prefix_rex")
16200 (match_test "<P:MODE>mode == DImode")
16202 (const_string "*")))
16203 (set_attr "prefix_rep" "1")])
16205 (define_expand "strlen<mode>"
16206 [(set (match_operand:P 0 "register_operand" "")
16207 (unspec:P [(match_operand:BLK 1 "general_operand" "")
16208 (match_operand:QI 2 "immediate_operand" "")
16209 (match_operand 3 "immediate_operand" "")]
16213 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16219 (define_expand "strlenqi_1"
16220 [(parallel [(set (match_operand 0 "register_operand" "")
16221 (match_operand 2 "" ""))
16222 (clobber (match_operand 1 "register_operand" ""))
16223 (clobber (reg:CC FLAGS_REG))])]
16225 "ix86_current_function_needs_cld = 1;")
16227 (define_insn "*strlenqi_1"
16228 [(set (match_operand:P 0 "register_operand" "=&c")
16229 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16230 (match_operand:QI 2 "register_operand" "a")
16231 (match_operand:P 3 "immediate_operand" "i")
16232 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16233 (clobber (match_operand:P 1 "register_operand" "=D"))
16234 (clobber (reg:CC FLAGS_REG))]
16235 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16237 [(set_attr "type" "str")
16238 (set_attr "mode" "QI")
16239 (set (attr "prefix_rex")
16241 (match_test "<P:MODE>mode == DImode")
16243 (const_string "*")))
16244 (set_attr "prefix_rep" "1")])
16246 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16247 ;; handled in combine, but it is not currently up to the task.
16248 ;; When used for their truth value, the cmpstrn* expanders generate
16257 ;; The intermediate three instructions are unnecessary.
16259 ;; This one handles cmpstrn*_nz_1...
16262 (set (reg:CC FLAGS_REG)
16263 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16264 (mem:BLK (match_operand 5 "register_operand" ""))))
16265 (use (match_operand 6 "register_operand" ""))
16266 (use (match_operand:SI 3 "immediate_operand" ""))
16267 (clobber (match_operand 0 "register_operand" ""))
16268 (clobber (match_operand 1 "register_operand" ""))
16269 (clobber (match_operand 2 "register_operand" ""))])
16270 (set (match_operand:QI 7 "register_operand" "")
16271 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16272 (set (match_operand:QI 8 "register_operand" "")
16273 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16274 (set (reg FLAGS_REG)
16275 (compare (match_dup 7) (match_dup 8)))
16277 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16279 (set (reg:CC FLAGS_REG)
16280 (compare:CC (mem:BLK (match_dup 4))
16281 (mem:BLK (match_dup 5))))
16282 (use (match_dup 6))
16283 (use (match_dup 3))
16284 (clobber (match_dup 0))
16285 (clobber (match_dup 1))
16286 (clobber (match_dup 2))])])
16288 ;; ...and this one handles cmpstrn*_1.
16291 (set (reg:CC FLAGS_REG)
16292 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16294 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16295 (mem:BLK (match_operand 5 "register_operand" "")))
16297 (use (match_operand:SI 3 "immediate_operand" ""))
16298 (use (reg:CC FLAGS_REG))
16299 (clobber (match_operand 0 "register_operand" ""))
16300 (clobber (match_operand 1 "register_operand" ""))
16301 (clobber (match_operand 2 "register_operand" ""))])
16302 (set (match_operand:QI 7 "register_operand" "")
16303 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16304 (set (match_operand:QI 8 "register_operand" "")
16305 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16306 (set (reg FLAGS_REG)
16307 (compare (match_dup 7) (match_dup 8)))
16309 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16311 (set (reg:CC FLAGS_REG)
16312 (if_then_else:CC (ne (match_dup 6)
16314 (compare:CC (mem:BLK (match_dup 4))
16315 (mem:BLK (match_dup 5)))
16317 (use (match_dup 3))
16318 (use (reg:CC FLAGS_REG))
16319 (clobber (match_dup 0))
16320 (clobber (match_dup 1))
16321 (clobber (match_dup 2))])])
16323 ;; Conditional move instructions.
16325 (define_expand "mov<mode>cc"
16326 [(set (match_operand:SWIM 0 "register_operand" "")
16327 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16328 (match_operand:SWIM 2 "<general_operand>" "")
16329 (match_operand:SWIM 3 "<general_operand>" "")))]
16331 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16333 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16334 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16335 ;; So just document what we're doing explicitly.
16337 (define_expand "x86_mov<mode>cc_0_m1"
16339 [(set (match_operand:SWI48 0 "register_operand" "")
16340 (if_then_else:SWI48
16341 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16342 [(match_operand 1 "flags_reg_operand" "")
16346 (clobber (reg:CC FLAGS_REG))])])
16348 (define_insn "*x86_mov<mode>cc_0_m1"
16349 [(set (match_operand:SWI48 0 "register_operand" "=r")
16350 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16351 [(reg FLAGS_REG) (const_int 0)])
16354 (clobber (reg:CC FLAGS_REG))]
16356 "sbb{<imodesuffix>}\t%0, %0"
16357 ; Since we don't have the proper number of operands for an alu insn,
16358 ; fill in all the blanks.
16359 [(set_attr "type" "alu")
16360 (set_attr "use_carry" "1")
16361 (set_attr "pent_pair" "pu")
16362 (set_attr "memory" "none")
16363 (set_attr "imm_disp" "false")
16364 (set_attr "mode" "<MODE>")
16365 (set_attr "length_immediate" "0")])
16367 (define_insn "*x86_mov<mode>cc_0_m1_se"
16368 [(set (match_operand:SWI48 0 "register_operand" "=r")
16369 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16370 [(reg FLAGS_REG) (const_int 0)])
16373 (clobber (reg:CC FLAGS_REG))]
16375 "sbb{<imodesuffix>}\t%0, %0"
16376 [(set_attr "type" "alu")
16377 (set_attr "use_carry" "1")
16378 (set_attr "pent_pair" "pu")
16379 (set_attr "memory" "none")
16380 (set_attr "imm_disp" "false")
16381 (set_attr "mode" "<MODE>")
16382 (set_attr "length_immediate" "0")])
16384 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16385 [(set (match_operand:SWI48 0 "register_operand" "=r")
16386 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16387 [(reg FLAGS_REG) (const_int 0)])))
16388 (clobber (reg:CC FLAGS_REG))]
16390 "sbb{<imodesuffix>}\t%0, %0"
16391 [(set_attr "type" "alu")
16392 (set_attr "use_carry" "1")
16393 (set_attr "pent_pair" "pu")
16394 (set_attr "memory" "none")
16395 (set_attr "imm_disp" "false")
16396 (set_attr "mode" "<MODE>")
16397 (set_attr "length_immediate" "0")])
16399 (define_insn "*mov<mode>cc_noc"
16400 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16401 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16402 [(reg FLAGS_REG) (const_int 0)])
16403 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16404 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16405 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16407 cmov%O2%C1\t{%2, %0|%0, %2}
16408 cmov%O2%c1\t{%3, %0|%0, %3}"
16409 [(set_attr "type" "icmov")
16410 (set_attr "mode" "<MODE>")])
16412 (define_insn "*movqicc_noc"
16413 [(set (match_operand:QI 0 "register_operand" "=r,r")
16414 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16415 [(reg FLAGS_REG) (const_int 0)])
16416 (match_operand:QI 2 "register_operand" "r,0")
16417 (match_operand:QI 3 "register_operand" "0,r")))]
16418 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16420 [(set_attr "type" "icmov")
16421 (set_attr "mode" "QI")])
16424 [(set (match_operand 0 "register_operand")
16425 (if_then_else (match_operator 1 "ix86_comparison_operator"
16426 [(reg FLAGS_REG) (const_int 0)])
16427 (match_operand 2 "register_operand")
16428 (match_operand 3 "register_operand")))]
16429 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16430 && (GET_MODE (operands[0]) == QImode
16431 || GET_MODE (operands[0]) == HImode)
16432 && reload_completed"
16433 [(set (match_dup 0)
16434 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16436 operands[0] = gen_lowpart (SImode, operands[0]);
16437 operands[2] = gen_lowpart (SImode, operands[2]);
16438 operands[3] = gen_lowpart (SImode, operands[3]);
16441 (define_expand "mov<mode>cc"
16442 [(set (match_operand:X87MODEF 0 "register_operand" "")
16443 (if_then_else:X87MODEF
16444 (match_operand 1 "ix86_fp_comparison_operator" "")
16445 (match_operand:X87MODEF 2 "register_operand" "")
16446 (match_operand:X87MODEF 3 "register_operand" "")))]
16447 "(TARGET_80387 && TARGET_CMOVE)
16448 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16449 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16451 (define_insn "*movxfcc_1"
16452 [(set (match_operand:XF 0 "register_operand" "=f,f")
16453 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16454 [(reg FLAGS_REG) (const_int 0)])
16455 (match_operand:XF 2 "register_operand" "f,0")
16456 (match_operand:XF 3 "register_operand" "0,f")))]
16457 "TARGET_80387 && TARGET_CMOVE"
16459 fcmov%F1\t{%2, %0|%0, %2}
16460 fcmov%f1\t{%3, %0|%0, %3}"
16461 [(set_attr "type" "fcmov")
16462 (set_attr "mode" "XF")])
16464 (define_insn "*movdfcc_1_rex64"
16465 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16466 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16467 [(reg FLAGS_REG) (const_int 0)])
16468 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16469 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16470 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16471 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16473 fcmov%F1\t{%2, %0|%0, %2}
16474 fcmov%f1\t{%3, %0|%0, %3}
16475 cmov%O2%C1\t{%2, %0|%0, %2}
16476 cmov%O2%c1\t{%3, %0|%0, %3}"
16477 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16478 (set_attr "mode" "DF,DF,DI,DI")])
16480 (define_insn "*movdfcc_1"
16481 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16482 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16483 [(reg FLAGS_REG) (const_int 0)])
16484 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16485 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16486 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16487 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16489 fcmov%F1\t{%2, %0|%0, %2}
16490 fcmov%f1\t{%3, %0|%0, %3}
16493 [(set_attr "type" "fcmov,fcmov,multi,multi")
16494 (set_attr "mode" "DF,DF,DI,DI")])
16497 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16498 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16499 [(reg FLAGS_REG) (const_int 0)])
16500 (match_operand:DF 2 "nonimmediate_operand")
16501 (match_operand:DF 3 "nonimmediate_operand")))]
16502 "!TARGET_64BIT && reload_completed"
16503 [(set (match_dup 2)
16504 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16506 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16508 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16509 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16512 (define_insn "*movsfcc_1_387"
16513 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16514 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16515 [(reg FLAGS_REG) (const_int 0)])
16516 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16517 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16518 "TARGET_80387 && TARGET_CMOVE
16519 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16521 fcmov%F1\t{%2, %0|%0, %2}
16522 fcmov%f1\t{%3, %0|%0, %3}
16523 cmov%O2%C1\t{%2, %0|%0, %2}
16524 cmov%O2%c1\t{%3, %0|%0, %3}"
16525 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16526 (set_attr "mode" "SF,SF,SI,SI")])
16528 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16529 ;; the scalar versions to have only XMM registers as operands.
16531 ;; XOP conditional move
16532 (define_insn "*xop_pcmov_<mode>"
16533 [(set (match_operand:MODEF 0 "register_operand" "=x")
16534 (if_then_else:MODEF
16535 (match_operand:MODEF 1 "register_operand" "x")
16536 (match_operand:MODEF 2 "register_operand" "x")
16537 (match_operand:MODEF 3 "register_operand" "x")))]
16539 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16540 [(set_attr "type" "sse4arg")])
16542 ;; These versions of the min/max patterns are intentionally ignorant of
16543 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16544 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16545 ;; are undefined in this condition, we're certain this is correct.
16547 (define_insn "<code><mode>3"
16548 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16550 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16551 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16552 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16554 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16555 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16556 [(set_attr "isa" "noavx,avx")
16557 (set_attr "prefix" "orig,vex")
16558 (set_attr "type" "sseadd")
16559 (set_attr "mode" "<MODE>")])
16561 ;; These versions of the min/max patterns implement exactly the operations
16562 ;; min = (op1 < op2 ? op1 : op2)
16563 ;; max = (!(op1 < op2) ? op1 : op2)
16564 ;; Their operands are not commutative, and thus they may be used in the
16565 ;; presence of -0.0 and NaN.
16567 (define_insn "*ieee_smin<mode>3"
16568 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16570 [(match_operand:MODEF 1 "register_operand" "0,x")
16571 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16573 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16575 min<ssemodesuffix>\t{%2, %0|%0, %2}
16576 vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16577 [(set_attr "isa" "noavx,avx")
16578 (set_attr "prefix" "orig,vex")
16579 (set_attr "type" "sseadd")
16580 (set_attr "mode" "<MODE>")])
16582 (define_insn "*ieee_smax<mode>3"
16583 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16585 [(match_operand:MODEF 1 "register_operand" "0,x")
16586 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16588 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16590 max<ssemodesuffix>\t{%2, %0|%0, %2}
16591 vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16592 [(set_attr "isa" "noavx,avx")
16593 (set_attr "prefix" "orig,vex")
16594 (set_attr "type" "sseadd")
16595 (set_attr "mode" "<MODE>")])
16597 ;; Make two stack loads independent:
16599 ;; fld %st(0) -> fld bb
16600 ;; fmul bb fmul %st(1), %st
16602 ;; Actually we only match the last two instructions for simplicity.
16604 [(set (match_operand 0 "fp_register_operand" "")
16605 (match_operand 1 "fp_register_operand" ""))
16607 (match_operator 2 "binary_fp_operator"
16609 (match_operand 3 "memory_operand" "")]))]
16610 "REGNO (operands[0]) != REGNO (operands[1])"
16611 [(set (match_dup 0) (match_dup 3))
16612 (set (match_dup 0) (match_dup 4))]
16614 ;; The % modifier is not operational anymore in peephole2's, so we have to
16615 ;; swap the operands manually in the case of addition and multiplication.
16619 if (COMMUTATIVE_ARITH_P (operands[2]))
16620 op0 = operands[0], op1 = operands[1];
16622 op0 = operands[1], op1 = operands[0];
16624 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16625 GET_MODE (operands[2]),
16629 ;; Conditional addition patterns
16630 (define_expand "add<mode>cc"
16631 [(match_operand:SWI 0 "register_operand" "")
16632 (match_operand 1 "ordered_comparison_operator" "")
16633 (match_operand:SWI 2 "register_operand" "")
16634 (match_operand:SWI 3 "const_int_operand" "")]
16636 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16638 ;; Misc patterns (?)
16640 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16641 ;; Otherwise there will be nothing to keep
16643 ;; [(set (reg ebp) (reg esp))]
16644 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16645 ;; (clobber (eflags)]
16646 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16648 ;; in proper program order.
16650 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16651 [(set (match_operand:P 0 "register_operand" "=r,r")
16652 (plus:P (match_operand:P 1 "register_operand" "0,r")
16653 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16654 (clobber (reg:CC FLAGS_REG))
16655 (clobber (mem:BLK (scratch)))]
16658 switch (get_attr_type (insn))
16661 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16664 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16665 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16666 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16668 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16671 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16672 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16675 [(set (attr "type")
16676 (cond [(and (eq_attr "alternative" "0")
16677 (not (match_test "TARGET_OPT_AGU")))
16678 (const_string "alu")
16679 (match_operand:<MODE> 2 "const0_operand" "")
16680 (const_string "imov")
16682 (const_string "lea")))
16683 (set (attr "length_immediate")
16684 (cond [(eq_attr "type" "imov")
16686 (and (eq_attr "type" "alu")
16687 (match_operand 2 "const128_operand" ""))
16690 (const_string "*")))
16691 (set_attr "mode" "<MODE>")])
16693 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16694 [(set (match_operand:P 0 "register_operand" "=r")
16695 (minus:P (match_operand:P 1 "register_operand" "0")
16696 (match_operand:P 2 "register_operand" "r")))
16697 (clobber (reg:CC FLAGS_REG))
16698 (clobber (mem:BLK (scratch)))]
16700 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16701 [(set_attr "type" "alu")
16702 (set_attr "mode" "<MODE>")])
16704 (define_insn "allocate_stack_worker_probe_<mode>"
16705 [(set (match_operand:P 0 "register_operand" "=a")
16706 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16707 UNSPECV_STACK_PROBE))
16708 (clobber (reg:CC FLAGS_REG))]
16709 "ix86_target_stack_probe ()"
16710 "call\t___chkstk_ms"
16711 [(set_attr "type" "multi")
16712 (set_attr "length" "5")])
16714 (define_expand "allocate_stack"
16715 [(match_operand 0 "register_operand" "")
16716 (match_operand 1 "general_operand" "")]
16717 "ix86_target_stack_probe ()"
16721 #ifndef CHECK_STACK_LIMIT
16722 #define CHECK_STACK_LIMIT 0
16725 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16726 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16728 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16729 stack_pointer_rtx, 0, OPTAB_DIRECT);
16730 if (x != stack_pointer_rtx)
16731 emit_move_insn (stack_pointer_rtx, x);
16735 x = copy_to_mode_reg (Pmode, operands[1]);
16737 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16739 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16740 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16741 stack_pointer_rtx, 0, OPTAB_DIRECT);
16742 if (x != stack_pointer_rtx)
16743 emit_move_insn (stack_pointer_rtx, x);
16746 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16750 ;; Use IOR for stack probes, this is shorter.
16751 (define_expand "probe_stack"
16752 [(match_operand 0 "memory_operand" "")]
16755 rtx (*gen_ior3) (rtx, rtx, rtx);
16757 gen_ior3 = (GET_MODE (operands[0]) == DImode
16758 ? gen_iordi3 : gen_iorsi3);
16760 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16764 (define_insn "adjust_stack_and_probe<mode>"
16765 [(set (match_operand:P 0 "register_operand" "=r")
16766 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16767 UNSPECV_PROBE_STACK_RANGE))
16768 (set (reg:P SP_REG)
16769 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16770 (clobber (reg:CC FLAGS_REG))
16771 (clobber (mem:BLK (scratch)))]
16773 "* return output_adjust_stack_and_probe (operands[0]);"
16774 [(set_attr "type" "multi")])
16776 (define_insn "probe_stack_range<mode>"
16777 [(set (match_operand:P 0 "register_operand" "=r")
16778 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16779 (match_operand:P 2 "const_int_operand" "n")]
16780 UNSPECV_PROBE_STACK_RANGE))
16781 (clobber (reg:CC FLAGS_REG))]
16783 "* return output_probe_stack_range (operands[0], operands[2]);"
16784 [(set_attr "type" "multi")])
16786 (define_expand "builtin_setjmp_receiver"
16787 [(label_ref (match_operand 0 "" ""))]
16788 "!TARGET_64BIT && flag_pic"
16794 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16795 rtx label_rtx = gen_label_rtx ();
16796 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16797 xops[0] = xops[1] = picreg;
16798 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16799 ix86_expand_binary_operator (MINUS, SImode, xops);
16803 emit_insn (gen_set_got (pic_offset_table_rtx));
16807 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16810 [(set (match_operand 0 "register_operand" "")
16811 (match_operator 3 "promotable_binary_operator"
16812 [(match_operand 1 "register_operand" "")
16813 (match_operand 2 "aligned_operand" "")]))
16814 (clobber (reg:CC FLAGS_REG))]
16815 "! TARGET_PARTIAL_REG_STALL && reload_completed
16816 && ((GET_MODE (operands[0]) == HImode
16817 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16818 /* ??? next two lines just !satisfies_constraint_K (...) */
16819 || !CONST_INT_P (operands[2])
16820 || satisfies_constraint_K (operands[2])))
16821 || (GET_MODE (operands[0]) == QImode
16822 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16823 [(parallel [(set (match_dup 0)
16824 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16825 (clobber (reg:CC FLAGS_REG))])]
16827 operands[0] = gen_lowpart (SImode, operands[0]);
16828 operands[1] = gen_lowpart (SImode, operands[1]);
16829 if (GET_CODE (operands[3]) != ASHIFT)
16830 operands[2] = gen_lowpart (SImode, operands[2]);
16831 PUT_MODE (operands[3], SImode);
16834 ; Promote the QImode tests, as i386 has encoding of the AND
16835 ; instruction with 32-bit sign-extended immediate and thus the
16836 ; instruction size is unchanged, except in the %eax case for
16837 ; which it is increased by one byte, hence the ! optimize_size.
16839 [(set (match_operand 0 "flags_reg_operand" "")
16840 (match_operator 2 "compare_operator"
16841 [(and (match_operand 3 "aligned_operand" "")
16842 (match_operand 4 "const_int_operand" ""))
16844 (set (match_operand 1 "register_operand" "")
16845 (and (match_dup 3) (match_dup 4)))]
16846 "! TARGET_PARTIAL_REG_STALL && reload_completed
16847 && optimize_insn_for_speed_p ()
16848 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16849 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16850 /* Ensure that the operand will remain sign-extended immediate. */
16851 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16852 [(parallel [(set (match_dup 0)
16853 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16856 (and:SI (match_dup 3) (match_dup 4)))])]
16859 = gen_int_mode (INTVAL (operands[4])
16860 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16861 operands[1] = gen_lowpart (SImode, operands[1]);
16862 operands[3] = gen_lowpart (SImode, operands[3]);
16865 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16866 ; the TEST instruction with 32-bit sign-extended immediate and thus
16867 ; the instruction size would at least double, which is not what we
16868 ; want even with ! optimize_size.
16870 [(set (match_operand 0 "flags_reg_operand" "")
16871 (match_operator 1 "compare_operator"
16872 [(and (match_operand:HI 2 "aligned_operand" "")
16873 (match_operand:HI 3 "const_int_operand" ""))
16875 "! TARGET_PARTIAL_REG_STALL && reload_completed
16876 && ! TARGET_FAST_PREFIX
16877 && optimize_insn_for_speed_p ()
16878 /* Ensure that the operand will remain sign-extended immediate. */
16879 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16880 [(set (match_dup 0)
16881 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16885 = gen_int_mode (INTVAL (operands[3])
16886 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16887 operands[2] = gen_lowpart (SImode, operands[2]);
16891 [(set (match_operand 0 "register_operand" "")
16892 (neg (match_operand 1 "register_operand" "")))
16893 (clobber (reg:CC FLAGS_REG))]
16894 "! TARGET_PARTIAL_REG_STALL && reload_completed
16895 && (GET_MODE (operands[0]) == HImode
16896 || (GET_MODE (operands[0]) == QImode
16897 && (TARGET_PROMOTE_QImode
16898 || optimize_insn_for_size_p ())))"
16899 [(parallel [(set (match_dup 0)
16900 (neg:SI (match_dup 1)))
16901 (clobber (reg:CC FLAGS_REG))])]
16903 operands[0] = gen_lowpart (SImode, operands[0]);
16904 operands[1] = gen_lowpart (SImode, operands[1]);
16908 [(set (match_operand 0 "register_operand" "")
16909 (not (match_operand 1 "register_operand" "")))]
16910 "! TARGET_PARTIAL_REG_STALL && reload_completed
16911 && (GET_MODE (operands[0]) == HImode
16912 || (GET_MODE (operands[0]) == QImode
16913 && (TARGET_PROMOTE_QImode
16914 || optimize_insn_for_size_p ())))"
16915 [(set (match_dup 0)
16916 (not:SI (match_dup 1)))]
16918 operands[0] = gen_lowpart (SImode, operands[0]);
16919 operands[1] = gen_lowpart (SImode, operands[1]);
16922 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16923 ;; transform a complex memory operation into two memory to register operations.
16925 ;; Don't push memory operands
16927 [(set (match_operand:SWI 0 "push_operand" "")
16928 (match_operand:SWI 1 "memory_operand" ""))
16929 (match_scratch:SWI 2 "<r>")]
16930 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16931 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16932 [(set (match_dup 2) (match_dup 1))
16933 (set (match_dup 0) (match_dup 2))])
16935 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16938 [(set (match_operand:SF 0 "push_operand" "")
16939 (match_operand:SF 1 "memory_operand" ""))
16940 (match_scratch:SF 2 "r")]
16941 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16942 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16943 [(set (match_dup 2) (match_dup 1))
16944 (set (match_dup 0) (match_dup 2))])
16946 ;; Don't move an immediate directly to memory when the instruction
16949 [(match_scratch:SWI124 1 "<r>")
16950 (set (match_operand:SWI124 0 "memory_operand" "")
16952 "optimize_insn_for_speed_p ()
16953 && !TARGET_USE_MOV0
16954 && TARGET_SPLIT_LONG_MOVES
16955 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16956 && peep2_regno_dead_p (0, FLAGS_REG)"
16957 [(parallel [(set (match_dup 2) (const_int 0))
16958 (clobber (reg:CC FLAGS_REG))])
16959 (set (match_dup 0) (match_dup 1))]
16960 "operands[2] = gen_lowpart (SImode, operands[1]);")
16963 [(match_scratch:SWI124 2 "<r>")
16964 (set (match_operand:SWI124 0 "memory_operand" "")
16965 (match_operand:SWI124 1 "immediate_operand" ""))]
16966 "optimize_insn_for_speed_p ()
16967 && TARGET_SPLIT_LONG_MOVES
16968 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16969 [(set (match_dup 2) (match_dup 1))
16970 (set (match_dup 0) (match_dup 2))])
16972 ;; Don't compare memory with zero, load and use a test instead.
16974 [(set (match_operand 0 "flags_reg_operand" "")
16975 (match_operator 1 "compare_operator"
16976 [(match_operand:SI 2 "memory_operand" "")
16978 (match_scratch:SI 3 "r")]
16979 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16980 [(set (match_dup 3) (match_dup 2))
16981 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16983 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16984 ;; Don't split NOTs with a displacement operand, because resulting XOR
16985 ;; will not be pairable anyway.
16987 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16988 ;; represented using a modRM byte. The XOR replacement is long decoded,
16989 ;; so this split helps here as well.
16991 ;; Note: Can't do this as a regular split because we can't get proper
16992 ;; lifetime information then.
16995 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16996 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16997 "optimize_insn_for_speed_p ()
16998 && ((TARGET_NOT_UNPAIRABLE
16999 && (!MEM_P (operands[0])
17000 || !memory_displacement_operand (operands[0], <MODE>mode)))
17001 || (TARGET_NOT_VECTORMODE
17002 && long_memory_operand (operands[0], <MODE>mode)))
17003 && peep2_regno_dead_p (0, FLAGS_REG)"
17004 [(parallel [(set (match_dup 0)
17005 (xor:SWI124 (match_dup 1) (const_int -1)))
17006 (clobber (reg:CC FLAGS_REG))])])
17008 ;; Non pairable "test imm, reg" instructions can be translated to
17009 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17010 ;; byte opcode instead of two, have a short form for byte operands),
17011 ;; so do it for other CPUs as well. Given that the value was dead,
17012 ;; this should not create any new dependencies. Pass on the sub-word
17013 ;; versions if we're concerned about partial register stalls.
17016 [(set (match_operand 0 "flags_reg_operand" "")
17017 (match_operator 1 "compare_operator"
17018 [(and:SI (match_operand:SI 2 "register_operand" "")
17019 (match_operand:SI 3 "immediate_operand" ""))
17021 "ix86_match_ccmode (insn, CCNOmode)
17022 && (true_regnum (operands[2]) != AX_REG
17023 || satisfies_constraint_K (operands[3]))
17024 && peep2_reg_dead_p (1, operands[2])"
17026 [(set (match_dup 0)
17027 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17030 (and:SI (match_dup 2) (match_dup 3)))])])
17032 ;; We don't need to handle HImode case, because it will be promoted to SImode
17033 ;; on ! TARGET_PARTIAL_REG_STALL
17036 [(set (match_operand 0 "flags_reg_operand" "")
17037 (match_operator 1 "compare_operator"
17038 [(and:QI (match_operand:QI 2 "register_operand" "")
17039 (match_operand:QI 3 "immediate_operand" ""))
17041 "! TARGET_PARTIAL_REG_STALL
17042 && ix86_match_ccmode (insn, CCNOmode)
17043 && true_regnum (operands[2]) != AX_REG
17044 && peep2_reg_dead_p (1, operands[2])"
17046 [(set (match_dup 0)
17047 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17050 (and:QI (match_dup 2) (match_dup 3)))])])
17053 [(set (match_operand 0 "flags_reg_operand" "")
17054 (match_operator 1 "compare_operator"
17057 (match_operand 2 "ext_register_operand" "")
17060 (match_operand 3 "const_int_operand" ""))
17062 "! TARGET_PARTIAL_REG_STALL
17063 && ix86_match_ccmode (insn, CCNOmode)
17064 && true_regnum (operands[2]) != AX_REG
17065 && peep2_reg_dead_p (1, operands[2])"
17066 [(parallel [(set (match_dup 0)
17075 (set (zero_extract:SI (match_dup 2)
17083 (match_dup 3)))])])
17085 ;; Don't do logical operations with memory inputs.
17087 [(match_scratch:SI 2 "r")
17088 (parallel [(set (match_operand:SI 0 "register_operand" "")
17089 (match_operator:SI 3 "arith_or_logical_operator"
17091 (match_operand:SI 1 "memory_operand" "")]))
17092 (clobber (reg:CC FLAGS_REG))])]
17093 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17094 [(set (match_dup 2) (match_dup 1))
17095 (parallel [(set (match_dup 0)
17096 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17097 (clobber (reg:CC FLAGS_REG))])])
17100 [(match_scratch:SI 2 "r")
17101 (parallel [(set (match_operand:SI 0 "register_operand" "")
17102 (match_operator:SI 3 "arith_or_logical_operator"
17103 [(match_operand:SI 1 "memory_operand" "")
17105 (clobber (reg:CC FLAGS_REG))])]
17106 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17107 [(set (match_dup 2) (match_dup 1))
17108 (parallel [(set (match_dup 0)
17109 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17110 (clobber (reg:CC FLAGS_REG))])])
17112 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17113 ;; refers to the destination of the load!
17116 [(set (match_operand:SI 0 "register_operand" "")
17117 (match_operand:SI 1 "register_operand" ""))
17118 (parallel [(set (match_dup 0)
17119 (match_operator:SI 3 "commutative_operator"
17121 (match_operand:SI 2 "memory_operand" "")]))
17122 (clobber (reg:CC FLAGS_REG))])]
17123 "REGNO (operands[0]) != REGNO (operands[1])
17124 && GENERAL_REGNO_P (REGNO (operands[0]))
17125 && GENERAL_REGNO_P (REGNO (operands[1]))"
17126 [(set (match_dup 0) (match_dup 4))
17127 (parallel [(set (match_dup 0)
17128 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17129 (clobber (reg:CC FLAGS_REG))])]
17130 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17133 [(set (match_operand 0 "register_operand" "")
17134 (match_operand 1 "register_operand" ""))
17136 (match_operator 3 "commutative_operator"
17138 (match_operand 2 "memory_operand" "")]))]
17139 "REGNO (operands[0]) != REGNO (operands[1])
17140 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17141 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17142 [(set (match_dup 0) (match_dup 2))
17144 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17146 ; Don't do logical operations with memory outputs
17148 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17149 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17150 ; the same decoder scheduling characteristics as the original.
17153 [(match_scratch:SI 2 "r")
17154 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17155 (match_operator:SI 3 "arith_or_logical_operator"
17157 (match_operand:SI 1 "nonmemory_operand" "")]))
17158 (clobber (reg:CC FLAGS_REG))])]
17159 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17160 /* Do not split stack checking probes. */
17161 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17162 [(set (match_dup 2) (match_dup 0))
17163 (parallel [(set (match_dup 2)
17164 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17165 (clobber (reg:CC FLAGS_REG))])
17166 (set (match_dup 0) (match_dup 2))])
17169 [(match_scratch:SI 2 "r")
17170 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17171 (match_operator:SI 3 "arith_or_logical_operator"
17172 [(match_operand:SI 1 "nonmemory_operand" "")
17174 (clobber (reg:CC FLAGS_REG))])]
17175 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17176 /* Do not split stack checking probes. */
17177 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17178 [(set (match_dup 2) (match_dup 0))
17179 (parallel [(set (match_dup 2)
17180 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17181 (clobber (reg:CC FLAGS_REG))])
17182 (set (match_dup 0) (match_dup 2))])
17184 ;; Attempt to use arith or logical operations with memory outputs with
17185 ;; setting of flags.
17187 [(set (match_operand:SWI 0 "register_operand" "")
17188 (match_operand:SWI 1 "memory_operand" ""))
17189 (parallel [(set (match_dup 0)
17190 (match_operator:SWI 3 "plusminuslogic_operator"
17192 (match_operand:SWI 2 "<nonmemory_operand>" "")]))
17193 (clobber (reg:CC FLAGS_REG))])
17194 (set (match_dup 1) (match_dup 0))
17195 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17196 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17197 && peep2_reg_dead_p (4, operands[0])
17198 && !reg_overlap_mentioned_p (operands[0], operands[1])
17199 && (<MODE>mode != QImode
17200 || immediate_operand (operands[2], QImode)
17201 || q_regs_operand (operands[2], QImode))
17202 && ix86_match_ccmode (peep2_next_insn (3),
17203 (GET_CODE (operands[3]) == PLUS
17204 || GET_CODE (operands[3]) == MINUS)
17205 ? CCGOCmode : CCNOmode)"
17206 [(parallel [(set (match_dup 4) (match_dup 5))
17207 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17208 (match_dup 2)]))])]
17210 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17211 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17212 copy_rtx (operands[1]),
17213 copy_rtx (operands[2]));
17214 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17215 operands[5], const0_rtx);
17219 [(parallel [(set (match_operand:SWI 0 "register_operand" "")
17220 (match_operator:SWI 2 "plusminuslogic_operator"
17222 (match_operand:SWI 1 "memory_operand" "")]))
17223 (clobber (reg:CC FLAGS_REG))])
17224 (set (match_dup 1) (match_dup 0))
17225 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17226 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17227 && GET_CODE (operands[2]) != MINUS
17228 && peep2_reg_dead_p (3, operands[0])
17229 && !reg_overlap_mentioned_p (operands[0], operands[1])
17230 && ix86_match_ccmode (peep2_next_insn (2),
17231 GET_CODE (operands[2]) == PLUS
17232 ? CCGOCmode : CCNOmode)"
17233 [(parallel [(set (match_dup 3) (match_dup 4))
17234 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17235 (match_dup 0)]))])]
17237 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17238 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17239 copy_rtx (operands[1]),
17240 copy_rtx (operands[0]));
17241 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17242 operands[4], const0_rtx);
17246 [(set (match_operand:SWI12 0 "register_operand" "")
17247 (match_operand:SWI12 1 "memory_operand" ""))
17248 (parallel [(set (match_operand:SI 4 "register_operand" "")
17249 (match_operator:SI 3 "plusminuslogic_operator"
17251 (match_operand:SI 2 "nonmemory_operand" "")]))
17252 (clobber (reg:CC FLAGS_REG))])
17253 (set (match_dup 1) (match_dup 0))
17254 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17255 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17256 && REG_P (operands[0]) && REG_P (operands[4])
17257 && REGNO (operands[0]) == REGNO (operands[4])
17258 && peep2_reg_dead_p (4, operands[0])
17259 && (<MODE>mode != QImode
17260 || immediate_operand (operands[2], SImode)
17261 || q_regs_operand (operands[2], SImode))
17262 && !reg_overlap_mentioned_p (operands[0], operands[1])
17263 && ix86_match_ccmode (peep2_next_insn (3),
17264 (GET_CODE (operands[3]) == PLUS
17265 || GET_CODE (operands[3]) == MINUS)
17266 ? CCGOCmode : CCNOmode)"
17267 [(parallel [(set (match_dup 4) (match_dup 5))
17268 (set (match_dup 1) (match_dup 6))])]
17270 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17271 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17272 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17273 copy_rtx (operands[1]), operands[2]);
17274 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17275 operands[5], const0_rtx);
17276 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17277 copy_rtx (operands[1]),
17278 copy_rtx (operands[2]));
17281 ;; Attempt to always use XOR for zeroing registers.
17283 [(set (match_operand 0 "register_operand" "")
17284 (match_operand 1 "const0_operand" ""))]
17285 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17286 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17287 && GENERAL_REG_P (operands[0])
17288 && peep2_regno_dead_p (0, FLAGS_REG)"
17289 [(parallel [(set (match_dup 0) (const_int 0))
17290 (clobber (reg:CC FLAGS_REG))])]
17291 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17294 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17296 "(GET_MODE (operands[0]) == QImode
17297 || GET_MODE (operands[0]) == HImode)
17298 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17299 && peep2_regno_dead_p (0, FLAGS_REG)"
17300 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17301 (clobber (reg:CC FLAGS_REG))])])
17303 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17305 [(set (match_operand:SWI248 0 "register_operand" "")
17307 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17308 && peep2_regno_dead_p (0, FLAGS_REG)"
17309 [(parallel [(set (match_dup 0) (const_int -1))
17310 (clobber (reg:CC FLAGS_REG))])]
17312 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17313 operands[0] = gen_lowpart (SImode, operands[0]);
17316 ;; Attempt to convert simple lea to add/shift.
17317 ;; These can be created by move expanders.
17320 [(set (match_operand:SWI48 0 "register_operand" "")
17321 (plus:SWI48 (match_dup 0)
17322 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17323 "peep2_regno_dead_p (0, FLAGS_REG)"
17324 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17325 (clobber (reg:CC FLAGS_REG))])])
17328 [(set (match_operand:SI 0 "register_operand" "")
17329 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17330 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17332 && peep2_regno_dead_p (0, FLAGS_REG)
17333 && REGNO (operands[0]) == REGNO (operands[1])"
17334 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17335 (clobber (reg:CC FLAGS_REG))])]
17336 "operands[2] = gen_lowpart (SImode, operands[2]);")
17339 [(set (match_operand:SWI48 0 "register_operand" "")
17340 (mult:SWI48 (match_dup 0)
17341 (match_operand:SWI48 1 "const_int_operand" "")))]
17342 "exact_log2 (INTVAL (operands[1])) >= 0
17343 && peep2_regno_dead_p (0, FLAGS_REG)"
17344 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17345 (clobber (reg:CC FLAGS_REG))])]
17346 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17349 [(set (match_operand:SI 0 "register_operand" "")
17350 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17351 (match_operand:DI 2 "const_int_operand" "")) 0))]
17353 && exact_log2 (INTVAL (operands[2])) >= 0
17354 && REGNO (operands[0]) == REGNO (operands[1])
17355 && peep2_regno_dead_p (0, FLAGS_REG)"
17356 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17357 (clobber (reg:CC FLAGS_REG))])]
17358 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17360 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17361 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17362 ;; On many CPUs it is also faster, since special hardware to avoid esp
17363 ;; dependencies is present.
17365 ;; While some of these conversions may be done using splitters, we use
17366 ;; peepholes in order to allow combine_stack_adjustments pass to see
17367 ;; nonobfuscated RTL.
17369 ;; Convert prologue esp subtractions to push.
17370 ;; We need register to push. In order to keep verify_flow_info happy we have
17372 ;; - use scratch and clobber it in order to avoid dependencies
17373 ;; - use already live register
17374 ;; We can't use the second way right now, since there is no reliable way how to
17375 ;; verify that given register is live. First choice will also most likely in
17376 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17377 ;; call clobbered registers are dead. We may want to use base pointer as an
17378 ;; alternative when no register is available later.
17381 [(match_scratch:P 1 "r")
17382 (parallel [(set (reg:P SP_REG)
17383 (plus:P (reg:P SP_REG)
17384 (match_operand:P 0 "const_int_operand" "")))
17385 (clobber (reg:CC FLAGS_REG))
17386 (clobber (mem:BLK (scratch)))])]
17387 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17388 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17389 [(clobber (match_dup 1))
17390 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17391 (clobber (mem:BLK (scratch)))])])
17394 [(match_scratch:P 1 "r")
17395 (parallel [(set (reg:P SP_REG)
17396 (plus:P (reg:P SP_REG)
17397 (match_operand:P 0 "const_int_operand" "")))
17398 (clobber (reg:CC FLAGS_REG))
17399 (clobber (mem:BLK (scratch)))])]
17400 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17401 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17402 [(clobber (match_dup 1))
17403 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17404 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17405 (clobber (mem:BLK (scratch)))])])
17407 ;; Convert esp subtractions to push.
17409 [(match_scratch:P 1 "r")
17410 (parallel [(set (reg:P SP_REG)
17411 (plus:P (reg:P SP_REG)
17412 (match_operand:P 0 "const_int_operand" "")))
17413 (clobber (reg:CC FLAGS_REG))])]
17414 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17415 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17416 [(clobber (match_dup 1))
17417 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17420 [(match_scratch:P 1 "r")
17421 (parallel [(set (reg:P SP_REG)
17422 (plus:P (reg:P SP_REG)
17423 (match_operand:P 0 "const_int_operand" "")))
17424 (clobber (reg:CC FLAGS_REG))])]
17425 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17426 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17427 [(clobber (match_dup 1))
17428 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17429 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17431 ;; Convert epilogue deallocator to pop.
17433 [(match_scratch:P 1 "r")
17434 (parallel [(set (reg:P SP_REG)
17435 (plus:P (reg:P SP_REG)
17436 (match_operand:P 0 "const_int_operand" "")))
17437 (clobber (reg:CC FLAGS_REG))
17438 (clobber (mem:BLK (scratch)))])]
17439 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17440 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17441 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17442 (clobber (mem:BLK (scratch)))])])
17444 ;; Two pops case is tricky, since pop causes dependency
17445 ;; on destination register. We use two registers if available.
17447 [(match_scratch:P 1 "r")
17448 (match_scratch:P 2 "r")
17449 (parallel [(set (reg:P SP_REG)
17450 (plus:P (reg:P SP_REG)
17451 (match_operand:P 0 "const_int_operand" "")))
17452 (clobber (reg:CC FLAGS_REG))
17453 (clobber (mem:BLK (scratch)))])]
17454 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17455 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17456 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17457 (clobber (mem:BLK (scratch)))])
17458 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17461 [(match_scratch:P 1 "r")
17462 (parallel [(set (reg:P SP_REG)
17463 (plus:P (reg:P SP_REG)
17464 (match_operand:P 0 "const_int_operand" "")))
17465 (clobber (reg:CC FLAGS_REG))
17466 (clobber (mem:BLK (scratch)))])]
17467 "optimize_insn_for_size_p ()
17468 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17469 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17470 (clobber (mem:BLK (scratch)))])
17471 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17473 ;; Convert esp additions to pop.
17475 [(match_scratch:P 1 "r")
17476 (parallel [(set (reg:P SP_REG)
17477 (plus:P (reg:P SP_REG)
17478 (match_operand:P 0 "const_int_operand" "")))
17479 (clobber (reg:CC FLAGS_REG))])]
17480 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17481 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17483 ;; Two pops case is tricky, since pop causes dependency
17484 ;; on destination register. We use two registers if available.
17486 [(match_scratch:P 1 "r")
17487 (match_scratch:P 2 "r")
17488 (parallel [(set (reg:P SP_REG)
17489 (plus:P (reg:P SP_REG)
17490 (match_operand:P 0 "const_int_operand" "")))
17491 (clobber (reg:CC FLAGS_REG))])]
17492 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17493 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17494 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17497 [(match_scratch:P 1 "r")
17498 (parallel [(set (reg:P SP_REG)
17499 (plus:P (reg:P SP_REG)
17500 (match_operand:P 0 "const_int_operand" "")))
17501 (clobber (reg:CC FLAGS_REG))])]
17502 "optimize_insn_for_size_p ()
17503 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17504 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17505 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17507 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17508 ;; required and register dies. Similarly for 128 to -128.
17510 [(set (match_operand 0 "flags_reg_operand" "")
17511 (match_operator 1 "compare_operator"
17512 [(match_operand 2 "register_operand" "")
17513 (match_operand 3 "const_int_operand" "")]))]
17514 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17515 && incdec_operand (operands[3], GET_MODE (operands[3])))
17516 || (!TARGET_FUSE_CMP_AND_BRANCH
17517 && INTVAL (operands[3]) == 128))
17518 && ix86_match_ccmode (insn, CCGCmode)
17519 && peep2_reg_dead_p (1, operands[2])"
17520 [(parallel [(set (match_dup 0)
17521 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17522 (clobber (match_dup 2))])])
17524 ;; Convert imul by three, five and nine into lea
17527 [(set (match_operand:SWI48 0 "register_operand" "")
17528 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17529 (match_operand:SWI48 2 "const359_operand" "")))
17530 (clobber (reg:CC FLAGS_REG))])]
17531 "!TARGET_PARTIAL_REG_STALL
17532 || <MODE>mode == SImode
17533 || optimize_function_for_size_p (cfun)"
17534 [(set (match_dup 0)
17535 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17537 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17541 [(set (match_operand:SWI48 0 "register_operand" "")
17542 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17543 (match_operand:SWI48 2 "const359_operand" "")))
17544 (clobber (reg:CC FLAGS_REG))])]
17545 "optimize_insn_for_speed_p ()
17546 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17547 [(set (match_dup 0) (match_dup 1))
17549 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17551 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17553 ;; imul $32bit_imm, mem, reg is vector decoded, while
17554 ;; imul $32bit_imm, reg, reg is direct decoded.
17556 [(match_scratch:SWI48 3 "r")
17557 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17558 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17559 (match_operand:SWI48 2 "immediate_operand" "")))
17560 (clobber (reg:CC FLAGS_REG))])]
17561 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17562 && !satisfies_constraint_K (operands[2])"
17563 [(set (match_dup 3) (match_dup 1))
17564 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17565 (clobber (reg:CC FLAGS_REG))])])
17568 [(match_scratch:SI 3 "r")
17569 (parallel [(set (match_operand:DI 0 "register_operand" "")
17571 (mult:SI (match_operand:SI 1 "memory_operand" "")
17572 (match_operand:SI 2 "immediate_operand" ""))))
17573 (clobber (reg:CC FLAGS_REG))])]
17575 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17576 && !satisfies_constraint_K (operands[2])"
17577 [(set (match_dup 3) (match_dup 1))
17578 (parallel [(set (match_dup 0)
17579 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17580 (clobber (reg:CC FLAGS_REG))])])
17582 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17583 ;; Convert it into imul reg, reg
17584 ;; It would be better to force assembler to encode instruction using long
17585 ;; immediate, but there is apparently no way to do so.
17587 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17589 (match_operand:SWI248 1 "nonimmediate_operand" "")
17590 (match_operand:SWI248 2 "const_int_operand" "")))
17591 (clobber (reg:CC FLAGS_REG))])
17592 (match_scratch:SWI248 3 "r")]
17593 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17594 && satisfies_constraint_K (operands[2])"
17595 [(set (match_dup 3) (match_dup 2))
17596 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17597 (clobber (reg:CC FLAGS_REG))])]
17599 if (!rtx_equal_p (operands[0], operands[1]))
17600 emit_move_insn (operands[0], operands[1]);
17603 ;; After splitting up read-modify operations, array accesses with memory
17604 ;; operands might end up in form:
17606 ;; movl 4(%esp), %edx
17608 ;; instead of pre-splitting:
17610 ;; addl 4(%esp), %eax
17612 ;; movl 4(%esp), %edx
17613 ;; leal (%edx,%eax,4), %eax
17616 [(match_scratch:P 5 "r")
17617 (parallel [(set (match_operand 0 "register_operand" "")
17618 (ashift (match_operand 1 "register_operand" "")
17619 (match_operand 2 "const_int_operand" "")))
17620 (clobber (reg:CC FLAGS_REG))])
17621 (parallel [(set (match_operand 3 "register_operand" "")
17622 (plus (match_dup 0)
17623 (match_operand 4 "x86_64_general_operand" "")))
17624 (clobber (reg:CC FLAGS_REG))])]
17625 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17626 /* Validate MODE for lea. */
17627 && ((!TARGET_PARTIAL_REG_STALL
17628 && (GET_MODE (operands[0]) == QImode
17629 || GET_MODE (operands[0]) == HImode))
17630 || GET_MODE (operands[0]) == SImode
17631 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17632 && (rtx_equal_p (operands[0], operands[3])
17633 || peep2_reg_dead_p (2, operands[0]))
17634 /* We reorder load and the shift. */
17635 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17636 [(set (match_dup 5) (match_dup 4))
17637 (set (match_dup 0) (match_dup 1))]
17639 enum machine_mode op1mode = GET_MODE (operands[1]);
17640 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17641 int scale = 1 << INTVAL (operands[2]);
17642 rtx index = gen_lowpart (Pmode, operands[1]);
17643 rtx base = gen_lowpart (Pmode, operands[5]);
17644 rtx dest = gen_lowpart (mode, operands[3]);
17646 operands[1] = gen_rtx_PLUS (Pmode, base,
17647 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17648 operands[5] = base;
17650 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17651 if (op1mode != Pmode)
17652 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17653 operands[0] = dest;
17656 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17657 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17658 ;; caught for use by garbage collectors and the like. Using an insn that
17659 ;; maps to SIGILL makes it more likely the program will rightfully die.
17660 ;; Keeping with tradition, "6" is in honor of #UD.
17661 (define_insn "trap"
17662 [(trap_if (const_int 1) (const_int 6))]
17664 { return ASM_SHORT "0x0b0f"; }
17665 [(set_attr "length" "2")])
17667 (define_expand "prefetch"
17668 [(prefetch (match_operand 0 "address_operand" "")
17669 (match_operand:SI 1 "const_int_operand" "")
17670 (match_operand:SI 2 "const_int_operand" ""))]
17671 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17673 int rw = INTVAL (operands[1]);
17674 int locality = INTVAL (operands[2]);
17676 gcc_assert (rw == 0 || rw == 1);
17677 gcc_assert (IN_RANGE (locality, 0, 3));
17679 if (TARGET_PREFETCHW && rw)
17680 operands[2] = GEN_INT (3);
17681 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17682 supported by SSE counterpart or the SSE prefetch is not available
17683 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17685 else if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17686 operands[2] = GEN_INT (3);
17688 operands[1] = const0_rtx;
17691 (define_insn "*prefetch_sse"
17692 [(prefetch (match_operand 0 "address_operand" "p")
17694 (match_operand:SI 1 "const_int_operand" ""))]
17695 "TARGET_PREFETCH_SSE"
17697 static const char * const patterns[4] = {
17698 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17701 int locality = INTVAL (operands[1]);
17702 gcc_assert (IN_RANGE (locality, 0, 3));
17704 return patterns[locality];
17706 [(set_attr "type" "sse")
17707 (set_attr "atom_sse_attr" "prefetch")
17708 (set (attr "length_address")
17709 (symbol_ref "memory_address_length (operands[0], false)"))
17710 (set_attr "memory" "none")])
17712 (define_insn "*prefetch_3dnow"
17713 [(prefetch (match_operand 0 "address_operand" "p")
17714 (match_operand:SI 1 "const_int_operand" "n")
17716 "TARGET_3DNOW || TARGET_PREFETCHW"
17718 if (INTVAL (operands[1]) == 0)
17719 return "prefetch\t%a0";
17721 return "prefetchw\t%a0";
17723 [(set_attr "type" "mmx")
17724 (set (attr "length_address")
17725 (symbol_ref "memory_address_length (operands[0], false)"))
17726 (set_attr "memory" "none")])
17728 (define_expand "stack_protect_set"
17729 [(match_operand 0 "memory_operand" "")
17730 (match_operand 1 "memory_operand" "")]
17731 "!TARGET_HAS_BIONIC"
17733 rtx (*insn)(rtx, rtx);
17735 #ifdef TARGET_THREAD_SSP_OFFSET
17736 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17737 insn = (TARGET_LP64
17738 ? gen_stack_tls_protect_set_di
17739 : gen_stack_tls_protect_set_si);
17741 insn = (TARGET_LP64
17742 ? gen_stack_protect_set_di
17743 : gen_stack_protect_set_si);
17746 emit_insn (insn (operands[0], operands[1]));
17750 (define_insn "stack_protect_set_<mode>"
17751 [(set (match_operand:PTR 0 "memory_operand" "=m")
17752 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17754 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17755 (clobber (reg:CC FLAGS_REG))]
17756 "!TARGET_HAS_BIONIC"
17757 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17758 [(set_attr "type" "multi")])
17760 (define_insn "stack_tls_protect_set_<mode>"
17761 [(set (match_operand:PTR 0 "memory_operand" "=m")
17762 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17763 UNSPEC_SP_TLS_SET))
17764 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17765 (clobber (reg:CC FLAGS_REG))]
17767 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17768 [(set_attr "type" "multi")])
17770 (define_expand "stack_protect_test"
17771 [(match_operand 0 "memory_operand" "")
17772 (match_operand 1 "memory_operand" "")
17773 (match_operand 2 "" "")]
17774 "!TARGET_HAS_BIONIC"
17776 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17778 rtx (*insn)(rtx, rtx, rtx);
17780 #ifdef TARGET_THREAD_SSP_OFFSET
17781 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17782 insn = (TARGET_LP64
17783 ? gen_stack_tls_protect_test_di
17784 : gen_stack_tls_protect_test_si);
17786 insn = (TARGET_LP64
17787 ? gen_stack_protect_test_di
17788 : gen_stack_protect_test_si);
17791 emit_insn (insn (flags, operands[0], operands[1]));
17793 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17794 flags, const0_rtx, operands[2]));
17798 (define_insn "stack_protect_test_<mode>"
17799 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17800 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17801 (match_operand:PTR 2 "memory_operand" "m")]
17803 (clobber (match_scratch:PTR 3 "=&r"))]
17804 "!TARGET_HAS_BIONIC"
17805 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17806 [(set_attr "type" "multi")])
17808 (define_insn "stack_tls_protect_test_<mode>"
17809 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17810 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17811 (match_operand:PTR 2 "const_int_operand" "i")]
17812 UNSPEC_SP_TLS_TEST))
17813 (clobber (match_scratch:PTR 3 "=r"))]
17815 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17816 [(set_attr "type" "multi")])
17818 (define_insn "sse4_2_crc32<mode>"
17819 [(set (match_operand:SI 0 "register_operand" "=r")
17821 [(match_operand:SI 1 "register_operand" "0")
17822 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17824 "TARGET_SSE4_2 || TARGET_CRC32"
17825 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17826 [(set_attr "type" "sselog1")
17827 (set_attr "prefix_rep" "1")
17828 (set_attr "prefix_extra" "1")
17829 (set (attr "prefix_data16")
17830 (if_then_else (match_operand:HI 2 "" "")
17832 (const_string "*")))
17833 (set (attr "prefix_rex")
17834 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17836 (const_string "*")))
17837 (set_attr "mode" "SI")])
17839 (define_insn "sse4_2_crc32di"
17840 [(set (match_operand:DI 0 "register_operand" "=r")
17842 [(match_operand:DI 1 "register_operand" "0")
17843 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17845 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17846 "crc32{q}\t{%2, %0|%0, %2}"
17847 [(set_attr "type" "sselog1")
17848 (set_attr "prefix_rep" "1")
17849 (set_attr "prefix_extra" "1")
17850 (set_attr "mode" "DI")])
17852 (define_expand "rdpmc"
17853 [(match_operand:DI 0 "register_operand" "")
17854 (match_operand:SI 1 "register_operand" "")]
17857 rtx reg = gen_reg_rtx (DImode);
17860 /* Force operand 1 into ECX. */
17861 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17862 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17863 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17868 rtvec vec = rtvec_alloc (2);
17869 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17870 rtx upper = gen_reg_rtx (DImode);
17871 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17872 gen_rtvec (1, const0_rtx),
17874 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17875 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17877 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17878 NULL, 1, OPTAB_DIRECT);
17879 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17883 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17884 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17888 (define_insn "*rdpmc"
17889 [(set (match_operand:DI 0 "register_operand" "=A")
17890 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17894 [(set_attr "type" "other")
17895 (set_attr "length" "2")])
17897 (define_insn "*rdpmc_rex64"
17898 [(set (match_operand:DI 0 "register_operand" "=a")
17899 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17901 (set (match_operand:DI 1 "register_operand" "=d")
17902 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17905 [(set_attr "type" "other")
17906 (set_attr "length" "2")])
17908 (define_expand "rdtsc"
17909 [(set (match_operand:DI 0 "register_operand" "")
17910 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17915 rtvec vec = rtvec_alloc (2);
17916 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17917 rtx upper = gen_reg_rtx (DImode);
17918 rtx lower = gen_reg_rtx (DImode);
17919 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17920 gen_rtvec (1, const0_rtx),
17922 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17923 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17925 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17926 NULL, 1, OPTAB_DIRECT);
17927 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17929 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17934 (define_insn "*rdtsc"
17935 [(set (match_operand:DI 0 "register_operand" "=A")
17936 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17939 [(set_attr "type" "other")
17940 (set_attr "length" "2")])
17942 (define_insn "*rdtsc_rex64"
17943 [(set (match_operand:DI 0 "register_operand" "=a")
17944 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17945 (set (match_operand:DI 1 "register_operand" "=d")
17946 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17949 [(set_attr "type" "other")
17950 (set_attr "length" "2")])
17952 (define_expand "rdtscp"
17953 [(match_operand:DI 0 "register_operand" "")
17954 (match_operand:SI 1 "memory_operand" "")]
17957 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17958 gen_rtvec (1, const0_rtx),
17960 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17961 gen_rtvec (1, const0_rtx),
17963 rtx reg = gen_reg_rtx (DImode);
17964 rtx tmp = gen_reg_rtx (SImode);
17968 rtvec vec = rtvec_alloc (3);
17969 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17970 rtx upper = gen_reg_rtx (DImode);
17971 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17972 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17973 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17975 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17976 NULL, 1, OPTAB_DIRECT);
17977 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17982 rtvec vec = rtvec_alloc (2);
17983 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17984 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17985 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17988 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17989 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17993 (define_insn "*rdtscp"
17994 [(set (match_operand:DI 0 "register_operand" "=A")
17995 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17996 (set (match_operand:SI 1 "register_operand" "=c")
17997 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18000 [(set_attr "type" "other")
18001 (set_attr "length" "3")])
18003 (define_insn "*rdtscp_rex64"
18004 [(set (match_operand:DI 0 "register_operand" "=a")
18005 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18006 (set (match_operand:DI 1 "register_operand" "=d")
18007 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18008 (set (match_operand:SI 2 "register_operand" "=c")
18009 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18012 [(set_attr "type" "other")
18013 (set_attr "length" "3")])
18015 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18017 ;; LWP instructions
18019 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18021 (define_expand "lwp_llwpcb"
18022 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18023 UNSPECV_LLWP_INTRINSIC)]
18026 (define_insn "*lwp_llwpcb<mode>1"
18027 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18028 UNSPECV_LLWP_INTRINSIC)]
18031 [(set_attr "type" "lwp")
18032 (set_attr "mode" "<MODE>")
18033 (set_attr "length" "5")])
18035 (define_expand "lwp_slwpcb"
18036 [(set (match_operand 0 "register_operand" "=r")
18037 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18042 insn = (TARGET_64BIT
18044 : gen_lwp_slwpcbsi);
18046 emit_insn (insn (operands[0]));
18050 (define_insn "lwp_slwpcb<mode>"
18051 [(set (match_operand:P 0 "register_operand" "=r")
18052 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18055 [(set_attr "type" "lwp")
18056 (set_attr "mode" "<MODE>")
18057 (set_attr "length" "5")])
18059 (define_expand "lwp_lwpval<mode>3"
18060 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18061 (match_operand:SI 2 "nonimmediate_operand" "rm")
18062 (match_operand:SI 3 "const_int_operand" "i")]
18063 UNSPECV_LWPVAL_INTRINSIC)]
18065 ;; Avoid unused variable warning.
18066 "(void) operands[0];")
18068 (define_insn "*lwp_lwpval<mode>3_1"
18069 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18070 (match_operand:SI 1 "nonimmediate_operand" "rm")
18071 (match_operand:SI 2 "const_int_operand" "i")]
18072 UNSPECV_LWPVAL_INTRINSIC)]
18074 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18075 [(set_attr "type" "lwp")
18076 (set_attr "mode" "<MODE>")
18077 (set (attr "length")
18078 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18080 (define_expand "lwp_lwpins<mode>3"
18081 [(set (reg:CCC FLAGS_REG)
18082 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18083 (match_operand:SI 2 "nonimmediate_operand" "rm")
18084 (match_operand:SI 3 "const_int_operand" "i")]
18085 UNSPECV_LWPINS_INTRINSIC))
18086 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18087 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18090 (define_insn "*lwp_lwpins<mode>3_1"
18091 [(set (reg:CCC FLAGS_REG)
18092 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18093 (match_operand:SI 1 "nonimmediate_operand" "rm")
18094 (match_operand:SI 2 "const_int_operand" "i")]
18095 UNSPECV_LWPINS_INTRINSIC))]
18097 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18098 [(set_attr "type" "lwp")
18099 (set_attr "mode" "<MODE>")
18100 (set (attr "length")
18101 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18103 (define_insn "rdfsbase<mode>"
18104 [(set (match_operand:SWI48 0 "register_operand" "=r")
18105 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18106 "TARGET_64BIT && TARGET_FSGSBASE"
18108 [(set_attr "type" "other")
18109 (set_attr "prefix_extra" "2")])
18111 (define_insn "rdgsbase<mode>"
18112 [(set (match_operand:SWI48 0 "register_operand" "=r")
18113 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18114 "TARGET_64BIT && TARGET_FSGSBASE"
18116 [(set_attr "type" "other")
18117 (set_attr "prefix_extra" "2")])
18119 (define_insn "wrfsbase<mode>"
18120 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18122 "TARGET_64BIT && TARGET_FSGSBASE"
18124 [(set_attr "type" "other")
18125 (set_attr "prefix_extra" "2")])
18127 (define_insn "wrgsbase<mode>"
18128 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18130 "TARGET_64BIT && TARGET_FSGSBASE"
18132 [(set_attr "type" "other")
18133 (set_attr "prefix_extra" "2")])
18135 (define_insn "rdrand<mode>_1"
18136 [(set (match_operand:SWI248 0 "register_operand" "=r")
18137 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18138 (set (reg:CCC FLAGS_REG)
18139 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18142 [(set_attr "type" "other")
18143 (set_attr "prefix_extra" "1")])
18145 (define_expand "pause"
18146 [(set (match_dup 0)
18147 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18150 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18151 MEM_VOLATILE_P (operands[0]) = 1;
18154 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18155 ;; They have the same encoding.
18156 (define_insn "*pause"
18157 [(set (match_operand:BLK 0 "" "")
18158 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18161 [(set_attr "length" "2")
18162 (set_attr "memory" "unknown")])
18166 (include "sync.md")